Add Inter Fonts
This commit is contained in:
@ -0,0 +1,28 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <fonts/ApplicationFontProvider.hpp>
|
||||
#include <fonts/GeneratedFont.hpp>
|
||||
#include <texts/TypedTextDatabase.hpp>
|
||||
<% if save_flashreader? %>
|
||||
|
||||
touchgfx::FlashDataReader* ApplicationFontProvider::fontFlashReader = 0;
|
||||
<% end %>
|
||||
|
||||
touchgfx::Font* ApplicationFontProvider::getFont(touchgfx::FontId typography)
|
||||
{
|
||||
<% if @typographies.empty? %>
|
||||
return 0;
|
||||
<% else %>
|
||||
switch (typography)
|
||||
{
|
||||
<% @typographies.each_with_index do |typography, index| %>
|
||||
case Typography::<%= typography.name.upcase %>:
|
||||
// <%= typography.cpp_name %>_<%= typography.font_size %>_<%= typography.bpp %>bpp
|
||||
return const_cast<touchgfx::Font*>(TypedTextDatabase::getFonts()[<%= get_font_index(index) %>]);
|
||||
<% end %>
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
<% end %>
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_APPLICATIONFONTPROVIDER_HPP
|
||||
#define TOUCHGFX_APPLICATIONFONTPROVIDER_HPP
|
||||
|
||||
#include <touchgfx/FontManager.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
class FlashDataReader;
|
||||
}
|
||||
|
||||
struct Typography
|
||||
{
|
||||
<% @typographies.each_with_index do |typography, index| %>
|
||||
static const touchgfx::FontId <%= typography.name.upcase %> = <%= index %>;
|
||||
<% end %>
|
||||
};
|
||||
|
||||
struct TypographyFontIndex
|
||||
{
|
||||
<% @typographies.each_with_index do |typography, index| %>
|
||||
static const touchgfx::FontId <%= typography.name.upcase %> = <%= get_font_index(index) %>; <%= get_font_comment_space(index) %>// <%= get_font_comment(index) %>
|
||||
<% end %>
|
||||
static const uint16_t NUMBER_OF_FONTS = <%= get_max_font_index %>;
|
||||
};
|
||||
|
||||
class ApplicationFontProvider : public touchgfx::FontProvider
|
||||
{
|
||||
public:
|
||||
virtual touchgfx::Font* getFont(touchgfx::FontId typography);
|
||||
|
||||
<% if save_flashreader? %>
|
||||
static void setFlashReader(touchgfx::FlashDataReader* flashReader)
|
||||
{
|
||||
fontFlashReader = flashReader;
|
||||
}
|
||||
|
||||
static touchgfx::FlashDataReader* getFlashReader()
|
||||
{
|
||||
return fontFlashReader;
|
||||
}
|
||||
|
||||
private:
|
||||
static touchgfx::FlashDataReader* fontFlashReader;
|
||||
<% else %>
|
||||
static void setFlashReader(touchgfx::FlashDataReader* /*flashReader*/)
|
||||
{
|
||||
}
|
||||
|
||||
static touchgfx::FlashDataReader* getFlashReader()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
<% end %>
|
||||
};
|
||||
|
||||
#endif // TOUCHGFX_APPLICATIONFONTPROVIDER_HPP
|
||||
@ -0,0 +1,55 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <fonts/CachedFont.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
const uint8_t* CachedFont::getPixelData(const GlyphNode* glyph) const
|
||||
{
|
||||
// If glyph is cached, then data is present just after the GlyphNode
|
||||
if (FontCache::isCached(glyph))
|
||||
{
|
||||
const uint8_t* data = FontCache::getPixelData(glyph);
|
||||
return data;
|
||||
}
|
||||
return flashFont->getPixelData(glyph);
|
||||
}
|
||||
|
||||
const GlyphNode* CachedFont::getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const
|
||||
{
|
||||
// Look first in internal flash font
|
||||
const GlyphNode* n = flashFont->find(unicode);
|
||||
|
||||
if ((n == 0) && (cache != 0))
|
||||
{
|
||||
// Now look in FontCache table
|
||||
n = cache->getGlyph(unicode, fontId);
|
||||
}
|
||||
|
||||
// Revert to normal behaviour if still not found
|
||||
if (n == 0 && unicode != 0 && unicode != '\n')
|
||||
{
|
||||
Unicode::UnicodeChar fallbackChar = flashFont->getFallbackChar();
|
||||
n = flashFont->find(fallbackChar);
|
||||
if (n == 0)
|
||||
{
|
||||
n = cache->getGlyph(fallbackChar, fontId);
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 0)
|
||||
{
|
||||
pixelData = getPixelData(n);
|
||||
bitsPerPixel = getBitsPerPixel();
|
||||
return n;
|
||||
}
|
||||
return (const GlyphNode*)0;
|
||||
}
|
||||
|
||||
int8_t CachedFont::getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const
|
||||
{
|
||||
// Kerning is not supported by Font Caching
|
||||
return 0;
|
||||
}
|
||||
} // namespace touchgfx
|
||||
@ -0,0 +1,93 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_CACHEDFONT_HPP
|
||||
#define TOUCHGFX_CACHEDFONT_HPP
|
||||
|
||||
#include <fonts/FontCache.hpp>
|
||||
#include <fonts/GeneratedFont.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
class CachedFont : public GeneratedFont
|
||||
{
|
||||
public:
|
||||
CachedFont(const struct touchgfx::BinaryFontData* data, FontId id, FontCache* _cache, const GeneratedFont* _flashFont)
|
||||
: GeneratedFont(0, // GlyphNode*
|
||||
data->numberOfGlyphs,
|
||||
data->fontHeight,
|
||||
data->baseline,
|
||||
data->pixAboveTop,
|
||||
data->pixBelowBottom,
|
||||
data->bitsPerPixel,
|
||||
data->byteAlignRow,
|
||||
data->maxLeft,
|
||||
data->maxRight,
|
||||
0, // glyphDataPointer
|
||||
0, // Kerning table not used for cached font
|
||||
data->fallbackChar,
|
||||
data->ellipsisChar,
|
||||
0, // lsubTablePointer
|
||||
0), // contextualFormsPointer
|
||||
fontId(id),
|
||||
cache(_cache),
|
||||
flashFont(_flashFont)
|
||||
{
|
||||
}
|
||||
|
||||
CachedFont()
|
||||
: GeneratedFont()
|
||||
{
|
||||
}
|
||||
|
||||
using GeneratedFont::getGlyph;
|
||||
|
||||
virtual const GlyphNode* getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const;
|
||||
|
||||
virtual const uint8_t* getPixelData(const GlyphNode* glyph) const;
|
||||
|
||||
virtual int8_t getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const;
|
||||
|
||||
void setFontCache(FontCache& cache);
|
||||
|
||||
FontId getFontId() const
|
||||
{
|
||||
return fontId;
|
||||
}
|
||||
|
||||
virtual const uint16_t* getGSUBTable() const
|
||||
{
|
||||
if (gsubTable != 0)
|
||||
{
|
||||
return gsubTable;
|
||||
}
|
||||
return flashFont->getGSUBTable();
|
||||
}
|
||||
|
||||
virtual void setGSUBTable(const uint16_t* table)
|
||||
{
|
||||
gsubTable = table;
|
||||
}
|
||||
|
||||
virtual const FontContextualFormsTable* getContextualFormsTable() const
|
||||
{
|
||||
if (arabicTable != 0)
|
||||
{
|
||||
return arabicTable;
|
||||
}
|
||||
return flashFont->getContextualFormsTable();
|
||||
}
|
||||
|
||||
virtual void setContextualFormsTable(const FontContextualFormsTable* table)
|
||||
{
|
||||
arabicTable = table;
|
||||
}
|
||||
|
||||
private:
|
||||
FontId fontId;
|
||||
FontCache* cache;
|
||||
const GeneratedFont* flashFont;
|
||||
};
|
||||
} // namespace touchgfx
|
||||
|
||||
#endif // TOUCHGFX_CACHEDFONT_HPP
|
||||
@ -0,0 +1,424 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <cstring>
|
||||
#include <touchgfx/TextProvider.hpp>
|
||||
#include <touchgfx/Utils.hpp>
|
||||
#include <fonts/CachedFont.hpp>
|
||||
#include <fonts/FontCache.hpp>
|
||||
#include <texts/TypedTextDatabase.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
FontCache::FontCache()
|
||||
: memorySize(0), memory(0), top(0), gsubStart(0), reader(0)
|
||||
{
|
||||
}
|
||||
|
||||
void FontCache::clear(bool keepGsubOrContextTable /* = false */)
|
||||
{
|
||||
memset(fontTable, 0, sizeof(fontTable));
|
||||
|
||||
// Top is beginning of memory, no glyphs are cached yet
|
||||
top = memory;
|
||||
|
||||
if (!keepGsubOrContextTable)
|
||||
{
|
||||
// gsubStart points to end of memory (nothing loaded yet)
|
||||
gsubStart = memory + memorySize;
|
||||
|
||||
// Round down to 32bit address
|
||||
gsubStart = (uint8_t*)((uintptr_t)gsubStart & ~(sizeof(void*) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
void FontCache::setMemory(uint8_t* _memory, uint32_t size)
|
||||
{
|
||||
memory = _memory;
|
||||
memorySize = size;
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void FontCache::setReader(FontDataReader* _reader)
|
||||
{
|
||||
reader = _reader;
|
||||
}
|
||||
|
||||
const GlyphNode* FontCache::getGlyph(Unicode::UnicodeChar unicode, FontId font) const
|
||||
{
|
||||
GlyphNode* g = (GlyphNode*)fontTable[font].first;
|
||||
while (g)
|
||||
{
|
||||
if (g->unicode == unicode)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
GlyphNode** next = (GlyphNode**)((uint8_t*)g + SizeGlyphNode);
|
||||
g = *next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FontCache::open()
|
||||
{
|
||||
if (reader)
|
||||
{
|
||||
reader->open();
|
||||
}
|
||||
}
|
||||
|
||||
void FontCache::close()
|
||||
{
|
||||
if (reader)
|
||||
{
|
||||
reader->close();
|
||||
}
|
||||
}
|
||||
|
||||
void FontCache::initializeCachedFont(TypedText t, CachedFont* font, bool loadGsubOrContextTable /*= false*/)
|
||||
{
|
||||
// Get font index from typed text
|
||||
FontId fontId = t.getFontId();
|
||||
// Reset to start of file
|
||||
open();
|
||||
setPosition(0);
|
||||
|
||||
assert(sizeof(touchgfx::BinaryFontData) < MAX_BUFFER_SIZE);
|
||||
readData(buffer, sizeof(touchgfx::BinaryFontData));
|
||||
const struct touchgfx::BinaryFontData* binaryFontData = reinterpret_cast<const struct touchgfx::BinaryFontData*>(buffer);
|
||||
|
||||
const Font** flashFonts = TypedTextDatabase::getFonts();
|
||||
const GeneratedFont* flashFont = static_cast<const GeneratedFont*>(flashFonts[fontId]);
|
||||
*font = CachedFont(reinterpret_cast<const struct touchgfx::BinaryFontData*>(buffer), fontId, this, flashFont);
|
||||
|
||||
if (loadGsubOrContextTable && (binaryFontData->offsetToGSUB != 0))
|
||||
{
|
||||
setPosition(binaryFontData->offsetToGSUB);
|
||||
|
||||
const uint32_t sizeOfGSUB = (binaryFontData->offsetToArabicTable != 0 ? binaryFontData->offsetToArabicTable : binaryFontData->sizeOfFontData) - binaryFontData->offsetToGSUB;
|
||||
|
||||
if (top + sizeOfGSUB < gsubStart) // Room for this GSUB table
|
||||
{
|
||||
// Round down to aligned address
|
||||
uint8_t* const gsubPosition = (uint8_t*)((uintptr_t)(gsubStart - sizeOfGSUB) & ~(sizeof(void*) - 1));
|
||||
readData(gsubPosition, sizeOfGSUB);
|
||||
font->setGSUBTable(reinterpret_cast<uint16_t*>(gsubPosition));
|
||||
gsubStart = gsubPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
font->setGSUBTable(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadGsubOrContextTable && (binaryFontData->offsetToArabicTable != 0))
|
||||
{
|
||||
setPosition(binaryFontData->offsetToArabicTable);
|
||||
|
||||
const uint32_t sizeTableData = binaryFontData->sizeOfFontData - binaryFontData->offsetToArabicTable;
|
||||
|
||||
if (top + sizeTableData + sizeof(FontContextualFormsTable) < gsubStart) // Room for the ContextualFormsTables
|
||||
{
|
||||
// Allocate FontContextualFormsTable first
|
||||
gsubStart -= sizeof(FontContextualFormsTable);
|
||||
// Round down to 32bit address
|
||||
gsubStart = (uint8_t*)((uintptr_t)gsubStart & ~(sizeof(void*) - 1));
|
||||
|
||||
FontContextualFormsTable* table = (FontContextualFormsTable*)gsubStart;
|
||||
font->setContextualFormsTable(table);
|
||||
gsubStart -= sizeTableData;
|
||||
readData(gsubStart, sizeTableData);
|
||||
|
||||
// Set pointers in table
|
||||
const uint16_t* const base = (const uint16_t*)gsubStart;
|
||||
// First elements in binary font are offsets to arrays in 16bit words
|
||||
table->contextualForms4Long = (FontContextualFormsTable::arrayOf5UnicodesPtr)(base + base[0]);
|
||||
table->contextualForms3Long = (FontContextualFormsTable::arrayOf5UnicodesPtr)(base + base[1]);
|
||||
table->contextualForms2Long = (FontContextualFormsTable::arrayOf5UnicodesPtr)(base + base[2]);
|
||||
table->contextualForms0621_063a = (FontContextualFormsTable::arrayOf4UnicodesPtr)(base + base[3]);
|
||||
table->contextualForms0641_064a = (FontContextualFormsTable::arrayOf4UnicodesPtr)(base + base[4]);
|
||||
table->contextualForms06XX = (FontContextualFormsTable::arrayOf5UnicodesPtr)(base + base[5]);
|
||||
table->contextualForms4LongSize = base[6];
|
||||
table->contextualForms3LongSize = base[7];
|
||||
table->contextualForms2LongSize = base[8];
|
||||
table->contextualForms06XXSize = base[9];
|
||||
}
|
||||
else
|
||||
{
|
||||
font->setContextualFormsTable(0);
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
bool FontCache::cacheString(TypedText t, const Unicode::UnicodeChar* string)
|
||||
{
|
||||
open();
|
||||
if (!createSortedString(string))
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
const bool result = cacheSortedString(t);
|
||||
close();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FontCache::cacheLigatures(CachedFont* font, TypedText t, const Unicode::UnicodeChar* string)
|
||||
{
|
||||
open();
|
||||
if (!createSortedLigatures(font, t, string, 0, 0))
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
const bool result = cacheSortedString(t);
|
||||
close();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FontCache::cacheSortedString(TypedText t)
|
||||
{
|
||||
setPosition(8); // Skip font index and size
|
||||
uint32_t glyphNodeOffset;
|
||||
uint32_t dummy;
|
||||
readData(&glyphNodeOffset, sizeof(uint32_t)); // offsetToTable
|
||||
readData(&dummy, sizeof(uint32_t)); // offsetToKerning
|
||||
readData(&glyphDataOffset, sizeof(uint32_t)); // offsetToGlyphs
|
||||
readData(&dummy, sizeof(uint32_t)); // offsetToGlyphs
|
||||
readData(&dummy, sizeof(uint32_t)); // offsetToArabicTable
|
||||
readData(&numGlyphs, sizeof(uint16_t)); // numberOfGlyphs
|
||||
|
||||
FontId fontId = t.getFontId(); // Get font index from typed text
|
||||
bpp = t.getFont()->getBitsPerPixel(); // Get BPP from standard font
|
||||
byteAlignRow = t.getFont()->getByteAlignRow(); // Get ByteAlign from font
|
||||
|
||||
setPosition(glyphNodeOffset); // Go to glyph nodes for font
|
||||
currentFileGlyphNumber = 0;
|
||||
currentFileGlyphNode.unicode = 0; // Force reading of first glyph
|
||||
|
||||
const Unicode::UnicodeChar* string = sortedString;
|
||||
Unicode::UnicodeChar last = 0;
|
||||
GlyphNode* firstNewGlyph = 0;
|
||||
bool outOfMemory = false;
|
||||
while (*string)
|
||||
{
|
||||
Unicode::UnicodeChar ch = *string;
|
||||
if (ch != last)
|
||||
{
|
||||
if (!contains(ch, fontId))
|
||||
{
|
||||
insert(ch, fontId, outOfMemory);
|
||||
if (outOfMemory)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (firstNewGlyph == 0)
|
||||
{
|
||||
firstNewGlyph = (GlyphNode*)fontTable[fontId].last;
|
||||
}
|
||||
}
|
||||
}
|
||||
last = ch;
|
||||
string++;
|
||||
}
|
||||
|
||||
cacheData(firstNewGlyph);
|
||||
return !outOfMemory;
|
||||
}
|
||||
|
||||
bool FontCache::contains(Unicode::UnicodeChar unicode, FontId font) const
|
||||
{
|
||||
GlyphNode* g = (GlyphNode*)fontTable[font].first;
|
||||
while (g)
|
||||
{
|
||||
if (g->unicode == unicode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
GlyphNode** next = (GlyphNode**)((uint8_t*)g + SizeGlyphNode);
|
||||
g = *next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FontCache::insert(Unicode::UnicodeChar unicode, FontId font, bool& outOfMemory)
|
||||
{
|
||||
// Insert new glyphnode and glyph after last for font.
|
||||
uint8_t* oldTop = top;
|
||||
top = copyGlyph(top, unicode, font, outOfMemory);
|
||||
|
||||
if (top == oldTop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (fontTable[font].last == 0)
|
||||
{
|
||||
// First glyph
|
||||
fontTable[font].first = oldTop;
|
||||
fontTable[font].last = oldTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set next pointer of old last glyph
|
||||
uint8_t** old_next = (uint8_t**)(fontTable[font].last + SizeGlyphNode);
|
||||
*old_next = oldTop;
|
||||
|
||||
// Save new glyph as last glyph
|
||||
fontTable[font].last = oldTop;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* FontCache::copyGlyph(uint8_t* top, Unicode::UnicodeChar unicode, FontId font, bool& outOfMemory)
|
||||
{
|
||||
while (currentFileGlyphNumber < numGlyphs && currentFileGlyphNode.unicode < unicode)
|
||||
{
|
||||
readData(¤tFileGlyphNode, sizeof(GlyphNode));
|
||||
currentFileGlyphNumber++;
|
||||
}
|
||||
if (currentFileGlyphNode.unicode != unicode)
|
||||
{
|
||||
// GlyphNode not found
|
||||
return top;
|
||||
}
|
||||
|
||||
// GlyphNode found
|
||||
uint32_t glyphSize = getGlyphSize(¤tFileGlyphNode);
|
||||
const int alignment = sizeof(void*);
|
||||
glyphSize = (glyphSize + (alignment - 1)) & ~(alignment - 1);
|
||||
uint32_t requiredMem = SizeGlyphNode + sizeof(void*) + glyphSize; // GlyphNode + next ptr + glyph
|
||||
|
||||
// Is space available before sortedString
|
||||
if (top + requiredMem > (uint8_t*)sortedString)
|
||||
{
|
||||
outOfMemory = true;
|
||||
return top;
|
||||
}
|
||||
|
||||
*(GlyphNode*)top = currentFileGlyphNode;
|
||||
|
||||
// Clear next pointer
|
||||
uint8_t** next = (uint8_t**)(top + SizeGlyphNode);
|
||||
*next = 0;
|
||||
top += requiredMem;
|
||||
return top;
|
||||
}
|
||||
|
||||
void FontCache::cacheData(GlyphNode* first)
|
||||
{
|
||||
GlyphNode* gn = first;
|
||||
while (gn)
|
||||
{
|
||||
uint8_t* p = (uint8_t*)gn;
|
||||
if (gn->dataOffset != 0xFFFFFFFF)
|
||||
{
|
||||
p += SizeGlyphNode;
|
||||
// Next pointer
|
||||
p += sizeof(void*);
|
||||
|
||||
// Seek and copy
|
||||
setPosition(glyphDataOffset + gn->dataOffset);
|
||||
readData(p, getGlyphSize(gn));
|
||||
|
||||
// Mark glyphNode as cached
|
||||
gn->dataOffset = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
GlyphNode** next = (GlyphNode**)((uint8_t*)gn + SizeGlyphNode);
|
||||
gn = *next;
|
||||
}
|
||||
}
|
||||
|
||||
bool FontCache::createSortedString(const Unicode::UnicodeChar* string)
|
||||
{
|
||||
int length = Unicode::strlen(string);
|
||||
// Sorted string is allocated at end of buffer
|
||||
sortedString = (Unicode::UnicodeChar*)(gsubStart - (length + 1) * 2);
|
||||
if ((uint8_t*)sortedString < top)
|
||||
{
|
||||
// Unable to allocate string buffer in end of memory
|
||||
return false;
|
||||
}
|
||||
int n = 0;
|
||||
Unicode::UnicodeChar* uc = sortedString;
|
||||
while (*string)
|
||||
{
|
||||
*uc++ = *string++;
|
||||
n++;
|
||||
}
|
||||
*uc = 0;
|
||||
return sortSortedString(n);
|
||||
}
|
||||
|
||||
bool FontCache::createSortedLigatures(CachedFont* font, TypedText t, const Unicode::UnicodeChar* string, ...)
|
||||
{
|
||||
va_list pArg;
|
||||
va_start(pArg, string);
|
||||
TextProvider tp;
|
||||
tp.initialize(string, pArg, font->getGSUBTable(), font->getContextualFormsTable());
|
||||
va_end(pArg);
|
||||
Unicode::UnicodeChar ligature;
|
||||
sortedString = (Unicode::UnicodeChar*)(gsubStart);
|
||||
if ((uint8_t*)(sortedString - 1) < top)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*--sortedString = 0;
|
||||
int n = 0;
|
||||
while ((ligature = tp.getNextLigature(t.getTextDirection())) != 0)
|
||||
{
|
||||
if ((uint8_t*)(sortedString - 1) < top)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*--sortedString = ligature;
|
||||
n++;
|
||||
}
|
||||
return sortSortedString(n);
|
||||
}
|
||||
|
||||
bool FontCache::sortSortedString(int n)
|
||||
{
|
||||
Unicode::UnicodeChar* uc = sortedString;
|
||||
for (int i = 0; i < n - 1; i++)
|
||||
{
|
||||
bool swapped = false;
|
||||
for (int j = 0; j < n - i - 1; j++)
|
||||
{
|
||||
if (uc[j] > uc[j + 1])
|
||||
{
|
||||
Unicode::UnicodeChar temp = uc[j];
|
||||
uc[j] = uc[j + 1];
|
||||
uc[j + 1] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If no two elements were swapped by inner loop, then break
|
||||
if (!swapped)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FontCache::setPosition(uint32_t position)
|
||||
{
|
||||
if (reader)
|
||||
{
|
||||
reader->setPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
void FontCache::readData(void* out, uint32_t numberOfBytes)
|
||||
{
|
||||
if (reader)
|
||||
{
|
||||
reader->readData(out, numberOfBytes);
|
||||
}
|
||||
}
|
||||
} // namespace touchgfx
|
||||
@ -0,0 +1,112 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_FONTCACHE_HPP
|
||||
#define TOUCHGFX_FONTCACHE_HPP
|
||||
|
||||
#include <touchgfx/Font.hpp>
|
||||
#include <touchgfx/TypedText.hpp>
|
||||
#include <fonts/ApplicationFontProvider.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
class CachedFont;
|
||||
|
||||
class FontDataReader
|
||||
{
|
||||
public:
|
||||
virtual ~FontDataReader()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void open() = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void setPosition(uint32_t position) = 0;
|
||||
virtual void readData(void* out, uint32_t numberOfBytes) = 0;
|
||||
};
|
||||
|
||||
class FontCache
|
||||
{
|
||||
public:
|
||||
FontCache();
|
||||
void setReader(FontDataReader* reader);
|
||||
void clear(bool keepGsubOrContextTable = false);
|
||||
void setMemory(uint8_t* memory, uint32_t size);
|
||||
void initializeCachedFont(TypedText t, CachedFont* font, bool loadGsubOrContextTable = false);
|
||||
bool cacheString(TypedText t, const Unicode::UnicodeChar* string);
|
||||
bool cacheLigatures(CachedFont* font, TypedText t, const Unicode::UnicodeChar* string);
|
||||
|
||||
const GlyphNode* getGlyph(Unicode::UnicodeChar unicode, FontId font) const;
|
||||
|
||||
uint32_t getMemoryUsage()
|
||||
{
|
||||
return memorySize - (gsubStart - top);
|
||||
}
|
||||
|
||||
void open();
|
||||
void close();
|
||||
|
||||
static inline const uint8_t* getPixelData(const GlyphNode* glyph)
|
||||
{
|
||||
return ((const uint8_t*)glyph) + SizeGlyphNode + sizeof(void*);
|
||||
}
|
||||
|
||||
static inline bool isCached(const GlyphNode* g)
|
||||
{
|
||||
return g->dataOffset == 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint32_t SizeGlyphNode = 16;
|
||||
|
||||
bool contains(Unicode::UnicodeChar unicode, FontId font) const;
|
||||
void insert(Unicode::UnicodeChar unicode, FontId font, bool& outOfMemory);
|
||||
uint8_t* copyGlyph(uint8_t* top, Unicode::UnicodeChar unicode, FontId font, bool& outOfMemory);
|
||||
|
||||
void cacheData(GlyphNode* first);
|
||||
bool cacheSortedString(TypedText t);
|
||||
bool createSortedString(const Unicode::UnicodeChar* string);
|
||||
bool createSortedLigatures(CachedFont* font, TypedText t, const Unicode::UnicodeChar* string, ...);
|
||||
bool sortSortedString(int n);
|
||||
|
||||
void setPosition(uint32_t position);
|
||||
void readData(void* out, uint32_t numberOfBytes);
|
||||
|
||||
uint32_t getGlyphSize(const GlyphNode* gn)
|
||||
{
|
||||
if (byteAlignRow)
|
||||
{
|
||||
// Round up line width to byte boundary and multiply by height
|
||||
return (gn->width() * bpp + 7) / 8 * gn->height();
|
||||
}
|
||||
// Calculate number of pixels and round up to byte bounday
|
||||
return (gn->width() * gn->height() * bpp + 7) / 8;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t* first; // First GlyphNode, glyph in cache;
|
||||
uint8_t* last; // Last GlyphNode, glyph in cache;
|
||||
} fontTable[MAX(TypographyFontIndex::NUMBER_OF_FONTS, 1)];
|
||||
|
||||
uint32_t memorySize;
|
||||
uint8_t* memory; // Start of memory
|
||||
uint8_t* top; // First unused byte
|
||||
uint8_t* gsubStart; // First address of GSUB tables, allocated in the end of the cache
|
||||
|
||||
FontDataReader* reader;
|
||||
|
||||
Unicode::UnicodeChar* sortedString;
|
||||
// Must be bigger than BinaryFontData
|
||||
static const uint32_t MAX_BUFFER_SIZE = 64;
|
||||
char buffer[MAX_BUFFER_SIZE];
|
||||
uint32_t glyphDataOffset;
|
||||
uint16_t numGlyphs;
|
||||
uint16_t currentFileGlyphNumber;
|
||||
uint8_t bpp;
|
||||
uint8_t byteAlignRow;
|
||||
GlyphNode currentFileGlyphNode;
|
||||
};
|
||||
} // namespace touchgfx
|
||||
|
||||
#endif // TOUCHGFX_FONTCACHE_HPP
|
||||
@ -0,0 +1,59 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <fonts/GeneratedFont.hpp>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
} // namespace touchgfx
|
||||
@ -0,0 +1,148 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_GENERATEDFONT_HPP
|
||||
#define TOUCHGFX_GENERATEDFONT_HPP
|
||||
|
||||
#include <touchgfx/ConstFont.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
class GeneratedFont : public ConstFont
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
using ConstFont::getGlyph;
|
||||
|
||||
virtual const uint8_t* getPixelData(const GlyphNode* glyph) const;
|
||||
|
||||
virtual int8_t getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const;
|
||||
|
||||
virtual const uint16_t* getGSUBTable() const
|
||||
{
|
||||
return gsubTable;
|
||||
}
|
||||
|
||||
virtual const FontContextualFormsTable* getContextualFormsTable() const
|
||||
{
|
||||
return arabicTable;
|
||||
}
|
||||
|
||||
protected:
|
||||
GeneratedFont()
|
||||
: ConstFont(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), glyphData(0), kerningData(0), gsubTable(0), arabicTable(0)
|
||||
{
|
||||
}
|
||||
|
||||
const void* glyphData; ///< The glyphs
|
||||
const KerningNode* kerningData; ///< The kerning
|
||||
const uint16_t* gsubTable; ///< The GSUB tables
|
||||
|
||||
const FontContextualFormsTable* arabicTable; ///< Contextual forms
|
||||
};
|
||||
|
||||
class FusedFont : public GeneratedFont
|
||||
{
|
||||
public:
|
||||
FusedFont(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, GlyphNode& fontFusedNode)
|
||||
: GeneratedFont(glyphs, numGlyphs, height, baseline, pixAboveTop, pixBelowBottom, bitsPerPixel, byteAlignRow,
|
||||
maxLeft, maxRight, glyphDataInternalFlash, kerningList, fallbackChar, ellipsisChar,
|
||||
gsubData, formsTable), fusedNode(fontFusedNode)
|
||||
{ }
|
||||
|
||||
using GeneratedFont::getGlyph;
|
||||
virtual const GlyphNode* getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const;
|
||||
private:
|
||||
GlyphNode& fusedNode;
|
||||
};
|
||||
|
||||
struct BinaryFontData
|
||||
{
|
||||
uint32_t fontIndex; // The font index (as used by TypedTextDatabase)
|
||||
uint32_t sizeOfFontData; // Size of the complete BinaryFont
|
||||
uint32_t offsetToTable; // GlyphNode[]
|
||||
uint32_t offsetToKerning; // KerningNode[]
|
||||
uint32_t offsetToGlyphs; // uint8_t[]
|
||||
uint32_t offsetToGSUB; // uint16_t[]
|
||||
uint32_t offsetToArabicTable; // FontContextualFormsTable
|
||||
uint16_t numberOfGlyphs; // Number of glyphs in Table and Glyphs
|
||||
uint16_t fontHeight; // Font height
|
||||
uint16_t baseline; // Distance to baseline
|
||||
uint8_t pixAboveTop; // Max pixels above top
|
||||
uint8_t pixBelowBottom; // Max pixels below bottom
|
||||
uint8_t bitsPerPixel; // Bpp
|
||||
uint8_t byteAlignRow; // A4/A2/A1
|
||||
uint8_t maxLeft; // The maximum a glyph extends to the left
|
||||
uint8_t maxRight; // The maximum a glyph extends to the right
|
||||
Unicode::UnicodeChar fallbackChar; // Fallback Character for the font
|
||||
Unicode::UnicodeChar ellipsisChar; // Ellipsis Character for the font
|
||||
};
|
||||
|
||||
class BinaryFont : public GeneratedFont
|
||||
{
|
||||
public:
|
||||
BinaryFont(const struct touchgfx::BinaryFontData* data)
|
||||
: GeneratedFont((const GlyphNode*)((const uint8_t*)data + data->offsetToTable),
|
||||
data->numberOfGlyphs,
|
||||
data->fontHeight,
|
||||
data->baseline,
|
||||
data->pixAboveTop,
|
||||
data->pixBelowBottom,
|
||||
data->bitsPerPixel,
|
||||
data->byteAlignRow,
|
||||
data->maxLeft,
|
||||
data->maxRight,
|
||||
0,
|
||||
(const KerningNode*)((const uint8_t*)data + data->offsetToKerning),
|
||||
data->fallbackChar,
|
||||
data->ellipsisChar,
|
||||
(data->offsetToGSUB == 0) ? 0 : (const uint16_t*)((const uint8_t*)data + data->offsetToGSUB),
|
||||
0),
|
||||
glyphData((const uint8_t*)data + data->offsetToGlyphs)
|
||||
{
|
||||
if (data->offsetToArabicTable > 0)
|
||||
{
|
||||
setupContextualTable(data);
|
||||
}
|
||||
}
|
||||
|
||||
BinaryFont()
|
||||
: GeneratedFont()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const uint8_t* getPixelData(const GlyphNode* glyph) const
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)glyphData;
|
||||
return &(data[glyph->dataOffset]);
|
||||
}
|
||||
|
||||
protected:
|
||||
const uint8_t* glyphData;
|
||||
FontContextualFormsTable contextualForms;
|
||||
|
||||
private:
|
||||
typedef const Unicode::UnicodeChar (*array5ptr)[5];
|
||||
typedef const Unicode::UnicodeChar (*array4ptr)[4];
|
||||
|
||||
void setupContextualTable(const struct touchgfx::BinaryFontData* data)
|
||||
{
|
||||
const uint16_t* const base = (const uint16_t*)(((const uint8_t*)data) + data->offsetToArabicTable);
|
||||
// First elements in binary font are offsets to arrays in 16bit words
|
||||
contextualForms.contextualForms4Long = (array5ptr)(base + base[0]);
|
||||
contextualForms.contextualForms3Long = (array5ptr)(base + base[1]);
|
||||
contextualForms.contextualForms2Long = (array5ptr)(base + base[2]);
|
||||
contextualForms.contextualForms0621_063a = (array4ptr)(base + base[3]);
|
||||
contextualForms.contextualForms0641_064a = (array4ptr)(base + base[4]);
|
||||
contextualForms.contextualForms06XX = (array5ptr)(base + base[5]);
|
||||
contextualForms.contextualForms4LongSize = base[6];
|
||||
contextualForms.contextualForms3LongSize = base[7];
|
||||
contextualForms.contextualForms2LongSize = base[8];
|
||||
contextualForms.contextualForms06XXSize = base[9];
|
||||
arabicTable = &contextualForms;
|
||||
}
|
||||
};
|
||||
} // namespace touchgfx
|
||||
|
||||
#endif // TOUCHGFX_GENERATEDFONT_HPP
|
||||
@ -0,0 +1,4 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
// Empty Language file
|
||||
@ -0,0 +1,48 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <touchgfx/Unicode.hpp>
|
||||
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const uint32_t indices<%= get_language %>[] TEXT_LOCATION_FLASH_ATTRIBUTE;
|
||||
|
||||
<% if remap_global? %>
|
||||
// Remap all strings
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const uint32_t indices<%= get_language %>[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% text_entries = get_text_entries %>
|
||||
<% if text_entries.empty? %>
|
||||
0
|
||||
<% else %>
|
||||
<% text_entries.each_with_index do |entry, index| %>
|
||||
<%= get_string_index(entry) %><%= ((index == text_entries.length - 1) ? (index == 0 ? '' : ' '): ',') %><%= get_string_index_spaces(entry)%>// <%= entry.text_id %>: "<%= unicode_array_to_string(entry.int_array) %>"
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
<% else %>
|
||||
// Remap local strings
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const touchgfx::Unicode::UnicodeChar texts<%= get_language %>[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% substrings_and_offset = get_substrings_and_offsets(@language_index) %>
|
||||
<% if substrings_and_offset.empty? %>
|
||||
0
|
||||
<% else %>
|
||||
<% get_substrings_and_offsets(@language_index).each do |unicode_array, offset, last| %>
|
||||
<%= unicode_array.map{|x|"0x%x"%x} * ', ' %><%= last ? '' : ',' %> // @<%= offset %> "<%= unicode_array_to_string(unicode_array) %>"
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const uint32_t indices<%= get_language %>[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% text_entries = get_text_entries %>
|
||||
<% if text_entries.empty? %>
|
||||
0
|
||||
<% else %>
|
||||
<% text_entries.each_with_index do |entry, index| %>
|
||||
<%= get_string_index(entry) %><%= ((index == text_entries.length-1) ? ' ': ',') %><%= get_string_index_spaces(entry)%>// <%= entry.text_id %>: "<%= unicode_array_to_string(entry.int_array) %>"
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
<% end %>
|
||||
@ -0,0 +1,23 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_TEXTKEYSANDLANGUAGES_HPP
|
||||
#define TOUCHGFX_TEXTKEYSANDLANGUAGES_HPP
|
||||
|
||||
enum LANGUAGES
|
||||
{
|
||||
<% get_languages.each do |language| %>
|
||||
<%= language %>,
|
||||
<% end %>
|
||||
NUMBER_OF_LANGUAGES
|
||||
};
|
||||
|
||||
enum TEXTS
|
||||
{
|
||||
<% get_texts.each do |text| %>
|
||||
<%= text.upcase %>,
|
||||
<% end %>
|
||||
NUMBER_OF_TEXT_KEYS
|
||||
};
|
||||
|
||||
#endif // TOUCHGFX_TEXTKEYSANDLANGUAGES_HPP
|
||||
@ -0,0 +1,195 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <touchgfx/TextProvider.hpp>
|
||||
#include <touchgfx/Texts.hpp>
|
||||
#include <touchgfx/TypedText.hpp>
|
||||
#include <touchgfx/Unicode.hpp>
|
||||
#include <touchgfx/hal/HAL.hpp>
|
||||
#include <touchgfx/lcd/LCD.hpp>
|
||||
#include <texts/TypedTextDatabase.hpp>
|
||||
|
||||
uint16_t touchgfx::Font::getStringWidth(const touchgfx::Unicode::UnicodeChar* text, ...) const
|
||||
{
|
||||
va_list pArg;
|
||||
va_start(pArg, text);
|
||||
uint16_t width = getStringWidth<%= is_rtl? ? 'RTL' : 'LTR' %>(TEXT_DIRECTION_LTR, text, pArg);
|
||||
va_end(pArg);
|
||||
return width;
|
||||
}
|
||||
|
||||
uint16_t touchgfx::Font::getStringWidth(touchgfx::TextDirection textDirection, const touchgfx::Unicode::UnicodeChar* text, ...) const
|
||||
{
|
||||
va_list pArg;
|
||||
va_start(pArg, text);
|
||||
uint16_t width = getStringWidth<%= is_rtl? ? 'RTL' : 'LTR' %>(textDirection, text, pArg);
|
||||
va_end(pArg);
|
||||
return width;
|
||||
}
|
||||
|
||||
touchgfx::Unicode::UnicodeChar touchgfx::TextProvider::getNextLigature(TextDirection direction)
|
||||
{
|
||||
<% if is_rtl? %>
|
||||
nextCharacters.replaceAt0(unicodeConverter(direction));
|
||||
<% end %>
|
||||
if (fontGsubTable && nextCharacters.peekChar())
|
||||
{
|
||||
substituteGlyphs();
|
||||
if (nextCharacters.peekChar(1) == 0x093F) // Hindi I-matra
|
||||
{
|
||||
nextCharacters.replaceAt1(nextCharacters.peekChar());
|
||||
nextCharacters.replaceAt0(0x093F);
|
||||
}
|
||||
}
|
||||
return getNextChar();
|
||||
}
|
||||
|
||||
void touchgfx::TextProvider::initializeInternal()
|
||||
{
|
||||
fillInputBuffer();
|
||||
<% if is_rtl? %>
|
||||
unicodeConverterInit();
|
||||
<% end %>
|
||||
}
|
||||
|
||||
void touchgfx::LCD::drawString(touchgfx::Rect widgetArea, const touchgfx::Rect& invalidatedArea, const touchgfx::LCD::StringVisuals& stringVisuals, const touchgfx::Unicode::UnicodeChar* format, ...)
|
||||
{
|
||||
va_list pArg;
|
||||
va_start(pArg, format);
|
||||
drawString<%= is_rtl? ? 'RTL' : 'LTR' %>(widgetArea, invalidatedArea, stringVisuals, format, pArg);
|
||||
va_end(pArg);
|
||||
}
|
||||
|
||||
// Default TypedTextDatabase
|
||||
extern const touchgfx::TypedText::TypedTextData* const typedTextDatabaseArray[];
|
||||
|
||||
<% if generate_binary_files? %>
|
||||
extern const touchgfx::Unicode::UnicodeChar EmptyLanguageTexts[];
|
||||
extern const uint32_t EmptyLanguageIndices[];
|
||||
|
||||
<% else %>
|
||||
<% if remap_global? %>
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const touchgfx::Unicode::UnicodeChar texts_all_languages[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% substrings_and_offsets = get_substrings_and_offsets %>
|
||||
<% if substrings_and_offsets.empty? %>
|
||||
0 // No texts in application
|
||||
<% else %>
|
||||
<% substrings_and_offsets.each do |(unicode_array, offset, last)| %>
|
||||
<%= unicode_array.map{|x|"0x%x"%x} * ', ' %><%= last ? '' : ',' %> // @<%= offset %> "<%= unicode_array_to_string(unicode_array) %>"
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
<% end %>
|
||||
<% get_capitalized_languages.each do |lang| %>
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const uint32_t indices<%= lang %>[] TEXT_LOCATION_FLASH_ATTRIBUTE;
|
||||
|
||||
<% if !remap_global? %>
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const touchgfx::Unicode::UnicodeChar texts<%= lang %>[] TEXT_LOCATION_FLASH_ATTRIBUTE;
|
||||
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
// Array holding dynamically installed languages
|
||||
struct TranslationHeader
|
||||
{
|
||||
uint32_t offset_to_texts;
|
||||
uint32_t offset_to_indices;
|
||||
uint32_t offset_to_typedtext;
|
||||
};
|
||||
static const TranslationHeader* languagesArray[<%= has_languages? ? get_number_of_languages : 1 %>] = { 0 };
|
||||
|
||||
// Compiled and linked in languages
|
||||
static const uint32_t* const staticLanguageIndices[] = {
|
||||
<% if generate_binary_files? %>
|
||||
EmptyLanguageIndices
|
||||
<% else %>
|
||||
<% if !has_languages? %>
|
||||
0
|
||||
<% else %>
|
||||
<% get_capitalized_languages.each_with_index do |lang, index| %>
|
||||
indices<%= lang %><%= (index == get_number_of_languages - 1) ? '': ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
<% if generate_binary_files? %>
|
||||
static const touchgfx::Unicode::UnicodeChar* const staticLanguageTexts[] = {
|
||||
EmptyLanguageTexts
|
||||
};
|
||||
<% else %>
|
||||
<% if not remap_global? %>
|
||||
static const touchgfx::Unicode::UnicodeChar* const staticLanguageTexts[] = {
|
||||
<% if !has_languages? %>
|
||||
0
|
||||
<% else %>
|
||||
<% get_capitalized_languages.each_with_index do |lang, index| %>
|
||||
texts<%= lang %><%= (index == get_number_of_languages - 1) ? '': ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
touchgfx::LanguageId touchgfx::Texts::currentLanguage = static_cast<touchgfx::LanguageId>(0);
|
||||
static const touchgfx::Unicode::UnicodeChar* currentLanguagePtr = 0;
|
||||
static const uint32_t* currentLanguageIndices = 0;
|
||||
|
||||
void touchgfx::Texts::setLanguage(touchgfx::LanguageId id)
|
||||
{
|
||||
const touchgfx::TypedText::TypedTextData* currentLanguageTypedText = 0;
|
||||
if (id < <%= has_languages? ? get_number_of_languages : 1 %>)
|
||||
{
|
||||
if (languagesArray[id] != 0)
|
||||
{
|
||||
// Dynamic translation is added
|
||||
const TranslationHeader* translation = languagesArray[id];
|
||||
currentLanguagePtr = (const touchgfx::Unicode::UnicodeChar*)(((const uint8_t*)translation) + translation->offset_to_texts);
|
||||
currentLanguageIndices = (const uint32_t*)(((const uint8_t*)translation) + translation->offset_to_indices);
|
||||
currentLanguageTypedText = (const touchgfx::TypedText::TypedTextData*)(((const uint8_t*)translation) + translation->offset_to_typedtext);
|
||||
}
|
||||
<% if generate_binary_files? %>
|
||||
else
|
||||
{
|
||||
// Compiled and linked empty texts and indices in typedTextData
|
||||
currentLanguagePtr = staticLanguageTexts[0];
|
||||
currentLanguageIndices = staticLanguageIndices[0];
|
||||
currentLanguageTypedText = typedTextDatabaseArray[0];
|
||||
}
|
||||
<% else %>
|
||||
else
|
||||
{
|
||||
// Compiled and linked in languages
|
||||
<% if remap_global? %>
|
||||
currentLanguagePtr = texts_all_languages;
|
||||
currentLanguageIndices = staticLanguageIndices[id];
|
||||
<% else %>
|
||||
currentLanguagePtr = staticLanguageTexts[id];
|
||||
currentLanguageIndices = staticLanguageIndices[id];
|
||||
<% end %>
|
||||
currentLanguageTypedText = typedTextDatabaseArray[id];
|
||||
}
|
||||
<% end %>
|
||||
}
|
||||
|
||||
if (currentLanguageTypedText)
|
||||
{
|
||||
currentLanguage = id;
|
||||
touchgfx::TypedText::registerTypedTextDatabase(currentLanguageTypedText,
|
||||
TypedTextDatabase::getFonts(), TypedTextDatabase::getInstanceSize());
|
||||
}
|
||||
}
|
||||
|
||||
void touchgfx::Texts::setTranslation(touchgfx::LanguageId id, const void* translation)
|
||||
{
|
||||
languagesArray[id] = (const TranslationHeader*)translation;
|
||||
}
|
||||
|
||||
const touchgfx::Unicode::UnicodeChar* touchgfx::Texts::getText(TypedTextId id) const
|
||||
{
|
||||
return ¤tLanguagePtr[currentLanguageIndices[id]];
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <touchgfx/TypedText.hpp>
|
||||
#include <fonts/<%= get_font_class_name %>.hpp>
|
||||
#include <texts/TypedTextDatabase.hpp>
|
||||
|
||||
<% get_fonts.each do |font| %>
|
||||
extern touchgfx::<%= get_font_class_name %>& <%= font %>();
|
||||
<% end %>
|
||||
|
||||
const touchgfx::Font* touchgfx_fonts[] = {
|
||||
<% if get_fonts.empty? %>
|
||||
0
|
||||
<% else %>
|
||||
<% get_fonts.each_with_index do |font, index| %>
|
||||
&(<%= font %>())<%= index == get_fonts.length-1 ? '' : ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
<% if generate_binary_files? %>
|
||||
extern const touchgfx::TypedText::TypedTextData typedText_database_EMPTY[];
|
||||
<% else %>
|
||||
extern const touchgfx::TypedText::TypedTextData typedText_database_DEFAULT[];
|
||||
<% end %>
|
||||
extern const touchgfx::TypedText::TypedTextData* const typedTextDatabaseArray[];
|
||||
|
||||
<% if generate_binary_files? %>
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const touchgfx::Unicode::UnicodeChar EmptyLanguageTexts[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% get_layouts.each do |layout| %>
|
||||
<% get_typed_texts(layout).each_with_index do |entry, index| %>
|
||||
0<%= ((index == get_typed_texts(layout).length-1) ? '': ',') %>
|
||||
<% end %>
|
||||
<% break %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
KEEP extern const uint32_t EmptyLanguageIndices[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% get_layouts.each do |layout| %>
|
||||
<% get_typed_texts(layout).each_with_index do |entry, index| %>
|
||||
<%= index %><%= ((index == get_typed_texts(layout).length-1) ? '': ',') %>
|
||||
<% end %>
|
||||
<% break %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
const touchgfx::TypedText::TypedTextData typedText_database_EMPTY[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% get_layouts.each do |layout| %>
|
||||
<% get_typed_texts(layout).each_with_index do |entry, index| %>
|
||||
<%= ('{ 0, touchgfx::LEFT, touchgfx::TEXT_DIRECTION_LTR }').to_s %><%= ((index == get_typed_texts(layout).length-1) ? '': ',') %>
|
||||
<% end %>
|
||||
<% break %>
|
||||
<% end %>
|
||||
};
|
||||
<% else %>
|
||||
<% get_layouts.each do |layout| %>
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
const touchgfx::TypedText::TypedTextData typedText_database_<%= layout %>[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% if get_typed_texts(layout).empty? %>
|
||||
{ 0, touchgfx::LEFT, touchgfx::TEXT_DIRECTION_LTR }
|
||||
<% else %>
|
||||
<% get_typed_texts(layout).each_with_index do |typed_text, index| %>
|
||||
<% fontIdx = get_font_index(typed_text.typography) %>
|
||||
<% alignment = get_touchgfx_aligment(typed_text.alignment) %>
|
||||
<% direction = get_touchgfx_direction(typed_text.direction) %>
|
||||
{ <%= fontIdx %>, <%= alignment %>, <%= direction %> }<%= index == get_typed_texts(layout).length-1 ? '' : ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
TEXT_LOCATION_FLASH_PRAGMA
|
||||
const touchgfx::TypedText::TypedTextData* const typedTextDatabaseArray[] TEXT_LOCATION_FLASH_ATTRIBUTE = {
|
||||
<% if generate_binary_files? %>
|
||||
<% get_languages.each_with_index do |entry,index| %>
|
||||
typedText_database_EMPTY<%= index == get_languages.length-1 ? '' : ',' %>
|
||||
<% end %>
|
||||
<% elsif languages.empty? %>
|
||||
typedText_database_DEFAULT
|
||||
<% else %>
|
||||
<% get_languages.each_with_index do |language, index| %>
|
||||
typedText_database_<%= get_layouts.find { |l| l == language } || 'DEFAULT' %><%= index == get_languages.length-1 ? '' : ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
namespace TypedTextDatabase
|
||||
{
|
||||
const touchgfx::TypedText::TypedTextData* getInstance(touchgfx::LanguageId id)
|
||||
{
|
||||
return typedTextDatabaseArray[id];
|
||||
}
|
||||
|
||||
uint16_t getInstanceSize()
|
||||
{
|
||||
<% if has_text_entries? %>
|
||||
<% if generate_binary_files? %>
|
||||
return sizeof(typedText_database_EMPTY) / sizeof(touchgfx::TypedText::TypedTextData);
|
||||
<% else %>
|
||||
return sizeof(typedText_database_DEFAULT) / sizeof(touchgfx::TypedText::TypedTextData);
|
||||
<% end %>
|
||||
<% else %>
|
||||
return 0;
|
||||
<% end %>
|
||||
}
|
||||
|
||||
const touchgfx::Font** getFonts()
|
||||
{
|
||||
return touchgfx_fonts;
|
||||
}
|
||||
|
||||
const touchgfx::Font* setFont(touchgfx::FontId fontId, const touchgfx::Font* font)
|
||||
{
|
||||
const touchgfx::Font* old = touchgfx_fonts[fontId];
|
||||
touchgfx_fonts[fontId] = font;
|
||||
return old;
|
||||
}
|
||||
|
||||
void resetFont(touchgfx::FontId fontId)
|
||||
{
|
||||
<% if !get_fonts.empty? %>
|
||||
switch (fontId)
|
||||
{
|
||||
<% get_fonts.each_with_index do |font, index| %>
|
||||
case <%= index %>:
|
||||
touchgfx_fonts[<%= index %>] = &(<%= font %>());
|
||||
break;
|
||||
<% end %>
|
||||
}
|
||||
<% end %>
|
||||
}
|
||||
} // namespace TypedTextDatabase
|
||||
@ -0,0 +1,21 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_TYPEDTEXTDATABASE_HPP
|
||||
#define TOUCHGFX_TYPEDTEXTDATABASE_HPP
|
||||
|
||||
#include <touchgfx/TypedText.hpp>
|
||||
#include <touchgfx/hal/Types.hpp>
|
||||
|
||||
namespace TypedTextDatabase
|
||||
{
|
||||
class TypedTextData;
|
||||
const touchgfx::TypedText::TypedTextData* getInstance(touchgfx::LanguageId id);
|
||||
const touchgfx::TypedText::TypedTextData* getInstance();
|
||||
const touchgfx::Font** getFonts();
|
||||
const touchgfx::Font* setFont(touchgfx::FontId fontId, const touchgfx::Font*);
|
||||
void resetFont(touchgfx::FontId fontId);
|
||||
uint16_t getInstanceSize();
|
||||
} // namespace TypedTextDatabase
|
||||
|
||||
#endif // TOUCHGFX_TYPEDTEXTDATABASE_HPP
|
||||
@ -0,0 +1,152 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <touchgfx/hal/FlashDataReader.hpp>
|
||||
#include <fonts/ApplicationFontProvider.hpp>
|
||||
#include <fonts/UnmappedDataFont.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
GlyphNode UnmappedDataFont::glyphNodeBuffer;
|
||||
|
||||
UnmappedDataFont::UnmappedDataFont(const GlyphNode* glyphs, const uint16_t* unicodeList, 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* glyphDataList, const KerningNode* kerningList, const Unicode::UnicodeChar fallbackChar, const Unicode::UnicodeChar ellipsisChar, const uint16_t* const gsubData, const FontContextualFormsTable* formsTable)
|
||||
: Font(height, baseline, pixAboveTop, pixBelowBottom, bitsPerPixel, byteAlignRow, maxLeft, maxRight, fallbackChar, ellipsisChar),
|
||||
glyphList(glyphs),
|
||||
listSize(numGlyphs),
|
||||
unicodes(unicodeList),
|
||||
glyphDataList(glyphDataList),
|
||||
kerningData(kerningList),
|
||||
gsubTable(gsubData),
|
||||
arabicTable(formsTable)
|
||||
{
|
||||
}
|
||||
|
||||
const GlyphNode* UnmappedDataFont::getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const
|
||||
{
|
||||
int index = lookupUnicode(unicode);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
// Read glyphNode from unmapped flash
|
||||
touchgfx::FlashDataReader* const flashReader = ApplicationFontProvider::getFlashReader();
|
||||
if (flashReader)
|
||||
{
|
||||
flashReader->copyData(glyphList + index, &glyphNodeBuffer, sizeof(GlyphNode));
|
||||
|
||||
pixelData = getPixelData(const_cast<const GlyphNode*>(&glyphNodeBuffer));
|
||||
bitsPerPixel = getBitsPerPixel();
|
||||
return &glyphNodeBuffer;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t* UnmappedDataFont::getPixelData(const GlyphNode* glyph) const
|
||||
{
|
||||
const uint8_t* const* table = (const uint8_t* const*)glyphDataList;
|
||||
return &(table[glyph->unicode / 2048][glyph->dataOffset]);
|
||||
}
|
||||
|
||||
int8_t UnmappedDataFont::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;
|
||||
}
|
||||
|
||||
int UnmappedDataFont::lookupUnicode(uint16_t unicode) const
|
||||
{
|
||||
int32_t min = 0;
|
||||
int32_t max = listSize - 1;
|
||||
|
||||
int32_t mid = min + (unicode - unicodes[min]); // Linear up from [min].unicode
|
||||
if (mid < min)
|
||||
{
|
||||
// Unicode < unicodes[min] => not found
|
||||
return -1;
|
||||
}
|
||||
if (mid > max)
|
||||
{
|
||||
// Linear up ends too high
|
||||
mid = max - (unicodes[max] - unicode); // Linear down from [max].unicode
|
||||
if (mid > max)
|
||||
{
|
||||
// Unicode > unicodes[max] => not found
|
||||
return -1;
|
||||
}
|
||||
if (mid < min)
|
||||
{
|
||||
// Linear down ends too low, take the middle element
|
||||
mid = (min + max) / 2;
|
||||
}
|
||||
}
|
||||
while (min <= max)
|
||||
{
|
||||
if (unicode == unicodes[mid])
|
||||
{
|
||||
// Found at [mid]
|
||||
return mid;
|
||||
}
|
||||
if (unicode < unicodes[mid])
|
||||
{
|
||||
// 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 - (unicodes[max] - 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 - unicodes[min]);
|
||||
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 -1;
|
||||
}
|
||||
} // namespace touchgfx
|
||||
@ -0,0 +1,126 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#ifndef TOUCHGFX_UNMAPPEDDATAFONT_HPP
|
||||
#define TOUCHGFX_UNMAPPEDDATAFONT_HPP
|
||||
|
||||
#include <touchgfx/Font.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
/**
|
||||
* An UnmappedDataFont has both glyph table and glyph data placed in a
|
||||
* flash which does not support random access read (indirect
|
||||
* access). A unicode table is located in a flash with random read
|
||||
* access (direct access).
|
||||
*
|
||||
* @see Font, ConstFont
|
||||
*/
|
||||
class UnmappedDataFont : public Font
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct the UnmappedDataFont.
|
||||
*
|
||||
* @param glyphs The array of glyphs known to this font (indirect).
|
||||
* @param unicodes The array of unicodes known to this font (direct).
|
||||
* @param numGlyphs The number of glyphs in list.
|
||||
* @param height The height in pixels of the highest character in this font.
|
||||
* @param baseline The height of the baseline in pixels.
|
||||
* @param pixBelowBottom The maximum number of pixels that can be drawn below the
|
||||
* bottom in this font.
|
||||
* @param bitsPerPixel The number of bits per pixel in this font.
|
||||
* @param byteAlignRow Are glyphs encoded using A4 format
|
||||
* @param maxLeft The maximum a character extends to the left.
|
||||
* @param maxRight The maximum a character extends to the right.
|
||||
* @param glyphDataList Pointer to pointers the glyph data for the font (indirect).
|
||||
* @param kerningList pointer to the kerning data for the font (direct).
|
||||
* @param fallbackChar The fallback character for the typography in case no glyph is
|
||||
* available.
|
||||
* @param ellipsisChar The ellipsis character used for truncating long texts.
|
||||
* @param gsubTable Pointer to GSUB table (direct).
|
||||
*/
|
||||
UnmappedDataFont(const GlyphNode* glyphs, const uint16_t* unicodes, 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* glyphDataList, const KerningNode* kerningList, const Unicode::UnicodeChar fallbackChar, const Unicode::UnicodeChar ellipsisChar, const uint16_t* const gsubData, const FontContextualFormsTable* formsTable);
|
||||
|
||||
using Font::getGlyph;
|
||||
|
||||
/**
|
||||
* Gets the glyph data associated with the specified Unicode. The
|
||||
GlyphNode is allocated in the buffer passed to the constructor.
|
||||
*
|
||||
* Please note that in case of Thai letters and Arabic letters
|
||||
* where diacritics can be placed relative to the previous
|
||||
* character(s), please use TextProvider::getNextLigature()
|
||||
* instead as it will create a temporary GlyphNode that will be
|
||||
* adjusted with respect to X/Y position.
|
||||
*
|
||||
* @param unicode The character to look up.
|
||||
* @param pixelData Pointer to the pixel data for the glyph if the glyph is
|
||||
* found. This is set by this method.
|
||||
* @param [out] bitsPerPixel Reference where to place the number of bits per pixel.
|
||||
*
|
||||
* @return A pointer to the glyph node or null if the glyph was not found.
|
||||
*/
|
||||
virtual const GlyphNode* getGlyph(Unicode::UnicodeChar unicode, const uint8_t*& pixelData, uint8_t& bitsPerPixel) const;
|
||||
|
||||
/**
|
||||
* Obtains the address to the pixel data for the specified glyph.
|
||||
*
|
||||
* @param glyph The glyph to get the pixels data of.
|
||||
*
|
||||
* @return The address of the pixel data of the glyph.
|
||||
*/
|
||||
virtual const uint8_t* getPixelData(const GlyphNode* glyph) const;
|
||||
|
||||
/**
|
||||
* Gets the kerning distance between two characters.
|
||||
*
|
||||
* @param prevChar The unicode value of the previous character.
|
||||
* @param glyph the glyph object for the current character.
|
||||
*
|
||||
* @return The kerning distance between prevChar and glyph char.
|
||||
*/
|
||||
virtual int8_t getKerning(Unicode::UnicodeChar prevChar, const GlyphNode* glyph) const;
|
||||
|
||||
/**
|
||||
* Gets GSUB table.
|
||||
*
|
||||
* @return The GSUB table or null if font has GSUB no table
|
||||
*/
|
||||
virtual const uint16_t* getGSUBTable() const
|
||||
{
|
||||
return gsubTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contextual forms table used in arabic fonts.
|
||||
*
|
||||
* @return The FontContextualFormsTable or null if the font has no table.
|
||||
*/
|
||||
virtual const FontContextualFormsTable* getContextualFormsTable() const
|
||||
{
|
||||
return arabicTable;
|
||||
}
|
||||
|
||||
protected:
|
||||
UnmappedDataFont()
|
||||
: Font(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), glyphList(0), unicodes(0), glyphDataList(0), kerningData(0), gsubTable(0)
|
||||
{
|
||||
}
|
||||
|
||||
int lookupUnicode(uint16_t unicode) const;
|
||||
|
||||
const GlyphNode* glyphList; ///< The list of glyphs
|
||||
uint16_t listSize; ///< The size of the list of glyphs
|
||||
const uint16_t* unicodes; ///< LookupTable with all unicodes in this font
|
||||
const void* glyphDataList; ///< The glyphs (list of pointers)
|
||||
const KerningNode* kerningData; ///< The kerning
|
||||
const uint16_t* gsubTable; ///< The GSUB tables
|
||||
|
||||
const FontContextualFormsTable* arabicTable; ///< Contextual forms
|
||||
|
||||
static GlyphNode glyphNodeBuffer; ///< Buffer for GlyphNodes read from unmapped flash
|
||||
};
|
||||
} // namespace touchgfx
|
||||
|
||||
#endif // TOUCHGFX_UNMAPPEDDATAFONT_HPP
|
||||
Reference in New Issue
Block a user