示例#1
0
static void match_fonts(ASS_Library *lib, ASS_FontProvider *provider,
                        char *name)
{
    const size_t attributes_n = 3;
    CTFontDescriptorRef ctdescrs[attributes_n];
    CFMutableDictionaryRef cfattrs[attributes_n];
    CFStringRef attributes[attributes_n] = {
        kCTFontFamilyNameAttribute,
        kCTFontDisplayNameAttribute,
        kCTFontNameAttribute,
    };

    CFStringRef cfname =
        CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);

    for (int i = 0; i < attributes_n; i++) {
        cfattrs[i] = CFDictionaryCreateMutable(NULL, 0, 0, 0);
        CFDictionaryAddValue(cfattrs[i], attributes[i], cfname);
        ctdescrs[i] = CTFontDescriptorCreateWithAttributes(cfattrs[i]);
    }

    CFArrayRef descriptors =
        CFArrayCreate(NULL, (const void **)&ctdescrs, attributes_n, NULL);

    CTFontCollectionRef ctcoll =
        CTFontCollectionCreateWithFontDescriptors(descriptors, 0);

    CFArrayRef fontsd =
        CTFontCollectionCreateMatchingFontDescriptors(ctcoll);

    process_descriptors(provider, fontsd);

    SAFE_CFRelease(fontsd);
    SAFE_CFRelease(ctcoll);

    for (int i = 0; i < attributes_n; i++) {
        SAFE_CFRelease(cfattrs[i]);
        SAFE_CFRelease(ctdescrs[i]);
    }

    SAFE_CFRelease(descriptors);
    SAFE_CFRelease(cfname);
}
示例#2
0
QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
{
    QCFString expectedFamily = QCFString(family);

    QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
    QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);

    QCFType<CFMutableSetRef> mandatoryAttributes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
    CFSetAddValue(mandatoryAttributes, kCTFontFamilyNameAttribute);

    QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
    QCFType<CTFontDescriptorRef> matched = CTFontDescriptorCreateMatchingFontDescriptor(descriptor, mandatoryAttributes);
    if (!matched)
        return family;

    QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(matched, kCTFontFamilyNameAttribute, NULL);
    return familyName;
}
示例#3
0
void QFontDatabase::load(const QFontPrivate *d, int script)
{
    // sanity checks
    if(!qApp)
        qWarning("QFont: Must construct a QApplication before a QFont");

    Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
    Q_UNUSED(script);

    QFontDef req = d->request;
    req.pixelSize = qt_mac_pixelsize(req, d->dpi);

    // set the point size to 0 to get better caching
    req.pointSize = 0;
    QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen);

    if(!(d->engineData = QFontCache::instance()->findEngineData(key))) {
        d->engineData = new QFontEngineData;
        QFontCache::instance()->insertEngineData(key, d->engineData);
    } else {
        d->engineData->ref.ref();
    }
    if(d->engineData->engine) // already loaded
        return;

    // set it to the actual pointsize, so QFontInfo will do the right thing
    req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi));

    QFontEngine *e = QFontCache::instance()->findEngine(key);
    if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
        e = new QTestFontEngine(req.pixelSize);
        e->fontDef = req;
    }

    if(e) {
        e->ref.ref();
        d->engineData->engine = e;
        return; // the font info and fontdef should already be filled
    }

    QFontEngine *engine = NULL;
#if defined(QT_MAC_USE_COCOA)
    // Shortcut to get the font directly without going through the font database
    if (!req.family.isEmpty() && !req.styleName.isEmpty()) {
        QCFString expectedFamily = QCFString(req.family);
        QCFString expectedStyle = QCFString(req.styleName);

        QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
            &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
        CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle);

        QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
        CGAffineTransform transform = qt_transform_from_fontdef(req);
        QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform);
        if (ctFont) {
            QCFString familyName = CTFontCopyFamilyName(ctFont);
            // Only accept the font if the family name is exactly the same as we specified
            if (CFEqual(expectedFamily, familyName)) {
                engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning);
            }
        }
    }
