X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/f2da6da9055cf4f6156ded1e2a8c0e11a4d080ef..e1c0692925:/fontft1.c diff --git a/fontft1.c b/fontft1.c index 7febeede..50602902 100644 --- a/fontft1.c +++ b/fontft1.c @@ -66,9 +66,16 @@ Some of these functions are internal. #define TT_MS_LANGID_ENGLISH_GENERAL 0x0409 #endif +static im_slot_t slot = -1; + /* convert a code point into an index in the glyph cache */ #define TT_HASH(x) ((x) & 0xFF) +typedef struct { + int initialized; + TT_Engine engine; +} i_tt_engine; + typedef struct i_glyph_entry_ { TT_Glyph glyph; unsigned long ch; @@ -105,6 +112,7 @@ struct TT_Fonthandle_ { #define TT_VALID( handle ) ( ( handle ).z != NULL ) static void i_tt_push_error(TT_Error rc); +static void i_tt_uninit(void *); /* Prototypes */ @@ -132,8 +140,6 @@ static undef_int i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *tx /* static globals needed */ -static int TT_initialized = 0; -static TT_Engine engine; static int LTT_dpi = 72; /* FIXME: this ought to be a part of the call interface */ static int LTT_hinted = 1; /* FIXME: this too */ @@ -142,58 +148,90 @@ static int LTT_hinted = 1; /* FIXME: this too */ * FreeType interface */ +void +i_tt_start(void) { + if (slot == -1) + slot = im_context_slot_new(i_tt_uninit); +} + /* =item init_tt() -Initializes the freetype font rendering engine +Initializes the freetype font rendering engine (if needed) =cut */ -static undef_int +static i_tt_engine * i_init_tt(void) { TT_Error error; + im_context_t ctx = im_get_context(); TT_Byte palette[] = { 0, 64, 127, 191, 255 }; + i_tt_engine *result = im_context_slot_get(ctx, slot); i_clear_error(); + if (result == NULL) { + result = mymalloc(sizeof(i_tt_engine)); + memset(result, 0, sizeof(*result)); + im_context_slot_set(ctx, slot, result); + mm_log((1, "allocated FT1 state %p\n", result)); + } + mm_log((1,"init_tt()\n")); - error = TT_Init_FreeType( &engine ); + + if (result->initialized) + return result; + + error = TT_Init_FreeType( &result->engine ); if ( error ){ mm_log((1,"Initialization of freetype failed, code = 0x%x\n", (unsigned)error)); i_tt_push_error(error); i_push_error(0, "Could not initialize freetype 1.x"); - return(1); + return NULL; } #ifdef FTXPOST - error = TT_Init_Post_Extension( engine ); + error = TT_Init_Post_Extension( result->engine ); if (error) { mm_log((1, "Initialization of Post extension failed = 0x%x\n", (unsigned)error)); i_tt_push_error(error); i_push_error(0, "Could not initialize FT 1.x POST extension"); - return 1; + return NULL; } #endif - error = TT_Set_Raster_Gray_Palette(engine, palette); + error = TT_Set_Raster_Gray_Palette(result->engine, palette); if (error) { mm_log((1, "Initialization of gray levels failed = 0x%x\n", (unsigned)error)); i_tt_push_error(error); i_push_error(0, "Could not initialize FT 1.x POST extension"); - return 1; + return NULL; } - TT_initialized = 1; + mm_log((1, "initialized FT1 state %p\n", result)); + + result->initialized = 1; - return(0); + return result; } +static void +i_tt_uninit(void *p) { + i_tt_engine *tteng = p; + + if (tteng->initialized) { + mm_log((1, "finalizing FT1 state %p\n", tteng)); + TT_Done_FreeType(tteng->engine); + } + mm_log((1, "freeing FT1 state %p\n", tteng)); + myfree(tteng); +} /* =item i_tt_get_instance(handle, points, smooth) @@ -315,8 +353,9 @@ i_tt_new(const char *fontname) { TT_Fonthandle *handle; unsigned short i,n; unsigned short platform,encoding; + i_tt_engine *tteng; - if (!TT_initialized && i_init_tt()) { + if ((tteng = i_init_tt()) == NULL) { i_push_error(0, "Could not initialize FT1 engine"); return NULL; } @@ -330,8 +369,9 @@ i_tt_new(const char *fontname) { handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */ /* load the typeface */ - error = TT_Open_Face( engine, fontname, &handle->face ); + error = TT_Open_Face( tteng->engine, fontname, &handle->face ); if ( error ) { + myfree(handle); if ( error == TT_Err_Could_Not_Open_File ) { mm_log((1, "Could not find/open %s.\n", fontname )); } @@ -573,7 +613,7 @@ i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j) { if ( LTT_hinted ) load_flags |= TTLOAD_HINT_GLYPH; if ( !TT_VALID(handle->char_map) ) { - code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1); + code = (j < ' ' - 1) ? 0 : (j - (' ' - 1)); if ( code >= handle->properties.num_Glyphs ) code = 0; } else code = TT_Char_Index( handle->char_map, j ); @@ -647,7 +687,7 @@ i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8, index = TT_Char_Index(handle->char_map, c); } else { - index = (c - ' ' + 1) < 0 ? 0 : (c - ' ' + 1); + index = (c < ' ' - 1) ? 0 : (c - (' ' - 1)); if (index >= handle->properties.num_Glyphs) index = 0; } @@ -723,12 +763,10 @@ i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bi if ( !smooth ) TT_Get_Glyph_Bitmap( glyph, bit, x_off * 64, y_off * 64); else { - TT_F26Dot6 xmin, ymin, xmax, ymax; + TT_F26Dot6 xmin, ymin; xmin = gmetrics->bbox.xMin & -64; ymin = gmetrics->bbox.yMin & -64; - xmax = (gmetrics->bbox.xMax + 63) & -64; - ymax = (gmetrics->bbox.yMax + 63) & -64; i_tt_clear_raster_map( small_bit ); TT_Get_Glyph_Pixmap( glyph, small_bit, -xmin, -ymin ); @@ -832,22 +870,30 @@ i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb } i_render_done(&r); } else { + unsigned char *bmp = mymalloc(bit->width); + i_render r; + + i_render_init(&r, im, bit->width); + for(y=0;yrows;y++) { unsigned mask = 0x80; unsigned char *p = bmap + y * bit->cols; + unsigned char *pout = bmp; for(x = 0; x < bit->width; x++) { - if (*p & mask) { - i_ppix(im, x+xb, y+yb, cl); - } + *pout++ = (*p & mask) ? 0xFF : 0; mask >>= 1; if (!mask) { mask = 0x80; ++p; } } + + i_render_color(&r, xb, yb+y, bit->width, bmp, cl); } + i_render_done(&r); + myfree(bmp); } } @@ -926,7 +972,7 @@ interface for generating single channel raster of text (internal) static int -i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, i_img_dim cords[6], double points, char const* txt, size_t len, int smooth, int utf8 ) { +i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, i_img_dim *cords, double points, char const* txt, size_t len, int smooth, int utf8 ) { int inst; i_img_dim width, height; TT_Raster_Map small_bit; @@ -1062,7 +1108,7 @@ Function to get texts bounding boxes given the instance of the font (internal) static undef_int -i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim cords[BOUNDING_BOX_COUNT], int utf8 ) { +i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim *cords, int utf8 ) { int upm, casc, cdesc, first; int start = 0; @@ -1074,8 +1120,6 @@ i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_ int rightb = 0; unsigned long j; - unsigned char *ustr; - ustr=(unsigned char*)txt; mm_log((1,"i_tt_box_inst(handle %p,inst %d,txt '%.*s', len %ld, utf8 %d)\n", handle, inst, (int)len, txt, (long)len, utf8)); @@ -1163,7 +1207,7 @@ Interface to get a strings bounding box */ undef_int -i_tt_bbox( TT_Fonthandle *handle, double points,const char *txt,size_t len,i_img_dim cords[6], int utf8) { +i_tt_bbox( TT_Fonthandle *handle, double points,const char *txt,size_t len,i_img_dim *cords, int utf8) { int inst; i_clear_error();