diff options
-rw-r--r-- | common.h | 22 | ||||
-rw-r--r-- | libskrift_close_font.c | 3 | ||||
-rw-r--r-- | libskrift_create_context.c | 4 | ||||
-rw-r--r-- | libskrift_get_grapheme_glyph.c | 27 | ||||
-rw-r--r-- | libskrift_open_font___.c | 39 |
5 files changed, 59 insertions, 36 deletions
@@ -14,31 +14,25 @@ #include <string.h> #include <unistd.h> -#include <schrift.h> #include <grapheme.h> +#include <schrift.h> #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define ELEMSOF(ARR) (sizeof(ARR) / sizeof(*(ARR))) +#define FLAGXOR(F, A, B) ((((F) / (A)) ^ ((F) / (B))) & 1) + #define FLEXSTRUCTSIZE(STRUCT, FLEXARRAY, FLEXARRAY_LENGTH)\ (offsetof(STRUCT, FLEXARRAY) + (FLEXARRAY_LENGTH) * sizeof(*((STRUCT *)NULL)->FLEXARRAY)) -enum font_type { - FONT_TYPE_SCHRIFT /* using libschrift backend */ -}; - struct libskrift_font { - enum font_type font_type; - union { - void *any; - SFT_Font *schrift; - } font; - void *memory_free; - void *memory_unmap; - size_t memory_size; - size_t refcount; + SFT_Font *font; + void *memory_free; + void *memory_unmap; + size_t memory_size; + size_t refcount; }; struct libskrift_context { diff --git a/libskrift_close_font.c b/libskrift_close_font.c index c665cdb..2786666 100644 --- a/libskrift_close_font.c +++ b/libskrift_close_font.c @@ -5,8 +5,7 @@ void libskrift_close_font(LIBSKRIFT_FONT *font) { if (font && !--font->refcount) { - if (font->font_type == FONT_TYPE_SCHRIFT) - sft_freefont(font->font.schrift); + sft_freefont(font->font); free(font->memory_free); if (font->memory_unmap) munmap(font->memory_unmap, font->memory_size); diff --git a/libskrift_create_context.c b/libskrift_create_context.c index 15f8d50..6554f6a 100644 --- a/libskrift_create_context.c +++ b/libskrift_create_context.c @@ -5,6 +5,7 @@ LIBSKRIFT_NO_AUTOHINTING |\ LIBSKRIFT_NO_AUTOKERNING) +/* TODO implement more flags */ #define IMPLEMENTED_FLAGS (LIBSKRIFT_REMOVE_GAMMA |\ LIBSKRIFT_MIRROR_TEXT |\ LIBSKRIFT_MIRROR_CHARS |\ @@ -38,7 +39,7 @@ transformation_hook(void *hook_data, double advance, double transform[6]) double schrift[6] = {transform[0], transform[2], transform[4], transform[1], transform[3], transform[5]}; double m1[6] = {1, 0, 0, 0, 1, 0}, m2[6] = {1, 0, 0, 0, 1, 0}; - if (((ctx->rendering.flags / LIBSKRIFT_MIRROR_CHARS) ^ (ctx->rendering.flags / LIBSKRIFT_MIRROR_TEXT)) & 1) + if (FLAGXOR(ctx->rendering.flags, LIBSKRIFT_MIRROR_CHARS, LIBSKRIFT_MIRROR_TEXT)) multiply_matrices((double []){-1, 0, advance / schrift[0], 0, 1, 0}, m2, m1); multiply_matrices(ctx->transformation, m1, m2); multiply_matrices(schrift, m2, m1); @@ -75,7 +76,6 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_ if (!*ctxp) return -1; - (*ctxp)->schrift_ctx.font = fonts[0]->font.schrift; (*ctxp)->schrift_ctx.yScale = height; (*ctxp)->char_x_advancement = 1; (*ctxp)->char_y_advancement = 0; diff --git a/libskrift_get_grapheme_glyph.c b/libskrift_get_grapheme_glyph.c index 515e81d..e0b699d 100644 --- a/libskrift_get_grapheme_glyph.c +++ b/libskrift_get_grapheme_glyph.c @@ -1,9 +1,9 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" -int -libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codepoint, - double cursor_x, double cursor_y, struct libskrift_glyph **glyphp) +static int +get_grapheme_glyph_with_font(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codepoint, double cursor_x, + double cursor_y, struct libskrift_glyph **glyphp, LIBSKRIFT_FONT *font) { struct SFT_Char sft_chr; struct SFT sft_ctx; @@ -15,12 +15,14 @@ libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codep memset(&sft_chr, 0, sizeof(sft_chr)); sft_ctx = ctx->schrift_ctx; + sft_ctx.font = font->font; sft_ctx.x = cursor_x * (ctx->subpixel_horizontally ? 3 : 1); sft_ctx.y = cursor_y * (ctx->subpixel_vertically ? 3 : 1); sft_ctx.flags = SFT_DOWNWARD_Y | SFT_CHAR_IMAGE; + errno = 0; if (sft_char(&sft_ctx, codepoint, &sft_chr)) - return -1; + return errno ? -1 : 1; if (ctx->subpixel_horizontally) { hmul = 3; @@ -99,3 +101,20 @@ libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codep free(sft_chr.image); return 0; } + +int +libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codepoint, + double cursor_x, double cursor_y, struct libskrift_glyph **glyphp) +{ + size_t i; + int r; + + for (i = 0; i < ctx->nfonts; i++) { + r = get_grapheme_glyph_with_font(ctx, codepoint, cursor_x, cursor_y, glyphp, ctx->fonts[i]); + if (r <= 0) + return r; + } + + /* TODO add callback for drawing fallback glyph, draw square by default. */ + return -1; +} diff --git a/libskrift_open_font___.c b/libskrift_open_font___.c index c1bcfb5..3668cb3 100644 --- a/libskrift_open_font___.c +++ b/libskrift_open_font___.c @@ -9,6 +9,10 @@ #define IS_PSF_V2() (size >= 32 && mem8[0] == 0x72 && mem8[1] == 0xb5 && mem8[2] == 0x4a && mem8[3] == 0x86) #if defined(GUNZIP_PATH) +# define WITH_DECOMPRESS +#endif + +#ifdef WITH_DECOMPRESS static int decompress(const char *path, const void *mem, size_t size, void **memp, size_t *sizep) { @@ -200,8 +204,10 @@ libskrift_open_font___(LIBSKRIFT_FONT **fontp, const void *mem_static, void *mem const void *mem = mem_static ? mem_static : mem_free ? mem_free : mem_unmap; const uint8_t *mem8 = mem; void *new_mem = NULL; -#if defined(GUNZIP_PATH) - size_t new_size = 0; +#ifdef WITH_DECOMPRESS + void *free_on_failure = NULL; + void *old_free = NULL, *old_unmap = NULL; + size_t new_size = 0, old_size = size; #endif *fontp = calloc(1, sizeof(**fontp)); @@ -213,28 +219,26 @@ libskrift_open_font___(LIBSKRIFT_FONT **fontp, const void *mem_static, void *mem if (IS_GZIP()) { if (decompress(GUNZIP_PATH, mem, size, &new_mem, &new_size)) return -1; - if (mem_free) - free(mem_free); - else if (mem_unmap) - munmap(mem_unmap, size); + old_free = mem_free; + old_unmap = mem_unmap; mem_static = NULL; mem_unmap = NULL; - mem8 = mem = mem_free = new_mem; + mem8 = mem = free_on_failure = mem_free = new_mem; size = new_size; } #endif - if (IS_PSF_V1() || IS_PSF_V2()) { /* TODO */ - errno = EBFONT; - return -1; - } else { - (*fontp)->font_type = FONT_TYPE_SCHRIFT; - (*fontp)->font.schrift = sft_loadmem(mem, size); + if (IS_PSF_V1() || IS_PSF_V2()) { + /* TODO Convert to TTF */ } - if (!(*fontp)->font.any) { + (*fontp)->font = sft_loadmem(mem, size); + if (!(*fontp)->font) { free(*fontp); *fontp = NULL; +#ifdef WITH_DECOMPRESS + free(free_on_failure); +#endif return -1; } @@ -246,5 +250,12 @@ libskrift_open_font___(LIBSKRIFT_FONT **fontp, const void *mem_static, void *mem (*fontp)->memory_size = size; } +#ifdef WITH_DECOMPRESS + if (old_free) + free(old_free); + else if (old_unmap) + munmap(old_unmap, old_size); +#endif + return 0; } |