Exemplo n.º 1
0
char*
GetGlyphName_AAT(ATSUStyle style, UInt16 gid, int* len)
{
	static char buffer[256];
	const char* namePtr;
	
	ATSUFontID	fontID;
	ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);

	ATSFontRef	fontRef = FMGetATSFontRefFromFont(fontID);

	ByteCount	length;
	OSStatus status = ATSFontGetTable(fontRef, kPost, 0, 0, 0, &length);
	if (status != noErr)
		return 0;

	void*	table = xmalloc(length);
	status = ATSFontGetTable(fontRef, kPost, 0, length, table, &length);
	if (status != noErr) {
		free(table);
		return 0;
	}
	
	namePtr = getGlyphNamePtr(table, length, gid, len);
	if (*len > 255)
		*len = 255;
	if (namePtr) {
		memcpy(buffer, namePtr, *len);
		buffer[*len] = 0;
	}
	
	free(table);

	return &buffer[0];
}
Exemplo n.º 2
0
int MapGlyphToIndex_AAT(ATSUStyle style, const char* glyphName)
{
	ATSUFontID	fontID;
	ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);

	ATSFontRef	fontRef = FMGetATSFontRefFromFont(fontID);

	ByteCount	length;
	OSStatus status = ATSFontGetTable(fontRef, kPost, 0, 0, 0, &length);
	if (status != noErr)
		return 0;

	void*	table = xmalloc(length);
	status = ATSFontGetTable(fontRef, kPost, 0, length, table, &length);
	if (status != noErr) {
		free(table);
		return 0;
	}
	
	int	rval = findGlyphInPostTable(table, length, glyphName);
	free(table);

	return rval;
}
Exemplo n.º 3
0
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
{
	const char *str;
	bool result = false;

	callback->FindMissingGlyphs(&str);

#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 if (strncmp(language_isocode, "ur", 2) == 0) {
			/* The urdu alphabet is variant of persian. As OS X has no default
			 * font that advertises an urdu language code, search for persian
			 * support instead. */
			strecpy(lang, "fa", 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';
		}

		CFStringRef lang_code;
		lang_code = CFStringCreateWithCString(kCFAllocatorDefault, lang, kCFStringEncodingUTF8);

		/* Create a font iterator and iterate over all fonts that
		 * are available to the application. */
		ATSFontIterator itr;
		ATSFontRef font;
		ATSFontIteratorCreate(kATSFontContextLocal, NULL, NULL, kATSOptionFlagsUnRestrictedScope, &itr);
		while (!result && ATSFontIteratorNext(itr, &font) == noErr) {
			/* Get CoreText font handle. */
			CTFontRef font_ref = CTFontCreateWithPlatformFont(font, 0.0, NULL, NULL);
			CFArrayRef langs = CTFontCopySupportedLanguages(font_ref);
			if (langs != NULL) {
				/* Font has a list of supported languages. */
				for (CFIndex i = 0; i < CFArrayGetCount(langs); i++) {
					CFStringRef lang = (CFStringRef)CFArrayGetValueAtIndex(langs, i);
					if (CFStringCompare(lang, lang_code, kCFCompareAnchored) == kCFCompareEqualTo) {
						/* Lang code is supported by font, get full font name. */
						CFStringRef font_name = CTFontCopyFullName(font_ref);
						char name[128];
						CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);
						CFRelease(font_name);
						/* Skip some inappropriate or ugly looking fonts that have better alternatives. */
						if (strncmp(name, "Courier", 7) == 0 || strncmp(name, "Apple Symbols", 13) == 0 ||
								strncmp(name, ".Aqua", 5) == 0 || strncmp(name, "LastResort", 10) == 0 ||
								strncmp(name, "GB18030 Bitmap", 14) == 0) continue;

						/* Save result. */
						callback->SetFontNames(settings, name);
						DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
						result = true;
						break;
					}
				}
				CFRelease(langs);
			}
			CFRelease(font_ref);
		}
		ATSFontIteratorRelease(&itr);
		CFRelease(lang_code);
	} else
