static const char* cff_get_ps_name( CFF_Face face ) { CFF_Font cff = (CFF_Font)face->extra.data; SFNT_Service sfnt = (SFNT_Service)face->sfnt; /* following the OpenType specification 1.7, we return the name stored */ /* in the `name' table for a CFF wrapped into an SFNT container */ if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) { FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); FT_Service_PsFontName service = (FT_Service_PsFontName)ft_module_get_service( sfnt_module, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, 0 ); if ( service && service->get_ps_font_name ) return service->get_ps_font_name( FT_FACE( face ) ); } return (const char*)cff->font_name; }
FT_Get_Gasp( FT_Face face, FT_UInt ppem ) { FT_Int result = FT_GASP_NO_TABLE; if ( face && FT_IS_SFNT( face ) ) { TT_Face ttface = (TT_Face)face; if ( ttface->gasp.numRanges > 0 ) { TT_GaspRange range = ttface->gasp.gaspRanges; TT_GaspRange range_end = range + ttface->gasp.numRanges; while ( ppem > range->maxPPEM ) { range++; if ( range >= range_end ) goto Exit; } result = range->gaspFlag; /* ensure that we don't have spurious bits */ if ( ttface->gasp.version == 0 ) result &= 3; } } Exit: return result; }
CAMLprim value is_sfnt(value f) { CAMLparam1(f); FT_Face face; face = *(FT_Face *)Data_custom_val(f); CAMLreturn(Val_bool(FT_IS_SFNT(face) != 0)); };
void Print_Type( FT_Face face ) { FT_Module module; printf( "font type entries\n" ); module = &face->driver->root; printf( " FreeType driver: %s\n", module->clazz->module_name ); /* Is it better to dump all sfnt tag names? */ printf( " sfnt wrapped: %s\n", FT_IS_SFNT( face ) ? (char *)"yes" : (char *)"no" ); /* isScalable? */ comma_flag = 0; printf( " type: " ); if ( FT_IS_SCALABLE( face ) ) { Print_Comma( "scalable" ); if ( FT_HAS_MULTIPLE_MASTERS( face ) ) Print_Comma( "multiple masters" ); } if ( FT_HAS_FIXED_SIZES( face ) ) Print_Comma( "fixed size" ); printf( "\n" ); /* Direction */ comma_flag = 0; printf( " direction: " ); if ( FT_HAS_HORIZONTAL( face ) ) Print_Comma( "horizontal" ); if ( FT_HAS_VERTICAL( face ) ) Print_Comma( "vertical" ); printf( "\n" ); printf( " fixed width: %s\n", FT_IS_FIXED_WIDTH( face ) ? (char *)"yes" : (char *)"no" ); printf( " glyph names: %s\n", FT_HAS_GLYPH_NAMES( face ) ? (char *)"yes" : (char *)"no" ); if ( FT_IS_SCALABLE( face ) ) { printf( " EM size: %d\n", face->units_per_EM ); printf( " global BBox: (%ld,%ld):(%ld,%ld)\n", face->bbox.xMin, face->bbox.yMin, face->bbox.xMax, face->bbox.yMax ); printf( " ascent: %d\n", face->ascender ); printf( " descent: %d\n", face->descender ); printf( " text height: %d\n", face->height ); } }
FT_Face_CheckTrueTypePatents( FT_Face face ) { FT_Bool result = FALSE; if ( face && FT_IS_SFNT( face ) ) result = _tt_face_check_patents( face ); return result; }
CAMLprim value is_postscript(value f) { CAMLparam1(f); FT_Face face; PS_PrivateRec p; face = *(FT_Face *)Data_custom_val(f); CAMLreturn(Val_bool(!FT_IS_SFNT(face) && (FT_Get_PS_Font_Private(face, &p) == 0))); };
HB_Error hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB_UInt *len) { FT_Face face = (FT_Face) voidface; FT_ULong ftlen = *len; if (!FT_IS_SFNT(face)) return HB_Err_Invalid_Argument; const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen); *len = ftlen; return (HB_Error) error; }
XeTeXFontInst_FT2::XeTeXFontInst_FT2(const char* pathname, int index, float pointSize, LEErrorCode &status) : XeTeXFontInst(pointSize, status) , face(0) , fFreeTypeOnly(false) { if (LE_FAILURE(status)) { return; } FT_Error err; if (!gFreeTypeLibrary) { err = FT_Init_FreeType(&gFreeTypeLibrary); if (err != 0) { fprintf(stderr, "FreeType initialization failed! (%d)\n", err); exit(1); } } err = FT_New_Face(gFreeTypeLibrary, (char*)pathname, index, &face); if (err != 0) { status = LE_FONT_FILE_NOT_FOUND_ERROR; return; } /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */ if (index == 0 && !FT_IS_SFNT(face)) { char* afm = new char[strlen((const char*)pathname) + 5]; // room to append ".afm" strcpy(afm, (const char*)pathname); char* p = strrchr(afm, '.'); if (p == NULL || strlen(p) != 4 || tolower(*(p+1)) != 'p' || tolower(*(p+2)) != 'f') strcat(afm, ".afm"); // append .afm if the extension didn't seem to be .pf[ab] else strcpy(p, ".afm"); // else replace extension with .afm FT_Attach_File(face, afm); // ignore error code; AFM might not exist delete[] afm; fFreeTypeOnly = true; } initialize(status); if (LE_FAILURE(status)) return; char buf[20]; if (index > 0) sprintf(buf, ":%d", index); else buf[0] = 0; fFilename = new char[strlen(pathname) + 2 + strlen(buf) + 1]; sprintf(fFilename, "[%s%s]", pathname, buf); }
static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length) { FT_Face face = (FT_Face)font; FT_ULong ftlen = *length; FT_Error error = 0; if (!FT_IS_SFNT(face)) return HB_Err_Invalid_Argument; error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen); *length = ftlen; return (HB_Error)error; }
/** * Checks face, which must be sfnt based, for the subtype. * Possible values: TTF, CFF, OTF */ void getSFontType(FT_Face face, ScFace::FontType & type) { if (FT_IS_SFNT(face)) { FT_ULong ret = 0; bool hasGlyph = ! FT_Load_Sfnt_Table(face, TTAG_glyf, 0, NULL, &ret); hasGlyph &= ret > 0; bool hasCFF = ! FT_Load_Sfnt_Table(face, TTAG_CFF, 0, NULL, &ret); hasCFF &= ret > 0; if (hasGlyph) type = ScFace::TTF; else if (hasCFF) type = ScFace::OTF; // TODO: CID or no } }
FT_Get_Sfnt_Name( FT_Face face, FT_UInt idx, FT_SfntName *aname ) { FT_Error error = FT_ERR( Invalid_Argument ); if ( aname && face && FT_IS_SFNT( face ) ) { TT_Face ttface = (TT_Face)face; if ( idx < (FT_UInt)ttface->num_names ) { TT_NameEntryRec* entry = ttface->name_table.names + idx; /* load name on demand */ if ( entry->stringLength > 0 && entry->string == NULL ) { FT_Memory memory = face->memory; FT_Stream stream = face->stream; if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || FT_STREAM_SEEK( entry->stringOffset ) || FT_STREAM_READ( entry->string, entry->stringLength ) ) { FT_FREE( entry->string ); entry->stringLength = 0; } } aname->platform_id = entry->platformID; aname->encoding_id = entry->encodingID; aname->language_id = entry->languageID; aname->name_id = entry->nameID; aname->string = (FT_Byte*)entry->string; aname->string_len = entry->stringLength; error = FT_Err_Ok; } } return error; }
FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ) { FT_Bool result = FALSE; #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) if ( face && FT_IS_SFNT( face ) ) { result = !face->internal->ignore_unpatented_hinter; face->internal->ignore_unpatented_hinter = !value; } #else FT_UNUSED( face ); FT_UNUSED( value ); #endif return result; }
bool gfxFT2LockedFace::GetFontTable(uint32_t aTag, FallibleTArray<uint8_t>& aBuffer) { if (!mFace || !FT_IS_SFNT(mFace)) return false; FT_ULong length = 0; // TRUETYPE_TAG is defined equivalent to FT_MAKE_TAG FT_Error error = FT_Load_Sfnt_Table(mFace, aTag, 0, NULL, &length); if (error != 0) return false; if (MOZ_UNLIKELY(length > static_cast<FallibleTArray<uint8_t>::size_type>(-1)) || MOZ_UNLIKELY(!aBuffer.SetLength(length))) return false; error = FT_Load_Sfnt_Table(mFace, aTag, 0, aBuffer.Elements(), &length); if (MOZ_UNLIKELY(error != 0)) { aBuffer.Clear(); return false; } return true; }
PRBool gfxFT2LockedFace::GetFontTable(PRUint32 aTag, FallibleTArray<PRUint8>& aBuffer) { if (!mFace || !FT_IS_SFNT(mFace)) return PR_FALSE; FT_ULong length = 0; // TRUETYPE_TAG is defined equivalent to FT_MAKE_TAG FT_Error error = FT_Load_Sfnt_Table(mFace, aTag, 0, NULL, &length); if (error != 0) return PR_FALSE; if (NS_UNLIKELY(length > static_cast<FallibleTArray<PRUint8>::size_type>(-1)) || NS_UNLIKELY(!aBuffer.SetLength(length))) return PR_FALSE; error = FT_Load_Sfnt_Table(mFace, aTag, 0, aBuffer.Elements(), &length); if (NS_UNLIKELY(error != 0)) { aBuffer.Clear(); return PR_FALSE; } return PR_TRUE; }
// // _checkLicenses(); // void FontFace::_checkLicenses(void){ // // Assign the default: // _licenseData = UnknownLicense::pData; std::string licenseString; /////////////////////////////////////// // // Handle both (1) TrueType/OpenType // and (2) Type1 fonts // /////////////////////////////////////// if(FT_IS_SFNT(_face)){ /////////////////////////////// // // TrueType / OpenType CASE: // /////////////////////////////// FT_UInt count=FT_Get_Sfnt_Name_Count(_face); FT_SfntName fontName; // // Check both the COPYRIGHT (TTF) and LICENSE (OPENTYPE) fields: // for(unsigned j=0;j<count;j++){ FT_Get_Sfnt_Name(_face,j,&fontName); if(fontName.name_id==NID_LICENSE || fontName.name_id==NID_COPYRIGHT){ licenseString = _getStringFromTrueTypeFont(fontName); if(fontName.name_id==NID_COPYRIGHT){ _storeCopyrightSummary(licenseString); } if(_checkAllKnownLicenses(licenseString)){ return; } } if(fontName.name_id==NID_URL_LICENSE){ _licenseURL = _getStringFromTrueTypeFont(fontName); } } // // Get here if not a known license string: // }else if(FT_IS_SCALABLE(_face)){ /////////////////////////////// // // Could be Type 1, Type 42, // CID, or PFR CASES: // /////////////////////////////// PS_FontInfoRec fi; FT_Get_PS_Font_Info(_face,&fi); if(fi.notice){ licenseString = fi.notice; _checkAllKnownLicenses(licenseString); _storeCopyrightSummary(licenseString); } } }
FT_Get_Sfnt_Name_Count( FT_Face face ) { return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; }
int main( int argc, char* argv[] ) { int i, file; char filename[128 + 4]; char alt_filename[128 + 4]; char* execname; int num_faces; int option; FT_Library library; /* the FreeType library */ FT_Face face; /* the font face */ execname = ft_basename( argv[0] ); while ( 1 ) { option = getopt( argc, argv, "dl:nv" ); if ( option == -1 ) break; switch ( option ) { case 'd': debug = 1; break; case 'l': trace_level = atoi( optarg ); if ( trace_level < 1 || trace_level > 7 ) usage( execname ); break; case 'n': name_tables = 1; break; case 'v': verbose = 1; break; default: usage( execname ); break; } } argc -= optind; argv += optind; if ( argc != 1 ) usage( execname ); #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 && FREETYPE_PATCH <= 8 if ( debug ) { # ifdef FT_DEBUG_LEVEL_TRACE FT_SetTraceLevel( trace_any, (FT_Byte)trace_level ); # else trace_level = 0; # endif } #elif 0 /* "setenv/putenv" is not ANSI and I don't want to mess */ /* with this portability issue right now */ if ( debug ) { char temp[32]; sprintf( temp, "any=%d", trace_level ); setenv( "FT2_DEBUG", temp ); } #endif file = 0; /* Initialize engine */ error = FT_Init_FreeType( &library ); if ( error ) PanicZ( "Could not initialize FreeType library" ); filename[128] = '\0'; alt_filename[128] = '\0'; strncpy( filename, argv[file], 128 ); strncpy( alt_filename, argv[file], 128 ); /* try to load the file name as is, first */ error = FT_New_Face( library, argv[file], 0, &face ); if ( !error ) goto Success; #ifndef macintosh i = strlen( argv[file] ); while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) { if ( argv[file][i] == '.' ) i = 0; i--; } if ( i >= 0 ) { strncpy( filename + strlen( filename ), ".ttf", 4 ); strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); } #endif /* Load face */ error = FT_New_Face( library, filename, 0, &face ); if ( error ) PanicZ( "Could not open face." ); Success: num_faces = face->num_faces; FT_Done_Face( face ); printf( "There %s %d %s in this file.\n", num_faces == 1 ? (char *)"is" : (char *)"are", num_faces, num_faces == 1 ? (char *)"face" : (char *)"faces" ); for ( i = 0; i < num_faces; i++ ) { error = FT_New_Face( library, filename, i, &face ); if ( error ) PanicZ( "Could not open face." ); printf( "\n----- Face number: %d -----\n\n", i ); Print_Name( face ); printf( "\n" ); Print_Type( face ); printf( " glyph count: %ld\n", face->num_glyphs ); if ( name_tables && FT_IS_SFNT( face ) ) { printf( "\n" ); Print_Sfnt_Names( face ); } if ( face->num_fixed_sizes ) { printf( "\n" ); Print_Fixed( face ); } if ( face->num_charmaps ) { printf( "\n" ); Print_Charmaps( face ); } FT_Done_Face( face ); } FT_Done_FreeType( library ); exit( 0 ); /* for safety reasons */ return 0; /* never reached */ }
static int doDirectory(const char *dirname_given, int numEncodings, ListPtr encodingsToDo) { char *dirname, *fontscale_name, *filename, *encdir; FILE *fontscale, *encfile; DIR *dirp; struct dirent *entry; FT_Error ftrc; FT_Face face; ListPtr encoding, xlfd, lp; HashTablePtr entries; HashBucketPtr *array; int i, n, found, rc; int isBitmap=0,xl=0; if (exclusionSuffix) xl = strlen (exclusionSuffix); i = strlen(dirname_given); if(i == 0) dirname = dsprintf("./"); else if(dirname_given[i - 1] != '/') dirname = dsprintf("%s/", dirname_given); else dirname = dsprintf("%s", dirname_given); if(dirname == NULL) { perror("dirname"); exit(1); } if (onlyEncodings) goto encodings; entries = makeHashTable(); if(doBitmaps && !doScalable) { readFontScale(entries, dirname); } if(strcmp(outfilename, "-") == 0) fontscale_name = NULL; else { if(outfilename[0] == '/') fontscale_name = dsprintf("%s", outfilename); else fontscale_name = dsprintf("%s%s", dirname, outfilename); if(fontscale_name == NULL) { perror("fontscale_name"); exit(1); } } dirp = opendir(dirname); if(dirp == NULL) { fprintf(stderr, "%s: ", dirname); perror("opendir"); return 0; } if(fontscale_name == NULL) fontscale = stdout; else fontscale = fopen(fontscale_name, "wb"); if(fontscale == NULL) { fprintf(stderr, "%s: ", fontscale_name); perror("fopen(w)"); return 0; } while((entry = readdir(dirp)) != NULL) { int have_face = 0; char *xlfd_name = NULL; struct stat f_stat; int tprio = 1; xlfd = NULL; if (xl) { int dl = strlen (entry->d_name); if (strcmp (entry->d_name + dl - xl, exclusionSuffix) == 0) continue; } filename = dsprintf("%s%s", dirname, entry->d_name); #define PRIO(x) ((x << 1) + tprio) #ifdef DT_LNK if (entry->d_type != DT_UNKNOWN) { if (entry->d_type == DT_LNK) tprio = 0; } else #endif #ifdef S_ISLNK { #ifndef WIN32 if (lstat(filename, &f_stat)) goto done; if (S_ISLNK(f_stat.st_mode)) tprio = 0; #endif } #else ; #endif if(doBitmaps) rc = bitmapIdentify(filename, &xlfd_name); else rc = 0; if(rc < 0) goto done; if(rc == 0) { ftrc = FT_New_Face(ft_library, filename, 0, &face); if(ftrc) goto done; have_face = 1; isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); if(!isBitmap) { /* Workaround for bitmap-only SFNT fonts */ if(FT_IS_SFNT(face) && face->num_fixed_sizes > 0 && strcmp(FT_Get_X11_Font_Format(face), "TrueType") == 0) { TT_MaxProfile *maxp; maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); if(maxp != NULL && maxp->maxContours == 0) isBitmap = 1; } } if(isBitmap) { if(!doBitmaps) goto done; } else { if(!doScalable) goto done; } if(isBitmap) { BDF_PropertyRec prop; rc = FT_Get_BDF_Property(face, "FONT", &prop); if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { xlfd_name = strdup(prop.u.atom); if(xlfd_name == NULL) goto done; } } } if(xlfd_name) { /* We know it's a bitmap font, and we know its XLFD */ int n = strlen(xlfd_name); if(reencodeLegacy && n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) { char *s; s = malloc(n - 10); memcpy(s, xlfd_name, n - 11); s[n - 11] = '\0'; xlfd = listCons(s, xlfd); } else { /* Not a reencodable font -- skip all the rest of the loop body */ putHash(entries, xlfd_name, entry->d_name, PRIO(filePrio(entry->d_name))); goto done; } } if(!have_face) { ftrc = FT_New_Face(ft_library, filename, 0, &face); if(ftrc) goto done; have_face = 1; isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); if(!isBitmap) { if(face->num_fixed_sizes > 0) { TT_MaxProfile *maxp; maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); if(maxp != NULL && maxp->maxContours == 0) isBitmap = 1; } } } if(xlfd == NULL) xlfd = makeXLFD(entry->d_name, face, isBitmap); found = 0; for(lp = xlfd; lp; lp = lp->next) { char buf[MAXFONTNAMELEN]; for(encoding = encodings; encoding; encoding = encoding->next) { if(checkEncoding(face, encoding->value)) { found = 1; snprintf(buf, MAXFONTNAMELEN, "%s-%s", lp->value, encoding->value); putHash(entries, buf, entry->d_name, PRIO(filePrio(entry->d_name))); } } for(encoding = extra_encodings; encoding; encoding = encoding->next) { if(checkExtraEncoding(face, encoding->value, found)) { /* Do not set found! */ snprintf(buf, MAXFONTNAMELEN, "%s-%s", lp->value, encoding->value); putHash(entries, buf, entry->d_name, PRIO(filePrio(entry->d_name))); } } } done: if(have_face) FT_Done_Face(face); deepDestroyList(xlfd); xlfd = NULL; free(filename); #undef PRIO } closedir(dirp); n = hashElements(entries); fprintf(fontscale, "%d\n", n); array = hashArray(entries, 1); for(i = 0; i < n; i++) fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key); destroyHashArray(array); entries = NULL; if(fontscale_name) { fclose(fontscale); free(fontscale_name); } encodings: encdir = dsprintf("%s%s", dirname, "encodings.dir"); if(encdir == NULL) { perror("encodings"); exit(1); } unlink(encdir); if (numEncodings) { encfile = fopen(encdir, "w"); if(encfile == NULL) { perror("open(encodings.dir)"); exit(1); } fprintf(encfile, "%d\n", numEncodings); encodingsToDo = sortList(encodingsToDo); for(lp = encodingsToDo; lp; lp = lp->next) { fprintf(encfile, "%s\n", lp->value); } fclose (encfile); } free(dirname); return 1; }
cff_get_advances( FT_Face face, FT_UInt start, FT_UInt count, FT_Int32 flags, FT_Fixed* advances ) { FT_UInt nn; FT_Error error = FT_Err_Ok; FT_GlyphSlot slot = face->glyph; if ( FT_IS_SFNT( face ) ) { /* OpenType 1.7 mandates that the data from `hmtx' table be used; */ /* it is no longer necessary that those values are identical to */ /* the values in the `CFF' table */ TT_Face ttface = (TT_Face)face; FT_Short dummy; if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without VVAR table */ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif /* check whether we have data from the `vmtx' table at all; */ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ /* table) */ if ( !ttface->vertical_info ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) { FT_UShort ah; ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, 1, start + nn, &dummy, &ah ); FT_TRACE5(( " idx %d: advance height %d font unit%s\n", start + nn, ah, ah == 1 ? "" : "s" )); advances[nn] = ah; } } else { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without HVAR table */ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif /* check whether we have data from the `hmtx' table at all */ if ( !ttface->horizontal.number_Of_HMetrics ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) { FT_UShort aw; ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, 0, start + nn, &dummy, &aw ); FT_TRACE5(( " idx %d: advance width %d font unit%s\n", start + nn, aw, aw == 1 ? "" : "s" )); advances[nn] = aw; } } return error; } Missing_Table: flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) { error = cff_glyph_load( slot, face->size, start + nn, flags ); if ( error ) break; advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) ? slot->linearVertAdvance : slot->linearHoriAdvance; } return error; }
XeTeXFontMgr::NameCollection* XeTeXFontMgr_FC::readNames(FcPattern* pat) { NameCollection* names = new NameCollection; char* pathname; if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch) return names; int index; if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch) return names; FT_Face face; if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0) return names; const char* name = FT_Get_Postscript_Name(face); if (name == NULL) return names; names->psName = name; // for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig if (FT_IS_SFNT(face)) { std::list<std::string> familyNames; std::list<std::string> subFamilyNames; FT_SfntName nameRec; for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) { char* utf8name = NULL; if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0) continue; switch (nameRec.name_id) { case kFontFullName: case kFontFamilyName: case kFontStyleName: case kPreferredFamilyName: case kPreferredSubfamilyName: { bool preferredName = false; if (nameRec.platform_id == TT_PLATFORM_MACINTOSH && nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) { utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len); preferredName = true; } else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE) || (nameRec.platform_id == TT_PLATFORM_MICROSOFT)) utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len); if (utf8name != NULL) { std::list<std::string>* nameList = NULL; switch (nameRec.name_id) { case kFontFullName: nameList = &names->fullNames; break; case kFontFamilyName: nameList = &names->familyNames; break; case kFontStyleName: nameList = &names->styleNames; break; case kPreferredFamilyName: nameList = &familyNames; break; case kPreferredSubfamilyName: nameList = &subFamilyNames; break; } if (preferredName) prependToList(nameList, utf8name); else appendToList(nameList, utf8name); } } break; } } if (familyNames.size() > 0) names->familyNames = familyNames; if (subFamilyNames.size() > 0) names->styleNames = subFamilyNames; } else { index = 0; while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch) appendToList(&names->fullNames, name); index = 0; while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch) appendToList(&names->familyNames, name); index = 0; while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch) appendToList(&names->styleNames, name); if (names->fullNames.size() == 0) { std::string fullName(names->familyNames.front()); if (names->styleNames.size() > 0) { fullName += " "; fullName += names->styleNames.front(); } names->fullNames.push_back(fullName); } } FT_Done_Face(face); return names; }
static void add_face_info(GtkWidget *table, gint *row_p, const gchar *uri, FT_Face face) { gchar *s; GFile *file; GFileInfo *info; PS_FontInfoRec ps_info; add_row(table, row_p, _("Name:"), face->family_name, FALSE, FALSE); if (face->style_name) add_row(table, row_p, _("Style:"), face->style_name, FALSE, FALSE); file = g_file_new_for_uri (uri); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_object_unref (file); if (info) { s = g_content_type_get_description (g_file_info_get_content_type (info)); add_row (table, row_p, _("Type:"), s, FALSE, FALSE); g_free (s); s = g_format_size (g_file_info_get_size (info)); add_row (table, row_p, _("Size:"), s, FALSE, FALSE); g_free (s); g_object_unref (info); } if (FT_IS_SFNT(face)) { gint i, len; gchar *version = NULL, *copyright = NULL, *description = NULL; len = FT_Get_Sfnt_Name_Count(face); for (i = 0; i < len; i++) { FT_SfntName sname; if (FT_Get_Sfnt_Name(face, i, &sname) != 0) continue; /* only handle the unicode names for US langid */ if (!(sname.platform_id == TT_PLATFORM_MICROSOFT && sname.encoding_id == TT_MS_ID_UNICODE_CS && sname.language_id == TT_MS_LANGID_ENGLISH_UNITED_STATES)) continue; switch (sname.name_id) { case TT_NAME_ID_COPYRIGHT: g_free(copyright); copyright = g_convert((gchar *)sname.string, sname.string_len, "UTF-8", "UTF-16BE", NULL, NULL, NULL); break; case TT_NAME_ID_VERSION_STRING: g_free(version); version = g_convert((gchar *)sname.string, sname.string_len, "UTF-8", "UTF-16BE", NULL, NULL, NULL); break; case TT_NAME_ID_DESCRIPTION: g_free(description); description = g_convert((gchar *)sname.string, sname.string_len, "UTF-8", "UTF-16BE", NULL, NULL, NULL); break; default: break; } } if (version) { add_row(table, row_p, _("Version:"), version, FALSE, FALSE); g_free(version); } if (copyright) { add_row(table, row_p, _("Copyright:"), copyright, TRUE, TRUE); g_free(copyright); } if (description) { add_row(table, row_p, _("Description:"), description, TRUE, TRUE); g_free(description); } } else if (FT_Get_PS_Font_Info(face, &ps_info) == 0) { if (ps_info.version && g_utf8_validate(ps_info.version, -1, NULL)) add_row(table, row_p, _("Version:"), ps_info.version, FALSE, FALSE); if (ps_info.notice && g_utf8_validate(ps_info.notice, -1, NULL)) add_row(table, row_p, _("Copyright:"), ps_info.notice, TRUE, FALSE); } }
void XeTeXFontInst::initialize(const char* pathname, int index, int &status) { TT_Postscript *postTable; TT_OS2* os2Table; FT_Error error; hb_face_t *hbFace; if (!gFreeTypeLibrary) { error = FT_Init_FreeType(&gFreeTypeLibrary); if (error) { fprintf(stderr, "FreeType initialization failed! (%d)\n", error); exit(1); } } error = FT_New_Face(gFreeTypeLibrary, pathname, index, &m_ftFace); if (error) { status = 1; return; } if (!FT_IS_SCALABLE(m_ftFace)) { status = 1; return; } /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */ if (index == 0 && !FT_IS_SFNT(m_ftFace)) { char* afm = xstrdup (xbasename (pathname)); char* p = strrchr (afm, '.'); if (p != NULL && strlen(p) == 4 && tolower(*(p+1)) == 'p' && tolower(*(p+2)) == 'f') strcpy(p, ".afm"); char *fullafm = kpse_find_file (afm, kpse_afm_format, 0); free (afm); if (fullafm) { FT_Attach_File(m_ftFace, fullafm); free (fullafm); } } m_filename = xstrdup(pathname); m_index = index; m_unitsPerEM = m_ftFace->units_per_EM; m_ascent = unitsToPoints(m_ftFace->ascender); m_descent = unitsToPoints(m_ftFace->descender); postTable = (TT_Postscript *) getFontTable(ft_sfnt_post); if (postTable != NULL) { m_italicAngle = Fix2D(postTable->italicAngle); } os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2); if (os2Table) { m_capHeight = unitsToPoints(os2Table->sCapHeight); m_xHeight = unitsToPoints(os2Table->sxHeight); } // Set up HarfBuzz font hbFace = hb_face_create_for_tables(_get_table, m_ftFace, NULL); hb_face_set_index(hbFace, index); hb_face_set_upem(hbFace, m_unitsPerEM); m_hbFont = hb_font_create(hbFace); hb_face_destroy(hbFace); if (hbFontFuncs == NULL) hbFontFuncs = _get_font_funcs(); hb_font_set_funcs(m_hbFont, hbFontFuncs, m_ftFace, NULL); hb_font_set_scale(m_hbFont, m_unitsPerEM, m_unitsPerEM); // We don’t want device tables adjustments hb_font_set_ppem(m_hbFont, 0, 0); return; }
// // Constructor: // FontFace::FontFace( FontLibrary &library, const std::string &fileName ){ _fileName=fileName; // // By default report on fragmentary and partial orthographic // support in addition to fully supported orthographies: // _reportMissing = true; _reportFragmentary = true; _reportPartial = true; _reportFull = true; _reportConscript = false; FT_Error err; err = FT_New_Face(library.get(),_fileName.c_str(),0, &_face ); if(err==FT_Err_Unknown_File_Format) throw Exception("FontFace()","Unknown file format."); else if(err) throw Exception("FontFace()","Unable to open or process font file."); // // // _commonName = _face->family_name; _subFamily = _face->style_name; _glyphCount = _face->num_glyphs; if(FT_IS_SFNT(_face)){ FT_UInt count=FT_Get_Sfnt_Name_Count(_face); FT_SfntName fontName; for(unsigned j=0;j<count;j++){ FT_Get_Sfnt_Name(_face,j,&fontName); if(fontName.platform_id==3 && fontName.encoding_id==1){ // // Microsoft 3:1 Platform: // if( fontName.language_id==0x0409 ){ // // This is the de-facto // default AMERICAN ENGLISH // entry: // switch(fontName.name_id){ case NID_FONT_FAMILY: if(_commonName.empty()) _commonName = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_FONT_SUBFAM: if(_subFamily.empty()) _subFamily = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_VERSION: if(_version.empty()) _version = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_VENDOR: if(_vendor.empty()) _vendor = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_DESIGNER: if(_designer.empty()) _designer = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_URL_VENDOR: if(_vendorURL.empty()) _vendorURL = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; case NID_URL_DESIGNER: if(_designerURL.empty()) _designerURL = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; default: break; } }else{ // // Some other language: // We take whatever the very first // other language is to be // our "nativeName" string: // switch(fontName.name_id){ case NID_FONT_FAMILY: if(_nativeName.empty()) _nativeName = _getPlatform3Encoding1String(fontName.string_len,fontName.string); break; default: break; } } // // DEBUG // //if(fontName.name_id==NID_COPYRIGHT){ // // DEBUG: // std::cout << ">>> COPYRIGHT: " << _getPlatform3Encoding1String(fontName.string_len,fontName.string) << std::endl; //} //if(fontName.name_id==NID_VERSION){ // // DEBUG: // std::cout << ">>> VERSION : " << _getPlatform3Encoding1String(fontName.string_len,fontName.string) << std::endl; //} }else if(fontName.platform_id==1 && fontName.encoding_id==0){ // // Macintosh 1:0 platform: This is going to // be English in the MacRoman encoding: // // NOTA BENE: We currently do not deal with // non-English Mac strings. They seem to be // very rare in real fonts out there in the world. // switch(fontName.name_id){ case NID_FONT_FAMILY: if(_commonName.empty()) _commonName = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_FONT_SUBFAM: if(_subFamily.empty()) _subFamily = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_VERSION: if(_version.empty()) _version = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_VENDOR: if(_vendor.empty()) _vendor = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_DESIGNER: if(_designer.empty()) _designer = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_URL_VENDOR: if(_vendorURL.empty()) _vendorURL = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; case NID_URL_DESIGNER: if(_designerURL.empty()) _designerURL = _getPlatform1Encoding0String(fontName.string_len,fontName.string); break; default: break; } } } } // // If native name is missing, fill it in: // //if(_nativeName.empty()) _nativeName = _commonName; _style=NORMAL; if( _face->style_flags & FT_STYLE_FLAG_ITALIC ) _style = ITALIC; _weight=NORMAL_WEIGHT; if( _face->style_flags & FT_STYLE_FLAG_BOLD ) _weight = BOLD; _isFixedWidth=FT_IS_FIXED_WIDTH(_face); // // Vertical metrics for Japanese, Chinese, Mongolian: // _hasVerticalMetrics = FT_HAS_VERTICAL(_face); // // Check for embedded bitmaps: // _hasFixedSizes = FT_HAS_FIXED_SIZES(_face); // // Get the set of unicode values this font covers // _getUnicodeValues(); // // Check orthographic coverage: // //_checkOrthographies(); // // Check license: // _checkLicenses(); }
FT_Error get_file_info(FontManagerFontInfo *fileinfo, const gchar * filepath, gint index) { FT_Face face; FT_Library library; FT_Error error; PS_FontInfoRec ps_info; BDF_PropertyRec prop; gsize filesize = 0; gchar * font = NULL; if (G_UNLIKELY(!g_file_get_contents(filepath, &font, &filesize, NULL))) { g_warning("Failed to load file : %s", filepath); return FT_Err_Cannot_Open_Resource; } error = FT_Init_FreeType(&library); if (G_UNLIKELY(error)) return error; error = FT_New_Memory_Face(library, (const FT_Byte *) font, (FT_Long) filesize, index, &face); if (G_UNLIKELY(error)) { g_warning("Failed to create FT_Face for file : %s", filepath); return error; } font_manager_font_info_set_owner(fileinfo, get_file_owner(filepath)); font_manager_font_info_set_filetype(fileinfo, FT_Get_X11_Font_Format(face)); gchar * _size = g_format_size(filesize); font_manager_font_info_set_filesize(fileinfo, _size); g_free0(_size); gchar * _md5 = g_compute_checksum_for_data(G_CHECKSUM_MD5, (const guchar *) font, filesize); font_manager_font_info_set_checksum(fileinfo, _md5); g_free0(_md5); font_manager_font_info_set_psname(fileinfo, FT_Get_Postscript_Name(face)); TT_OS2 * os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2); if (G_LIKELY(os2 && os2->version >= 0x0001 && os2->version != 0xffff)) { gchar * _vendor = get_vendor_from_vendor_id((gchar *) os2->achVendID); font_manager_font_info_set_vendor(fileinfo, _vendor); g_free0(_vendor); gchar * panose = g_strdup_printf("%i:%i:%i:%i:%i:%i:%i:%i:%i:%i", os2->panose[0], os2->panose[1], os2->panose[2], os2->panose[3], os2->panose[4], os2->panose[5], os2->panose[6], os2->panose[7], os2->panose[8], os2->panose[9]); font_manager_font_info_set_panose(fileinfo, panose); g_free0(panose); } if (G_LIKELY(FT_IS_SFNT(face))) get_sfnt_info(fileinfo, face); if (FT_Get_PS_Font_Info(face, &ps_info) == 0) get_ps_info(fileinfo, ps_info, face); gint lic_type = get_license_type(font_manager_font_info_get_license_data(fileinfo), font_manager_font_info_get_copyright(fileinfo), font_manager_font_info_get_license_url(fileinfo)); gchar * _name = get_license_name(lic_type); font_manager_font_info_set_license_type(fileinfo, _name); g_free0(_name); if (!font_manager_font_info_get_license_url(fileinfo)) { gchar * _url = get_license_url(lic_type); if (_url) font_manager_font_info_set_license_url(fileinfo, _url); g_free0(_url); } if (!font_manager_font_info_get_version(fileinfo)) { TT_Header * head = (TT_Header *) FT_Get_Sfnt_Table (face, ft_sfnt_head); if (head) if (head->Font_Revision) { gchar * rev = g_strdup_printf("%f", (float) head->Font_Revision); font_manager_font_info_set_version(fileinfo, rev); g_free0(rev); } } if (!font_manager_font_info_get_vendor(fileinfo)) { int result = FT_Get_BDF_Property(face, "FOUNDRY", &prop); if(result == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) font_manager_font_info_set_vendor(fileinfo, prop.u.atom); else font_manager_font_info_set_vendor(fileinfo, "Unknown Vendor"); } FT_Done_Face(face); error = FT_Done_FreeType(library); g_free0(font); return error; }
cff_get_advances( FT_Face face, FT_UInt start, FT_UInt count, FT_Int32 flags, FT_Fixed* advances ) { FT_UInt nn; FT_Error error = FT_Err_Ok; FT_GlyphSlot slot = face->glyph; if ( FT_IS_SFNT( face ) ) { /* OpenType 1.7 mandates that the data from `hmtx' table be used; */ /* it is no longer necessary that those values are identical to */ /* the values in the `CFF' table */ TT_Face ttface = (TT_Face)face; FT_Short dummy; if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { /* check whether we have data from the `vmtx' table at all; */ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ /* table) */ if ( !ttface->vertical_info ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) { FT_UShort ah; ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, 1, start + nn, &dummy, &ah ); FT_TRACE5(( " idx %d: advance height %d font units\n", start + nn, ah )); advances[nn] = ah; } } else { /* check whether we have data from the `hmtx' table at all */ if ( !ttface->horizontal.number_Of_HMetrics ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) { FT_UShort aw; ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, 0, start + nn, &dummy, &aw ); FT_TRACE5(( " idx %d: advance width %d font units\n", start + nn, aw )); advances[nn] = aw; } } return error; } Missing_Table: flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) { error = cff_glyph_load( slot, face->size, start + nn, flags ); if ( error ) break; advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) ? slot->linearVertAdvance : slot->linearHoriAdvance; } return error; }