280 lines
8.4 KiB
Plaintext
280 lines
8.4 KiB
Plaintext
/* DO NOT EDIT THIS FILE */
|
|
/* This file is autogenerated by the text-database code generator */
|
|
|
|
#include <fonts/GeneratedFont.hpp>
|
|
#include <math.h>
|
|
|
|
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<const GlyphNode*>(&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
|