#endif
	{
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !__LP64__
		/* Determine fallback font using ATSUI. This uses a string sample with
		 * missing characters. This is not failure-proof, but a better way like
		 * using the isocode as in the CoreText code path is not available.
		 * ATSUI was deprecated with 10.6 and is only partially available in
		 * 64-bit mode. */

		/* Remove all control characters in the range from SCC_CONTROL_START to
		 * SCC_CONTROL_END as well as all ASCII < 0x20 from the string as it will
		 * mess with the automatic font detection */
		char buff[256]; // This length is enough to find a suitable replacement font
		strecpy(buff, str, lastof(buff));
		str_validate(buff, lastof(buff), SVS_ALLOW_NEWLINE);

		/* Extract a UniChar representation of the sample string. */
		CFStringRef cf_str = CFStringCreateWithCString(kCFAllocatorDefault, buff, kCFStringEncodingUTF8);
		if (cf_str == NULL) {
			/* Something went wrong. Corrupt/invalid sample string? */
			return false;
		}
		CFIndex str_len = CFStringGetLength(cf_str);
		UniChar string[str_len];
		CFStringGetCharacters(cf_str, CFRangeMake(0, str_len), string);

		/* Create a default text style with the default font. */
		ATSUStyle style;
		ATSUCreateStyle(&style);

		/* Create a text layout object from the sample string using the text style. */
		UniCharCount run_len = kATSUToTextEnd;
		ATSUTextLayout text_layout;
		ATSUCreateTextLayoutWithTextPtr(string, kATSUFromTextBeginning, kATSUToTextEnd, str_len, 1, &run_len, &style, &text_layout);

		/* Try to match a font for the sample text. ATSUMatchFontsToText stops after
		 * it finds the first continuous character run not renderable with the currently
		 * selected font starting at offset. The matching needs to be repeated until
		 * the end of the string is reached to make sure the fallback font matches for
		 * all characters in the string and not only the first run. */
		UniCharArrayOffset offset = kATSUFromTextBeginning;
		OSStatus os_err;
		do {
			ATSUFontID font;
			UniCharCount run_len;
			os_err = ATSUMatchFontsToText(text_layout, offset, kATSUToTextEnd, &font, &offset, &run_len);
			if (os_err == kATSUFontsMatched) {
				/* Found a better fallback font. Update the text layout
				 * object with the new font. */
				ATSUAttributeTag tag = kATSUFontTag;
				ByteCount size = sizeof(font);
				ATSUAttributeValuePtr val = &font;
				ATSUSetAttributes(style, 1, &tag, &size, &val);
				offset += run_len;
			}
			/* Exit if the end of the string is reached or some other error occurred. */
		} while (os_err == kATSUFontsMatched && offset < (UniCharArrayOffset)str_len);

		if (os_err == noErr || os_err == kATSUFontsMatched) {
			/* ATSUMatchFontsToText exited normally. Extract font
			 * out of the text layout object. */
			ATSUFontID font;
			ByteCount act_len;
			ATSUGetAttribute(style, kATSUFontTag, sizeof(font), &font, &act_len);

			/* Get unique font name. The result is not a c-string, we have
			 * to leave space for a \0 and terminate it ourselves. */
			char name[128];
			ATSUFindFontName(font, kFontUniqueName, kFontNoPlatformCode, kFontNoScriptCode, kFontNoLanguageCode, 127, name, &act_len, NULL);
			name[act_len > 127 ? 127 : act_len] = '\0';

			/* Save Result. */
			callback->SetFontNames(settings, name);
			DEBUG(freetype, 2, "ATSUI-Font for %s: %s", language_isocode, name);
			result = true;
		}

		ATSUDisposeTextLayout(text_layout);
		ATSUDisposeStyle(style);
		CFRelease(cf_str);
#endif
	}

	if (result && strncmp(settings->medium.font, "Geeza Pro", 9) == 0) {
		/* The font 'Geeza Pro' is often found for arabic characters, but
		 * it has the 'tiny' problem of not having any latin characters.
		 * 'Arial Unicode MS' on the other hand has arabic and latin glyphs,
		 * but seems to 'forget' to inform the OS about this fact. Manually
		 * substitute the latter for the former if it is loadable. */
		bool ft_init = _library != NULL;
		FT_Face face;
		/* Init FreeType if needed. */
		if ((ft_init || FT_Init_FreeType(&_library) == FT_Err_Ok) && GetFontByFaceName("Arial Unicode MS", &face) == FT_Err_Ok) {
			FT_Done_Face(face);
			callback->SetFontNames(settings, "Arial Unicode MS");
			DEBUG(freetype, 1, "Replacing font 'Geeza Pro' with 'Arial Unicode MS'");
		}
		if (!ft_init) {
			/* Uninit FreeType if we did the init. */
			FT_Done_FreeType(_library);
			_library = NULL;
		}
	 }

	callback->FindMissingGlyphs(NULL);
	return result;
}
Exemplo n.º 4
0
QFixed QFontEngineMac::leading() const
{
    ATSUTextMeasurement metric;
    ATSUGetAttribute(style, kATSULeadingTag, sizeof(metric), &metric, 0);
    return FixRound(metric);
}
Exemplo n.º 5
0
static
OSStatus AddFunkyVariationsAndFeatures(
	ATSUStyle	styleToMangle )
{
	OSStatus				err;
	ItemCount				i;
	ATSUFontID				fontID;
	ItemCount				count;
	ItemCount				selectorCount;
	ATSUFontVariationAxis	variationAxis;
	ATSUFontVariationValue	variationMinimum;
	ATSUFontVariationValue	variationMaximum;
	ATSUFontVariationValue	variationDefault;
	Boolean					selectorMutex;
	ATSUFontFeatureType		*typeBuffer = NULL;
	ATSUFontFeatureSelector	*selectorBuffer = NULL;
	Boolean					*defaultBuffer = NULL;
	ItemCount				selectorBufferSize = 0;
	
	
	// get the fontID from the style
	err = ATSUGetAttribute( styleToMangle, kATSUFontTag, sizeof( ATSUStyle ),
		&fontID, NULL );
	require_noerr( err, AddFunkyVariationsAndFeatures_err );

	// get a count of all of the variations supported by the current font
	err = ATSUCountFontVariations( fontID, &count );
	require_noerr( err, AddFunkyVariationsAndFeatures_err );
	
	// loop through, setting all of the variations to the max!
	for ( i = 0; i < count; i++ )
	{
		// get the settings for the variations
		err = ATSUGetIndFontVariation( fontID, i, &variationAxis,
			&variationMinimum, &variationMaximum, &variationDefault );
		require_noerr( err, AddFunkyVariationsAndFeatures_err );
		
		// set the variation for this font to the max!
		err = ATSUSetVariations( styleToMangle, 1, &variationAxis,
			&variationMaximum );
		require_noerr( err, AddFunkyVariationsAndFeatures_err );
		
	}
	
	
	// get a count of all of the features
	err = ATSUCountFontFeatureTypes( fontID, &count );
	require_noerr( err, AddFunkyVariationsAndFeatures_err );
	
	// allocate a buffer for the feature types
	typeBuffer = (ATSUFontFeatureType *) malloc( sizeof( ATSUFontFeatureType )
		* count );
	require_action( typeBuffer != NULL, AddFunkyVariationsAndFeatures_err,
		err = paramErr );
		
	// get all of the font features
	err = ATSUGetFontFeatureTypes( fontID, count, typeBuffer, &selectorCount );
	require_noerr( err, AddFunkyVariationsAndFeatures_err );
	
	// loop through, setting all of the features
	for ( i = 0; i < count; i++ )
	{
		// get the selector count
		err = ATSUCountFontFeatureSelectors( fontID, typeBuffer[i],
			&selectorCount );
		require_noerr( err, AddFunkyVariationsAndFeatures_err );
		
		// if the selector buffer size is greater than what we had before,
		// then allocate some new buffers. Just use realloc, as when
		// the buffers are pointing to NULL, it will simply act as malloc.
		if ( selectorBufferSize < count ) 
		{
			ItemCount		newCount;
			
			// set the new size to be twice the old size
			newCount = 2 * count;
			
			// allocate  the selectorBuffer
			selectorBuffer = (ATSUFontFeatureSelector *) realloc( 
				selectorBuffer, newCount * sizeof( ATSUFontFeatureSelector ) );
			require_action( selectorBuffer != NULL,
				AddFunkyVariationsAndFeatures_err, err = memFullErr );
				
			// allocate the defaultBuffer
			defaultBuffer = (Boolean  *) realloc( defaultBuffer,
				newCount * sizeof( Boolean ) );
			require_action( defaultBuffer != NULL,
				AddFunkyVariationsAndFeatures_err, err = memFullErr );
				
			selectorBufferSize = newCount;
		}
		
		// get the font feature selectors
		err = ATSUGetFontFeatureSelectors( fontID, typeBuffer[i],
			selectorBufferSize, selectorBuffer, defaultBuffer, &selectorCount,
			&selectorMutex );
		require_noerr( err, AddFunkyVariationsAndFeatures_err );
		
		// if the features are not mutually exclusive, then go ahead and
		// set them all.
		if ( selectorMutex == false )
		{
			ItemCount	j;
			
			// loop through and set all of the features
			for ( j = 0; j < selectorCount; j++ )
			{
				if ( defaultBuffer[j] == false )
				{
					err = ATSUSetFontFeatures( styleToMangle, 1, &typeBuffer[i],
						&selectorBuffer[j] );
					require_noerr( err, AddFunkyVariationsAndFeatures_err );
				}
			}
			
		}
		else
		{
			// just set the last option, then since we can't set them all
			err = ATSUSetFontFeatures( styleToMangle, 1, &typeBuffer[i],
				&selectorBuffer[selectorCount - 1] );
			require_noerr( err, AddFunkyVariationsAndFeatures_err );
		}
		
	}
		
	// that should be enough style perversion for now!
	
	
AddFunkyVariationsAndFeatures_err:

	if ( typeBuffer != NULL )
	{
		free( typeBuffer );
	}
	
	if ( selectorBuffer != NULL )
	{
		free( selectorBuffer );
	}
	
	if ( defaultBuffer != NULL )
	{
		free( defaultBuffer );
	}

	return err;
	
}