void QFontDatabase::createDatabase() { if(db) return; db = new QFontDatabasePrivate; qfontdatabase_cleanup.set(&db); FMFontFamilyIterator it; QString foundry_name = "Mac"; if(!FMCreateFontFamilyIterator(NULL, NULL, kFMUseGlobalScopeOption, &it)) { FMFontFamily fam; QString fam_name; while(!FMGetNextFontFamily(&it, &fam)) { static Str255 n; if(FMGetFontFamilyName(fam, n) != noErr) qDebug("Qt: internal: WH0A, %s %d", __FILE__, __LINE__); if(!n[0] || n[1] == '.') //throw out ones starting with a . continue; { short fnum; ATSUFontID fond; GetFNum(n, &fnum); if(ATSUFONDtoFontID(fnum, 0, &fond) != noErr) continue; } TextEncoding encoding; FMGetFontFamilyTextEncoding(fam, &encoding); TextToUnicodeInfo uni_info; CreateTextToUnicodeInfoByEncoding(encoding, &uni_info); unsigned long len = n[0] * 2; unsigned char *buff = (unsigned char *)malloc(len); ConvertFromPStringToUnicode(uni_info, n, len, &len, (UniCharArrayPtr)buff); fam_name = ""; for(unsigned long x = 0; x < len; x+=2) { #if defined(__i386__) fam_name += QChar(buff[x], buff[x+1]); #else fam_name += QChar(buff[x+1], buff[x]); #endif } free(buff); DisposeTextToUnicodeInfo(&uni_info); QtFontFamily *family = db->family( fam_name, TRUE ); family->macFamily = fam; for(int script = 0; script < QFont::LastPrivateScript; ++script) family->scripts[script] = QtFontFamily::Supported; QtFontFoundry *foundry = family->foundry( foundry_name, TRUE ); FMFontFamilyInstanceIterator fit; if(!FMCreateFontFamilyInstanceIterator(fam, &fit)) { FMFont font; FMFontStyle font_style; FMFontSize font_size; while(!FMGetNextFontFamilyInstance(&fit, &font, &font_style, &font_size)) { bool italic = (bool)(font_style & ::italic); int weight = ((font_style & ::bold) ? QFont::Bold : QFont::Normal); QtFontStyle::Key styleKey; styleKey.italic = italic; styleKey.oblique = false; styleKey.weight = weight; QtFontStyle *style = foundry->style( styleKey, TRUE ); style->smoothScalable = TRUE; if( !italic ) { styleKey.oblique = TRUE; style = foundry->style( styleKey, TRUE ); style->smoothScalable = TRUE; styleKey.oblique = FALSE; } if(weight < QFont::DemiBold) { // Can make bolder styleKey.weight = QFont::Bold; if(italic) { style = foundry->style( styleKey, TRUE ); style->smoothScalable = TRUE; } else { styleKey.oblique = TRUE; style = foundry->style( styleKey, TRUE ); style->smoothScalable = TRUE; } } } FMDisposeFontFamilyInstanceIterator(&fit); } } FMDisposeFontFamilyIterator(&it); } }
static OSStatus AddTextLabel( const char *textString, CGContextRef cgContext, Fixed currentXPos, Fixed *currentYPos ) { OSStatus err; UniChar *textBuffer = NULL; ByteCount textBufferLen; ByteCount sourceRead; ByteCount convertedTextLen; TextToUnicodeInfo textToUnicodeInfo; TextEncoding macEncoding; // create an encoding for mac roman macEncoding = CreateTextEncoding( kTextEncodingMacRoman, kTextEncodingDefaultVariant, kTextEncodingDefaultFormat ); // create a text to unicode converter err = CreateTextToUnicodeInfoByEncoding( macEncoding, &textToUnicodeInfo ); require_noerr( err, AddTextLabel_err ); textBufferLen = strlen( textString ); // loop until we have a buffer big enough to hold the whole conversion do { // allocate a textBuffer. Twice the size of the text should be about right. textBufferLen = textBufferLen * 2; textBuffer = (UniChar *) realloc( textBuffer, sizeof( char ) * textBufferLen ); require_action( textBuffer != NULL, AddTextLabel_err, err = memFullErr ); // run the conversion. If we get a full error, then reallocate otherwise, // bail err = ConvertFromTextToUnicode( textToUnicodeInfo, strlen( textString ), textString, kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask, 0, NULL, NULL, NULL, textBufferLen, &sourceRead, &convertedTextLen, textBuffer ); } while ( err == kTECOutputBufferFullStatus ); // dispose of the converter DisposeTextToUnicodeInfo( &textToUnicodeInfo ); // fallback error is okay. Everything else is bad. if ( err != kTECUsedFallbacksStatus ) { require_noerr( err, AddTextLabel_err ); } // finally, we can get to actual ATSUI stuff. Create the layout with // all of the default stuff for the test labels. err = DrawLayoutForStyleAndRunInfo( &gInfoStyle, 1, NULL, 0, textBuffer, (UniCharCount) (convertedTextLen / 2), cgContext, currentXPos, currentYPos ); require_noerr( err, AddTextLabel_err ); AddTextLabel_err: if ( textBuffer != NULL ) { free( textBuffer ); } return err; }