diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2018-03-17 13:15:39 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2018-03-17 13:15:39 +0000 |
| commit | 69e534b48fe13064b027cece43e05b7b48671868 (patch) | |
| tree | be44697d0986124d0b66568f894809c427d3424b | |
| parent | 1084602fecd948ddc67f1e03b3c40fa3b1af1032 (diff) | |
Android: basic font management structure is complete.
Next: cleanup, document, add caching, add other font related calls,
add clipping, add font paths for package resources
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12764 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Font.H | 37 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Font.cxx | 171 |
2 files changed, 127 insertions, 81 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.H b/src/drivers/Android/Fl_Android_Graphics_Font.H index 1423a1b67..8b035521a 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Font.H +++ b/src/drivers/Android/Fl_Android_Graphics_Font.H @@ -24,18 +24,45 @@ #include "stb_truetype.h" -class Fl_Android_Font_Descriptor : public Fl_Font_Descriptor +class Fl_Android_Bytemap +{ +public: + Fl_Android_Bytemap(); + ~Fl_Android_Bytemap(); + +public: + int pWidth, pHeight, pStride, pXOffset, pYOffset; + unsigned char *pBytes; +}; + + +class Fl_Android_Font_Source { private: stbtt_fontinfo pFont; - Fl_Font pFontIndex; uint8_t *pFileBuffer; + const char *pName; + Fl_Font pFontIndex; + +public: + Fl_Android_Font_Source(const char *fname, Fl_Font fnum); + void load_font(); + Fl_Android_Bytemap *get_bytemap(uint32_t c, int size); + float get_advance(uint32_t c, Fl_Fontsize size); +}; + + +class Fl_Android_Font_Descriptor : public Fl_Font_Descriptor +{ +private: + Fl_Android_Font_Source *pFontSource; + Fl_Font pFontIndex; public: - Fl_Android_Font_Descriptor(const char* fontname, Fl_Font fnum, Fl_Fontsize size); - uint8_t *get_bitmap(uint32_t c, int *w, int *h, int *dx, int *dy); - void free_bitmap(uint8_t *bitmap); + Fl_Android_Font_Descriptor(const char *fname, Fl_Android_Font_Source *fsrc, Fl_Font fnum, Fl_Fontsize size); float get_advance(uint32_t c); + Fl_Android_Bytemap *get_bytemap(uint32_t c); + Fl_Android_Font_Source *get_font_source() { return pFontSource; } }; diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.cxx b/src/drivers/Android/Fl_Android_Graphics_Font.cxx index 0d292a2c1..47af9ec45 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Font.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Font.cxx @@ -33,6 +33,9 @@ //}; +// TODO: font names starting with a $ will have the system font path inserted +// TODO: font names starting with a . or / have a known path and will not change +// TODO: font names starting with a ~ will have the package resource path for fonts added static Fl_Fontdesc built_in_table[] = { {"Roboto-Regular"}, {"Roboto-Bold"}, @@ -55,35 +58,38 @@ static Fl_Fontdesc built_in_table[] = { Fl_Fontdesc* fl_fonts = built_in_table; -Fl_Android_Font_Descriptor::Fl_Android_Font_Descriptor(const char* fontname, Fl_Font fnum, Fl_Fontsize size) : - Fl_Font_Descriptor(fontname, size), - pFontIndex(fnum), - pFileBuffer(0) +Fl_Android_Bytemap::Fl_Android_Bytemap() : + pBytes(0L) { - // --- This is what we have to live with: - // Fl_Font_Descriptor *next; - // Fl_Fontsize size; /**< font size */ - // Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); - // FL_EXPORT ~Fl_Font_Descriptor() {} - // short ascent, descent, q_width; - // unsigned int listbase; // base of display list, 0 = none +} +Fl_Android_Bytemap::~Fl_Android_Bytemap() +{ + if (pBytes) ::free(pBytes); } -unsigned char *Fl_Android_Font_Descriptor::get_bitmap(uint32_t c, int *w, int *h, int *dx, int *dy) +// ----------------------------------------------------------------------------- + + +Fl_Android_Font_Source::Fl_Android_Font_Source(const char *fname, Fl_Font fnum) : + pFileBuffer(0L), + pName(fname), + pFontIndex(fnum) { - unsigned char *bitmap; +} + +void Fl_Android_Font_Source::load_font() +{ if (pFileBuffer==0) { char buf[1024]; sprintf(buf, "/system/fonts/%s.ttf", fl_fonts[pFontIndex].name); -// FILE *f = fopen("/system/fonts/DroidSans.ttf", "rb"); FILE *f = fopen(buf, "rb"); if (f==NULL) { - Fl_Android_Application::log_e("ERROR reading font %d!", errno); - return 0; + Fl_Android_Application::log_e("ERROR reading font %d from '%s'!", errno, buf); + return; } fseek(f, 0, SEEK_END); size_t fsize = (size_t)ftell(f); @@ -91,9 +97,16 @@ unsigned char *Fl_Android_Font_Descriptor::get_bitmap(uint32_t c, int *w, int *h pFileBuffer = (uint8_t*)malloc(fsize); fread(pFileBuffer, 1, fsize, f); fclose(f); - stbtt_InitFont(&pFont, pFileBuffer, stbtt_GetFontOffsetForIndex(pFileBuffer,0)); } +} + + +Fl_Android_Bytemap *Fl_Android_Font_Source::get_bytemap(uint32_t c, int size) +{ + if (pFileBuffer==0) load_font(); + + Fl_Android_Bytemap *byteMap = new Fl_Android_Bytemap(); #if 0 scale = stbtt_ScaleForPixelHeight(&font, 15); @@ -117,44 +130,79 @@ unsigned char *Fl_Android_Font_Descriptor::get_bitmap(uint32_t c, int *w, int *h } #endif - int ww, hh, ddx, ddy; + float hgt = stbtt_ScaleForPixelHeight(&pFont, size); - bitmap = stbtt_GetCodepointBitmap(&pFont, 0, hgt, c, w, h, dx, dy); - return bitmap; + byteMap->pBytes = stbtt_GetCodepointBitmap(&pFont, 0, hgt, c, + &byteMap->pWidth, &byteMap->pHeight, + &byteMap->pXOffset, &byteMap->pYOffset); + byteMap->pStride = byteMap->pWidth; + return byteMap; } -void Fl_Android_Font_Descriptor::free_bitmap(uint8_t *bitmap) +float Fl_Android_Font_Source::get_advance(uint32_t c, Fl_Fontsize size) { - stbtt_FreeBitmap(bitmap, 0L); + int advance, lsb; + + if (pFileBuffer==0) load_font(); + stbtt_GetCodepointHMetrics(&pFont, c, &advance, &lsb); + float scale = stbtt_ScaleForPixelHeight(&pFont, size); + return scale * advance; +} + + +// ----------------------------------------------------------------------------- + + +Fl_Android_Font_Descriptor::Fl_Android_Font_Descriptor(const char *fname, Fl_Android_Font_Source *fsrc, Fl_Font fnum, Fl_Fontsize fsize) : + Fl_Font_Descriptor(fname, fsize), + pFontSource(fsrc), + pFontIndex(fnum) +{ + if (!pFontSource) { + pFontSource = new Fl_Android_Font_Source(fname, fnum); + } + // --- We probably must fill these values in: + // Fl_Font_Descriptor *next; + // Fl_Fontsize size; /**< font size */ + // Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); + // FL_EXPORT ~Fl_Font_Descriptor() {} + // short ascent, descent, q_width; + // unsigned int listbase; // base of display list, 0 = none } float Fl_Android_Font_Descriptor::get_advance(uint32_t c) { - int advance, lsb; - stbtt_GetCodepointHMetrics(&pFont, c, &advance, &lsb); - float scale = stbtt_ScaleForPixelHeight(&pFont, size); + return pFontSource->get_advance(c, size); +} - return scale * advance; + +Fl_Android_Bytemap *Fl_Android_Font_Descriptor::get_bytemap(uint32_t c) +{ + // TODO: cache bytemaps here for fast access + return pFontSource->get_bytemap(c, size); } static Fl_Android_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { - Fl_Fontdesc *s = fl_fonts + fnum; - if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_Fontdesc &s = fl_fonts[fnum]; + if (!s.name) s = fl_fonts[0]; // use 0 if fnum undefined - Fl_Android_Font_Descriptor *f; - for (f = (Fl_Android_Font_Descriptor *) s->first; f; f = (Fl_Android_Font_Descriptor *) f->next) { - if (f->size == size) return f; + Fl_Font_Descriptor *f; + for (f = s.first; f; f = f->next) { + if (f->size==size) return (Fl_Android_Font_Descriptor*)f; } - f = new Fl_Android_Font_Descriptor(s->name, fnum, size); - f->next = s->first; - s->first = f; - return f; + Fl_Android_Font_Source *fsrc = nullptr; + if (s.first) fsrc = ((Fl_Android_Font_Descriptor*)s.first)->get_font_source(); + + Fl_Android_Font_Descriptor *af = new Fl_Android_Font_Descriptor(s.name, fsrc, fnum, size); + af->next = s.first; + s.first = af; + return af; } @@ -169,30 +217,29 @@ void Fl_Android_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) { } -// -- fun with text rendering - int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c) { - unsigned char *bitmap; - int w, h, size = 30; - int dx, dy; +// unsigned char *bitmap; + int oxx = xx; +// int w, h, size = 30; +// int dx, dy; // find the font descriptor Fl_Android_Font_Descriptor *fd = (Fl_Android_Font_Descriptor*)font_descriptor(); if (!fd) return xx; // this should not happen - bitmap = fd->get_bitmap(c, &w, &h, &dx, &dy); + Fl_Android_Bytemap *bm = fd->get_bytemap(c); // rrrr.rggg.gggb.bbbb - xx += dx; yy += dy; + xx += bm->pXOffset; yy += bm->pYOffset; uint16_t cc = make565(fl_color()), cc12 = (cc&0xf7de)>>1, cc14 = (cc12&0xf7de)>>1, cc34 = cc12+cc14; int32_t ss = pStride; uint16_t *bits = pBits; - uint32_t ww = w; - uint32_t hh = h; - unsigned char *s = bitmap; + uint32_t ww = bm->pWidth; + uint32_t hh = bm->pHeight; for (uint32_t iy = 0; iy<hh; ++iy) { uint16_t *d = bits + (yy+iy)*ss + xx; + unsigned char *s = bm->pBytes + iy*bm->pStride; for (uint32_t ix = 0; ix<ww; ++ix) { #if 1 // 5 step antialiasing @@ -218,14 +265,13 @@ int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c) d++; } } - fd->free_bitmap(bitmap); - return xx+fd->get_advance(c); + delete bm; + return oxx + fd->get_advance(c); } + void Fl_Android_Graphics_Driver::draw_unscaled(const char* str, int n, int x, int y) { - if (!str) return; - if (str) { x = x+16*(-n/2); for (int i=0; i<n; i++) @@ -234,33 +280,6 @@ void Fl_Android_Graphics_Driver::draw_unscaled(const char* str, int n, int x, in } -#if 0 - -//"DroidSans.ttf", "DroidSans-Bold.ttf" -> links to "Roboto-Regular.ttf"" -// -//"CutiveMono.ttf" -//"DroidSansMono.ttf" -// -//"Roboto-*.ttf", Regular Bold Italic BoldItalic -// -//"NotoSerif-*.ttf", Regular Bold Italic BoldItalic -// -//"NotoSansSymbols-Regular-Subsetted.ttf" -//"NotoSansSymbols-Regular-Subsetted2.ttf" -// -//"NotoColorEmoji.ttf" - -#include "../../config_lib.h" -#include "Fl_Android_Application.H" -#include "Fl_Android_Graphics_Driver.H" -#include "Fl_Android_Screen_Driver.H" -#include <FL/Fl.H> -#include <FL/platform.H> -#include <errno.h> - - -#endif - // // End of "$Id$". // |