#endif
    if (!engine)
        engine = loadFromDatabase(req, d);

    if (engine) {
        d->engineData->engine = engine;
        engine->ref.ref();
        QFontCache::instance()->insertEngine(key, engine);
    }
}
示例#4
0
static QFontEngine *loadFromDatabase(QFontDef &req, const QFontPrivate *d)
{
#if defined(QT_MAC_USE_COCOA)
    QCFString fontName = NULL;
#else
    ATSFontFamilyRef familyRef = 0;
    ATSFontRef fontRef = 0;
#endif

    QStringList family_list = familyList(req);

    const char *stylehint = styleHint(req);
    if (stylehint)
        family_list << QLatin1String(stylehint);

    // add QFont::defaultFamily() to the list, for compatibility with previous versions
    family_list << QApplication::font().defaultFamily();

    QMutexLocker locker(fontDatabaseMutex());
    QFontDatabasePrivate *db = privateDb();
    if (!db->count)
        initializeDb();
    for (int i = 0; i < family_list.size(); ++i) {
        for (int k = 0; k < db->count; ++k) {
            if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
#if defined(QT_MAC_USE_COCOA)
                CFStringRef familyName = QCFString::toCFStringRef(db->families[k]->name);
                QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(
                                    QCFType<CFDictionaryRef>(CFDictionaryCreate(kCFAllocatorDefault,
                                        (const void**)&kCTFontFamilyNameAttribute,
                                        (const void**)&familyName, 1,
                                        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)));
                CFRelease(familyName);
                QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, 0, NULL);
                if (ctFont) {
                    fontName = CTFontCopyFullName(ctFont);
                    goto found;
                }
#else
                familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
                if (familyRef) {
                    fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
                    goto found;
                }
#endif
            }
        }
    }
found:
#ifdef QT_MAC_USE_COCOA
    if (fontName)
        return new QCoreTextFontEngineMulti(fontName, req, d->kerning);
#else
    if (familyRef) {
        QCFString actualName;
        if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
            req.family = actualName;
        return new QFontEngineMacMulti(familyRef, fontRef, req, d->kerning);
    }
#endif
    return NULL;
}
示例#5
0
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
{
	bool result = false;

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
	if (MacOSVersionIsAtLeast(10, 5, 0)) {
		/* Determine fallback font using CoreText. This uses the language isocode
		 * to find a suitable font. CoreText is available from 10.5 onwards. */
		char lang[16];
		if (strcmp(language_isocode, "zh_TW") == 0) {
			/* Traditional Chinese */
			strecpy(lang, "zh-Hant", lastof(lang));
		} else if (strcmp(language_isocode, "zh_CN") == 0) {
			/* Simplified Chinese */
			strecpy(lang, "zh-Hans", lastof(lang));
		} else {
			/* Just copy the first part of the isocode. */
			strecpy(lang, language_isocode, lastof(lang));
			char *sep = strchr(lang, '_');
			if (sep != NULL) *sep = '\0';
		}

		/* Create a font descriptor matching the wanted language and latin (english) glyphs. */
		CFStringRef lang_codes[2];
		lang_codes[0] = CFStringCreateWithCString(kCFAllocatorDefault, lang, kCFStringEncodingUTF8);
		lang_codes[1] = CFSTR("en");
		CFArrayRef lang_arr = CFArrayCreate(kCFAllocatorDefault, (const void **)lang_codes, lengthof(lang_codes), &kCFTypeArrayCallBacks);
		CFDictionaryRef lang_attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontLanguagesAttribute, (const void **)&lang_arr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		CTFontDescriptorRef lang_desc = CTFontDescriptorCreateWithAttributes(lang_attribs);
		CFRelease(lang_arr);
		CFRelease(lang_attribs);
		CFRelease(lang_codes[0]);

		/* Get array of all font descriptors for the wanted language. */
		CFSetRef mandatory_attribs = CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks);
		CFArrayRef descs = CTFontDescriptorCreateMatchingFontDescriptors(lang_desc, mandatory_attribs);
		CFRelease(mandatory_attribs);
		CFRelease(lang_desc);

		for (CFIndex i = 0; descs != NULL && i < CFArrayGetCount(descs); i++) {
			CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs, i);

			/* Get font traits. */
			CFDictionaryRef traits = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
			CTFontSymbolicTraits symbolic_traits;
			CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait), kCFNumberIntType, &symbolic_traits);
			CFRelease(traits);

			/* Skip symbol fonts and vertical fonts. */
			if ((symbolic_traits & kCTFontClassMaskTrait) == (CTFontStylisticClass)kCTFontSymbolicClass || (symbolic_traits & kCTFontVerticalTrait)) continue;
			/* Skip bold fonts (especially Arial Bold, which looks worse than regular Arial). */
			if (symbolic_traits & kCTFontBoldTrait) continue;
			/* Select monospaced fonts if asked for. */
			if (((symbolic_traits & kCTFontMonoSpaceTrait) == kCTFontMonoSpaceTrait) != callback->Monospace()) continue;

			/* Get font name. */
			char name[128];
			CFStringRef font_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontDisplayNameAttribute);
			CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);
			CFRelease(font_name);

			/* There are some special fonts starting with an '.' and the last
			 * resort font that aren't usable. Skip them. */
			if (name[0] == '.' || strncmp(name, "LastResort", 10) == 0) continue;

			/* Save result. */
			callback->SetFontNames(settings, name);
			if (!callback->FindMissingGlyphs(NULL)) {
				DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
				result = true;
				break;
			}
		}
		if (descs != NULL) CFRelease(descs);
	} else
