/* DO NOT EDIT THIS FILE */ /* This file is autogenerated by the text-database code generator */ #include #include namespace touchgfx { GeneratedFont::GeneratedFont(const GlyphNode* glyphs, uint16_t numGlyphs, uint16_t height, uint16_t baseline, uint8_t pixAboveTop, uint8_t pixBelowBottom, uint8_t bitsPerPixel, uint8_t byteAlignRow, uint8_t maxLeft, uint8_t maxRight, const uint8_t* const* glyphDataInternalFlash, const KerningNode* kerningList, const Unicode::UnicodeChar fallbackChar, const Unicode::UnicodeChar ellipsisChar, const uint16_t* const gsubData, const FontContextualFormsTable* formsTable) : ConstFont(glyphs, numGlyphs, height, baseline, pixAboveTop, pixBelowBottom, bitsPerPixel, byteAlignRow, maxLeft, maxRight, fallbackChar, ellipsisChar), glyphData(glyphDataInternalFlash), kerningData(kerningList), gsubTable(gsubData), arabicTable(formsTable) { } const uint8_t* GeneratedFont::getPixelData(const GlyphNode* glyph) const { const uint8_t* const* table = (const uint8_t* const*)glyphData; return &(table[glyph->unicode / 2048][glyph->dataOffset]); } int8_t GeneratedFont::getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const { if (!glyph || glyph->kerningTableSize == 0) { return 0; } const KerningNode* kerndata = kerningData + glyph->kerningTablePos(); for (uint16_t i = glyph->kerningTableSize; i > 0; i--, kerndata++) { if (prevChar == kerndata->unicodePrevChar) { return kerndata->distance; } if (prevChar < kerndata->unicodePrevChar) { break; } } return 0; } const GlyphNode* FusedFont::getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const { if (unicode < 0xAC00 || unicode > 0xD7A3) { return GeneratedFont::getGlyph(unicode, pixelData, bitsPerPixel); } else { fusedNode.unicode = unicode; bitsPerPixel = 1; pixelData = 0; return const_cast(&fusedNode); } } GlyphNode GeneratedVectorFont::glyphNode; // Static member GeneratedVectorFont::GeneratedVectorFont(uint16_t baseline, float scale, const VectorFontNode* vectorGlyphs, const VectorFontData& fontData, const uint16_t* const* glyphData, const VectorKerningNode* kerning, const uint16_t* const gsubData, const FontContextualFormsTable* formsTable) : Font((int)ceilf((fontData.maxBelowBottom + fontData.baselineHeight) * scale), baseline, (uint8_t)ceilf(fontData.maxAboveTop * scale), (uint8_t)ceilf(fontData.maxBelowBottom * scale), 0 /*bitsPerPixel*/, 0 /*byteAlignRow*/, (uint8_t)ceilf(fontData.maxLeft * scale), (uint8_t)ceilf(fontData.maxRight * scale), fontData.fallbackChar, fontData.ellipsisChar), scaleFactor(scale), vectorNodes(vectorGlyphs), vectorTable(glyphData), kerningTable(kerning), arabicTable(formsTable), numberOfGlyphs(fontData.numberOfGlyphs) { if (gsubData[0] != 0) { gsubTable = gsubData; } else { gsubTable = 0; } } const GlyphNode* GeneratedVectorFont::getGlyph(Unicode::UnicodeChar unicode) const { const VectorFontNode* const node = find(unicode); if (node == 0) { return 0; } else { return getGlyphNode(node); } } const GlyphNode* GeneratedVectorFont::getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const { const VectorFontNode* const node = find(unicode); if (node == 0) { return 0; } else { const uint16_t* contourData = &(vectorTable[unicode / 2048][node->dataOffset]); pixelData = (const uint8_t*)contourData; bitsPerPixel = 0xFF; return getGlyphNode(node); } } const GlyphNode* GeneratedVectorFont::getGlyphNode(const VectorFontNode* node) const { glyphNode.dataOffset = 0; uint8_t flags = 0; //Convert data from VectorFontNode to glyphNode using scaleFactor glyphNode.unicode = node->unicode; const int width = (node->width == 0) ? 0 : ((int)ceilf(node->width * scaleFactor) + 1); glyphNode._width = width; // Save low 8 bit // Set flags bits for values above 8 bit if (width > 255) { flags |= GLYPH_DATA_WIDTH_BIT8; } const int height = (int)ceilf(node->height * scaleFactor); glyphNode._height = height; if (height > 255) { flags |= GLYPH_DATA_HEIGHT_BIT8; } const int top = (int)ceilf(node->top * scaleFactor); glyphNode._top = top; if (top > 255) { flags |= ((top & 0x300) >> 3); // GLYPH_DATA_TOP_BIT8 + 9 } const int left = (int)(node->left * scaleFactor); glyphNode.left = left; const int advance = (int)(node->advance * scaleFactor + 0.5f); glyphNode._advance = advance; if (advance > 255) { flags |= GLYPH_DATA_ADVANCE_BIT8; } glyphNode._kerningTablePos = (uint8_t)node->kerningTablePos; if (node->kerningTablePos > 255) { flags |= (node->kerningTablePos >> 8) & GLYPH_DATA_KERNINGTABLEPOS_BIT8_10; } glyphNode.kerningTableSize = node->kerningTableSize; glyphNode.flags = flags; return &glyphNode; } int8_t GeneratedVectorFont::getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const { if (!glyph || glyph->kerningTableSize == 0) { return 0; } const VectorKerningNode* kerndata = kerningTable + glyph->kerningTablePos(); for (uint16_t i = glyph->kerningTableSize; i > 0; i--, kerndata++) { if (prevChar == kerndata->unicodePrevChar) { const float scaledDistance = kerndata->distance * scaleFactor; return (int)(scaledDistance >= 0.0f ? (scaledDistance + 0.5f) : (scaledDistance - 0.5f)); } if (prevChar < kerndata->unicodePrevChar) { break; } } return 0; } const VectorFontNode* GeneratedVectorFont::find(Unicode::UnicodeChar unicode) const { // Some fonts does not have a glyphList. Cannot be searched... if (vectorNodes == 0) { return 0; } int32_t min = 0; int32_t max = numberOfGlyphs - 1; int32_t mid = min + (unicode - vectorNodes[min].unicode); // Linear up from [min].unicode if (mid < min) { // Unicode < [min].unicode => not found return (VectorFontNode*)0; } if (mid > max) { // Linear up ends too high mid = max - (vectorNodes[max].unicode - unicode); // Linear down from [max].unicode if (mid > max) { // Unicode > [max].unicode => not found return (VectorFontNode*)0; } if (mid < min) { // Linear down ends too low, take the middle element mid = (min + max) / 2; } } while (min <= max) { const Unicode::UnicodeChar midUnicode = vectorNodes[mid].unicode; if (unicode == midUnicode) { // Found at [mid] return vectorNodes + mid; } if (unicode < midUnicode) { // Unicode is in lower half max = mid - 1; if (max < min) { // Range is empty => not found break; } // We adjusted max, try linear down from [max].unicode mid = max - (vectorNodes[max].unicode - unicode); if (mid > max) { // Unicode > [max].unicode => not found break; } if (mid < min) { // Linear down ends too low, take the middle element mid = (min + max) / 2; } } else { // Unicode is in upper half min = mid + 1; if (min > max) { // Range is empty => not found break; } // We adjusted min, try linear up from [min].unicode mid = min + (unicode - vectorNodes[min].unicode); if (mid < min) { // Unicode < [min].unicode => not found break; } if (mid > max) { // Linear up ends too high, take the middle element mid = (min + max) / 2; } } } return (VectorFontNode*)0; } } // namespace touchgfx