static void initializeDb() { QFontDatabasePrivate *db = privateDb(); if(!db || db->count) return; #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0); if(!collection) return; QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection); if(!fonts) return; QString foundry_name = "CoreText"; const int numFonts = CFArrayGetCount(fonts); for(int i = 0; i < numFonts; ++i) { CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i); QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute); QtFontFamily *family = db->family(family_name, true); for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) family->writingSystems[ws] = QtFontFamily::Supported; QtFontFoundry *foundry = family->foundry(foundry_name, true); QtFontStyle::Key styleKey; if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) { if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) { Q_ASSERT(CFNumberIsFloatType(weight)); double d; if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) { //qDebug() << "BOLD" << (QString)family_name << d; styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal; } } if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) { Q_ASSERT(CFNumberIsFloatType(italic)); double d; if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) { //qDebug() << "ITALIC" << (QString)family_name << d; if (d > 0.0) styleKey.style = QFont::StyleItalic; } } } QtFontStyle *style = foundry->style(styleKey, true); style->smoothScalable = true; if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) { //qDebug() << "WHEE"; int pixel_size=0; if(CFNumberIsFloatType(size)) { double d; CFNumberGetValue(size, kCFNumberDoubleType, &d); pixel_size = d; } else { CFNumberGetValue(size, kCFNumberIntType, &pixel_size); } //qDebug() << "SIZE" << (QString)family_name << pixel_size; if(pixel_size) style->pixelSize(pixel_size, true); } else { //qDebug() << "WTF?"; } } } else #endif { FMFontIterator it; if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) { while (true) { FMFont fmFont; if (FMGetNextFont(&it, &fmFont) != noErr) break; FMFontFamily fmFamily; FMFontStyle fmStyle; QString familyName; QtFontStyle::Key styleKey; ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont); if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) { { //sanity check the font, and see if we can use it at all! --Sam ATSUFontID fontID; if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr) continue; } if (fmStyle & ::italic) styleKey.style = QFont::StyleItalic; if (fmStyle & ::bold) styleKey.weight = QFont::Bold; ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily); QCFString cfFamilyName;; ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName); familyName = cfFamilyName; } else { QCFString cfFontName; ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName); familyName = cfFontName; quint16 macStyle = 0; { uchar data[4]; ByteCount len = 4; if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr) macStyle = qFromBigEndian<quint16>(data); } if (macStyle & 1) styleKey.weight = QFont::Bold; if (macStyle & 2) styleKey.style = QFont::StyleItalic; } QtFontFamily *family = db->family(familyName, true); QtFontFoundry *foundry = family->foundry(QString(), true); QtFontStyle *style = foundry->style(styleKey, true); style->pixelSize(0, true); style->smoothScalable = true; initWritingSystems(family, atsFont); } FMDisposeFontIterator(&it); } } }
int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path) { fontenum_t *state = (fontenum_t *)enum_state; FMFontIterator *Iterator = &state->Iterator; FMFont Font; FourCharCode Format; FMFontFamily FontFamily; FMFontStyle Style; FSSpec FontContainer; char type[5]; char fontpath[256]; char *psname; fond_table *table = NULL; OSStatus result; result = FMGetNextFont(Iterator, &Font); if (result != noErr) return 0; /* no more fonts */ result = FMGetFontFormat(Font, &Format); type[0] = ((char*)&Format)[0]; type[1] = ((char*)&Format)[1]; type[2] = ((char*)&Format)[2]; type[3] = ((char*)&Format)[3]; type[4] = '\0'; FMGetFontFamilyInstanceFromFont(Font, &FontFamily, &Style); if (state->name) free (state->name); psname = makePSFontName(FontFamily, Style); if (psname == NULL) { state->name = strdup("GSPlaceHolder"); } else { state->name = psname; } result = FMGetFontContainer(Font, &FontContainer); if (!memcmp(&FontContainer, &state->last_container, sizeof(FSSpec))) { /* we have cached data on this file */ strncpy(fontpath, state->last_container_path, 256); table = state->last_table; } else { convertSpecToPath(&FontContainer, fontpath, 256); if (!is_ttf_file(fontpath) && !is_otf_file(fontpath)) table = parse_fond(&FontContainer); /* cache data on the new font file */ memcpy(&state->last_container, &FontContainer, sizeof(FSSpec)); if (state->last_container_path) free (state->last_container_path); state->last_container_path = strdup(fontpath); if (state->last_table) fond_table_free(state->last_table); state->last_table = table; } if (state->path) { free(state->path); state->path = NULL; } if (table != NULL) { int i; for (i = 0; i < table->entries; i++) { if (table->refs[i].size == 0) { /* ignore non-scalable fonts */ if (table->refs[i].style == Style) { int len = strlen(fontpath) + strlen("%macresource%#sfnt+") + 6; state->path = malloc(len); snprintf(state->path, len, "%%macresource%%%s#sfnt+%d", fontpath, table->refs[i].id); break; } } } } else { /* regular font file */ state->path = strdup(fontpath); } if (state->path == NULL) { /* no matching font was found in the FOND resource table. this usually */ /* means an LWFN file, which we don't handle yet. */ /* we still specify these with a %macresource% path, but no res id */ /* TODO: check file type */ int len = strlen(fontpath) + strlen("%macresource%#POST") + 1; state->path = malloc(len); snprintf(state->path, len, "%%macresource%%%s#POST", fontpath); } #ifdef DEBUG dlprintf2("fontenum: returning '%s' in '%s'\n", state->name, state->path); #endif *fontname = state->name; *path = state->path; state->count += 1; return 1; }