void qt_mac_to_pascal_string(const QString &s, Str255 str, TextEncoding encoding, int len) { if(len == -1) len = s.length(); #if 0 UnicodeMapping mapping; mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicode16BitFormat); mapping.otherEncoding = (encoding ? encoding : ); mapping.mappingVersion = kUnicodeUseLatestMapping; UnicodeToTextInfo info; OSStatus err = CreateUnicodeToTextInfo(&mapping, &info); if(err != noErr) { qDebug("Qt: internal: Unable to create pascal string '%s'::%d [%ld]", s.left(len).latin1(), (int)encoding, err); return; } const int unilen = len * 2; const UniChar *unibuf = (UniChar *)s.unicode(); ConvertFromUnicodeToPString(info, unilen, unibuf, str); DisposeUnicodeToTextInfo(&info); #else Q_UNUSED(encoding); CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding()); #endif }
static const wxUint16* GetEncTable(wxFontEncoding enc) { #ifdef __WXMAC__ if( enc >= wxFONTENCODING_MACMIN && enc <= wxFONTENCODING_MACMAX ) { int i = enc-wxFONTENCODING_MACMIN ; if ( gMacEncodingsInited[i] == false ) { TECObjectRef converter ; TextEncodingBase code = wxMacGetSystemEncFromFontEnc( enc ) ; TextEncodingBase unicode = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ; OSStatus status = TECCreateConverter(&converter,code,unicode); char s[2] ; s[1] = 0 ; ByteCount byteInLen, byteOutLen ; for( unsigned char c = 255 ; c >= 128 ; --c ) { s[0] = c ; status = TECConvertText(converter, (ConstTextPtr) &s , 1, &byteInLen, (TextPtr) &gMacEncodings[i][c-128] , 2, &byteOutLen); } status = TECDisposeConverter(converter); gMacEncodingsInited[i]=true; } return gMacEncodings[i] ; } #endif for (int i = 0; encodings_list[i].table != NULL; i++) { if (encodings_list[i].encoding == enc) return encodings_list[i].table; } return NULL; }
TextEncoding MacOSUnicodeConverter::discoverLCPEncoding() { TextEncoding encoding = 0; // Ask the OS for the best text encoding for this application // We would call GetApplicationTextEncoding(), but it's available only in // Carbon (not CarbonCore), and we try to link with frameworks only in CoreServices. // encoding = GetApplicationTextEncoding(); // Get TextEncoding for the current Mac System Script, falling back to Mac Roman if (noErr != UpgradeScriptInfoToTextEncoding( smSystemScript, kTextLanguageDontCare, kTextRegionDontCare, NULL, &encoding)) encoding = CreateTextEncoding(kTextEncodingMacRoman, kTextEncodingDefaultVariant, kTextEncodingDefaultFormat); // Traditionally, the Mac transcoder has used the current system script // as the LCP text encoding. // // As of Xerces 2.6, this continues to be the case if XML_MACOS_LCP_TRADITIONAL // is defined. // // Otherwise, but only for Mac OS X, utf-8 will be used instead. // Since posix paths are utf-8 encoding on OS X, and the OS X // terminal uses utf-8 by default, this seems to make the most sense. #if !defined(XML_MACOS_LCP_TRADITIONAL) if (true /*gMacOSXOrBetter*/) { // Manufacture a text encoding for UTF8 encoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicodeUTF8Format); } #endif return encoding; }
XMLTranscoder* MacOSUnicodeConverter::makeNewXMLTranscoder(const XMLCh* const encodingName , XMLTransService::Codes& resValue , const XMLSize_t blockSize , TextEncoding textEncoding , MemoryManager* const manager) { XMLTranscoder* result = NULL; resValue = XMLTransService::Ok; OSStatus status = noErr; TECObjectRef textToUnicode = NULL; TECObjectRef unicodeToText = NULL; // We convert to and from utf16 TextEncoding utf16Encoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicode16BitFormat); // Create a TEC from our encoding to utf16 if (status == noErr) status = TECCreateConverter(&textToUnicode, textEncoding, utf16Encoding); // Create a TEC from utf16 to our encoding if (status == noErr) status = TECCreateConverter(&unicodeToText, utf16Encoding, textEncoding); if (status != noErr) { // Clean up on error if (textToUnicode != NULL) TECDisposeConverter(textToUnicode); if (unicodeToText != NULL) TECDisposeConverter(unicodeToText); resValue = XMLTransService::UnsupportedEncoding; } else { // Create our transcoder, passing in the converters result = new (manager) MacOSTranscoder(encodingName, textToUnicode, unicodeToText, blockSize, manager); } return result; }
OSStatus TextCodecMac::createTECConverter() const { bool cachedEncodingEqual = cachedConverterEncoding == m_encoding; cachedConverterEncoding = invalidEncoding; if (cachedEncodingEqual && cachedConverterTEC) { m_converterTEC = cachedConverterTEC; cachedConverterTEC = 0; TECClearConverterContextInfo(m_converterTEC); } else { OSStatus status = TECCreateConverter(&m_converterTEC, m_encoding, CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicode16BitFormat)); if (status) return status; TECSetBasicOptions(m_converterTEC, kUnicodeForceASCIIRangeMask); } return noErr; }
void Internat::Init() { // Save decimal point character struct lconv * localeInfo = localeconv(); if (localeInfo) mDecimalSeparator = wxString(localeInfo->decimal_point, wxConvLocal).GetChar(0); // wxLogDebug(wxT("Decimal separator set to '%c'"), mDecimalSeparator); #ifndef __WXMAC__ // Set up character-set conversion for UTF-8 input and output. mConvLocal = new wxCSConv(wxLocale::GetSystemEncodingName()); #else // Set up a special converter to/from the Mac-specific local // encoding (usually MacRoman) OSStatus status = noErr; TECObjectRef ec; TextEncoding MacEncoding = GetApplicationTextEncoding(); TextEncoding UTF8 = CreateTextEncoding(kTextEncodingUnicodeDefault, kUnicodeNoSubset, kUnicodeUTF8Format); status = TECCreateConverter(&ec, MacEncoding, UTF8); if (status == noErr) mTECToUTF = (void *)ec; else mTECToUTF = NULL; status = TECCreateConverter(&ec, UTF8, MacEncoding); if (status == noErr) mTECFromUTF = (void *)ec; else mTECFromUTF = NULL; #endif }
wxUint32 wxMacGetSystemEncFromFontEnc(wxFontEncoding encoding) { CFStringEncoding enc = 0 ; if ( encoding == wxFONTENCODING_DEFAULT ) { #if wxUSE_GUI encoding = wxFont::GetDefaultEncoding() ; #else encoding = wxFONTENCODING_SYSTEM; // to be set below #endif } if ( encoding == wxFONTENCODING_SYSTEM ) { enc = CFStringGetSystemEncoding(); } switch( encoding) { case wxFONTENCODING_ISO8859_1 : enc = kCFStringEncodingISOLatin1 ; break ; case wxFONTENCODING_ISO8859_2 : enc = kCFStringEncodingISOLatin2; break ; case wxFONTENCODING_ISO8859_3 : enc = kCFStringEncodingISOLatin3 ; break ; case wxFONTENCODING_ISO8859_4 : enc = kCFStringEncodingISOLatin4; break ; case wxFONTENCODING_ISO8859_5 : enc = kCFStringEncodingISOLatinCyrillic; break ; case wxFONTENCODING_ISO8859_6 : enc = kCFStringEncodingISOLatinArabic; break ; case wxFONTENCODING_ISO8859_7 : enc = kCFStringEncodingISOLatinGreek; break ; case wxFONTENCODING_ISO8859_8 : enc = kCFStringEncodingISOLatinHebrew; break ; case wxFONTENCODING_ISO8859_9 : enc = kCFStringEncodingISOLatin5; break ; case wxFONTENCODING_ISO8859_10 : enc = kCFStringEncodingISOLatin6; break ; case wxFONTENCODING_ISO8859_13 : enc = kCFStringEncodingISOLatin7; break ; case wxFONTENCODING_ISO8859_14 : enc = kCFStringEncodingISOLatin8; break ; case wxFONTENCODING_ISO8859_15 : enc = kCFStringEncodingISOLatin9; break ; case wxFONTENCODING_KOI8 : enc = kCFStringEncodingKOI8_R; break ; case wxFONTENCODING_ALTERNATIVE : // MS-DOS CP866 enc = kCFStringEncodingDOSRussian; break ; /* case wxFONTENCODING_BULGARIAN : enc = ; break ; */ case wxFONTENCODING_CP437 : enc =kCFStringEncodingDOSLatinUS ; break ; case wxFONTENCODING_CP850 : enc = kCFStringEncodingDOSLatin1; break ; case wxFONTENCODING_CP852 : enc = kCFStringEncodingDOSLatin2; break ; case wxFONTENCODING_CP855 : enc = kCFStringEncodingDOSCyrillic; break ; case wxFONTENCODING_CP866 : enc =kCFStringEncodingDOSRussian ; break ; case wxFONTENCODING_CP874 : enc = kCFStringEncodingDOSThai; break ; case wxFONTENCODING_CP932 : enc = kCFStringEncodingDOSJapanese; break ; case wxFONTENCODING_CP936 : enc = kCFStringEncodingDOSChineseSimplif ; break ; case wxFONTENCODING_CP949 : enc = kCFStringEncodingDOSKorean; break ; case wxFONTENCODING_CP950 : enc = kCFStringEncodingDOSChineseTrad; break ; case wxFONTENCODING_CP1250 : enc = kCFStringEncodingWindowsLatin2; break ; case wxFONTENCODING_CP1251 : enc =kCFStringEncodingWindowsCyrillic ; break ; case wxFONTENCODING_CP1252 : enc =kCFStringEncodingWindowsLatin1 ; break ; case wxFONTENCODING_CP1253 : enc = kCFStringEncodingWindowsGreek; break ; case wxFONTENCODING_CP1254 : enc = kCFStringEncodingWindowsLatin5; break ; case wxFONTENCODING_CP1255 : enc =kCFStringEncodingWindowsHebrew ; break ; case wxFONTENCODING_CP1256 : enc =kCFStringEncodingWindowsArabic ; break ; case wxFONTENCODING_CP1257 : enc = kCFStringEncodingWindowsBalticRim; break ; #if 0 case wxFONTENCODING_UTF7 : enc = CreateTextEncoding(kCFStringEncodingUnicodeDefault,0,kUnicodeUTF7Format) ; break ; #endif case wxFONTENCODING_UTF8 : enc = kCFStringEncodingUTF8; break ; case wxFONTENCODING_EUC_JP : enc = kCFStringEncodingEUC_JP; break ; case wxFONTENCODING_UTF16BE : enc = kCFStringEncodingUTF16BE; break ; case wxFONTENCODING_UTF16LE : enc = kCFStringEncodingUTF16LE; break ; case wxFONTENCODING_UTF32BE : enc = kCFStringEncodingUTF32BE; break ; case wxFONTENCODING_UTF32LE : enc = kCFStringEncodingUTF32LE; break ; case wxFONTENCODING_MACROMAN : enc = kCFStringEncodingMacRoman ; break ; case wxFONTENCODING_MACJAPANESE : enc = kCFStringEncodingMacJapanese ; break ; case wxFONTENCODING_MACCHINESETRAD : enc = kCFStringEncodingMacChineseTrad ; break ; case wxFONTENCODING_MACKOREAN : enc = kCFStringEncodingMacKorean ; break ; case wxFONTENCODING_MACARABIC : enc = kCFStringEncodingMacArabic ; break ; case wxFONTENCODING_MACHEBREW : enc = kCFStringEncodingMacHebrew ; break ; case wxFONTENCODING_MACGREEK : enc = kCFStringEncodingMacGreek ; break ; case wxFONTENCODING_MACCYRILLIC : enc = kCFStringEncodingMacCyrillic ; break ; case wxFONTENCODING_MACDEVANAGARI : enc = kCFStringEncodingMacDevanagari ; break ; case wxFONTENCODING_MACGURMUKHI : enc = kCFStringEncodingMacGurmukhi ; break ; case wxFONTENCODING_MACGUJARATI : enc = kCFStringEncodingMacGujarati ; break ; case wxFONTENCODING_MACORIYA : enc = kCFStringEncodingMacOriya ; break ; case wxFONTENCODING_MACBENGALI : enc = kCFStringEncodingMacBengali ; break ; case wxFONTENCODING_MACTAMIL : enc = kCFStringEncodingMacTamil ; break ; case wxFONTENCODING_MACTELUGU : enc = kCFStringEncodingMacTelugu ; break ; case wxFONTENCODING_MACKANNADA : enc = kCFStringEncodingMacKannada ; break ; case wxFONTENCODING_MACMALAJALAM : enc = kCFStringEncodingMacMalayalam ; break ; case wxFONTENCODING_MACSINHALESE : enc = kCFStringEncodingMacSinhalese ; break ; case wxFONTENCODING_MACBURMESE : enc = kCFStringEncodingMacBurmese ; break ; case wxFONTENCODING_MACKHMER : enc = kCFStringEncodingMacKhmer ; break ; case wxFONTENCODING_MACTHAI : enc = kCFStringEncodingMacThai ; break ; case wxFONTENCODING_MACLAOTIAN : enc = kCFStringEncodingMacLaotian ; break ; case wxFONTENCODING_MACGEORGIAN : enc = kCFStringEncodingMacGeorgian ; break ; case wxFONTENCODING_MACARMENIAN : enc = kCFStringEncodingMacArmenian ; break ; case wxFONTENCODING_MACCHINESESIMP : enc = kCFStringEncodingMacChineseSimp ; break ; case wxFONTENCODING_MACTIBETAN : enc = kCFStringEncodingMacTibetan ; break ; case wxFONTENCODING_MACMONGOLIAN : enc = kCFStringEncodingMacMongolian ; break ; case wxFONTENCODING_MACETHIOPIC : enc = kCFStringEncodingMacEthiopic ; break ; case wxFONTENCODING_MACCENTRALEUR : enc = kCFStringEncodingMacCentralEurRoman ; break ; case wxFONTENCODING_MACVIATNAMESE : enc = kCFStringEncodingMacVietnamese ; break ; case wxFONTENCODING_MACARABICEXT : enc = kCFStringEncodingMacExtArabic ; break ; case wxFONTENCODING_MACSYMBOL : enc = kCFStringEncodingMacSymbol ; break ; case wxFONTENCODING_MACDINGBATS : enc = kCFStringEncodingMacDingbats ; break ; case wxFONTENCODING_MACTURKISH : enc = kCFStringEncodingMacTurkish ; break ; case wxFONTENCODING_MACCROATIAN : enc = kCFStringEncodingMacCroatian ; break ; case wxFONTENCODING_MACICELANDIC : enc = kCFStringEncodingMacIcelandic ; break ; case wxFONTENCODING_MACROMANIAN : enc = kCFStringEncodingMacRomanian ; break ; case wxFONTENCODING_MACCELTIC : enc = kCFStringEncodingMacCeltic ; break ; case wxFONTENCODING_MACGAELIC : enc = kCFStringEncodingMacGaelic ; break ; case wxFONTENCODING_MACKEYBOARD : enc = 41; /* kTextEncodingMacKeyboardGlyphs ; */ break ; default : // to make gcc happy break ; }; return enc ; }
wxFontEncoding wxMacGetFontEncFromSystemEnc(wxUint32 encoding) { wxFontEncoding enc = wxFONTENCODING_DEFAULT ; switch( encoding) { case kCFStringEncodingISOLatin1 : enc = wxFONTENCODING_ISO8859_1 ; break ; case kCFStringEncodingISOLatin2 : enc = wxFONTENCODING_ISO8859_2; break ; case kCFStringEncodingISOLatin3 : enc = wxFONTENCODING_ISO8859_3 ; break ; case kCFStringEncodingISOLatin4 : enc = wxFONTENCODING_ISO8859_4; break ; case kCFStringEncodingISOLatinCyrillic : enc = wxFONTENCODING_ISO8859_5; break ; case kCFStringEncodingISOLatinArabic : enc = wxFONTENCODING_ISO8859_6; break ; case kCFStringEncodingISOLatinGreek : enc = wxFONTENCODING_ISO8859_7; break ; case kCFStringEncodingISOLatinHebrew : enc = wxFONTENCODING_ISO8859_8; break ; case kCFStringEncodingISOLatin5 : enc = wxFONTENCODING_ISO8859_9; break ; case kCFStringEncodingISOLatin6 : enc = wxFONTENCODING_ISO8859_10; break ; case kCFStringEncodingISOLatin7 : enc = wxFONTENCODING_ISO8859_13; break ; case kCFStringEncodingISOLatin8 : enc = wxFONTENCODING_ISO8859_14; break ; case kCFStringEncodingISOLatin9 : enc =wxFONTENCODING_ISO8859_15 ; break ; case kCFStringEncodingKOI8_R : enc = wxFONTENCODING_KOI8; break ; /* case : enc = wxFONTENCODING_BULGARIAN; break ; */ case kCFStringEncodingDOSLatinUS : enc = wxFONTENCODING_CP437; break ; case kCFStringEncodingDOSLatin1 : enc = wxFONTENCODING_CP850; break ; case kCFStringEncodingDOSLatin2 : enc =wxFONTENCODING_CP852 ; break ; case kCFStringEncodingDOSCyrillic : enc = wxFONTENCODING_CP855; break ; case kCFStringEncodingDOSRussian : enc = wxFONTENCODING_CP866; break ; case kCFStringEncodingDOSThai : enc =wxFONTENCODING_CP874 ; break ; case kCFStringEncodingDOSJapanese : enc = wxFONTENCODING_CP932; break ; case kCFStringEncodingDOSChineseSimplif : enc = wxFONTENCODING_CP936; break ; case kCFStringEncodingDOSKorean : enc = wxFONTENCODING_CP949; break ; case kCFStringEncodingDOSChineseTrad : enc = wxFONTENCODING_CP950; break ; case kCFStringEncodingWindowsLatin2 : enc = wxFONTENCODING_CP1250; break ; case kCFStringEncodingWindowsCyrillic : enc = wxFONTENCODING_CP1251; break ; case kCFStringEncodingWindowsLatin1 : enc = wxFONTENCODING_CP1252; break ; case kCFStringEncodingWindowsGreek : enc = wxFONTENCODING_CP1253; break ; case kCFStringEncodingWindowsLatin5 : enc = wxFONTENCODING_CP1254; break ; case kCFStringEncodingWindowsHebrew : enc = wxFONTENCODING_CP1255; break ; case kCFStringEncodingWindowsArabic : enc = wxFONTENCODING_CP1256; break ; case kCFStringEncodingWindowsBalticRim : enc =wxFONTENCODING_CP1257 ; break ; case kCFStringEncodingEUC_JP : enc = wxFONTENCODING_EUC_JP; break ; case kCFStringEncodingUTF8 : enc = wxFONTENCODING_UTF8; break ; case kCFStringEncodingUTF16BE : enc = wxFONTENCODING_UTF16BE; break ; case kCFStringEncodingUTF16LE : enc = wxFONTENCODING_UTF16LE; break ; case kCFStringEncodingUTF32BE : enc = wxFONTENCODING_UTF32BE; break ; case kCFStringEncodingUTF32LE : enc = wxFONTENCODING_UTF32LE; break ; #if 0 case wxFONTENCODING_UTF7 : enc = CreateTextEncoding(kCFStringEncodingUnicodeDefault,0,kUnicodeUTF7Format) ; break ; #endif case kCFStringEncodingMacRoman : enc = wxFONTENCODING_MACROMAN ; break ; case kCFStringEncodingMacJapanese : enc = wxFONTENCODING_MACJAPANESE ; break ; case kCFStringEncodingMacChineseTrad : enc = wxFONTENCODING_MACCHINESETRAD ; break ; case kCFStringEncodingMacKorean : enc = wxFONTENCODING_MACKOREAN ; break ; case kCFStringEncodingMacArabic : enc =wxFONTENCODING_MACARABIC ; break ; case kCFStringEncodingMacHebrew : enc = wxFONTENCODING_MACHEBREW ; break ; case kCFStringEncodingMacGreek : enc = wxFONTENCODING_MACGREEK ; break ; case kCFStringEncodingMacCyrillic : enc = wxFONTENCODING_MACCYRILLIC ; break ; case kCFStringEncodingMacDevanagari : enc = wxFONTENCODING_MACDEVANAGARI ; break ; case kCFStringEncodingMacGurmukhi : enc = wxFONTENCODING_MACGURMUKHI ; break ; case kCFStringEncodingMacGujarati : enc = wxFONTENCODING_MACGUJARATI ; break ; case kCFStringEncodingMacOriya : enc =wxFONTENCODING_MACORIYA ; break ; case kCFStringEncodingMacBengali : enc =wxFONTENCODING_MACBENGALI ; break ; case kCFStringEncodingMacTamil : enc = wxFONTENCODING_MACTAMIL ; break ; case kCFStringEncodingMacTelugu : enc = wxFONTENCODING_MACTELUGU ; break ; case kCFStringEncodingMacKannada : enc = wxFONTENCODING_MACKANNADA ; break ; case kCFStringEncodingMacMalayalam : enc = wxFONTENCODING_MACMALAJALAM ; break ; case kCFStringEncodingMacSinhalese : enc = wxFONTENCODING_MACSINHALESE ; break ; case kCFStringEncodingMacBurmese : enc = wxFONTENCODING_MACBURMESE ; break ; case kCFStringEncodingMacKhmer : enc = wxFONTENCODING_MACKHMER ; break ; case kCFStringEncodingMacThai : enc = wxFONTENCODING_MACTHAI ; break ; case kCFStringEncodingMacLaotian : enc = wxFONTENCODING_MACLAOTIAN ; break ; case kCFStringEncodingMacGeorgian : enc = wxFONTENCODING_MACGEORGIAN ; break ; case kCFStringEncodingMacArmenian : enc = wxFONTENCODING_MACARMENIAN ; break ; case kCFStringEncodingMacChineseSimp : enc = wxFONTENCODING_MACCHINESESIMP ; break ; case kCFStringEncodingMacTibetan : enc = wxFONTENCODING_MACTIBETAN ; break ; case kCFStringEncodingMacMongolian : enc = wxFONTENCODING_MACMONGOLIAN ; break ; case kCFStringEncodingMacEthiopic : enc = wxFONTENCODING_MACETHIOPIC ; break ; case kCFStringEncodingMacCentralEurRoman: enc = wxFONTENCODING_MACCENTRALEUR ; break ; case kCFStringEncodingMacVietnamese: enc = wxFONTENCODING_MACVIATNAMESE ; break ; case kCFStringEncodingMacExtArabic : enc = wxFONTENCODING_MACARABICEXT ; break ; case kCFStringEncodingMacSymbol : enc = wxFONTENCODING_MACSYMBOL ; break ; case kCFStringEncodingMacDingbats : enc = wxFONTENCODING_MACDINGBATS ; break ; case kCFStringEncodingMacTurkish : enc = wxFONTENCODING_MACTURKISH ; break ; case kCFStringEncodingMacCroatian : enc = wxFONTENCODING_MACCROATIAN ; break ; case kCFStringEncodingMacIcelandic : enc = wxFONTENCODING_MACICELANDIC ; break ; case kCFStringEncodingMacRomanian : enc = wxFONTENCODING_MACROMANIAN ; break ; case kCFStringEncodingMacCeltic : enc = wxFONTENCODING_MACCELTIC ; break ; case kCFStringEncodingMacGaelic : enc = wxFONTENCODING_MACGAELIC ; break ; case 41 /* kTextEncodingMacKeyboardGlyphs */ : enc = wxFONTENCODING_MACKEYBOARD ; break ; } ; return enc ; }
PsychError SCREENTextBounds(void) { //for debugging TextEncodingBase textEncodingBase; TextEncodingVariant textEncodingVariant; TextEncodingFormat textEncodingFormat; /////// PsychWindowRecordType *winRec; char *textCString; Str255 textPString; UniChar *textUniString; OSStatus callError; PsychRectType resultPsychRect, resultPsychNormRect; ATSUTextLayout textLayout; //layout is a pointer to an opaque struct. int stringLengthChars; int uniCharBufferLengthElements, uniCharBufferLengthChars, uniCharBufferLengthBytes; ByteCount uniCharStringLengthBytes; TextToUnicodeInfo textToUnicodeInfo; TextEncoding textEncoding; ATSUStyle atsuStyle; Boolean foundFont; //for ATSU style attributes PsychFontStructPtrType psychFontRecord; //all subfunctions should have these two lines. PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for correct the number of arguments before getting involved PsychErrorExit(PsychCapNumInputArgs(2)); PsychErrorExit(PsychRequireNumInputArgs(2)); PsychErrorExit(PsychCapNumOutputArgs(2)); //get the window pointer and the text string and check that the window record has a font set PsychAllocInWindowRecordArg(1, kPsychArgRequired, &winRec); foundFont=PsychGetFontRecordFromFontNumber(winRec->textAttributes.textFontNumber, &psychFontRecord); if(!foundFont) PsychErrorExitMsg(PsychError_user, "Attempt to determine the bounds of text with no font or invalid font number"); //it would be better to both prevent the user from setting invalid font numbers and init to the OS 9 default font. //read in the string and get its length and convert it to a unicode string. PsychAllocInCharArg(2, kPsychArgRequired, &textCString); stringLengthChars=strlen(textCString); if(stringLengthChars > 255) PsychErrorExitMsg(PsychError_unimplemented, "Cut corners and TextBounds will not accept a string longer than 255 characters"); CopyCStringToPascal(textCString, textPString); uniCharBufferLengthChars= stringLengthChars * CHAR_TO_UNICODE_LENGTH_FACTOR; uniCharBufferLengthElements= uniCharBufferLengthChars + 1; uniCharBufferLengthBytes= sizeof(UniChar) * uniCharBufferLengthElements; textUniString=(UniChar*)malloc(uniCharBufferLengthBytes); //Using a TextEncoding type describe the encoding of the text to be converteed. textEncoding=CreateTextEncoding(kTextEncodingMacRoman, kMacRomanDefaultVariant, kTextEncodingDefaultFormat); //Take apart the encoding we just made to check it: textEncodingBase=GetTextEncodingBase(textEncoding); textEncodingVariant=GetTextEncodingVariant(textEncoding); textEncodingFormat=GetTextEncodingFormat(textEncoding); //Create a structure holding conversion information from the text encoding type we just created. callError=CreateTextToUnicodeInfoByEncoding(textEncoding,&textToUnicodeInfo); //Convert the text to a unicode string callError=ConvertFromPStringToUnicode(textToUnicodeInfo, textPString, (ByteCount)uniCharBufferLengthBytes, &uniCharStringLengthBytes, textUniString); //create the text layout object callError=ATSUCreateTextLayout(&textLayout); //associate our unicode text string with the text layout object callError=ATSUSetTextPointerLocation(textLayout, textUniString, kATSUFromTextBeginning, kATSUToTextEnd, (UniCharCount)stringLengthChars); //create an ATSU style object callError=ATSUCreateStyle(&atsuStyle); callError=ATSUClearStyle(atsuStyle); //Not that we have a style object we have to set style charactersitics. These include but are more general than Font Manager styles. //ATSU Style objects have three sets of characteristics: attributes, variations, and features. //attributes are things we need to set to match OS 9 behavior, such as the font ID, size, boldness, and italicization. //features are esoteric settings which we don't need for reproducing OS 9 behavior. Whatever clearstyle sets should be fine. //font variations are axes of variation through the space of font characteristics. The font definition includes available axes of variation. Something else we can ignore for now. PsychSetATSUStyleAttributesFromPsychWindowRecord(atsuStyle, winRec); //don't bother to set the variations of the style. //don't bother to set the features of the style. //associate the style with our layout object. This call assigns a style to every character of the string to be displayed. callError=ATSUSetRunStyle(textLayout, atsuStyle, (UniCharArrayOffset)0, (UniCharCount)stringLengthChars); //Get the bounds for our text so that and create a texture of sufficient size to containt it. ATSTrapezoid trapezoid; ItemCount oActualNumberOfBounds = 0; callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 0, NULL, &oActualNumberOfBounds); if (callError || oActualNumberOfBounds!=1) { PsychErrorExitMsg(PsychError_internal, "Failed to compute bounding box in call 1 to ATSUGetGlyphBounds() (nrbounds!=1)\n"); } callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &trapezoid, &oActualNumberOfBounds); if (callError || oActualNumberOfBounds!=1) { PsychErrorExitMsg(PsychError_internal, "Failed to retrieve bounding box in call 2 to ATSUGetGlyphBounds() (nrbounds!=1)\n"); } resultPsychRect[kPsychLeft]=(Fix2X(trapezoid.upperLeft.x) < Fix2X(trapezoid.lowerLeft.x)) ? Fix2X(trapezoid.upperLeft.x) : Fix2X(trapezoid.lowerLeft.x); resultPsychRect[kPsychRight]=(Fix2X(trapezoid.upperRight.x) > Fix2X(trapezoid.lowerRight.x)) ? Fix2X(trapezoid.upperRight.x) : Fix2X(trapezoid.lowerRight.x); resultPsychRect[kPsychTop]=(Fix2X(trapezoid.upperLeft.y) < Fix2X(trapezoid.upperRight.y)) ? Fix2X(trapezoid.upperLeft.y) : Fix2X(trapezoid.upperRight.y); resultPsychRect[kPsychBottom]=(Fix2X(trapezoid.lowerLeft.y) > Fix2X(trapezoid.lowerRight.y)) ? Fix2X(trapezoid.lowerLeft.y) : Fix2X(trapezoid.lowerRight.y); PsychNormalizeRect(resultPsychRect, resultPsychNormRect); PsychCopyOutRectArg(1, FALSE, resultPsychNormRect); PsychCopyOutRectArg(2, FALSE, resultPsychRect); //release resources free((void*)textUniString); callError=ATSUDisposeStyle(atsuStyle); return(PsychError_none); }
PsychError SCREENTextBounds(void) { //for debugging TextEncodingBase textEncodingBase; TextEncodingVariant textEncodingVariant; TextEncodingFormat textEncodingFormat; /////// PsychWindowRecordType *winRec; char *textCString; Str255 textPString; UniChar *textUniString; OSStatus callError; PsychRectType resultPsychRect, resultPsychNormRect; ATSUTextLayout textLayout; //layout is a pointer to an opaque struct. int stringLengthChars; int uniCharBufferLengthElements, uniCharBufferLengthChars, uniCharBufferLengthBytes, yPositionIsBaseline; double textHeightToBaseline; ByteCount uniCharStringLengthBytes; TextToUnicodeInfo textToUnicodeInfo; TextEncoding textEncoding; ATSUStyle atsuStyle; Boolean foundFont; //for ATSU style attributes PsychFontStructPtrType psychFontRecord; //all subfunctions should have these two lines. PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for correct the number of arguments before getting involved PsychErrorExit(PsychCapNumInputArgs(5)); PsychErrorExit(PsychRequireNumInputArgs(2)); PsychErrorExit(PsychCapNumOutputArgs(2)); //get the window pointer and the text string and check that the window record has a font set PsychAllocInWindowRecordArg(1, kPsychArgRequired, &winRec); foundFont=PsychGetFontRecordFromFontNumber(winRec->textAttributes.textFontNumber, &psychFontRecord); if(!foundFont) PsychErrorExitMsg(PsychError_user, "Attempt to determine the bounds of text with no font or invalid font number"); //it would be better to both prevent the user from setting invalid font numbers and init to the OS 9 default font. //read in the string and get its length and convert it to a unicode string. PsychAllocInCharArg(2, kPsychArgRequired, &textCString); stringLengthChars=strlen(textCString); if(stringLengthChars < 1) PsychErrorExitMsg(PsychError_user, "You asked me to compute the bounding box of an empty text string?!? Sorry, that's a no no..."); if(stringLengthChars > 255) PsychErrorExitMsg(PsychError_unimplemented, "Cut corners and TextBounds will not accept a string longer than 255 characters"); CopyCStringToPascal(textCString, textPString); uniCharBufferLengthChars= stringLengthChars * CHAR_TO_UNICODE_LENGTH_FACTOR; uniCharBufferLengthElements= uniCharBufferLengthChars + 1; uniCharBufferLengthBytes= sizeof(UniChar) * uniCharBufferLengthElements; textUniString=(UniChar*)malloc(uniCharBufferLengthBytes); PsychCopyInDoubleArg(3, kPsychArgOptional, &(winRec->textAttributes.textPositionX)); PsychCopyInDoubleArg(4, kPsychArgOptional, &(winRec->textAttributes.textPositionY)); //Using a TextEncoding type describe the encoding of the text to be converteed. textEncoding=CreateTextEncoding(kTextEncodingMacRoman, kMacRomanDefaultVariant, kTextEncodingDefaultFormat); //Take apart the encoding we just made to check it: textEncodingBase=GetTextEncodingBase(textEncoding); textEncodingVariant=GetTextEncodingVariant(textEncoding); textEncodingFormat=GetTextEncodingFormat(textEncoding); //Create a structure holding conversion information from the text encoding type we just created. callError=CreateTextToUnicodeInfoByEncoding(textEncoding,&textToUnicodeInfo); //Convert the text to a unicode string callError=ConvertFromPStringToUnicode(textToUnicodeInfo, textPString, (ByteCount)uniCharBufferLengthBytes, &uniCharStringLengthBytes, textUniString); //create the text layout object callError=ATSUCreateTextLayout(&textLayout); //associate our unicode text string with the text layout object callError=ATSUSetTextPointerLocation(textLayout, textUniString, kATSUFromTextBeginning, kATSUToTextEnd, (UniCharCount)stringLengthChars); //create an ATSU style object callError=ATSUCreateStyle(&atsuStyle); callError=ATSUClearStyle(atsuStyle); //Not that we have a style object we have to set style charactersitics. These include but are more general than Font Manager styles. //ATSU Style objects have three sets of characteristics: attributes, variations, and features. //attributes are things we need to set to match OS 9 behavior, such as the font ID, size, boldness, and italicization. //features are esoteric settings which we don't need for reproducing OS 9 behavior. Whatever clearstyle sets should be fine. //font variations are axes of variation through the space of font characteristics. The font definition includes available axes of variation. Something else we can ignore for now. PsychSetATSUStyleAttributesFromPsychWindowRecord(atsuStyle, winRec); //don't bother to set the variations of the style. //don't bother to set the features of the style. //associate the style with our layout object. This call assigns a style to every character of the string to be displayed. callError=ATSUSetRunStyle(textLayout, atsuStyle, (UniCharArrayOffset)0, (UniCharCount)stringLengthChars); // Define the meaning of the y position of the specified drawing cursor. // We get the global setting from the Screen preference, but allow to override // it on a per-invocation basis via the optional 7th argument to 'DrawText': yPositionIsBaseline = PsychPrefStateGet_TextYPositionIsBaseline(); PsychCopyInIntegerArg(5, kPsychArgOptional, &yPositionIsBaseline); if (yPositionIsBaseline) { // Y position of drawing cursor defines distance between top of text and // baseline of text, i.e. the textheight excluding descenders of letters: // Need to compute offset via ATSU: ATSUTextMeasurement mleft, mright, mtop, mbottom; callError=ATSUGetUnjustifiedBounds(textLayout, kATSUFromTextBeginning, kATSUToTextEnd, &mleft, &mright, &mbottom, &mtop); if (callError) { PsychErrorExitMsg(PsychError_internal, "Failed to compute unjustified text height to baseline in call to ATSUGetUnjustifiedBounds().\n"); } // Only take height including ascenders into account, not the descenders. // MK: Honestly, i have no clue why this is the correct calculation (or if it is // the correct calculation), but visually it seems to provide the correct results // and i'm not a typographic expert and don't intend to become one... textHeightToBaseline = fabs(Fix2X(mbottom)); } else { // Y position of drawing cursor defines top of text, therefore no offset (==0) needed: textHeightToBaseline = 0; } //Get the bounds for our text so that and create a texture of sufficient size to containt it. ATSTrapezoid trapezoid; ItemCount oActualNumberOfBounds = 0; callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 0, NULL, &oActualNumberOfBounds); if (callError || oActualNumberOfBounds!=1) { PsychErrorExitMsg(PsychError_internal, "Failed to compute bounding box in call 1 to ATSUGetGlyphBounds() (nrbounds!=1)\n"); } callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &trapezoid, &oActualNumberOfBounds); if (callError || oActualNumberOfBounds!=1) { PsychErrorExitMsg(PsychError_internal, "Failed to retrieve bounding box in call 2 to ATSUGetGlyphBounds() (nrbounds!=1)\n"); } resultPsychRect[kPsychLeft]=(Fix2X(trapezoid.upperLeft.x) < Fix2X(trapezoid.lowerLeft.x)) ? Fix2X(trapezoid.upperLeft.x) : Fix2X(trapezoid.lowerLeft.x); resultPsychRect[kPsychRight]=(Fix2X(trapezoid.upperRight.x) > Fix2X(trapezoid.lowerRight.x)) ? Fix2X(trapezoid.upperRight.x) : Fix2X(trapezoid.lowerRight.x); resultPsychRect[kPsychTop]=(Fix2X(trapezoid.upperLeft.y) < Fix2X(trapezoid.upperRight.y)) ? Fix2X(trapezoid.upperLeft.y) : Fix2X(trapezoid.upperRight.y); resultPsychRect[kPsychBottom]=(Fix2X(trapezoid.lowerLeft.y) > Fix2X(trapezoid.lowerRight.y)) ? Fix2X(trapezoid.lowerLeft.y) : Fix2X(trapezoid.lowerRight.y); PsychNormalizeRect(resultPsychRect, resultPsychNormRect); resultPsychRect[kPsychLeft]=resultPsychNormRect[kPsychLeft] + winRec->textAttributes.textPositionX; resultPsychRect[kPsychRight]=resultPsychNormRect[kPsychRight] + winRec->textAttributes.textPositionX; resultPsychRect[kPsychTop]=resultPsychNormRect[kPsychTop] + winRec->textAttributes.textPositionY - textHeightToBaseline; resultPsychRect[kPsychBottom]=resultPsychNormRect[kPsychBottom] + winRec->textAttributes.textPositionY - textHeightToBaseline; PsychCopyOutRectArg(1, FALSE, resultPsychNormRect); PsychCopyOutRectArg(2, FALSE, resultPsychRect); //release resources free((void*)textUniString); callError=ATSUDisposeStyle(atsuStyle); return(PsychError_none); }
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; }