point gd_textsize(char *str, char *fontname, double fontsz) { char *fontlist,*err; point rv; int brect[8]; fontlist = gd_alternate_fontlist(fontname); rv.x = rv.y = 0.0; if (fontlist && *str) { if (fontsz <= FONTSIZE_MUCH_TOO_SMALL) { /* ignore entirely */ rv.x = rv.y = 0; return rv; } else if (fontsz <= FONTSIZE_TOO_SMALL) { /* draw line in place of text */ /* fake a finite fontsize so that line length is calculated */ fontsz = FONTSIZE_TOO_SMALL; } /* call gdImageStringFT with null *im to get brect */ err = gdImageStringFT(NULL, brect, -1, fontlist, fontsz, 0, 0, 0, str); if (!err) { rv.x = (brect[4] - brect[0]); /* rv.y = (brect[5] - brect[1]); */ rv.y = (brect[5] - 0 ); /* ignore descenders */ rv.x /= SCALE; rv.y /= SCALE; } } return rv; }
static boolean gd_textlayout(textpara_t * para, char **fontpath) { char *err; char *fontlist; int brect[8]; gdFTStringExtra strex; double fontsize; strex.fontpath = NULL; strex.flags = gdFTEX_RETURNFONTPATHNAME | gdFTEX_RESOLUTION; strex.hdpi = strex.vdpi = POINTS_PER_INCH; if (strstr(para->fontname, "/")) strex.flags |= gdFTEX_FONTPATHNAME; else strex.flags |= gdFTEX_FONTCONFIG; para->width = 0.0; para->height = 0.0; para->yoffset_layout = 0.0; para->layout = NULL; para->free_layout = NULL; fontsize = para->fontsize; para->yoffset_centerline = 0.1 * fontsize; if (para->fontname) { if (fontsize <= FONTSIZE_MUCH_TOO_SMALL) { return TRUE; /* OK, but ignore text entirely */ } else if (fontsize <= FONTSIZE_TOO_SMALL) { /* draw line in place of text */ /* fake a finite fontsize so that line length is calculated */ fontsize = FONTSIZE_TOO_SMALL; } /* call gdImageStringFT with null *im to get brect and to set font cache */ #ifdef HAVE_GD_FONTCONFIG if (para->postscript_alias) fontlist = psfontResolve (para->postscript_alias); else fontlist = para->fontname; #else fontlist = gd_alternate_fontlist(para->fontname); #endif err = gdImageStringFTEx(NULL, brect, -1, fontlist, fontsize, 0, 0, 0, para->str, &strex); if (err) { agerr(AGERR,"%s\n", err); return FALSE; /* indicate error */ } if (fontpath) *fontpath = strex.fontpath; else free (strex.fontpath); /* strup'ed in libgd */ if (para->str && para->str[0]) { /* can't use brect on some archtectures if strlen 0 */ para->width = (double) (brect[4] - brect[0]); /* 1.2 specifies how much extra space to leave between lines; * see LINESPACING in const.h. */ para->height = (int)(para->fontsize * 1.2); } } return TRUE; }
static void gd_textline(point p, textline_t *line) { char *fontlist, *err; pointf mp,ep; int brect[8]; char *str = line->str; double fontsz = cstk[SP].fontsz; if (cstk[SP].pen == P_NONE) return; fontlist = gd_alternate_fontlist(cstk[SP].fontfam); switch(line->just) { case 'l': mp.x = p.x; break; case 'r': mp.x = p.x - line->width; break; default: case 'n': mp.x = p.x - line->width / 2; break; } ep.y = mp.y = p.y; ep.x = mp.x + line->width; mp = gdpt(mp); if (fontsz <= FONTSIZE_MUCH_TOO_SMALL) { /* ignore entirely */ } else if (fontsz <= FONTSIZE_TOO_SMALL) { /* draw line in place of text */ ep = gdpt(ep); gdImageLine(im, ROUND(mp.x), ROUND(mp.y), ROUND(ep.x), ROUND(ep.y), cstk[SP].pencolor); } else { err = gdImageStringFT(im, brect, cstk[SP].pencolor, fontlist, fontsz, (Rot? 90.0 : 0.0) * PI / 180.0, ROUND(mp.x), ROUND(mp.y), str); if (err) { /* revert to builtin fonts */ gd_missingfont (err, cstk[SP].fontfam); if (fontsz <= 8.5) { gdImageString(im, gdFontTiny, ROUND(mp.x), ROUND(mp.y-9.), (unsigned char *)str, cstk[SP].pencolor); } else if (fontsz <= 9.5) { gdImageString(im, gdFontSmall, ROUND(mp.x), ROUND(mp.y-12.), (unsigned char *)str, cstk[SP].pencolor); } else if (fontsz <= 10.5) { gdImageString(im, gdFontMediumBold, ROUND(mp.x), ROUND(mp.y-13.), (unsigned char *)str, cstk[SP].pencolor); } else if (fontsz <= 11.5) { gdImageString(im, gdFontLarge, ROUND(mp.x), ROUND(mp.y-14.), (unsigned char *)str, cstk[SP].pencolor); } else { gdImageString(im, gdFontGiant, ROUND(mp.x), ROUND(mp.y-15.), (unsigned char *)str, cstk[SP].pencolor); } } } }
static void gd_textline(point p, textline_t * line) { char *str, *fontlist, *err; pointf mp, ep; int brect[8]; double fontsz; gdFTStringExtra strex; int pencolor; if (!im) return; strex.flags = gdFTEX_RESOLUTION; strex.hdpi = strex.vdpi = Dpi * Zoom; if (cstk[SP].pen == P_NONE) return; pencolor = cstk[SP].pencolor; if (!im->trueColor && cstk[SP].fillcolor == transparent) pencolor = -pencolor; /* disable antialiasing */ if (strstr(cstk[SP].fontfam, "/")) strex.flags |= gdFTEX_FONTPATHNAME; else strex.flags |= gdFTEX_FONTCONFIG; str = line->str; fontlist = gd_alternate_fontlist(cstk[SP].fontfam); fontsz = cstk[SP].fontsz; switch (line->just) { case 'l': mp.x = p.x; break; case 'r': mp.x = p.x - line->width; break; default: case 'n': mp.x = p.x - line->width / 2; break; } ep.y = mp.y = p.y; ep.x = mp.x + line->width; mp = gdpt(mp); if (fontsz <= FONTSIZE_MUCH_TOO_SMALL) { /* ignore entirely */ } else if (fontsz <= FONTSIZE_TOO_SMALL) { /* draw line in place of text */ ep = gdpt(ep); gdImageLine(im, ROUND(mp.x), ROUND(mp.y), ROUND(ep.x), ROUND(ep.y), cstk[SP].pencolor); } else { #ifdef HAVE_GD_FREETYPE err = gdImageStringFTEx(im, brect, pencolor, fontlist, fontsz, Rot ? (PI / 2) : 0, ROUND(mp.x), ROUND(mp.y), str, &strex); #if 0 gdImagePolygon(im, (gdPointPtr) brect, 4, cstk[SP].pencolor); #endif #if 0 fprintf(stderr, "textline: font=%s size=%g pos=%g,%g width=%g dpi=%d width/dpi=%g\n", fontlist, fontsz, mp.x, mp.y, (double) (brect[4] - brect[0]), strex.hdpi, (((double) (brect[4] - brect[0])) / strex.hdpi)); #endif if (err) { /* revert to builtin fonts */ gd_missingfont(err, cstk[SP].fontfam); #endif mp.y += 2; if (fontsz <= 8.5) { gdImageString(im, gdFontTiny, ROUND(mp.x), ROUND(mp.y - 9.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 9.5) { gdImageString(im, gdFontSmall, ROUND(mp.x), ROUND(mp.y - 12.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 10.5) { gdImageString(im, gdFontMediumBold, ROUND(mp.x), ROUND(mp.y - 13.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 11.5) { gdImageString(im, gdFontLarge, ROUND(mp.x), ROUND(mp.y - 14.), (unsigned char *) str, cstk[SP].pencolor); } else { gdImageString(im, gdFontGiant, ROUND(mp.x), ROUND(mp.y - 15.), (unsigned char *) str, cstk[SP].pencolor); } #ifdef HAVE_GD_FREETYPE } #endif } }