#endif
	{
		/* Create a font iterator and iterate over all fonts that
		 * are available to the application. */
		ATSFontIterator itr;
		ATSFontRef font;
		ATSFontIteratorCreate(kATSFontContextLocal, NULL, NULL, kATSOptionFlagsDefaultScope, &itr);
		while (!result && ATSFontIteratorNext(itr, &font) == noErr) {
			/* Get font name. */
			char name[128];
			CFStringRef font_name;
			ATSFontGetName(font, kATSOptionFlagsDefault, &font_name);
			CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);

			bool monospace = IsMonospaceFont(font_name);
			CFRelease(font_name);

			/* Select monospaced fonts if asked for. */
			if (monospace != callback->Monospace()) continue;

			/* We only want the base font and not bold or italic variants. */
			if (strstr(name, "Italic") != NULL || strstr(name, "Bold")) continue;

			/* Skip some inappropriate or ugly looking fonts that have better alternatives. */
			if (name[0] == '.' || strncmp(name, "Apple Symbols", 13) == 0 || strncmp(name, "LastResort", 10) == 0) continue;

			/* Save result. */
			callback->SetFontNames(settings, name);
			if (!callback->FindMissingGlyphs(NULL)) {
				DEBUG(freetype, 2, "ATS-Font for %s: %s", language_isocode, name);
				result = true;
				break;
			}
		}
		ATSFontIteratorRelease(&itr);
	}

	if (!result) {
		/* For some OS versions, the font 'Arial Unicode MS' does not report all languages it
		 * supports. If we didn't find any other font, just try it, maybe we get lucky. */
		callback->SetFontNames(settings, "Arial Unicode MS");
		result = !callback->FindMissingGlyphs(NULL);
	}

	callback->FindMissingGlyphs(NULL);
	return result;
}
示例#6
0
static void *coretext_font_create_with_name_and_size(MCStringRef p_name, uint32_t p_size)
{
	/*CFStringRef t_name;
	t_name = CFStringCreateWithCString(NULL, p_name, kCFStringEncodingMacRoman);
	
	CTFontRef t_font;
    t_font = NULL;
    
    if (t_name != NULL)
    {
        t_font = CTFontCreateWithName(t_name, p_size, NULL);
        CFRelease(t_name);
    }
    
	return (void *)t_font;*/
    
    bool t_success;
    t_success = true;
    
    MCAutoStringRefAsCFString t_cf_name;
    t_success = t_cf_name . Lock(p_name);
    
    CFDictionaryRef t_attributes;
    t_attributes = NULL;
    if (t_success)
    {
        // MW-2014-07-23: [[ Bug 12426 ]] Only specify the 'name' attribute in the font descriptor
        //   otherwise things don't work correctly on iOS. It seems going via a descriptor stops
        //   the warning on 10.9.
        //
        // Updated the font creation routine to use font descriptors. Though CTFontCreateWithName worked,
        // it logged warnings (on 10.9) whenever it was passed a non-postscript font name. Hopefully using
        // the display name first in the descriptor will remove the warnings but still keep the fall back behaviour.
        CFStringRef t_keys[] =
        {
//            kCTFontDisplayNameAttribute,
            kCTFontNameAttribute,
//            kCTFontFamilyNameAttribute,
        };
        CFTypeRef t_values[] = {
            *t_cf_name,
            *t_cf_name,
            *t_cf_name,
        };
        t_attributes = CFDictionaryCreate(NULL,
                                          (const void **)&t_keys, (const void **)&t_values,
                                          sizeof(t_keys) / sizeof(t_keys[0]),
                                          &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        t_success = t_attributes != NULL;
    }
    
    CTFontDescriptorRef t_descriptor;
    t_descriptor = NULL;
    if (t_success)
    {
        t_descriptor = CTFontDescriptorCreateWithAttributes(t_attributes);
        t_success = t_descriptor != NULL;
    }
    
    CTFontRef t_font;
    t_font = NULL;
    if (t_success)
        t_font = CTFontCreateWithFontDescriptor(t_descriptor, p_size, NULL);
    
    CFStringRef t_font_name = CTFontCopyFullName(t_font);
    
    if (t_descriptor != NULL)
        CFRelease(t_descriptor);
    if (t_attributes != NULL)
        CFRelease(t_attributes);
    
    return (void *)t_font;
}
示例#7
0
static void
pango_core_text_family_list_faces (PangoFontFamily  *family,
                                   PangoFontFace  ***faces,
                                   int              *n_faces)
{
  PangoCoreTextFamily *ctfamily = PANGO_CORE_TEXT_FAMILY (family);

  if (ctfamily->n_faces < 0)
    {
      GList *l;
      GList *faces = NULL;
      GList *synthetic_faces = NULL;
      GHashTable *italic_faces;
      const char *real_family = get_real_family (ctfamily->family_name);
      CTFontCollectionRef collection;
      CFArrayRef ctfaces;
      CFArrayRef font_descriptors;
      CFDictionaryRef attributes;
      CFIndex i, count;

      CFTypeRef keys[] = {
          (CFTypeRef) kCTFontFamilyNameAttribute
      };

      CFStringRef values[] = {
          CFStringCreateWithCString (kCFAllocatorDefault,
                                     real_family,
                                     kCFStringEncodingUTF8)
      };

      CTFontDescriptorRef descriptors[1];

      attributes = CFDictionaryCreate (kCFAllocatorDefault,
                                       (const void **)keys,
                                       (const void **)values,
                                       1,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks);
      descriptors[0] = CTFontDescriptorCreateWithAttributes (attributes);
      font_descriptors = CFArrayCreate (kCFAllocatorDefault,
                                        (const void **)descriptors,
                                        1,
                                        &kCFTypeArrayCallBacks);
      collection = CTFontCollectionCreateWithFontDescriptors (font_descriptors,
                                                              NULL);

      ctfaces = CTFontCollectionCreateMatchingFontDescriptors (collection);

      italic_faces = g_hash_table_new (g_direct_hash, g_direct_equal);

      count = CFArrayGetCount (ctfaces);
      for (i = 0; i < count; i++)
        {
          PangoCoreTextFace *face;
          CTFontDescriptorRef desc = CFArrayGetValueAtIndex (ctfaces, i);

          face = pango_core_text_face_from_ct_font_descriptor (desc);
          face->family = ctfamily;

          faces = g_list_prepend (faces, face);

          if (face->traits & kCTFontItalicTrait
              || pango_core_text_face_is_oblique (face))
            g_hash_table_insert (italic_faces,
				 GINT_TO_POINTER ((gint)face->weight),
                                 face);
        }

      CFRelease (font_descriptors);
      CFRelease (attributes);
      CFRelease (ctfaces);

      /* For all fonts for which a non-synthetic italic variant does
       * not exist on the system, we create synthesized versions here.
       */
      for (l = faces; l; l = l->next)
        {
          PangoCoreTextFace *face = l->data;

          if (!g_hash_table_lookup (italic_faces,
                                    GINT_TO_POINTER ((gint)face->weight)))
            {
              PangoCoreTextFace *italic_face;

              italic_face = g_object_new (PANGO_TYPE_CORE_TEXT_FACE, NULL);

              italic_face->family = ctfamily;
              italic_face->postscript_name = g_strdup (face->postscript_name);
              italic_face->weight = face->weight;
              italic_face->traits = face->traits | kCTFontItalicTrait;
              italic_face->synthetic_italic = TRUE;
              italic_face->coverage = pango_coverage_ref (face->coverage);

              /* Try to create a sensible face name. */
              if (strcasecmp (face->style_name, "regular") == 0)
                italic_face->style_name = g_strdup ("Oblique");
              else
                italic_face->style_name = g_strdup_printf ("%s Oblique",
                                                           face->style_name);

              synthetic_faces = g_list_prepend (synthetic_faces, italic_face);
            }
        }

      faces = g_list_concat (faces, synthetic_faces);

      ctfamily->n_faces = g_list_length (faces);
      ctfamily->faces = g_new (PangoFontFace *, ctfamily->n_faces);

      for (l = faces, i = 0; l; l = l->next, i++)
	ctfamily->faces[i] = l->data;

      g_list_free (faces);
      g_hash_table_destroy (italic_faces);
    }