Exemple #1
0
ATSUFontFeatureSelector
find_selector_by_name(ATSUFontID fontID, ATSUFontFeatureType featureType, const char* name, int nameLength)
{
	ATSUFontFeatureSelector	result = 0x0000FFFF;

	Str255	inName;
	inName[0] = nameLength;
	int i;
	for (i = 0; i < inName[0]; ++i)
		inName[i + 1] = name[i];

	ItemCount	selectorCount;
	ATSUCountFontFeatureSelectors(fontID, featureType, &selectorCount);
	if (selectorCount > 0) {
		ATSUFontFeatureSelector*	selectors = (ATSUFontFeatureSelector*)xmalloc(selectorCount * sizeof(ATSUFontFeatureSelector));
		ATSUGetFontFeatureSelectors(fontID, featureType, selectorCount, selectors, 0, 0, 0);
		for (i = 0; i < selectorCount; ++i) {
			FontNameCode	nameCode;
			ATSUGetFontFeatureNameCode(fontID, featureType, selectors[i], &nameCode);
			Str255		name;
			ByteCount	nameLen;
			ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
                                 255, (Ptr)&name[1], &nameLen, 0);
			name[0] = nameLen;
			if (EqualString(inName, name, false, true)) {
				result = selectors[i];
				break;
			}
		}
		free((char*)selectors);
	}
	
	return result;
}
Exemple #2
0
ATSUFontFeatureType
find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength)
{
	ATSUFontFeatureType	result = 0x0000FFFF;

	Str255	inName;
	inName[0] = nameLength;
	int i;
	for (i = 0; i < inName[0]; ++i)
		inName[i + 1] = name[i];

	ItemCount	typeCount;
	ATSUCountFontFeatureTypes(fontID, &typeCount);
	if (typeCount > 0) {
		ATSUFontFeatureType*	types = (ATSUFontFeatureType*)xmalloc(typeCount * sizeof(ATSUFontFeatureType));
		ATSUGetFontFeatureTypes(fontID, typeCount, types, 0);
		for (i = 0; i < typeCount; ++i) {
			FontNameCode	nameCode;
			ATSUGetFontFeatureNameCode(fontID, types[i], 0x0000FFFF, &nameCode);
			Str255		name;
			ByteCount	nameLen;
			ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
                                 255, (Ptr)&name[1], &nameLen, 0);
			name[0] = nameLen;
			if (EqualString(inName, name, false, true)) {
				result = types[i];
				break;
			}
		}
		free((char*)types);
	}
	
	return result;
}
Exemple #3
0
ATSUFontVariationAxis
find_axis_by_name(ATSUFontID fontID, const char* name, int nameLength)
{
	ATSUFontVariationAxis	result = 0;

	Str255	inName;
	inName[0] = nameLength;
	int i;
	for (i = 0; i < inName[0]; ++i)
		inName[i + 1] = name[i];

	ItemCount	varCount;
	ATSUCountFontVariations(fontID, &varCount);
	if (varCount > 0) {
		for (i = 0; i < varCount; ++i) {
			ATSUFontVariationAxis	axis;
			ATSUGetIndFontVariation(fontID, i, &axis, 0, 0, 0);
			FontNameCode	nameCode;
			ATSUGetFontVariationNameCode(fontID, axis, &nameCode);
			Str255		name;
			ByteCount	nameLen;
			ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
                                 255, (Ptr)&name[1], &nameLen, 0);
			name[0] = nameLen;
			if (EqualString(inName, name, false, true)) {
				result = axis;
				break;
			}
		}
	}
	
	return result;
}
Exemple #4
0
bool MCField::macmatchfontname(const char *p_font_name, char p_derived_font_name[])
{
	ATSUFontID t_font_id;
	if (ATSUFindFontFromName(p_font_name, strlen(p_font_name), kFontFullName, kFontNoPlatform, kFontNoScript, kFontNoLanguage, &t_font_id) == noErr ||
		ATSUFindFontFromName(p_font_name, strlen(p_font_name), kFontUniqueName, kFontNoPlatform, kFontNoScript, kFontNoLanguage, &t_font_id) == noErr ||
		ATSUFindFontFromName(p_font_name, strlen(p_font_name), kFontFamilyName, kFontNoPlatform, kFontNoScript, kFontNoLanguage, &t_font_id) == noErr ||
		ATSUFindFontFromName(p_font_name, strlen(p_font_name), kFontNoName, kFontNoPlatform, kFontNoScript, kFontNoLanguage, &t_font_id) == noErr)
	{
		// Fetch the style name
		char t_style_name[64];
		ByteCount t_style_name_length;
		t_style_name_length = 0;
		ATSUFindFontName(t_font_id, kFontStyleName, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage, 63, t_style_name, &t_style_name_length, NULL);
		t_style_name[t_style_name_length] = '\0';
		
		// Fetch the full name
		char t_full_name[256];
		ByteCount t_full_name_length;
		t_full_name_length = 0;
		ATSUFindFontName(t_font_id, kFontFullName, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage, 255, t_full_name, &t_full_name_length, NULL);
		t_full_name[t_full_name_length] = '\0';
		
		// MW-2011-09-02: Make sure we don't do anything at all if style is regular
		//   (output name should be fullname!)
		if (MCCStringEqualCaseless(t_style_name, "Regular"))
			p_font_name = p_font_name; // Do nothing
		else if (MCCStringEndsWithCaseless(t_full_name, "Bold Italic"))
			t_full_name[t_full_name_length - 12] = '\0';
		else if (MCCStringEndsWithCaseless(t_full_name, "Bold"))
			t_full_name[t_full_name_length - 5] = '\0';
		else if (MCCStringEndsWithCaseless(t_full_name, "Italic"))
			t_full_name[t_full_name_length - 7] = '\0';
		
		strcpy(p_derived_font_name, t_full_name);
		
		return true;
	}
	
	return false;
}
Exemple #5
0
pascal OSStatus
wxMacCarbonFontPanelHandler(EventHandlerCallRef WXUNUSED(nextHandler),
                            EventRef event,
                            void *userData)
{
    OSStatus result = eventNotHandledErr ;
    wxFontDialog *fontdialog = (wxFontDialog*) userData ;
    wxFontData& fontdata= fontdialog->GetFontData() ;

    wxMacCarbonEvent cEvent( event );
    switch(cEvent.GetKind())
    {
        case kEventFontSelection :
        {
            bool setup = false ;
#if wxOSX_USE_CORE_TEXT
            if (  UMAGetSystemVersion() >= 0x1050 )
            {
                CTFontDescriptorRef descr;
                if ( cEvent.GetParameter<CTFontDescriptorRef>( kEventParamCTFontDescriptor, typeCTFontDescriptorRef, &descr ) == noErr )
                {
                    wxFont font;
                    wxNativeFontInfo fontinfo;
                    fontinfo.Init(descr);
                    font.Create(fontinfo);
                    fontdata.SetChosenFont( font ) ;
                    setup = true;
                }
            }
#endif
#if wxOSX_USE_ATSU_TEXT
            ATSUFontID fontId = 0 ;
            if ( !setup && (cEvent.GetParameter<ATSUFontID>(kEventParamATSUFontID, &fontId) == noErr) )
            {
                FMFontStyle fontStyle = cEvent.GetParameter<FMFontStyle>(kEventParamFMFontStyle);
                FMFontSize fontSize = cEvent.GetParameter<FMFontSize>(kEventParamFMFontSize);

                CFStringRef cfName = NULL;
#if 1
                FMFontFamily fontFamily = cEvent.GetParameter<FMFontFamily>(kEventParamFMFontFamily);
                ATSFontFamilyRef atsfontfamilyref = FMGetATSFontFamilyRefFromFontFamily( fontFamily ) ;
                OSStatus err = ATSFontFamilyGetName( atsfontfamilyref , kATSOptionFlagsDefault , &cfName ) ;
                if ( err != noErr )
                {
                    wxFAIL_MSG("ATSFontFamilyGetName failed");
                }
#else
                // we don't use the ATSU naming anymore
                ByteCount actualLength = 0;
                char *c = NULL;
                OSStatus err = ATSUFindFontName(fontId , kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
                                                kFontNoLanguageCode , 0 , NULL , &actualLength , NULL );
                if ( err == noErr)
                {
                    actualLength += 1 ;
                    char *c = (char*)malloc( actualLength );
                    err = ATSUFindFontName(fontId, kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
                                           kFontNoLanguageCode, actualLength, c , NULL, NULL);
                    cfName = CFStringCreateWithCharacters(NULL, (UniChar*) c, (actualLength-1) >> 1);
                }
                else
                {
                    err = ATSUFindFontName(fontId , kFontFamilyName, kFontNoPlatformCode, kFontNoScriptCode,
                                           kFontNoLanguageCode , 0 , NULL , &actualLength , NULL );
                    if ( err == noErr )
                    {
                        actualLength += 1 ;
                        c = (char*)malloc(actualLength);
                        err = ATSUFindFontName(fontId, kFontFamilyName, kFontNoPlatformCode, kFontNoScriptCode,
                                               kFontNoLanguageCode, actualLength, c , NULL, NULL);
                        c[actualLength-1] = 0;
                        cfName = CFStringCreateWithCString(NULL, c, kCFStringEncodingMacRoman );
                    }
                }
                if ( c!=NULL )
                    free(c);
#endif
                if ( cfName!=NULL )
                {
                    fontdata.m_chosenFont.SetFaceName(wxCFStringRef(cfName).AsString(wxLocale::GetSystemEncoding()));
                    fontdata.m_chosenFont.SetPointSize(fontSize);
                    fontdata.m_chosenFont.SetStyle(fontStyle & italic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL);
                    fontdata.m_chosenFont.SetUnderlined((fontStyle & underline)!=0);
                    fontdata.m_chosenFont.SetWeight(fontStyle & bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
                }
            }
Exemple #6
0
void PlatformFont::enumeratePlatformFonts( Vector< StringTableEntry >& fonts, UTF16* fontFamily )
{
   if( fontFamily )
   {
      // Determine the font ID from the family name.
      
      ATSUFontID fontID;
      if( ATSUFindFontFromName(
            fontFamily,
            dStrlen( fontFamily ) * 2,
            kFontFamilyName,
            kFontMicrosoftPlatform,
            kFontNoScriptCode,
            kFontNoLanguageCode, &fontID ) != kATSUInvalidFontErr )
      {
         // Get the number of fonts in the family.
         
         ItemCount numFonts;
         ATSUCountFontNames( fontID, &numFonts );
         
         // Read out font names.
         
         U32 bufferSize = 512;
         char* buffer = ( char* ) dMalloc( bufferSize );
         
         for( U32 i = 0; i < numFonts; ++ i )
         {
            for( U32 n = 0; n < 2; ++ n )
            {
               ByteCount actualNameLength;
               FontNameCode fontNameCode;
               FontPlatformCode fontPlatformCode;
               FontScriptCode fontScriptCode;
               FontLanguageCode fontLanguageCode;
               
               if( ATSUGetIndFontName(
                     fontID,
                     i,
                     bufferSize - 2,
                     buffer,
                     &actualNameLength,
                     &fontNameCode,
                     &fontPlatformCode,
                     &fontScriptCode,
                     &fontLanguageCode ) == noErr )
               {
                  *( ( UTF16* ) &buffer[ actualNameLength ] ) = '\0';
                  char* utf8 = convertUTF16toUTF8( ( UTF16* ) buffer );
                  fonts.push_back( StringTable->insert( utf8 ) );
                  delete [] utf8;
                  break;
               }
               
               // Allocate larger buffer.
               
               bufferSize = actualNameLength + 2;
               buffer = ( char* ) dRealloc( buffer, bufferSize );
            }
         }
         
         dFree( buffer );
      }
   }
   else
   {
      // Get the number of installed fonts.
      
      ItemCount numFonts;
      ATSUFontCount( &numFonts );
      
      // Get all the font IDs.
      
      ATSUFontID* fontIDs = new ATSUFontID[ numFonts ];
      if( ATSUGetFontIDs( fontIDs, numFonts, &numFonts ) == noErr )
      {
         U32 bufferSize = 512;
         char* buffer = ( char* ) dMalloc( bufferSize );
         
         // Read all family names.
         
         for( U32 i = 0; i < numFonts; ++ i )
         {
            for( U32 n = 0; n < 2; ++ n )
            {
               ByteCount actualNameLength;
               ItemCount fontIndex;
               
               OSStatus result = ATSUFindFontName(
                     fontIDs[ i ],
                     kFontFamilyName,
                     kFontMicrosoftPlatform,
                     kFontNoScriptCode,
                     kFontNoLanguageCode,
                     bufferSize - 2,
                     buffer,
                     &actualNameLength,
                     &fontIndex );
               
               if( result == kATSUNoFontNameErr )
                  break;
               else if( result == noErr )
               {
                  *( ( UTF16* ) &buffer[ actualNameLength ] ) = '\0';
                  char* utf8 = convertUTF16toUTF8( ( UTF16* ) buffer );
                  StringTableEntry name = StringTable->insert( utf8 );
                  delete [] utf8;
                  
                  // Avoid duplicates.
                  
                  bool duplicate = false;
                  for( U32 i = 0, num = fonts.size(); i < num; ++ i )
                     if( fonts[ i ] == name )
                     {
                        duplicate = true;
                        break;
                     }
                     
                  if( !duplicate )
                     fonts.push_back( name );
                     
                  break;
               }
               
               // Allocate larger buffer.
               
               bufferSize = actualNameLength + 2;
               buffer = ( char* ) dRealloc( buffer, bufferSize );
            }
         }
         
         dFree( buffer );
      }
      
      delete [] fontIDs;
   }
}
Exemple #7
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;
}