X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/919e000036fafbcd32820043c35ba707bb55e92f..335078fc1032a3f10dfc337e18f61f6ae89a5243:/font.c diff --git a/font.c b/font.c index 0ab6f912..f6f69a87 100644 --- a/font.c +++ b/font.c @@ -9,7 +9,6 @@ #include #ifdef HAVE_LIBT1 -#include #endif @@ -24,7 +23,7 @@ font.c - implements font handling functions for t1 and truetype fonts #ifdef HAVE_LIBT1 fontnum = i_t1_new(path_to_pfb, path_to_afm); - i_t1_bbox(fontnum, points, "foo", 3, int cords[6]); + i_t1_bbox(fontnum, points, "foo", 3, i_img_dim cords[BOUNDING_BOX_COUNT]); rc = i_t1_destroy(fontnum); #endif @@ -50,712 +49,6 @@ Some of these functions are internal. */ -/* -=item i_init_fonts() - -Initialize font rendering libraries if they are avaliable. - -=cut -*/ - -undef_int -i_init_fonts(int t1log) { - mm_log((1,"Initializing fonts\n")); - -#ifdef HAVE_LIBT1 - i_init_t1(t1log); -#endif - -#ifdef HAVE_LIBTT - i_init_tt(); -#endif - -#ifdef HAVE_FT2 - if (!i_ft2_init()) - return 0; -#endif - - return(1); /* FIXME: Always true - check the return values of the init_t1 and init_tt functions */ -} - - - - -#ifdef HAVE_LIBT1 - -static int t1_get_flags(char const *flags); -static char *t1_from_utf8(char const *in, int len, int *outlen); - -static void t1_push_error(void); - -static int t1_active_fonts = 0; -static int t1_initialized = 0; - -/* -=item i_init_t1(t1log) - -Initializes the t1lib font rendering engine. - -=cut -*/ - -undef_int -i_init_t1(int t1log) { - int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE; - mm_log((1,"init_t1()\n")); - - if (t1_active_fonts) { - mm_log((1, "Cannot re-initialize T1 - active fonts\n")); - return 1; - } - - if (t1_initialized) { - T1_CloseLib(); - } - - if (t1log) - init_flags |= LOGFILE; - if ((T1_InitLib(init_flags) == NULL)){ - mm_log((1,"Initialization of t1lib failed\n")); - return(1); - } - T1_SetLogLevel(T1LOG_DEBUG); - i_t1_set_aa(1); /* Default Antialias value */ - - ++t1_initialized; - - return(0); -} - - -/* -=item i_close_t1() - -Shuts the t1lib font rendering engine down. - - This it seems that this function is never used. - -=cut -*/ - -void -i_close_t1(void) { - T1_CloseLib(); - t1_initialized = 0; -} - - -/* -=item i_t1_new(pfb, afm) - -Loads the fonts with the given filenames, returns its font id - - pfb - path to pfb file for font - afm - path to afm file for font - -=cut -*/ - -int -i_t1_new(char *pfb,char *afm) { - int font_id; - - mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL"))); - font_id = T1_AddFont(pfb); - if (font_id<0) { - mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id)); - return font_id; - } - - if (afm != NULL) { - mm_log((1,"i_t1_new: requesting afm file '%s'.\n",afm)); - if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm)); - } - - ++t1_active_fonts; - - return font_id; -} - -/* -=item i_t1_destroy(font_id) - -Frees resources for a t1 font with given font id. - - font_id - number of the font to free - -=cut -*/ - -int -i_t1_destroy(int font_id) { - mm_log((1,"i_t1_destroy(font_id %d)\n",font_id)); - - --t1_active_fonts; - - return T1_DeleteFont(font_id); -} - - -/* -=item i_t1_set_aa(st) - -Sets the antialiasing level of the t1 library. - - st - 0 = NONE, 1 = LOW, 2 = HIGH. - -=cut -*/ - -void -i_t1_set_aa(int st) { - int i; - unsigned long cst[17]; - switch(st) { - case 0: - T1_AASetBitsPerPixel( 8 ); - T1_AASetLevel( T1_AA_NONE ); - T1_AANSetGrayValues( 0, 255 ); - mm_log((1,"setting T1 antialias to none\n")); - break; - case 1: - T1_AASetBitsPerPixel( 8 ); - T1_AASetLevel( T1_AA_LOW ); - T1_AASetGrayValues( 0,65,127,191,255 ); - mm_log((1,"setting T1 antialias to low\n")); - break; - case 2: - T1_AASetBitsPerPixel(8); - T1_AASetLevel(T1_AA_HIGH); - for(i=0;i<17;i++) cst[i]=(i*255)/16; - T1_AAHSetGrayValues( cst ); - mm_log((1,"setting T1 antialias to high\n")); - } -} - - -/* -=item i_t1_cp(im, xb, yb, channel, fontnum, points, str, len, align) - -Interface to text rendering into a single channel in an image - - im pointer to image structure - xb x coordinate of start of string - yb y coordinate of start of string ( see align ) - channel - destination channel - fontnum - t1 library font id - points - number of points in fontheight - str - string to render - len - string length - align - (0 - top of font glyph | 1 - baseline ) - -=cut -*/ - -undef_int -i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,int len,int align, int utf8, char const *flags) { - GLYPH *glyph; - int xsize,ysize,x,y; - i_color val; - int mod_flags = t1_get_flags(flags); - - unsigned int ch_mask_store; - - if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); } - - if (utf8) { - int worklen; - char *work = t1_from_utf8(str, len, &worklen); - glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL); - myfree(work); - } - else { - glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL); - } - if (glyph == NULL) - return 0; - - mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent)); - mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing)); - mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY)); - mm_log((1,"bpp: %d\n",glyph->bpp)); - - xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing; - ysize=glyph->metrics.ascent-glyph->metrics.descent; - - mm_log((1,"width: %d height: %d\n",xsize,ysize)); - - ch_mask_store=im->ch_mask; - im->ch_mask=1<metrics.leftSideBearing; yb-=glyph->metrics.ascent; } - - for(y=0;ybits[y*xsize+x]; - i_ppix(im,x+xb,y+yb,&val); - } - - im->ch_mask=ch_mask_store; - return 1; -} - -static void -t1_fix_bbox(BBox *bbox, const char *str, int len, int advance, - int space_position) { - /* never called with len == 0 */ - if (str[0] == space_position && bbox->llx > 0) - bbox->llx = 0; - if (str[len-1] == space_position && bbox->urx < advance) - bbox->urx = advance; - if (bbox->lly > bbox->ury) - bbox->lly = bbox->ury = 0; -} - -/* -=item i_t1_bbox(handle, fontnum, points, str, len, cords) - -function to get a strings bounding box given the font id and sizes - - handle - pointer to font handle - fontnum - t1 library font id - points - number of points in fontheight - str - string to measure - len - string length - cords - the bounding box (modified in place) - -=cut -*/ - -int -i_t1_bbox(int fontnum,float points,const char *str,int len,int cords[6], int utf8,char const *flags) { - BBox bbox; - BBox gbbox; - int mod_flags = t1_get_flags(flags); - int advance; - int space_position = T1_GetEncodingIndex(fontnum, "space"); - - mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len)); - T1_LoadFont(fontnum); /* FIXME: Here a return code is ignored - haw haw haw */ - - if (len == 0) { - /* len == 0 has special meaning to T1lib, but it means there's - nothing to draw, so return that */ - bbox.llx = bbox.lly = bbox.urx = bbox.ury = 0; - advance = 0; - } - else { - if (utf8) { - int worklen; - char *work = t1_from_utf8(str, len, &worklen); - advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags); - bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags); - t1_fix_bbox(&bbox, work, worklen, advance, space_position); - myfree(work); - } - else { - advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags); - bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags); - t1_fix_bbox(&bbox, str, len, advance, space_position); - } - } - gbbox = T1_GetFontBBox(fontnum); - - mm_log((1,"bbox: (%d,%d,%d,%d)\n", - (int)(bbox.llx*points/1000), - (int)(gbbox.lly*points/1000), - (int)(bbox.urx*points/1000), - (int)(gbbox.ury*points/1000), - (int)(bbox.lly*points/1000), - (int)(bbox.ury*points/1000) )); - - - cords[BBOX_NEG_WIDTH]=((float)bbox.llx*points)/1000; - cords[BBOX_POS_WIDTH]=((float)bbox.urx*points)/1000; - - cords[BBOX_GLOBAL_DESCENT]=((float)gbbox.lly*points)/1000; - cords[BBOX_GLOBAL_ASCENT]=((float)gbbox.ury*points)/1000; - - cords[BBOX_DESCENT]=((float)bbox.lly*points)/1000; - cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000; - - cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000; - cords[BBOX_RIGHT_BEARING] = - cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH]; - - return BBOX_RIGHT_BEARING+1; -} - - -/* -=item i_t1_text(im, xb, yb, cl, fontnum, points, str, len, align) - -Interface to text rendering in a single color onto an image - - im - pointer to image structure - xb - x coordinate of start of string - yb - y coordinate of start of string ( see align ) - cl - color to draw the text in - fontnum - t1 library font id - points - number of points in fontheight - str - char pointer to string to render - len - string length - align - (0 - top of font glyph | 1 - baseline ) - -=cut -*/ - -undef_int -i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,int len,int align, int utf8, char const *flags) { - GLYPH *glyph; - int xsize,ysize,y; - int mod_flags = t1_get_flags(flags); - i_render r; - - if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); } - - if (utf8) { - int worklen; - char *work = t1_from_utf8(str, len, &worklen); - glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL); - myfree(work); - } - else { - /* T1_AASetString() accepts a char * not a const char */ - glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL); - } - if (glyph == NULL) - return 0; - - mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent)); - mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing)); - mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY)); - mm_log((1,"bpp: %d\n",glyph->bpp)); - - xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing; - ysize=glyph->metrics.ascent-glyph->metrics.descent; - - mm_log((1,"width: %d height: %d\n",xsize,ysize)); - - if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; } - - i_render_init(&r, im, xsize); - for(y=0;ybits+y*xsize, cl); - } - i_render_done(&r); - - return 1; -} - -/* -=item t1_get_flags(flags) - -Processes the characters in I to create a mod_flags value used -by some T1Lib functions. - -=cut - */ -static int -t1_get_flags(char const *flags) { - int mod_flags = T1_KERNING; - - while (*flags) { - switch (*flags++) { - case 'u': case 'U': mod_flags |= T1_UNDERLINE; break; - case 'o': case 'O': mod_flags |= T1_OVERLINE; break; - case 's': case 'S': mod_flags |= T1_OVERSTRIKE; break; - /* ignore anything we don't recognize */ - } - } - - return mod_flags; -} - -/* -=item t1_from_utf8(char const *in, int len, int *outlen) - -Produces an unencoded version of I by dropping any Unicode -character over 255. - -Returns a newly allocated buffer which should be freed with myfree(). -Sets *outlen to the number of bytes used in the output string. - -=cut -*/ - -static char * -t1_from_utf8(char const *in, int len, int *outlen) { - /* at this point len is from a perl SV, so can't approach MAXINT */ - char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */ - char *p = out; - unsigned long c; - - while (len) { - c = i_utf8_advance(&in, &len); - if (c == ~0UL) { - myfree(out); - i_push_error(0, "invalid UTF8 character"); - return 0; - } - /* yeah, just drop them */ - if (c < 0x100) { - *p++ = (char)c; - } - } - *p = '\0'; - *outlen = p - out; - - return out; -} - -/* -=item i_t1_has_chars(font_num, text, len, utf8, out) - -Check if the given characters are defined by the font. Note that len -is the number of bytes, not the number of characters (when utf8 is -non-zero). - -out[char index] will be true if the character exists. - -Accepts UTF-8, but since T1 can only have 256 characters, any chars -with values over 255 will simply be returned as false. - -Returns the number of characters that were checked. - -=cut -*/ - -int -i_t1_has_chars(int font_num, const char *text, int len, int utf8, - char *out) { - int count = 0; - - mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %d, utf8 %d)\n", - font_num, text, len, utf8)); - - i_clear_error(); - if (T1_LoadFont(font_num)) { - t1_push_error(); - return 0; - } - - while (len) { - unsigned long c; - if (utf8) { - c = i_utf8_advance(&text, &len); - if (c == ~0UL) { - i_push_error(0, "invalid UTF8 character"); - return 0; - } - } - else { - c = (unsigned char)*text++; - --len; - } - - if (c >= 0x100) { - /* limit of 256 characters for T1 */ - *out++ = 0; - } - else { - char const * name = T1_GetCharName(font_num, (unsigned char)c); - - if (name) { - *out++ = strcmp(name, ".notdef") != 0; - } - else { - mm_log((2, " No name found for character %lx\n", c)); - *out++ = 0; - } - } - ++count; - } - - return count; -} - -/* -=item i_t1_face_name(font_num, name_buf, name_buf_size) - -Copies the face name of the given C to C. Returns -the number of characters required to store the name (which can be -larger than C, including the space required to store -the terminating NUL). - -If name_buf is too small (as specified by name_buf_size) then the name -will be truncated. name_buf will always be NUL termintaed. - -=cut -*/ - -int -i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size) { - char *name; - - T1_errno = 0; - if (T1_LoadFont(font_num)) { - t1_push_error(); - return 0; - } - name = T1_GetFontName(font_num); - - if (name) { - strncpy(name_buf, name, name_buf_size); - name_buf[name_buf_size-1] = '\0'; - return strlen(name) + 1; - } - else { - t1_push_error(); - return 0; - } -} - -int -i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf, - size_t name_buf_size) { - char *name; - - i_clear_error(); - if (ch > 0xFF) { - return 0; - } - if (T1_LoadFont(font_num)) { - t1_push_error(); - return 0; - } - name = T1_GetCharName(font_num, (unsigned char)ch); - if (name) { - if (strcmp(name, ".notdef")) { - strncpy(name_buf, name, name_buf_size); - name_buf[name_buf_size-1] = '\0'; - return strlen(name) + 1; - } - else { - return 0; - } - } - else { - t1_push_error(); - return 0; - } -} - -static void -t1_push_error(void) { - switch (T1_errno) { - case 0: - i_push_error(0, "No error"); - break; - -#ifdef T1ERR_SCAN_FONT_FORMAT - case T1ERR_SCAN_FONT_FORMAT: - i_push_error(T1ERR_SCAN_FONT_FORMAT, "SCAN_FONT_FORMAT"); - break; -#endif - -#ifdef T1ERR_SCAN_FILE_OPEN_ERR - case T1ERR_SCAN_FILE_OPEN_ERR: - i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "SCAN_FILE_OPEN_ERR"); - break; -#endif - -#ifdef T1ERR_SCAN_OUT_OF_MEMORY - case T1ERR_SCAN_OUT_OF_MEMORY: - i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "SCAN_OUT_OF_MEMORY"); - break; -#endif - -#ifdef T1ERR_SCAN_ERROR - case T1ERR_SCAN_ERROR: - i_push_error(T1ERR_SCAN_ERROR, "SCAN_ERROR"); - break; -#endif - -#ifdef T1ERR_SCAN_FILE_EOF - case T1ERR_SCAN_FILE_EOF: - i_push_error(T1ERR_SCAN_FILE_EOF, "SCAN_FILE_EOF"); - break; -#endif - -#ifdef T1ERR_PATH_ERROR - case T1ERR_PATH_ERROR: - i_push_error(T1ERR_PATH_ERROR, "PATH_ERROR"); - break; -#endif - -#ifdef T1ERR_PARSE_ERROR - case T1ERR_PARSE_ERROR: - i_push_error(T1ERR_PARSE_ERROR, "PARSE_ERROR"); - break; -#endif - -#ifdef T1ERR_TYPE1_ABORT - case T1ERR_TYPE1_ABORT: - i_push_error(T1ERR_TYPE1_ABORT, "TYPE1_ABORT"); - break; -#endif - -#ifdef T1ERR_INVALID_FONTID - case T1ERR_INVALID_FONTID: - i_push_error(T1ERR_INVALID_FONTID, "INVALID_FONTID"); - break; -#endif - -#ifdef T1ERR_INVALID_PARAMETER - case T1ERR_INVALID_PARAMETER: - i_push_error(T1ERR_INVALID_PARAMETER, "INVALID_PARAMETER"); - break; -#endif - -#ifdef T1ERR_OP_NOT_PERMITTED - case T1ERR_OP_NOT_PERMITTED: - i_push_error(T1ERR_OP_NOT_PERMITTED, "OP_NOT_PERMITTED"); - break; -#endif - -#ifdef T1ERR_ALLOC_MEM - case T1ERR_ALLOC_MEM: - i_push_error(T1ERR_ALLOC_MEM, "ALLOC_MEM"); - break; -#endif - -#ifdef T1ERR_FILE_OPEN_ERR - case T1ERR_FILE_OPEN_ERR: - i_push_error(T1ERR_FILE_OPEN_ERR, "FILE_OPEN_ERR"); - break; -#endif - -#ifdef T1ERR_UNSPECIFIED - case T1ERR_UNSPECIFIED: - i_push_error(T1ERR_UNSPECIFIED, "UNSPECIFIED"); - break; -#endif - -#ifdef T1ERR_NO_AFM_DATA - case T1ERR_NO_AFM_DATA: - i_push_error(T1ERR_NO_AFM_DATA, "NO_AFM_DATA"); - break; -#endif - -#ifdef T1ERR_X11 - case T1ERR_X11: - i_push_error(T1ERR_X11, "X11"); - break; -#endif - -#ifdef T1ERR_COMPOSITE_CHAR - case T1ERR_COMPOSITE_CHAR: - i_push_error(T1ERR_COMPOSITE_CHAR, "COMPOSITE_CHAR"); - break; -#endif - - default: - i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno); - } -} - -#endif /* HAVE_LIBT1 */ - /* Truetype font support */ #ifdef HAVE_LIBTT @@ -801,8 +94,8 @@ struct TT_Instancehandle_ { TT_Glyph_Metrics gmetrics[256]; i_tt_glyph_entry glyphs[256]; int smooth; - int ptsize; int order; + i_img_dim ptsize; }; typedef struct TT_Instancehandle_ TT_Instancehandle; @@ -827,30 +120,31 @@ static void i_tt_push_error(TT_Error rc); /* Prototypes */ -static int i_tt_get_instance( TT_Fonthandle *handle, int points, int smooth ); -static void i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ); +static int i_tt_get_instance( TT_Fonthandle *handle, i_img_dim points, int smooth ); +static void i_tt_init_raster_map( TT_Raster_Map* bit, i_img_dim width, i_img_dim height, int smooth ); static void i_tt_done_raster_map( TT_Raster_Map *bit ); static void i_tt_clear_raster_map( TT_Raster_Map* bit ); -static void i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off ); +static void i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,i_img_dim x_off, i_img_dim y_off ); static int i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j ); static void i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bit, TT_Raster_Map *small_bit, - int x_off, int y_off, int smooth ); + i_img_dim x_off, i_img_dim y_off, int smooth ); static int i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit, - TT_Raster_Map *small_bit, int cords[6], - char const* txt, int len, int smooth, int utf8 ); -static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth ); -static void i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, int xb, int yb, int channel, int smooth ); + TT_Raster_Map *small_bit, i_img_dim cords[6], + char const* txt, size_t len, int smooth, int utf8 ); +static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, const i_color *cl, int smooth ); +static void i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, int channel, int smooth ); static int -i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6], - float points, char const* txt, int len, int smooth, int utf8 ); -static undef_int i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, int len, int cords[6], int utf8 ); +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 ); +static undef_int i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim cords[6], int utf8 ); /* 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 */ @@ -870,31 +164,45 @@ Initializes the freetype font rendering engine */ undef_int -i_init_tt() { +i_init_tt(void) { TT_Error error; TT_Byte palette[] = { 0, 64, 127, 191, 255 }; + i_clear_error(); + mm_log((1,"init_tt()\n")); error = TT_Init_FreeType( &engine ); if ( error ){ - mm_log((1,"Initialization of freetype failed, code = 0x%x\n",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); } #ifdef FTXPOST error = TT_Init_Post_Extension( engine ); if (error) { - mm_log((1, "Initialization of Post extension failed = 0x%x\n", 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; } #endif error = TT_Set_Raster_Gray_Palette(engine, palette); if (error) { - mm_log((1, "Initialization of gray levels failed = 0x%x\n", 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; } + TT_initialized = 1; + return(0); } @@ -915,12 +223,12 @@ allocates room and returns its cache entry static int -i_tt_get_instance( TT_Fonthandle *handle, int points, int smooth ) { +i_tt_get_instance( TT_Fonthandle *handle, i_img_dim points, int smooth ) { int i,idx; TT_Error error; - mm_log((1,"i_tt_get_instance(handle 0x%X, points %d, smooth %d)\n", - handle,points,smooth)); + mm_log((1,"i_tt_get_instance(handle %p, points %" i_DF ", smooth %d)\n", + handle, i_DFc(points), smooth)); if (smooth == -1) { /* Smooth doesn't matter for this search */ for(i=0;iinstanceh[idx].instance) )); if ( USTRCT(handle->instanceh[idx].instance) ) { @@ -975,7 +283,8 @@ i_tt_get_instance( TT_Fonthandle *handle, int points, int smooth ) { ( error = TT_Set_Instance_CharSize( handle->instanceh[idx].instance, points*64 ) ) ); if ( error ) { - mm_log((1, "Could not create and initialize instance: error 0x%x.\n",error )); + mm_log((1, "Could not create and initialize instance: error %x.\n", + (unsigned)error )); return -1; } @@ -1019,6 +328,11 @@ i_tt_new(const char *fontname) { unsigned short i,n; unsigned short platform,encoding; + if (!TT_initialized && i_init_tt()) { + i_push_error(0, "Could not initialize FT1 engine"); + return NULL; + } + i_clear_error(); mm_log((1,"i_tt_new(fontname '%s')\n",fontname)); @@ -1035,7 +349,7 @@ i_tt_new(const char *fontname) { } else { mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname, - error )); + (unsigned)error )); } i_tt_push_error(error); return NULL; @@ -1075,7 +389,7 @@ i_tt_new(const char *fontname) { handle->loaded_names = 0; #endif - mm_log((1,"i_tt_new <- 0x%X\n",handle)); + mm_log((1,"i_tt_new <- %p\n",handle)); return handle; } @@ -1100,9 +414,10 @@ Allocates internal memory for the bitmap as needed by the parameters (internal) static void -i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ) { +i_tt_init_raster_map( TT_Raster_Map* bit, i_img_dim width, i_img_dim height, int smooth ) { - mm_log((1,"i_tt_init_raster_map( bit 08x%08X, width %d, height %d, smooth %d)\n", bit, width, height, smooth)); + mm_log((1,"i_tt_init_raster_map( bit %p, width %" i_DF ", height %" i_DF + ", smooth %d)\n", bit, i_DFc(width), i_DFc(height), smooth)); bit->rows = height; bit->width = ( width + 3 ) & -4; @@ -1122,7 +437,7 @@ i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ) { bit->width, bit->rows); } - mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %d)\n", bit->width, bit->cols, bit->rows, bit->size )); + mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %ld)\n", bit->width, bit->cols, bit->rows, bit->size )); bit->bitmap = (void *) mymalloc( bit->size ); /* checked 6Nov05 tonyc */ if ( !bit->bitmap ) i_fatal(0,"Not enough memory to allocate bitmap (%d)!\n",bit->size ); @@ -1180,9 +495,9 @@ function that blits one raster map into another (internal) static void -i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off ) { - int x, y; - int x1, x2, y1, y2; +i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,i_img_dim x_off, i_img_dim y_off ) { + i_img_dim x, y; + i_img_dim x1, x2, y1, y2; unsigned char *s, *d; x1 = x_off < 0 ? -x_off : 0; @@ -1247,14 +562,14 @@ i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j) { unsigned short load_flags, code; TT_Error error; - mm_log((1, "i_tt_get_glyph(handle 0x%X, inst %d, j %d (%c))\n", - handle,inst,j, ((j >= ' ' && j <= '~') ? j : '.'))); + mm_log((1, "i_tt_get_glyph(handle %p, inst %d, j %lu (%c))\n", + handle,inst,j, (int)((j >= ' ' && j <= '~') ? j : '.'))); /*mm_log((1, "handle->instanceh[inst].glyphs[j]=0x%08X\n",handle->instanceh[inst].glyphs[j] ));*/ if ( TT_VALID(handle->instanceh[inst].glyphs[TT_HASH(j)].glyph) && handle->instanceh[inst].glyphs[TT_HASH(j)].ch == j) { - mm_log((1,"i_tt_get_glyph: %d in cache\n",j)); + mm_log((1,"i_tt_get_glyph: %lu in cache\n",j)); return 1; } @@ -1275,12 +590,12 @@ i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j) { } else code = TT_Char_Index( handle->char_map, j ); if ( (error = TT_New_Glyph( handle->face, &handle->instanceh[inst].glyphs[TT_HASH(j)].glyph)) ) { - mm_log((1, "Cannot allocate and load glyph: error 0x%x.\n", error )); + mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error )); i_push_error(error, "TT_New_Glyph()"); return 0; } if ( (error = TT_Load_Glyph( handle->instanceh[inst].instance, handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, code, load_flags)) ) { - mm_log((1, "Cannot allocate and load glyph: error 0x%x.\n", error )); + mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error )); /* Don't leak */ TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ); USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL; @@ -1295,7 +610,7 @@ i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j) { error = TT_Get_Glyph_Metrics( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, &handle->instanceh[inst].gmetrics[TT_HASH(j)] ); if (error) { - mm_log((1, "TT_Get_Glyph_Metrics: error 0x%x.\n", error )); + mm_log((1, "TT_Get_Glyph_Metrics: error %#x.\n", (unsigned)error )); TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ); USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL; handle->instanceh[inst].glyphs[TT_HASH(j)].ch = TT_NOCHAR; @@ -1318,12 +633,12 @@ Returns the number of characters that were checked. =cut */ -int -i_tt_has_chars(TT_Fonthandle *handle, char const *text, int len, int utf8, +size_t +i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8, char *out) { - int count = 0; - mm_log((1, "i_tt_has_chars(handle %p, text %p, len %d, utf8 %d)\n", - handle, text, len, utf8)); + size_t count = 0; + mm_log((1, "i_tt_has_chars(handle %p, text %p, len %ld, utf8 %d)\n", + handle, text, (long)len, utf8)); while (len) { unsigned long c; @@ -1412,10 +727,11 @@ Renders a single glyph into the bit rastermap (internal) static void -i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bit, TT_Raster_Map *small_bit, int x_off, int y_off, int smooth ) { +i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bit, TT_Raster_Map *small_bit, i_img_dim x_off, i_img_dim y_off, int smooth ) { - mm_log((1,"i_tt_render_glyph(glyph 0x0%X, gmetrics 0x0%X, bit 0x%X, small_bit 0x%X, x_off %d, y_off %d, smooth %d)\n", - USTRCT(glyph), gmetrics, bit, small_bit, x_off,y_off,smooth)); + mm_log((1,"i_tt_render_glyph(glyph %p, gmetrics %p, bit %p, small_bit %p, x_off %" i_DF ", y_off %" i_DF ", smooth %d)\n", + USTRCT(glyph), gmetrics, bit, small_bit, i_DFc(x_off), + i_DFc(y_off), smooth)); if ( !smooth ) TT_Get_Glyph_Bitmap( glyph, bit, x_off * 64, y_off * 64); else { @@ -1452,13 +768,13 @@ calls i_tt_render_glyph to render each glyph into the bit rastermap (internal) static int i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit, - TT_Raster_Map *small_bit, int cords[6], - char const* txt, int len, int smooth, int utf8 ) { + TT_Raster_Map *small_bit, i_img_dim cords[6], + char const* txt, size_t len, int smooth, int utf8 ) { unsigned long j; TT_F26Dot6 x,y; - mm_log((1,"i_tt_render_all_glyphs( handle 0x%X, inst %d, bit 0x%X, small_bit 0x%X, txt '%.*s', len %d, smooth %d, utf8 %d)\n", - handle, inst, bit, small_bit, len, txt, len, smooth, utf8)); + mm_log((1,"i_tt_render_all_glyphs( handle %p, inst %d, bit %p, small_bit %p, txt '%.*s', len %ld, smooth %d, utf8 %d)\n", + handle, inst, bit, small_bit, (int)len, txt, (long)len, smooth, utf8)); /* y=-( handle->properties.horizontal->Descender * handle->instanceh[inst].imetrics.y_ppem )/(handle->properties.header->Units_Per_EM); @@ -1511,10 +827,11 @@ Function to dump a raster onto an image in color used by i_tt_text() (internal). static void -i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth ) { +i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, const i_color *cl, int smooth ) { unsigned char *bmap; - int x, y; - mm_log((1,"i_tt_dump_raster_map2(im 0x%x, bit 0x%X, xb %d, yb %d, cl 0x%X)\n",im,bit,xb,yb,cl)); + i_img_dim x, y; + mm_log((1,"i_tt_dump_raster_map2(im %p, bit %p, xb %" i_DF ", yb %" i_DF ", cl %p)\n", + im, bit, i_DFc(xb), i_DFc(yb), cl)); bmap = bit->bitmap; @@ -1523,18 +840,7 @@ i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_co i_render r; i_render_init(&r, im, bit->cols); for(y=0;yrows;y++) { -#if 0 - for(x=0;xwidth;x++) { - c = (unsigned char)bmap[y*(bit->cols)+x]; - i=255-c; - i_gpix(im,x+xb,y+yb,&val); - for(ch=0;chchannels;ch++) - val.channel[ch] = (c*cl->channel[ch]+i*val.channel[ch])/255; - i_ppix(im,x+xb,y+yb,&val); - } -#else i_render_color(&r, xb, yb+y, bit->cols, bmap + y*bit->cols, cl); -#endif } i_render_done(&r); } else { @@ -1574,14 +880,16 @@ Function to dump a raster onto a single channel image in color (internal) static void -i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, int xb, int yb, int channel, int smooth ) { +i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, int channel, int smooth ) { unsigned char *bmap; i_color val; - int c,x,y; + int c; + i_img_dim x,y; int old_mask = im->ch_mask; im->ch_mask = 1 << channel; - mm_log((1,"i_tt_dump_raster_channel(im 0x%x, bit 0x%X, xb %d, yb %d, channel %d)\n",im,bit,xb,yb,channel)); + mm_log((1,"i_tt_dump_raster_channel(im %p, bit %p, xb %" i_DF ", yb %" i_DF ", channel %d)\n", + im, bit, i_DFc(xb), i_DFc(yb), channel)); bmap = bit->bitmap; @@ -1630,9 +938,9 @@ interface for generating single channel raster of text (internal) static int -i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6], float points, char const* txt, int len, int smooth, int utf8 ) { +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 ) { int inst; - int width, height; + i_img_dim width, height; TT_Raster_Map small_bit; /* find or install an instance */ @@ -1649,7 +957,8 @@ i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6], float p width = cords[2]-cords[0]; height = cords[5]-cords[4]; - mm_log((1,"i_tt_rasterize: width=%d, height=%d\n",width, height )); + mm_log((1,"i_tt_rasterize: width=%" i_DF ", height=%" i_DF "\n", + i_DFc(width), i_DFc(height) )); i_tt_init_raster_map ( bit, width, height, smooth ); i_tt_clear_raster_map( bit ); @@ -1691,10 +1000,10 @@ Interface to text rendering into a single channel in an image */ undef_int -i_tt_cp( TT_Fonthandle *handle, i_img *im, int xb, int yb, int channel, float points, char const* txt, int len, int smooth, int utf8, int align ) { +i_tt_cp( TT_Fonthandle *handle, i_img *im, i_img_dim xb, i_img_dim yb, int channel, double points, char const* txt, size_t len, int smooth, int utf8, int align ) { - int cords[BOUNDING_BOX_COUNT]; - int ascent, st_offset, y; + i_img_dim cords[BOUNDING_BOX_COUNT]; + i_img_dim ascent, st_offset, y; TT_Raster_Map bit; i_clear_error(); @@ -1729,9 +1038,9 @@ Interface to text rendering in a single color onto an image */ undef_int -i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, const i_color *cl, float points, char const* txt, int len, int smooth, int utf8, int align) { - int cords[BOUNDING_BOX_COUNT]; - int ascent, st_offset, y; +i_tt_text( TT_Fonthandle *handle, i_img *im, i_img_dim xb, i_img_dim yb, const i_color *cl, double points, char const* txt, size_t len, int smooth, int utf8, int align) { + i_img_dim cords[BOUNDING_BOX_COUNT]; + i_img_dim ascent, st_offset, y; TT_Raster_Map bit; i_clear_error(); @@ -1765,11 +1074,11 @@ 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, int len, int 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[BOUNDING_BOX_COUNT], int utf8 ) { int upm, casc, cdesc, first; int start = 0; - int width = 0; + i_img_dim width = 0; int gdescent = 0; int gascent = 0; int descent = 0; @@ -1780,7 +1089,8 @@ i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, int len, int c unsigned char *ustr; ustr=(unsigned char*)txt; - mm_log((1,"i_tt_box_inst(handle 0x%X,inst %d,txt '%.*s', len %d, utf8 %d)\n",handle,inst,len,txt,len, utf8)); + 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)); upm = handle->properties.header->Units_Per_EM; gascent = ( handle->properties.horizontal->Ascender * handle->instanceh[inst].imetrics.y_ppem + upm - 1) / upm; @@ -1811,7 +1121,7 @@ i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, int len, int c cdesc = (gm->bbox.yMin-63) / 64; mm_log((1, "i_tt_box_inst: glyph='%c' casc=%d cdesc=%d\n", - ((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc)); + (int)((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc)); if (first) { start = gm->bbox.xMin / 64; @@ -1865,11 +1175,12 @@ Interface to get a strings bounding box */ undef_int -i_tt_bbox( TT_Fonthandle *handle, float points,const char *txt,int len,int cords[6], int utf8) { +i_tt_bbox( TT_Fonthandle *handle, double points,const char *txt,size_t len,i_img_dim cords[6], int utf8) { int inst; i_clear_error(); - mm_log((1,"i_tt_box(handle 0x%X,points %f,txt '%.*s', len %d, utf8 %d)\n",handle,points,len,txt,len, utf8)); + mm_log((1,"i_tt_box(handle %p,points %f,txt '%.*s', len %ld, utf8 %d)\n", + handle, points, (int)len, txt, (long)len, utf8)); if ( (inst=i_tt_get_instance(handle,points,-1)) < 0) { i_push_errorf(0, "i_tt_get_instance(%g)", points); @@ -1889,7 +1200,7 @@ This is complicated by the need to handle encodings and so on. =cut */ -int +size_t i_tt_face_name(TT_Fonthandle *handle, char *name_buf, size_t name_buf_size) { TT_Face_Properties props; int name_count; @@ -1982,7 +1293,7 @@ void i_tt_dump_names(TT_Fonthandle *handle) { fflush(stdout); } -int +size_t i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf, size_t name_buf_size) { #ifdef FTXPOST @@ -2000,7 +1311,8 @@ i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf, } if (handle->load_cond) { - i_push_errorf(handle->load_cond, "error loading names (%d)", handle->load_cond); + i_push_errorf(handle->load_cond, "error loading names (%#x)", + (unsigned)handle->load_cond); return 0; }