示例#1
0
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);
    }
}
}
示例#2
0
文件: osxtext.cpp 项目: kant/livecode
static bool osx_draw_text_to_cgcontext_at_location(const void *p_text, uindex_t p_length, MCGPoint p_location, const MCGFont &p_font, CGContextRef p_cgcontext, MCGIntRectangle &r_bounds)
{	
	OSStatus t_err;
	t_err = noErr;	
	
	ATSUFontID t_font_id;
	Fixed t_font_size;
	t_font_size = p_font . size << 16;	
	
	ATSUAttributeTag t_tags[] =
	{
		kATSUFontTag,
		kATSUSizeTag,
	};
	ByteCount t_sizes[] =
	{
		sizeof(ATSUFontID),
		sizeof(Fixed),
	};
	ATSUAttributeValuePtr t_attrs[] =
	{
		&t_font_id,
		&t_font_size,
	};	
	
	ATSLineLayoutOptions t_layout_options;
	ATSUAttributeTag t_layout_tags[] =
	{
		kATSULineLayoutOptionsTag,
		kATSUCGContextTag,
	};
	ByteCount t_layout_sizes[] =
	{
		sizeof(ATSLineLayoutOptions),
		sizeof(CGContextRef),
	};
	ATSUAttributeValuePtr t_layout_attrs[] =
	{
		&t_layout_options,
		&p_cgcontext,
	};	
	
	if (t_err == noErr)
	{
		// if the specified fon't can't be found, just use the default
		if (ATSUFONDtoFontID((short)(intptr_t)p_font . fid, p_font . style, &t_font_id) != noErr)
			t_err = ATSUFONDtoFontID(0, p_font . style, &t_font_id);
	}
	
	ATSUStyle t_style;
	t_style = NULL;
	if (t_err == noErr)
		t_err = ATSUCreateStyle(&t_style);
	if (t_err == noErr)
		t_err = ATSUSetAttributes(t_style, sizeof(t_tags) / sizeof(ATSUAttributeTag), t_tags, t_sizes, t_attrs);
	
	ATSUTextLayout t_layout;
	t_layout = NULL;
	if (t_err == noErr)
	{
		UniCharCount t_run;
		t_run = p_length / 2;
		t_err = ATSUCreateTextLayoutWithTextPtr((const UniChar *)p_text, 0, p_length / 2, p_length / 2, 1, &t_run, &t_style, &t_layout);
	}
	if (t_err == noErr)
		t_err = ATSUSetTransientFontMatching(t_layout, true);
	if (t_err == noErr)
	{
		t_layout_options = kATSLineUseDeviceMetrics | kATSLineFractDisable;
		t_err = ATSUSetLayoutControls(t_layout, sizeof(t_layout_tags) / sizeof(ATSUAttributeTag), t_layout_tags, t_layout_sizes, t_layout_attrs);
	}	
	
	MCGIntRectangle t_bounds;
	if (p_cgcontext == NULL)
	{
		ATSUTextMeasurement t_before, t_after, t_ascent, t_descent;
		if (t_err == noErr)
			t_err = ATSUGetUnjustifiedBounds(t_layout, 0, p_length / 2, &t_before, &t_after, &t_ascent, &t_descent);
		
		if (t_err == noErr)
		{
			t_ascent = (t_ascent + 0xffff) >> 16;
			t_descent = (t_descent + 0xffff) >> 16;
			t_after = (t_after + 0xffff) >> 16;
			
			t_bounds . x = p_location . x;
			t_bounds . y = p_location . y - p_font . ascent;
			t_bounds . width = t_after;
			t_bounds . height = p_font . descent + p_font . ascent;
			
			r_bounds = t_bounds;
		}
示例#3
0
文件: osxtext.cpp 项目: kant/livecode
static bool osx_prepare_text(const void *p_text, uindex_t p_length, const MCGFont &p_font)
{
    OSStatus t_err;
	t_err = noErr;
    
	if (t_err == noErr)
		if (s_layout == NULL)
			t_err = ATSUCreateTextLayout(&s_layout);
	
	if (t_err == noErr)
		if (s_style == NULL)
			t_err = ATSUCreateStyle(&s_style);
    
    if (t_err == noErr)
        if (s_colour_space == NULL)
            s_colour_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
    
    if (t_err == noErr)
        if (s_colour == NULL)
        {
            // Components are grey and alpha
            const float t_colour_components[] = {1.0, 1.0};
            s_colour = CGColorCreate(s_colour_space, t_colour_components);
        }
	
	ATSUFontID t_font_id;
	Fixed t_font_size;
	Boolean t_font_is_italic;
	ATSUTextMeasurement t_imposed_width;
    if (t_err == noErr)
    {
        t_font_size = p_font . size << 16;
		
		// MM-2013-09-16: [[ Bug 11283 ]] It appears that ATSUI doesn't like italic being passed as a style parameter to ATSUFONDtoFontID.
		//   Instead, set italic as an attribute tag.
		uint8_t t_style;
		t_style = p_font . style & ~italic;
		t_font_is_italic = p_font . style & italic;
		
		// MW-2013-12-05: [[ Bug 11535 ]] Set the imposed width to the fixed advance width
		//   if non-zero. Otherwise use the glyph advance.
		if (p_font . fixed_advance != 0)
			t_imposed_width = p_font . fixed_advance << 16;
		else
			t_imposed_width = kATSUseGlyphAdvance;
			
		// if the specified font can't be found, just use the default
		// MM-2013-09-16: [[ Bug 11283 ]] Do the same for font styles - if the font/style paring cannot be found, try font with no style.
		t_err = ATSUFONDtoFontID((short)(intptr_t)p_font . fid, t_style, &t_font_id);
		if (t_err != noErr)
			t_err = ATSUFONDtoFontID((short)(intptr_t)p_font . fid, 0, &t_font_id);
		if (t_err != noErr)
			t_err = ATSUFONDtoFontID(0, t_style, &t_font_id);
		if (t_err != noErr)
			t_err = ATSUFONDtoFontID(0, 0, &t_font_id);
    }
	ATSUAttributeTag t_tags[] =
	{
		kATSUFontTag,
		kATSUSizeTag,
		kATSUQDItalicTag,
		kATSUImposeWidthTag,
	};
	ByteCount t_sizes[] =
	{
		sizeof(ATSUFontID),
		sizeof(Fixed),
		sizeof(Boolean),
		sizeof(ATSUTextMeasurement),
	};
	ATSUAttributeValuePtr t_attrs[] =
	{
		&t_font_id,
		&t_font_size,
		&t_font_is_italic,
		&t_imposed_width,
	};
	if (t_err == noErr)
		t_err = ATSUSetAttributes(s_style, sizeof(t_tags) / sizeof(ATSUAttributeTag), t_tags, t_sizes, t_attrs);
	if (t_err == noErr)
		t_err = ATSUSetTextPointerLocation(s_layout, (const UniChar *) p_text, 0, p_length / 2, p_length / 2);
	if (t_err == noErr)
		t_err = ATSUSetRunStyle(s_layout, s_style, 0, p_length / 2);
	if (t_err == noErr)
		t_err = ATSUSetTransientFontMatching(s_layout, true);
	
	return t_err == noErr;
}
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);
    }
}