static char * t1_from_utf8(char const *in, size_t len, int *outlen) { /* at this point len is from a STRLEN which should be size_t and can't be too big for mymalloc */ char *out = mymalloc(len+1); /* rechecked 29jul11 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; }
int i_t1_has_chars(i_t1_font_t font, const char *text, size_t len, int utf8, char *out) { int count = 0; int font_num = font->font_id; i_mutex_lock(mutex); mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %u, utf8 %d)\n", font_num, text, (unsigned)len, utf8)); i_clear_error(); if (T1_LoadFont(font_num)) { t1_push_error(); i_mutex_unlock(mutex); 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"); i_mutex_unlock(mutex); 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; } i_mutex_unlock(mutex); return count; }
static int i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit, 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 %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); */ x=-cords[0]; /* FIXME: If you font is antialiased this should be expanded by one to allow for aa expansion and the allocation too - do before passing here */ y=-cords[4]; while (len) { if (utf8) { j = i_utf8_advance(&txt, &len); if (j == ~0UL) { i_push_error(0, "invalid UTF8 character"); return 0; } } else { j = (unsigned char)*txt++; --len; } if ( !i_tt_get_glyph(handle,inst,j) ) continue; i_tt_render_glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, &handle->instanceh[inst].gmetrics[TT_HASH(j)], bit, small_bit, x, y, smooth ); x += handle->instanceh[inst].gmetrics[TT_HASH(j)].advance / 64; } return 1; }
size_t i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8, char *out) { 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; int index; 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 (TT_VALID(handle->char_map)) { index = TT_Char_Index(handle->char_map, c); } else { index = (c - ' ' + 1) < 0 ? 0 : (c - ' ' + 1); if (index >= handle->properties.num_Glyphs) index = 0; } *out++ = index != 0; ++count; } return count; }
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 ) { int upm, casc, cdesc, first; int start = 0; i_img_dim width = 0; int gdescent = 0; int gascent = 0; int descent = 0; int ascent = 0; int rightb = 0; unsigned long j; 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; gdescent = ( handle->properties.horizontal->Descender * handle->instanceh[inst].imetrics.y_ppem - upm + 1) / upm; width = 0; start = 0; mm_log((1, "i_tt_box_inst: gascent=%d gdescent=%d\n", gascent, gdescent)); first=1; while (len) { if (utf8) { j = i_utf8_advance(&txt, &len); if (j == ~0UL) { i_push_error(0, "invalid UTF8 character"); return 0; } } else { j = (unsigned char)*txt++; --len; } if ( i_tt_get_glyph(handle,inst,j) ) { TT_Glyph_Metrics *gm = handle->instanceh[inst].gmetrics + TT_HASH(j); width += gm->advance / 64; casc = (gm->bbox.yMax+63) / 64; cdesc = (gm->bbox.yMin-63) / 64; mm_log((1, "i_tt_box_inst: glyph='%c' casc=%d cdesc=%d\n", (int)((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc)); if (first) { start = gm->bbox.xMin / 64; ascent = (gm->bbox.yMax+63) / 64; descent = (gm->bbox.yMin-63) / 64; first = 0; } if (!len) { /* if at end of string */ /* the right-side bearing - in case the right-side of a character goes past the right of the advance width, as is common for italic fonts */ rightb = gm->advance - gm->bearingX - (gm->bbox.xMax - gm->bbox.xMin); /* fprintf(stderr, "font info last: %d %d %d %d\n", gm->bbox.xMax, gm->bbox.xMin, gm->advance, rightb); */ } ascent = (ascent > casc ? ascent : casc ); descent = (descent < cdesc ? descent : cdesc); } } cords[BBOX_NEG_WIDTH]=start; cords[BBOX_GLOBAL_DESCENT]=gdescent; cords[BBOX_POS_WIDTH]=width; if (rightb < 0) cords[BBOX_POS_WIDTH] -= rightb / 64; cords[BBOX_GLOBAL_ASCENT]=gascent; cords[BBOX_DESCENT]=descent; cords[BBOX_ASCENT]=ascent; cords[BBOX_ADVANCE_WIDTH] = width; cords[BBOX_RIGHT_BEARING] = rightb / 64; return BBOX_RIGHT_BEARING + 1; }