void TTFget_subfont(Font *fnt, long *array) { int i, j, Num; if (!fnt || !array) oops("Invalid parameter in call to TTFget_subfont()"); for (i = 0; i <= 0xFF; i++) { j = fnt->sf_code[i]; if (j < 0) array[i] = j; else { Num = TT_Char_Index(char_map, j); if (Num < 0) oops("cmap mapping failure."); else array[i] = j; } } }
Boolean TTFprocess(Font *fnt, long Code, byte **bitmap, int *width, int *height, int *hoff, int *voff, Boolean hinting, Boolean quiet) { int Num; TT_Error error; if (!bitmap || !width || !height || !hoff || !voff) oops("Invalid parameter in call to TTFprocess()"); if (Code >= 0x1000000) Num = Code & 0xFFFFFF; else { Num = TT_Char_Index(char_map, Code); if (has_gsub) { in_string[0] = Num; error = TT_GSUB_Apply_String(gsub, &in, &out); if (error && error != TTO_Err_Not_Covered) warning("Cannot get the vertical glyph form for glyph index %d.", Num); else Num = out.string[0]; } } if ((error = LoadTrueTypeChar(fnt, Num, hinting, quiet)) == TT_Err_Ok) { memset(Bit.bitmap, 0, Bit.size); TT_Get_Glyph_Bitmap(glyph, &Bit, x_offset * 64, y_offset * 64); FlipBit(); *bitmap = Bit2.bitmap; *width = Bit2.width; *height = Bit2.rows; *hoff = x_offset; *voff = y_offset; /* *voff = Bit2.rows - y_offset; */ /* printf("%D %d\n", *hoff, *voff); */ /* Output(Bit2); */ return True; } else return False; }
static void ttf_translate_16bit(TT_CharMap charMap, unsigned short *what, int **dest, int len, int base) { int i; dest[0]=(int*)xalloc(len*sizeof(int)); THREADS_ALLOW(); for (i=0; i<len; i++) dest[0][i] = TT_Char_Index(charMap, (TT_UShort)(what[i] + base)); THREADS_DISALLOW(); }
size_t i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf, size_t name_buf_size) { #ifdef FTXPOST TT_Error rc; TT_String *psname; TT_UShort index; i_clear_error(); if (!handle->loaded_names) { TT_Post post; mm_log((1, "Loading PS Names")); handle->load_cond = TT_Load_PS_Names(handle->face, &post); ++handle->loaded_names; } if (handle->load_cond) { i_push_errorf(handle->load_cond, "error loading names (%#x)", (unsigned)handle->load_cond); return 0; } index = TT_Char_Index(handle->char_map, ch); if (!index) { i_push_error(0, "no such character"); return 0; } rc = TT_Get_PS_Name(handle->face, index, &psname); if (rc) { i_push_error(rc, "error getting name"); return 0; } strncpy(name_buf, psname, name_buf_size); name_buf[name_buf_size-1] = '\0'; return strlen(psname) + 1; #else mm_log((1, "FTXPOST extension not enabled\n")); i_clear_error(); i_push_error(0, "Use of FTXPOST extension disabled"); return 0; #endif }
SWFFont loadSWFFontfromTTF(char *filename) { int i; TT_Engine *engine; TT_Face face; TT_Instance instance; TT_Glyph glyph; TT_Glyph_Metrics metrics; TT_Outline outline; TT_CharMap charmap; TT_Face_Properties properties; TT_UShort pid, eid; TT_Init_FreeType(engine); error = TT_Open_Face(engine, filename, &face); if(error) fprintf(stderr, "Could not open face.\n"); TT_Get_Face_Properties(face, &properties); for(i=0; i<properties->num_CharMaps; ++i) TT_Get_CharMap_ID(face, i, &pid, &eid); TT_Get_CharMap(face, charmapIndex, &charmap); TT_New_Instance(face, &instance); TT_New_Glyph(face, &glyph); for(i=0; i<whatever; ++i) { TT_Load_Glyph(instance, glyph, TT_Char_Index(charmap, i), loadFlags); TT_Get_Glyph_Outline(glyph, &outline); TT_Get_Glyph_Metrics(glyph, &metrics); } TT_Done_FreeType(engine); }
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; }
encoding * TTFget_first_glyphs(Font *fnt, long *array) { unsigned int i, j, Num; unsigned int index_array[257]; /* we ignore glyph index 0 */ char *n; encoding *e = (encoding *)mymalloc(sizeof (encoding)); if (!array) oops("Invalid parameter in call to TTFget_first_glyphs()"); for (i = 0; i < 257; i++) index_array[i] = 0; j = 0; if (fnt->PSnames != Only) { for (i = 0; i <= 0x16FFFF; i++) { Num = TT_Char_Index(char_map, i); if (Num < 0) oops("cmap mapping failure."); if (Num == 0) continue; if (Num <= 256) index_array[Num] = 1; if (fnt->PSnames) (void)TT_Get_PS_Name(face, Num, &n); else n = code_to_adobename(i); if (strcmp(n, ".notdef") == 0) continue; if (strcmp(n, ".null") == 0) continue; if (strcmp(n, "nonmarkingreturn") == 0) continue; if (j < 256) { array[j] = i; e->vec[j] = n; } else return e; j++; } if (!fnt->PSnames) { for (i = 1; i < properties.num_Glyphs; i++) { if (index_array[i] == 0) { if (j < 256) { array[j] = i | 0x1000000; e->vec[j] = code_to_adobename(i | 0x1000000); } else return e; j++; } } } } else { for (i = 0; i < properties.num_Glyphs; i++) { char *n; (void)TT_Get_PS_Name(face, i, &n); if (strcmp(n, ".notdef") == 0) continue; if (strcmp(n, ".null") == 0) continue; if (strcmp(n, "nonmarkingreturn") == 0) continue; if (j < 256) { array[j] = i | 0x1000000; e->vec[j] = n; } else return e; j++; } } return NULL; /* never reached */ }
static TT_Error Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph) { TT_UShort index; TT_Glyph_Metrics metrics; TT_Outline outline; int x_offset; int y_offset; TT_Error error; /* Load the glyph */ index = TT_Char_Index(font->map, UNICODE(ch)); error = TT_Load_Glyph(font->inst, font->glyph, index, TTLOAD_DEFAULT); if ( error ) return error; /* Get the bounding box */ TT_Get_Glyph_Metrics(font->glyph, &metrics); glyph->minx = (metrics.bbox.xMin & -64) / 64; glyph->maxx = ((metrics.bbox.xMax + 63) & -64) / 64; glyph->miny = (metrics.bbox.yMin & -64) / 64; glyph->maxy = ((metrics.bbox.yMax + 63) & -64) / 64; glyph->advance = (metrics.advance & -64) / 64; /* Adjust for bold and italic text */ if ( font->style & TTF_STYLE_BOLD ) { glyph->maxx += font->glyph_overhang; } if ( font->style & TTF_STYLE_ITALIC ) { glyph->maxx += round(font->glyph_italics); } /* Get the bitmap memory */ glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7; glyph->bitmap.rows = font->height; glyph->bitmap.cols = glyph->bitmap.width/8; glyph->bitmap.flow = TT_Flow_Down; glyph->bitmap.size = (glyph->bitmap.rows * glyph->bitmap.cols); if ( glyph->bitmap.size ) { glyph->bitmap.bitmap = malloc(glyph->bitmap.size); if ( ! glyph->bitmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->bitmap.bitmap, 0, glyph->bitmap.size); } else { glyph->bitmap.bitmap = 0; } /* Get the pixmap memory */ glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3; glyph->pixmap.rows = font->height; glyph->pixmap.cols = glyph->pixmap.width; glyph->pixmap.flow = TT_Flow_Down; glyph->pixmap.size = (glyph->pixmap.rows * glyph->pixmap.cols); if ( glyph->pixmap.size ) { glyph->pixmap.bitmap = malloc(glyph->pixmap.size); if ( ! glyph->pixmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->pixmap.bitmap, 0, glyph->pixmap.size); } else { glyph->pixmap.bitmap = 0; } /* Render the glyph into the bitmap and pixmap */ error = TT_Get_Glyph_Outline(font->glyph, &outline); /* Handle the italic style */ if ( font->style & TTF_STYLE_ITALIC ) { TT_Matrix shear; shear.xx = 1<<16; shear.xy = (int)(font->glyph_italics*(1<<16))/font->height; shear.yx = 0; shear.yy = 1<<16; TT_Transform_Outline(&outline, &shear); } x_offset = -glyph->minx * 64; y_offset = -round(font->descent) * 64; TT_Translate_Outline(&outline, x_offset, y_offset); error += TT_Get_Outline_Bitmap(engine, &outline, &glyph->bitmap); error += TT_Get_Outline_Pixmap(engine, &outline, &glyph->pixmap); /* Handle the bold style */ if ( font->style & TTF_STYLE_BOLD ) { int row, col; int offset; int pixel; Uint8 *pixmap; /* The bitmap is easy, just render another copy */ for ( offset=0; offset < font->glyph_overhang; ++offset ) { TT_Translate_Outline(&outline, 64, 0); error += TT_Get_Outline_Bitmap(engine, &outline,&glyph->bitmap); } x_offset += font->glyph_overhang*64; /* The pixmap is a little harder, we have to add and clamp */ for ( row=glyph->pixmap.rows-1; row >= 0; --row ) { pixmap = (Uint8 *)glyph->pixmap.bitmap + row*glyph->pixmap.cols; for (offset=1; offset<=font->glyph_overhang; ++offset) { for (col=glyph->pixmap.cols-1; col > 0; --col) { pixel=(pixmap[col]+pixmap[col-1]); if ( pixel > 4 ) { pixel = 4; } pixmap[col] = (Uint8)pixel; } } } } TT_Translate_Outline(&outline, -x_offset, -y_offset); was_error: if ( error ) { if ( glyph->bitmap.bitmap ) { free(glyph->bitmap.bitmap); glyph->bitmap.bitmap = 0; } if ( glyph->pixmap.bitmap ) { free(glyph->pixmap.bitmap); glyph->pixmap.bitmap = 0; } return error; } /* We're done, mark this glyph cached */ glyph->cached = ch; return TT_Err_Ok; }
void readttf(Font *fnt, Boolean quiet, Boolean only_range) { TT_Error error; ttfinfo *ti, *Ti; long Num, index; unsigned int i, j; long k, max_k; unsigned short num_cmap; unsigned short cmap_plat, cmap_enc; int index_array[257]; static Boolean initialized = False; TT_UShort in_string[2]; TTO_GSUB_String in, out; TT_UShort script_index, language_index, feature_index; TT_UShort req_feature_index = 0xFFFF; /* * We allocate a placeholder boundary and the `.notdef' character. */ if (!only_range) { ti = newchar(fnt); ti->charcode = -1; ti->adobename = ".notdef"; ti = newchar(fnt); ti->charcode = -1; ti->adobename = "||"; /* boundary character name */ } /* * Initialize FreeType engine. */ if (!initialized) { if ((error = TT_Init_FreeType(&engine))) oops("Cannot initialize engine (error code = 0x%x).", error); if ((error = TT_Init_Kerning_Extension(engine))) oops("Cannot initialize kerning (error code = 0x%x).", error); if (fnt->PSnames) if ((error = TT_Init_Post_Extension(engine))) oops("Cannot initialize PS name support (error code = 0x%x).", error); if (fnt->rotate) if ((error = TT_Init_GSUB_Extension(engine))) oops("Cannot initialize GSUB support (error code = 0x%x).", error); /* * Load face. */ real_ttfname = TeX_search_ttf_file(&(fnt->ttfname)); if (!real_ttfname) oops("Cannot find `%s'.", fnt->ttfname); if ((error = TT_Open_Face(engine, real_ttfname, &face))) oops("Cannot open `%s'.", real_ttfname); /* * Get face properties and allocate preload arrays. */ TT_Get_Face_Properties(face, &properties); /* * Now we try to open the proper font in a collection. */ if (fnt->fontindex != 0) { if (properties.num_Faces == 1) { warning("This isn't a TrueType collection.\n" "Parameter `-f' is ignored."); fnt->fontindex = 0; fnt->fontindexparam = NULL; } else { TT_Close_Face(face); if ((error = TT_Open_Collection(engine, real_ttfname, fnt->fontindex, &face))) oops("Cannot open font %lu in TrueType Collection `%s'.", fnt->fontindex, real_ttfname); } } /* * Create instance. */ if ((error = TT_New_Instance(face, &instance))) oops("Cannot create instance for `%s' (error code = 0x%x).", real_ttfname, error); /* * We use a dummy glyph size of 10pt. */ if ((error = TT_Set_Instance_CharSize(instance, 10 * 64))) oops("Cannot set character size (error code = 0x%x).", error); matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024); matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024); matrix1.yx = (TT_Fixed)0; matrix1.yy = (TT_Fixed)(1L<<16); if (fnt->rotate) { matrix2.xx = 0; matrix2.yx = 1L << 16; matrix2.xy = -matrix2.yx; matrix2.yy = matrix2.xx; } if ((error = TT_Set_Instance_Transform_Flags( instance, fnt->rotate ? 1 : 0, fnt->efactor != 1.0 ? 1 : 0))) oops("Cannot set transform flags (error code = 0x%x).", error); /* * Create glyph container. */ if ((error = TT_New_Glyph(face, &glyph))) oops("Cannot create glyph container (error code = 0x%x).", error); fnt->units_per_em = properties.header->Units_Per_EM; fnt->fixedpitch = properties.postscript->isFixedPitch; fnt->italicangle = properties.postscript->italicAngle / 65536.0; if (fnt->PSnames != Only) { num_cmap = properties.num_CharMaps; for (i = 0; i < num_cmap; i++) { if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) oops("Cannot query cmap (error code = 0x%x).", error); if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) break; } if (i == num_cmap) { fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n", progname); if (num_cmap == 1) fprintf(stderr, " The only valid PID/EID pair is"); else fprintf(stderr, " Valid PID/EID pairs are:\n"); for (i = 0; i < num_cmap; i++) { TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc); fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc); } fprintf(stderr, "\n"); exit(1); } if ((error = TT_Get_CharMap(face, i, &char_map))) oops("Cannot load cmap (error code = 0x%x).", error); } if (fnt->PSnames) { if ((error = TT_Load_PS_Names(face, &post))) oops("Cannot load TrueType PS names (error code = 0x%x).", error); } else if (cmap_plat == Microsoft_platform && cmap_enc == Microsoft_Unicode_encoding) set_encoding_scheme(encUnicode, fnt); else if (cmap_plat == Macintosh_platform && cmap_enc == Macintosh_encoding) set_encoding_scheme(encMac, fnt); else set_encoding_scheme(encFontSpecific, fnt); if (fnt->rotate) { gsub = &gsub_; error = TT_Load_GSUB_Table(face, gsub, NULL); if (!error) has_gsub = True; else if (error != TT_Err_Table_Missing) warning("Cannot load GSUB table (error code = 0x%x).", error); else warning("No GSUB data available " "for vertical glyph presentation forms."); /* we check for the `vert' feature in Chinese, Japanese, and Korean */ error = TT_GSUB_Select_Script(gsub, SCRIPT_kana, &script_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_JAN, script_index, &language_index, &req_feature_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hani; else goto Done; } else goto Done; check_hani: error = TT_GSUB_Select_Script(gsub, SCRIPT_hani, &script_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_CHN, script_index, &language_index, &req_feature_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hang; else goto Done; } else goto Done; check_hang: error = TT_GSUB_Select_Script(gsub, SCRIPT_hang, &script_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_KOR, script_index, &language_index, &req_feature_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); } Done: if (error) { warning("There is no data for vertical typesetting in GSUB table."); has_gsub = False; } if (req_feature_index != 0xFFFF) TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); in.length = 1; in.pos = 0; in.string = in_string; in.properties = NULL; out.pos = 0; out.allocated = 0; out.string = NULL; out.properties = NULL; } initialized = True; } if (!quiet) { if (only_range) printf("\n\n%s:\n", fnt->fullname); printf("\n"); printf("Glyph Code Glyph Name "); printf("Width llx lly urx ury\n"); printf("---------------------------------------"); printf("---------------------------------\n"); } /* * We load only glyphs with a valid cmap entry. Nevertheless, for * the default mapping, we use the first 256 glyphs addressed by * ascending code points, followed by glyphs not in the cmap. * * If we compute a range, we take the character codes given in * the fnt->sf_code array. * * If the -N flag is set, no cmap is used at all. Instead, the * first 256 glyphs (with a valid PS name) are used for the default * mapping. */ if (!only_range) for (i = 0; i < 257; i++) index_array[i] = 0; else for (i = 0; i < 256; i++) fnt->inencptrs[i] = 0; j = 0; if (fnt->PSnames == Only) max_k = properties.num_Glyphs - 1; else max_k = only_range ? 0xFF : 0x16FFFF; for (k = 0; k <= max_k; k++) { char *an; if (fnt->PSnames != Only) { if (only_range) { index = fnt->sf_code[k]; if (index < 0) continue; j = k; } else index = k; Num = TT_Char_Index(char_map, index); /* now we try to get a vertical glyph form */ if (has_gsub) { in_string[0] = Num; error = TT_GSUB_Apply_String(gsub, &in, &out); if (error && error != TTO_Err_Not_Covered) warning("Cannot get the vertical glyph form for glyph index %d.", Num); else Num = out.string[0]; } if (Num < 0) oops("Failure on cmap mapping from %s.", fnt->ttfname); if (Num == 0) continue; if (!only_range) if (Num <= 256) index_array[Num] = 1; } else { Num = k; index = 0; } error = TT_Load_Glyph(instance, glyph, Num, 0); if (!error) error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); if (!error) error = TT_Get_Glyph_Outline(glyph, &outline); if (!error) { if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) TT_Transform_Outline(&outline, &matrix1); if (fnt->rotate) TT_Transform_Outline(&outline, &matrix2); } if (!error) error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- grid-fitted bbox */ if (!error) { if (fnt->PSnames) (void)TT_Get_PS_Name(face, Num, &an); else an = code_to_adobename(index); /* ignore characters not usable for typesetting with TeX */ if (strcmp(an, ".notdef") == 0) continue; if (strcmp(an, ".null") == 0) continue; if (strcmp(an, "nonmarkingreturn") == 0) continue; ti = newchar(fnt); ti->charcode = index; ti->glyphindex = Num; ti->adobename = an; ti->llx = bbox.xMin * 1000 / fnt->units_per_em; ti->lly = bbox.yMin * 1000 / fnt->units_per_em; ti->urx = bbox.xMax * 1000 / fnt->units_per_em; ti->ury = bbox.yMax * 1000 / fnt->units_per_em; /* * We must now shift the rotated character both horizontally * and vertically. The vertical amount is 25% by default. */ if (fnt->rotate) { ti->llx += (metrics.vertBearingY - bbox.xMin) * 1000 / fnt->units_per_em; ti->lly -= 1000 * fnt->y_offset; ti->urx += (metrics.vertBearingY - bbox.xMin) * 1000 / fnt->units_per_em; ti->ury -= 1000 * fnt->y_offset; } /* * We need to avoid negative heights or depths. They break accents * in math mode, among other things. */ if (ti->lly > 0) ti->lly = 0; if (ti->ury < 0) ti->ury = 0; if (fnt->rotate) ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em; else ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em, 0, fnt->efactor, fnt->slant); if (!quiet) printf("%5ld %05lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", Num, index, ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); if (j < 256) { fnt->inencptrs[j] = ti; ti->incode = j; } j++; } } /* * Now we load glyphs without a cmap entry, provided some slots are * still free -- we skip this if we have to compute a range or use * PS names. */ if (!only_range && !fnt->PSnames) { for (i = 1; i <= properties.num_Glyphs; i++) { char *an; if (index_array[i] == 0) { error = TT_Load_Glyph(instance, glyph, i, 0); if (!error) error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); if (!error) error = TT_Get_Glyph_Outline(glyph, &outline); if (!error) error = TT_Get_Outline_BBox(&outline, &bbox); if (!error) { an = code_to_adobename(i | 0x1000000); ti = newchar(fnt); ti->charcode = i | 0x1000000; ti->glyphindex = i; ti->adobename = an; ti->llx = bbox.xMin * 1000 / fnt->units_per_em; ti->lly = bbox.yMin * 1000 / fnt->units_per_em; ti->urx = bbox.xMax * 1000 / fnt->units_per_em; ti->ury = bbox.yMax * 1000 / fnt->units_per_em; if (ti->lly > 0) ti->lly = 0; if (ti->ury < 0) ti->ury = 0; ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em, 0, fnt->efactor, fnt->slant); if (!quiet) printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", i, ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); if (j < 256) { fnt->inencptrs[j] = ti; ti->incode = j; } else break; j++; } } } } /* Finally, we construct a `Germandbls' glyph if necessary */ if (!only_range) { if (NULL == findadobe("Germandbls", fnt->charlist) && NULL != (Ti = findadobe("S", fnt->charlist))) { pcc *np, *nq; ti = newchar(fnt); ti->charcode = properties.num_Glyphs | 0x1000000; ti->glyphindex = properties.num_Glyphs; ti->adobename = "Germandbls"; ti->width = Ti->width << 1; ti->llx = Ti->llx; ti->lly = Ti->lly; ti->urx = Ti->width + Ti->urx; ti->ury = Ti->ury; ti->kerns = Ti->kerns; np = newpcc(); np->partname = "S"; nq = newpcc(); nq->partname = "S"; nq->xoffset = Ti->width; np->next = nq; ti->pccs = np; ti->constructed = True; if (!quiet) printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); } } /* kerning between subfonts isn't available */ if (!only_range) readttf_kern(fnt); }
static int 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 %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: %lu in cache\n",j)); return 1; } if ( TT_VALID(handle->instanceh[inst].glyphs[TT_HASH(j)].glyph) ) { /* clean up the entry */ 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; } /* Ok - it wasn't cached - try to get it in */ load_flags = TTLOAD_SCALE_GLYPH; if ( LTT_hinted ) load_flags |= TTLOAD_HINT_GLYPH; if ( !TT_VALID(handle->char_map) ) { code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1); if ( code >= handle->properties.num_Glyphs ) code = 0; } 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 %#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 %#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; i_push_error(error, "TT_Load_Glyph()"); return 0; } /* At this point the glyph should be allocated and loaded */ handle->instanceh[inst].glyphs[TT_HASH(j)].ch = j; /* Next get the glyph metrics */ 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 %#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; i_push_error(error, "TT_Get_Glyph_Metrics()"); return 0; } return 1; }