diff --git a/src/blob.S b/src/blob.S index a23135e..19b56cd 100644 --- a/src/blob.S +++ b/src/blob.S @@ -1,8 +1,15 @@ .global heliBlobDefaultFont .global heliBlobDefaultFontSize + .global heliBlobUnicodeFont + .global heliBlobUnicodeFontSize .section .rodata heliBlobDefaultFont: - .incbin "src/data/unifont.ttf" + .incbin "src/data/canada1500-rg.ttf" 1: +heliBlobUnicodeFont: + .incbin "src/data/unifont.ttf" +2: heliBlobDefaultFontSize: .int 1b - heliBlobDefaultFont +heliBlobUnicodeFontSize: + .int 2b - heliBlobUnicodeFont diff --git a/src/data/canada1500-rg.ttf b/src/data/canada1500-rg.ttf new file mode 100644 index 0000000..ef03b4d Binary files /dev/null and b/src/data/canada1500-rg.ttf differ diff --git a/src/font.c b/src/font.c index 40e3c68..9297f90 100644 --- a/src/font.c +++ b/src/font.c @@ -84,6 +84,8 @@ static HeliFontMap *fontMapFirst, *fontMapLast; static HeliGlyph blankGlyph; static const char blankPath[] = ""; static Font defaultFont = NULL; +static Font unicodeFont = NULL; + static HeliFontMap* createFontMap() { HeliFontMap *map = calloc(1, sizeof(*map)); @@ -241,7 +243,7 @@ static HeliFontInstance* loadFont(const char *path) { ftInitialized = TRUE; } if (ftLibrary) { - if (path[0]) { + if (path[0] && path[0] != 1) { if (FT_New_Face(ftLibrary, path, 0, &fi->face)) { fprintf(stderr, "helianthus: cannot load font from file: %s\n", path); fi->face = NULL; @@ -249,10 +251,10 @@ static HeliFontInstance* loadFont(const char *path) { } else { FT_Open_Args args = {}; args.flags = FT_OPEN_MEMORY; - args.memory_base = (FT_Byte*)heliBlobDefaultFont; - args.memory_size = heliBlobDefaultFontSize; + args.memory_base = path[0] ? (FT_Byte*)heliBlobUnicodeFont : (FT_Byte*)heliBlobDefaultFont; + args.memory_size = path[0] ? heliBlobUnicodeFontSize : heliBlobDefaultFontSize; if (FT_Open_Face(ftLibrary, &args, 0, &fi->face)) { - fprintf(stderr, "helianthus: cannot initialize default font\n"); + fprintf(stderr, "helianthus: cannot initialize %s font\n", path[0] ? "unicode" : "default"); fi->face = NULL; } } @@ -333,24 +335,34 @@ TextLayout createTextLayout(const char *text) { HeliDrawingState *drawingState = heliDrawingGetState(); if (!defaultFont) defaultFont = createFont(NULL); - HeliFontInstance *f = drawingState->font ? drawingState->font->instance : NULL; - HeliFontInstance *ff = defaultFont ? defaultFont->instance : NULL; - if (!f) f = ff; - if (!ff) ff = f; - if (!f) return layout; - - if (!f->face) f = ff; - if (!ff->face) ff = f; - if (!f->face) return layout; + if (!unicodeFont) unicodeFont = createFont("\1"); + + HeliFontInstance *fonts[10]; + int fontsCount = 0; + if ( drawingState->font + && drawingState->font->instance + && drawingState->font->instance->face ) + fonts[fontsCount++] = drawingState->font->instance; + if ( defaultFont + && defaultFont->instance + && defaultFont->instance->face ) + fonts[fontsCount++] = defaultFont->instance; + if ( unicodeFont + && unicodeFont->instance + && unicodeFont->instance->face ) + fonts[fontsCount++] = unicodeFont->instance; + + if (!fontsCount) + return layout; int linesAllocated = 256; layout->linesCount = 1; layout->lines = calloc(linesAllocated, sizeof(HeliLineDesc)); HeliLineDesc *line = layout->lines; - line->height = f->height; + line->height = fonts[0]->height; layout->chars = calloc(strlen(text) + 1, sizeof(HeliCharDesc)); - if (defaultFont && defaultFont->instance != f) - layout->font = createFont(f->path); + if (fonts[0]->path && fonts[0]->path[0] != '\1') + layout->font = createFont(fonts[0]->path); // gather glyphs const char *c = text; @@ -377,10 +389,10 @@ TextLayout createTextLayout(const char *text) { HeliGlyph *glyph = &blankGlyph; int code2 = (code == 0 || code == 10 || code == 13) ? 32 : code; - if (!glyph->fi) glyph = getGlyph(f, code2); - if (!glyph->fi) glyph = getGlyph(ff, code2); - if (!glyph->fi) glyph = getGlyph(f, FONT_BADCHAR_CODE); - if (!glyph->fi) glyph = getGlyph(ff, FONT_BADCHAR_CODE); + for(int i = 0; i < fontsCount && !glyph->fi; ++i) + glyph = getGlyph(fonts[i], code2); + for(int i = 0; i < fontsCount && !glyph->fi; ++i) + glyph = getGlyph(fonts[i], FONT_BADCHAR_CODE); if (!glyph->fi) continue; HeliCharDesc *cc = &layout->chars[line->end++]; @@ -417,7 +429,7 @@ TextLayout createTextLayout(const char *text) { ++line; ++layout->linesCount; line->begin = line->end = (line - 1)->end; - line->height = f->height; + line->height = fonts[0]->height; } if (code == 0) break; } @@ -637,6 +649,8 @@ double textLayoutGetHeight(TextLayout layout) { void heliFontFinish() { + defaultFont = NULL; + unicodeFont = NULL; heliArrayDestroy(&fontCache); if (ftInitialized && ftLibrary) FT_Done_FreeType(ftLibrary); ftLibrary = NULL; diff --git a/src/private.h b/src/private.h index 3b5821e..f576acf 100644 --- a/src/private.h +++ b/src/private.h @@ -32,6 +32,8 @@ extern char heliBlobDefaultFont[] asm("heliBlobDefaultFont"); extern int heliBlobDefaultFontSize asm("heliBlobDefaultFontSize"); +extern char heliBlobUnicodeFont[] asm("heliBlobUnicodeFont"); +extern int heliBlobUnicodeFontSize asm("heliBlobUnicodeFontSize"); // string