GFX Develop Branch
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <fonts/GeneratedFont.hpp>
|
||||
#include <math.h>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
@ -56,4 +57,223 @@ const GlyphNode* FusedFont::getGlyph(Unicode::UnicodeChar unicode, const uint8_t
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user