xref: /aoo41x/main/vcl/aqua/source/gdi/ctfonts.cxx (revision 5b651169)
12822fc04SHerbert Dürr /**************************************************************
22822fc04SHerbert Dürr  *
32822fc04SHerbert Dürr  * Licensed to the Apache Software Foundation (ASF) under one
42822fc04SHerbert Dürr  * or more contributor license agreements.  See the NOTICE file
52822fc04SHerbert Dürr  * distributed with this work for additional information
62822fc04SHerbert Dürr  * regarding copyright ownership.  The ASF licenses this file
72822fc04SHerbert Dürr  * to you under the Apache License, Version 2.0 (the
82822fc04SHerbert Dürr  * "License"); you may not use this file except in compliance
92822fc04SHerbert Dürr  * with the License.  You may obtain a copy of the License at
102822fc04SHerbert Dürr  *
112822fc04SHerbert Dürr  *   http://www.apache.org/licenses/LICENSE-2.0
122822fc04SHerbert Dürr  *
132822fc04SHerbert Dürr  * Unless required by applicable law or agreed to in writing,
142822fc04SHerbert Dürr  * software distributed under the License is distributed on an
152822fc04SHerbert Dürr  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162822fc04SHerbert Dürr  * KIND, either express or implied.  See the License for the
172822fc04SHerbert Dürr  * specific language governing permissions and limitations
182822fc04SHerbert Dürr  * under the License.
192822fc04SHerbert Dürr  *
202822fc04SHerbert Dürr  *************************************************************/
212822fc04SHerbert Dürr 
222822fc04SHerbert Dürr // MARKER(update_precomp.py): autogen include statement, do not remove
232822fc04SHerbert Dürr #include "precompiled_vcl.hxx"
242822fc04SHerbert Dürr 
252822fc04SHerbert Dürr #include "impfont.hxx"
262822fc04SHerbert Dürr #include "outfont.hxx"
272822fc04SHerbert Dürr #include "sallayout.hxx"
282822fc04SHerbert Dürr 
292822fc04SHerbert Dürr #include "aqua/salinst.h"
302822fc04SHerbert Dürr #include "aqua/saldata.hxx"
312822fc04SHerbert Dürr #include "aqua/salgdi.h"
322822fc04SHerbert Dürr #include "ctfonts.hxx"
332822fc04SHerbert Dürr 
342822fc04SHerbert Dürr #include "basegfx/polygon/b2dpolygon.hxx"
352822fc04SHerbert Dürr #include "basegfx/matrix/b2dhommatrix.hxx"
362822fc04SHerbert Dürr 
372822fc04SHerbert Dürr #ifndef DISABLE_CORETEXT_DYNLOAD
382822fc04SHerbert Dürr #include <dlfcn.h>
392822fc04SHerbert Dürr #endif
402822fc04SHerbert Dürr 
412822fc04SHerbert Dürr // =======================================================================
422822fc04SHerbert Dürr 
432822fc04SHerbert Dürr // CoreText specific physically available font face
442822fc04SHerbert Dürr class CTFontData
452822fc04SHerbert Dürr :	public ImplMacFontData
462822fc04SHerbert Dürr {
472822fc04SHerbert Dürr public:
482822fc04SHerbert Dürr 	explicit				CTFontData( const ImplDevFontAttributes&, sal_IntPtr nFontId );
492822fc04SHerbert Dürr 	virtual					~CTFontData( void );
502822fc04SHerbert Dürr 	virtual ImplFontData*   Clone( void ) const;
512822fc04SHerbert Dürr 
522822fc04SHerbert Dürr 	virtual ImplMacTextStyle*	CreateMacTextStyle( const ImplFontSelectData& ) const;
532822fc04SHerbert Dürr 	virtual ImplFontEntry*		CreateFontInstance( /*const*/ ImplFontSelectData& ) const;
542822fc04SHerbert Dürr 	virtual int					GetFontTable( const char pTagName[5], unsigned char* ) const;
552822fc04SHerbert Dürr };
562822fc04SHerbert Dürr 
572822fc04SHerbert Dürr // =======================================================================
582822fc04SHerbert Dürr 
592822fc04SHerbert Dürr class CTFontList
602822fc04SHerbert Dürr :	public SystemFontList
612822fc04SHerbert Dürr {
622822fc04SHerbert Dürr public:
632822fc04SHerbert Dürr 	explicit	CTFontList( void );
642822fc04SHerbert Dürr 	virtual		~CTFontList( void );
652822fc04SHerbert Dürr 
662822fc04SHerbert Dürr 	bool		Init( void );
672822fc04SHerbert Dürr 	void		AddFont( CTFontData* );
682822fc04SHerbert Dürr 
692822fc04SHerbert Dürr 	virtual void    AnnounceFonts( ImplDevFontList& ) const;
702822fc04SHerbert Dürr 	virtual ImplMacFontData* GetFontDataFromId( sal_IntPtr ) const;
712822fc04SHerbert Dürr 
722822fc04SHerbert Dürr private:
732822fc04SHerbert Dürr 	CTFontCollectionRef mpCTFontCollection;
742822fc04SHerbert Dürr 	CFArrayRef mpCTFontArray;
752822fc04SHerbert Dürr 
762822fc04SHerbert Dürr 	typedef std::hash_map<sal_IntPtr,CTFontData*> CTFontContainer;
772822fc04SHerbert Dürr 	CTFontContainer	maFontContainer;
782822fc04SHerbert Dürr };
792822fc04SHerbert Dürr 
802822fc04SHerbert Dürr // =======================================================================
812822fc04SHerbert Dürr 
CTTextStyle(const ImplFontSelectData & rFSD)822822fc04SHerbert Dürr CTTextStyle::CTTextStyle( const ImplFontSelectData& rFSD )
832822fc04SHerbert Dürr :	ImplMacTextStyle( rFSD )
842822fc04SHerbert Dürr ,	mpStyleDict( NULL )
852822fc04SHerbert Dürr {
862822fc04SHerbert Dürr 	mpFontData = (CTFontData*)rFSD.mpFontData;
872822fc04SHerbert Dürr 	const ImplFontSelectData* const pReqFont = &rFSD;
882822fc04SHerbert Dürr 
892822fc04SHerbert Dürr 	double fScaledFontHeight = pReqFont->mfExactHeight;
902822fc04SHerbert Dürr #if 0 // TODO: does CoreText need font size limiting???
912822fc04SHerbert Dürr 	static const float fMaxFontHeight = 144.0; // TODO: is there a limit for CoreText?
922822fc04SHerbert Dürr 	if( fScaledFontHeight > fMaxFontHeight )
932822fc04SHerbert Dürr 	{
942822fc04SHerbert Dürr 		mfFontScale = fScaledFontHeight / fMaxFontHeight;
952822fc04SHerbert Dürr 		fScaledFontHeight = fMaxFontHeight;
962822fc04SHerbert Dürr 	}
972822fc04SHerbert Dürr #endif
982822fc04SHerbert Dürr 
992822fc04SHerbert Dürr 	// convert font rotation to radian
1002822fc04SHerbert Dürr 	mfFontRotation = pReqFont->mnOrientation * (M_PI / 1800.0);
1012822fc04SHerbert Dürr 
1022822fc04SHerbert Dürr 	// handle font stretching if any
1032822fc04SHerbert Dürr 	const CGAffineTransform* pMatrix = NULL;
1042822fc04SHerbert Dürr 	CGAffineTransform aMatrix;
1052822fc04SHerbert Dürr 	if( (pReqFont->mnWidth != 0) && (pReqFont->mnWidth != pReqFont->mnHeight) )
1062822fc04SHerbert Dürr 	{
1072822fc04SHerbert Dürr 		mfFontStretch = (float)pReqFont->mnWidth / pReqFont->mnHeight;
1082822fc04SHerbert Dürr 		aMatrix = CGAffineTransformMakeScale( mfFontStretch, 1.0F );
1092822fc04SHerbert Dürr 		pMatrix = &aMatrix;
1102822fc04SHerbert Dürr 	}
1112822fc04SHerbert Dürr 
112703fc9f0SHerbert Dürr 	// handle emulation of italic/oblique styles if requested and the font doesn't provide them
113703fc9f0SHerbert Dürr 	if( ((pReqFont->meItalic == ITALIC_NORMAL) || (pReqFont->meItalic == ITALIC_OBLIQUE))
1147ac1eb31SHerbert Dürr 	&& (mpFontData->meItalic == ITALIC_NONE))
115703fc9f0SHerbert Dürr 	{
116703fc9f0SHerbert Dürr 		if( !pMatrix)
117703fc9f0SHerbert Dürr 			pMatrix = &(aMatrix = CGAffineTransformIdentity);
118703fc9f0SHerbert Dürr 		aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMake( 1, 0, 0.375F, 1, 0, 0));
119703fc9f0SHerbert Dürr 	}
120703fc9f0SHerbert Dürr 
1212822fc04SHerbert Dürr 	// create the style object for CoreText font attributes
1222822fc04SHerbert Dürr 	static const CFIndex nMaxDictSize = 16; // TODO: does this really suffice?
1232822fc04SHerbert Dürr 	mpStyleDict = CFDictionaryCreateMutable( NULL, nMaxDictSize,
1242822fc04SHerbert Dürr 		&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
1252822fc04SHerbert Dürr 
1262822fc04SHerbert Dürr 	// set some default styles: no kerning, regular ligatures
1272822fc04SHerbert Dürr 	static const CGFloat fValZero = 0.0;
1282822fc04SHerbert Dürr 	CFNumberRef pCFFloatNumZero = CFNumberCreate( NULL, kCFNumberFloatType, &fValZero );
1292822fc04SHerbert Dürr 	CFDictionarySetValue( mpStyleDict, kCTKernAttributeName, pCFFloatNumZero );
1302822fc04SHerbert Dürr 	CFRelease( pCFFloatNumZero);
1312822fc04SHerbert Dürr 	static const int nValOne = 1;
1322822fc04SHerbert Dürr 	CFNumberRef pCFIntNumOne = CFNumberCreate( NULL, kCFNumberIntType, &nValOne );
1332822fc04SHerbert Dürr 	CFDictionarySetValue( mpStyleDict, kCTLigatureAttributeName, pCFIntNumOne );
1342822fc04SHerbert Dürr 	CFRelease( pCFIntNumOne);
1352822fc04SHerbert Dürr 	CFBooleanRef pCFVertBool = pReqFont->mbVertical ? kCFBooleanTrue : kCFBooleanFalse;
1362822fc04SHerbert Dürr 	CFDictionarySetValue( mpStyleDict, kCTVerticalFormsAttributeName, pCFVertBool );
1372822fc04SHerbert Dürr 
1382822fc04SHerbert Dürr 	CTFontDescriptorRef pFontDesc = (CTFontDescriptorRef)mpFontData->GetFontId();
1392822fc04SHerbert Dürr 	CTFontRef pNewCTFont = CTFontCreateWithFontDescriptor( pFontDesc, fScaledFontHeight, pMatrix );
1402822fc04SHerbert Dürr 	CFDictionarySetValue( mpStyleDict, kCTFontAttributeName, pNewCTFont );
1412822fc04SHerbert Dürr 	CFRelease( pNewCTFont);
1422822fc04SHerbert Dürr 
143*5b651169SHerbert Dürr 	// allow delayed setting the font color, i.e. after the text layout
144*5b651169SHerbert Dürr 	CFDictionarySetValue( mpStyleDict, kCTForegroundColorFromContextAttributeName, kCFBooleanTrue );
145*5b651169SHerbert Dürr 
14641145ab3SHerbert Dürr 	// handle emulation of bold styles if requested and the font that doesn't provide them
14741145ab3SHerbert Dürr 	if( (pReqFont->meWeight > WEIGHT_MEDIUM)
14841145ab3SHerbert Dürr 	&&  (mpFontData->meWeight <= WEIGHT_MEDIUM)
14941145ab3SHerbert Dürr 	&&  (mpFontData->meWeight != WEIGHT_DONTKNOW))
15041145ab3SHerbert Dürr 	{
15141145ab3SHerbert Dürr 		const int nBoldFactor = -lrint( (3.5F * pReqFont->meWeight) / mpFontData->meWeight);
15241145ab3SHerbert Dürr 		CFNumberRef pCFIntBold = CFNumberCreate( NULL, kCFNumberIntType, &nBoldFactor);
15341145ab3SHerbert Dürr 		CFDictionarySetValue( mpStyleDict, kCTStrokeWidthAttributeName, pCFIntBold);
15441145ab3SHerbert Dürr 	}
15541145ab3SHerbert Dürr 
1562822fc04SHerbert Dürr #if 0 // LastResort is implicit in CoreText's font cascading
1572822fc04SHerbert Dürr 	const void* aGFBDescriptors[] = { CTFontDescriptorCreateWithNameAndSize( CFSTR("LastResort"), 0) }; // TODO: use the full GFB list
1582822fc04SHerbert Dürr 	const int nGfbCount = sizeof(aGFBDescriptors) / sizeof(*aGFBDescriptors);
1592822fc04SHerbert Dürr 	CFArrayRef pGfbList = CFArrayCreate( NULL, aGFBDescriptors, nGfbCount, &kCFTypeArrayCallBacks);
1602822fc04SHerbert Dürr 	CFDictionaryAddValue( mpStyleDict, kCTFontCascadeListAttribute, pGfbList);
1612822fc04SHerbert Dürr 	CFRelease( pGfbList);
1622822fc04SHerbert Dürr #endif
1632822fc04SHerbert Dürr }
1642822fc04SHerbert Dürr 
1652822fc04SHerbert Dürr // -----------------------------------------------------------------------
1662822fc04SHerbert Dürr 
~CTTextStyle(void)1672822fc04SHerbert Dürr CTTextStyle::~CTTextStyle( void )
1682822fc04SHerbert Dürr {
1692822fc04SHerbert Dürr 	if( mpStyleDict )
1702822fc04SHerbert Dürr 		CFRelease( mpStyleDict );
1712822fc04SHerbert Dürr }
1722822fc04SHerbert Dürr 
1732822fc04SHerbert Dürr // -----------------------------------------------------------------------
1742822fc04SHerbert Dürr 
GetFontMetric(float fDPIY,ImplFontMetricData & rMetric) const1752822fc04SHerbert Dürr void CTTextStyle::GetFontMetric( float fDPIY, ImplFontMetricData& rMetric ) const
1762822fc04SHerbert Dürr {
1772822fc04SHerbert Dürr 	// get the matching CoreText font handle
1782822fc04SHerbert Dürr 	// TODO: is it worth it to cache the CTFontRef in SetFont() and reuse it here?
1792822fc04SHerbert Dürr 	CTFontRef aCTFontRef = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName );
1802822fc04SHerbert Dürr 
1812822fc04SHerbert Dürr 	const double fPixelSize = (mfFontScale * fDPIY);
182d443b74fSHerbert Dürr 	const CGFloat fAscent = CTFontGetAscent( aCTFontRef );
183d443b74fSHerbert Dürr 	const CGFloat fCapHeight = CTFontGetCapHeight( aCTFontRef );
184d443b74fSHerbert Dürr 	rMetric.mnAscent       = lrint( fAscent * fPixelSize);
1852822fc04SHerbert Dürr 	rMetric.mnDescent      = lrint( CTFontGetDescent( aCTFontRef ) * fPixelSize);
186d443b74fSHerbert Dürr 	rMetric.mnExtLeading   = lrint( CTFontGetLeading( aCTFontRef ) * fPixelSize);
187d443b74fSHerbert Dürr 	rMetric.mnIntLeading   = lrint( (fAscent - fCapHeight) * fPixelSize);
188d443b74fSHerbert Dürr 
1892822fc04SHerbert Dürr 	// since ImplFontMetricData::mnWidth is only used for stretching/squeezing fonts
1902822fc04SHerbert Dürr 	// setting this width to the pixel height of the fontsize is good enough
1912822fc04SHerbert Dürr 	// it also makes the calculation of the stretch factor simple
1922822fc04SHerbert Dürr 	rMetric.mnWidth        = lrint( CTFontGetSize( aCTFontRef ) * fPixelSize * mfFontStretch);
1932822fc04SHerbert Dürr 
1942822fc04SHerbert Dürr 	// all CoreText fonts are scalable
1952822fc04SHerbert Dürr 	rMetric.mbScalableFont = true;
1962822fc04SHerbert Dürr 	// TODO: check if any kerning is supported
1972822fc04SHerbert Dürr 	rMetric.mbKernableFont = true;
1982822fc04SHerbert Dürr }
1992822fc04SHerbert Dürr 
2002822fc04SHerbert Dürr // -----------------------------------------------------------------------
2012822fc04SHerbert Dürr 
GetGlyphBoundRect(sal_GlyphId aGlyphId,Rectangle & rRect) const2022822fc04SHerbert Dürr bool CTTextStyle::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect ) const
2032822fc04SHerbert Dürr {
2042822fc04SHerbert Dürr 	const DynCoreTextSyms& rCT = DynCoreTextSyms::get();
2052822fc04SHerbert Dürr 	CGGlyph nCGGlyph = aGlyphId & GF_IDXMASK; // NOTE: CoreText handles glyph fallback itself
2062822fc04SHerbert Dürr 	CTFontRef aCTFontRef = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName );
2072822fc04SHerbert Dürr 
2082822fc04SHerbert Dürr 	const CTFontOrientation aFontOrientation = kCTFontDefaultOrientation; // TODO: horz/vert
2092822fc04SHerbert Dürr 	const CGRect aCGRect = rCT.FontGetBoundingRectsForGlyphs( aCTFontRef, aFontOrientation, &nCGGlyph, NULL, 1 );
2102822fc04SHerbert Dürr 
2112822fc04SHerbert Dürr 	rRect.Left()   = lrint( mfFontScale * aCGRect.origin.x );
2122822fc04SHerbert Dürr 	rRect.Top()    = lrint( mfFontScale * aCGRect.origin.y );
2132822fc04SHerbert Dürr 	rRect.Right()  = lrint( mfFontScale * (aCGRect.origin.x + aCGRect.size.width) );
2142822fc04SHerbert Dürr 	rRect.Bottom() = lrint( mfFontScale * (aCGRect.origin.y + aCGRect.size.height) );
2152822fc04SHerbert Dürr 	return true;
2162822fc04SHerbert Dürr }
2172822fc04SHerbert Dürr 
2182822fc04SHerbert Dürr // -----------------------------------------------------------------------
2192822fc04SHerbert Dürr 
2202822fc04SHerbert Dürr // callbacks from CTFontCreatePathForGlyph+CGPathApply for GetGlyphOutline()
2212822fc04SHerbert Dürr struct GgoData { basegfx::B2DPolygon maPolygon; basegfx::B2DPolyPolygon* mpPolyPoly; };
2222822fc04SHerbert Dürr 
MyCGPathApplierFunc(void * pData,const CGPathElement * pElement)2232822fc04SHerbert Dürr static void MyCGPathApplierFunc( void* pData, const CGPathElement* pElement )
2242822fc04SHerbert Dürr {
2252822fc04SHerbert Dürr 	basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon;
2262822fc04SHerbert Dürr 	const int nPointCount = rPolygon.count();
2272822fc04SHerbert Dürr 
2282822fc04SHerbert Dürr 	switch( pElement->type )
2292822fc04SHerbert Dürr 	{
2302822fc04SHerbert Dürr 	case kCGPathElementCloseSubpath:
2312822fc04SHerbert Dürr 	case kCGPathElementMoveToPoint:
2322822fc04SHerbert Dürr 		if( nPointCount > 0 ) {
2332822fc04SHerbert Dürr 			static_cast<GgoData*>(pData)->mpPolyPoly->append( rPolygon );
2342822fc04SHerbert Dürr 			rPolygon.clear();
2352822fc04SHerbert Dürr 		}
2362822fc04SHerbert Dürr 		// fall through for kCGPathElementMoveToPoint:
2372822fc04SHerbert Dürr 		if( pElement->type != kCGPathElementMoveToPoint )
2382822fc04SHerbert Dürr 			break;
2392822fc04SHerbert Dürr 	case kCGPathElementAddLineToPoint:
2402822fc04SHerbert Dürr 		rPolygon.append( basegfx::B2DPoint( +pElement->points[0].x, -pElement->points[0].y ) );
2412822fc04SHerbert Dürr 		break;
2422822fc04SHerbert Dürr 	case kCGPathElementAddCurveToPoint:
2432822fc04SHerbert Dürr 		rPolygon.append( basegfx::B2DPoint( +pElement->points[2].x, -pElement->points[2].y ) );
2442822fc04SHerbert Dürr 		rPolygon.setNextControlPoint( nPointCount-1, basegfx::B2DPoint( pElement->points[0].x, -pElement->points[0].y ) );
2452822fc04SHerbert Dürr 		rPolygon.setPrevControlPoint( nPointCount+0, basegfx::B2DPoint( pElement->points[1].x, -pElement->points[1].y ) );
2462822fc04SHerbert Dürr 		break;
2472822fc04SHerbert Dürr 	case kCGPathElementAddQuadCurveToPoint: {
2482822fc04SHerbert Dürr 		const basegfx::B2DPoint aStartPt = rPolygon.getB2DPoint( nPointCount-1 );
2492822fc04SHerbert Dürr 		const basegfx::B2DPoint aCtrPt1( (aStartPt.getX() + 2* pElement->points[0].x) / 3.0,
2502822fc04SHerbert Dürr 					(aStartPt.getY() - 2 * pElement->points[0].y) / 3.0 );
2512822fc04SHerbert Dürr 		const basegfx::B2DPoint aCtrPt2( (+2 * +pElement->points[0].x + pElement->points[1].x) / 3.0,
2522822fc04SHerbert Dürr 				(-2 * pElement->points[0].y - pElement->points[1].y) / 3.0 );
2532822fc04SHerbert Dürr 		rPolygon.append( basegfx::B2DPoint( +pElement->points[1].x, -pElement->points[1].y ) );
2542822fc04SHerbert Dürr 		rPolygon.setNextControlPoint( nPointCount-1, aCtrPt1 );
2552822fc04SHerbert Dürr 		rPolygon.setPrevControlPoint( nPointCount+0, aCtrPt2 );
2562822fc04SHerbert Dürr 		} break;
2572822fc04SHerbert Dürr 	}
2582822fc04SHerbert Dürr }
2592822fc04SHerbert Dürr 
GetGlyphOutline(sal_GlyphId aGlyphId,basegfx::B2DPolyPolygon & rResult) const2602822fc04SHerbert Dürr bool CTTextStyle::GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& rResult ) const
2612822fc04SHerbert Dürr {
2622822fc04SHerbert Dürr 	rResult.clear();
2632822fc04SHerbert Dürr 
2642822fc04SHerbert Dürr 	const DynCoreTextSyms& rCT = DynCoreTextSyms::get();
2652822fc04SHerbert Dürr 	// TODO: GF_FONTMASK if using non-native glyph fallback
2662822fc04SHerbert Dürr 	CGGlyph nCGGlyph = aGlyphId & GF_IDXMASK;
2672822fc04SHerbert Dürr 	CTFontRef pCTFont = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName );
2682822fc04SHerbert Dürr 	CGPathRef xPath = rCT.FontCreatePathForGlyph( pCTFont, nCGGlyph, NULL );
2692822fc04SHerbert Dürr 
2702822fc04SHerbert Dürr 	GgoData aGgoData;
2712822fc04SHerbert Dürr 	aGgoData.mpPolyPoly = &rResult;
2722822fc04SHerbert Dürr 	CGPathApply( xPath, (void*)&aGgoData, MyCGPathApplierFunc );
2732822fc04SHerbert Dürr #if 0 // TODO: does OSX ensure that the last polygon is always closed?
2742822fc04SHerbert Dürr 	const CGPathElement aClosingElement = { kCGPathElementCloseSubpath, NULL };
2752822fc04SHerbert Dürr 	MyCGPathApplierFunc( (void*)&aGgoData, &aClosingElement );
2762822fc04SHerbert Dürr #endif
2772822fc04SHerbert Dürr 
2782822fc04SHerbert Dürr 	// apply the font scale
2792822fc04SHerbert Dürr 	if( mfFontScale != 1.0 ) {
2802822fc04SHerbert Dürr 		basegfx::B2DHomMatrix aScale;
2812822fc04SHerbert Dürr 		aScale.scale( +mfFontScale, +mfFontScale );
2822822fc04SHerbert Dürr 		rResult.transform( aScale );
2832822fc04SHerbert Dürr 	}
2842822fc04SHerbert Dürr 
2852822fc04SHerbert Dürr 	return true;
2862822fc04SHerbert Dürr }
2872822fc04SHerbert Dürr 
2882822fc04SHerbert Dürr // =======================================================================
2892822fc04SHerbert Dürr 
CTFontData(const ImplDevFontAttributes & rDFA,sal_IntPtr nFontId)2902822fc04SHerbert Dürr CTFontData::CTFontData( const ImplDevFontAttributes& rDFA, sal_IntPtr nFontId )
2912822fc04SHerbert Dürr :	ImplMacFontData( rDFA, nFontId )
2922822fc04SHerbert Dürr {}
2932822fc04SHerbert Dürr 
2942822fc04SHerbert Dürr // -----------------------------------------------------------------------
2952822fc04SHerbert Dürr 
~CTFontData(void)2962822fc04SHerbert Dürr CTFontData::~CTFontData( void )
2972822fc04SHerbert Dürr {
2982822fc04SHerbert Dürr 	// TODO: any resources to release?
2992822fc04SHerbert Dürr }
3002822fc04SHerbert Dürr 
3012822fc04SHerbert Dürr // -----------------------------------------------------------------------
3022822fc04SHerbert Dürr 
Clone(void) const3032822fc04SHerbert Dürr ImplFontData* CTFontData::Clone( void ) const
3042822fc04SHerbert Dürr {
3052822fc04SHerbert Dürr 	return new CTFontData( *this);
3062822fc04SHerbert Dürr }
3072822fc04SHerbert Dürr 
3082822fc04SHerbert Dürr // -----------------------------------------------------------------------
3092822fc04SHerbert Dürr 
CreateMacTextStyle(const ImplFontSelectData & rFSD) const3102822fc04SHerbert Dürr ImplMacTextStyle* CTFontData::CreateMacTextStyle( const ImplFontSelectData& rFSD ) const
3112822fc04SHerbert Dürr {
3122822fc04SHerbert Dürr 	return new CTTextStyle( rFSD);
3132822fc04SHerbert Dürr }
3142822fc04SHerbert Dürr 
3152822fc04SHerbert Dürr // -----------------------------------------------------------------------
3162822fc04SHerbert Dürr 
CreateFontInstance(ImplFontSelectData & rFSD) const3172822fc04SHerbert Dürr ImplFontEntry* CTFontData::CreateFontInstance( /*const*/ ImplFontSelectData& rFSD ) const
3182822fc04SHerbert Dürr {
3192822fc04SHerbert Dürr 	return new ImplFontEntry( rFSD);
3202822fc04SHerbert Dürr }
3212822fc04SHerbert Dürr 
3222822fc04SHerbert Dürr // -----------------------------------------------------------------------
3232822fc04SHerbert Dürr 
GetFontTable(const char pTagName[5],unsigned char * pResultBuf) const3242822fc04SHerbert Dürr int CTFontData::GetFontTable( const char pTagName[5], unsigned char* pResultBuf ) const
3252822fc04SHerbert Dürr {
3262822fc04SHerbert Dürr 	DBG_ASSERT( pTagName[4]=='\0', "CTFontData::GetFontTable with invalid tagname!\n" );
3272822fc04SHerbert Dürr 
3282822fc04SHerbert Dürr 	const CTFontTableTag nTagCode = (pTagName[0]<<24) + (pTagName[1]<<16) + (pTagName[2]<<8) + (pTagName[3]<<0);
3292822fc04SHerbert Dürr 
3302822fc04SHerbert Dürr 	// get the raw table length
3312822fc04SHerbert Dürr 	CTFontDescriptorRef pFontDesc = reinterpret_cast<CTFontDescriptorRef>( GetFontId());
3322822fc04SHerbert Dürr 	CTFontRef rCTFont = CTFontCreateWithFontDescriptor( pFontDesc, 0.0, NULL);
3332822fc04SHerbert Dürr 	CFDataRef pDataRef = CTFontCopyTable( rCTFont, nTagCode, kCTFontTableOptionExcludeSynthetic);
3342822fc04SHerbert Dürr 	CFRelease( rCTFont);
3352822fc04SHerbert Dürr 	if( !pDataRef)
3362822fc04SHerbert Dürr 		return 0;
3372822fc04SHerbert Dürr 
3382822fc04SHerbert Dürr 	const CFIndex nByteLength = CFDataGetLength( pDataRef);
3392822fc04SHerbert Dürr 
3402822fc04SHerbert Dürr 	// get the raw table data if requested
3412822fc04SHerbert Dürr 	if( pResultBuf && (nByteLength > 0))
3422822fc04SHerbert Dürr 	{
3432822fc04SHerbert Dürr 		const CFRange aFullRange = CFRangeMake( 0, nByteLength);
3442822fc04SHerbert Dürr 		CFDataGetBytes( pDataRef, aFullRange, (UInt8*)pResultBuf);
3452822fc04SHerbert Dürr 	}
3462822fc04SHerbert Dürr 
3472822fc04SHerbert Dürr 	CFRelease( pDataRef);
3482822fc04SHerbert Dürr 
3492822fc04SHerbert Dürr 	return (int)nByteLength;
3502822fc04SHerbert Dürr }
3512822fc04SHerbert Dürr 
3522822fc04SHerbert Dürr // =======================================================================
3532822fc04SHerbert Dürr 
CTFontEnumCallBack(const void * pValue,void * pContext)3542822fc04SHerbert Dürr static void CTFontEnumCallBack( const void* pValue, void* pContext )
3552822fc04SHerbert Dürr {
3562822fc04SHerbert Dürr 	CTFontDescriptorRef pFD = static_cast<CTFontDescriptorRef>(pValue);
3572822fc04SHerbert Dürr 
3582822fc04SHerbert Dürr 	// all CoreText fonts are device fonts that can rotate just fine
3592822fc04SHerbert Dürr 	ImplDevFontAttributes rDFA;
3602822fc04SHerbert Dürr 	rDFA.mbOrientation = true;
3612822fc04SHerbert Dürr 	rDFA.mbDevice      = true;
3622822fc04SHerbert Dürr 	rDFA.mnQuality     = 0;
3632822fc04SHerbert Dürr 
3642822fc04SHerbert Dürr 	// reset the font attributes
3652822fc04SHerbert Dürr 	rDFA.meFamily     = FAMILY_DONTKNOW;
3662822fc04SHerbert Dürr 	rDFA.mePitch      = PITCH_VARIABLE;
3672822fc04SHerbert Dürr 	rDFA.meWidthType  = WIDTH_NORMAL;
3682822fc04SHerbert Dürr 	rDFA.meWeight     = WEIGHT_NORMAL;
3692822fc04SHerbert Dürr 	rDFA.meItalic     = ITALIC_NONE;
3702822fc04SHerbert Dürr 	rDFA.mbSymbolFlag = false;
3712822fc04SHerbert Dürr 
3722822fc04SHerbert Dürr 	// all scalable fonts on this platform are subsettable
3732822fc04SHerbert Dürr 	rDFA.mbEmbeddable = false;
3742822fc04SHerbert Dürr 	rDFA.mbSubsettable = true;
3752822fc04SHerbert Dürr 
3762822fc04SHerbert Dürr 	// get font name
3772822fc04SHerbert Dürr 	// TODO: use kCTFontDisplayNameAttribute instead???
3782822fc04SHerbert Dürr 	CFStringRef pFamilyName = (CFStringRef)CTFontDescriptorCopyAttribute( pFD, kCTFontFamilyNameAttribute );
3792822fc04SHerbert Dürr 	rDFA.maName = GetOUString( pFamilyName );
3802822fc04SHerbert Dürr 	// get font style
3812822fc04SHerbert Dürr 	CFStringRef pStyleName = (CFStringRef)CTFontDescriptorCopyAttribute( pFD, kCTFontStyleNameAttribute );
3822822fc04SHerbert Dürr 	rDFA.maStyleName = GetOUString( pStyleName );
3832822fc04SHerbert Dürr 
3842822fc04SHerbert Dürr 	// get font-enabled status
3852822fc04SHerbert Dürr 	int bFontEnabled = FALSE;
3862822fc04SHerbert Dürr 	CFNumberRef pFontEnabled = (CFNumberRef)CTFontDescriptorCopyAttribute( pFD, kCTFontEnabledAttribute );
3872822fc04SHerbert Dürr 	CFNumberGetValue( pFontEnabled, kCFNumberIntType, &bFontEnabled );
3882822fc04SHerbert Dürr 
3892822fc04SHerbert Dürr 	// get font attributes
3902822fc04SHerbert Dürr 	CFDictionaryRef pAttrDict = (CFDictionaryRef)CTFontDescriptorCopyAttribute( pFD, kCTFontTraitsAttribute );
3912822fc04SHerbert Dürr 
3922822fc04SHerbert Dürr 	// get symbolic trait
3932822fc04SHerbert Dürr 	// TODO: use other traits such as MonoSpace/Condensed/Expanded or Vertical too
3942822fc04SHerbert Dürr 	SInt64 nSymbolTrait = 0;
3952822fc04SHerbert Dürr 	CFNumberRef pSymbolNum = NULL;
3962822fc04SHerbert Dürr 	if( CFDictionaryGetValueIfPresent( pAttrDict, kCTFontSymbolicTrait, (const void**)&pSymbolNum ) ) {
3972822fc04SHerbert Dürr 		CFNumberGetValue( pSymbolNum, kCFNumberSInt64Type, &nSymbolTrait );
3982822fc04SHerbert Dürr 		rDFA.mbSymbolFlag = ((nSymbolTrait & kCTFontClassMaskTrait) == kCTFontSymbolicClass);
3992822fc04SHerbert Dürr 	}
4002822fc04SHerbert Dürr 
4012822fc04SHerbert Dürr 	// get the font weight
4022822fc04SHerbert Dürr 	double fWeight = 0;
4032822fc04SHerbert Dürr 	CFNumberRef pWeightNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontWeightTrait );
4042822fc04SHerbert Dürr 	CFNumberGetValue( pWeightNum, kCFNumberDoubleType, &fWeight );
4052822fc04SHerbert Dürr 	int nInt = WEIGHT_NORMAL;
4062822fc04SHerbert Dürr 	if( fWeight > 0 ) {
4072822fc04SHerbert Dürr 		nInt = rint(WEIGHT_NORMAL + fWeight * ((WEIGHT_BLACK - WEIGHT_NORMAL)/0.68));
4082822fc04SHerbert Dürr 		if( nInt > WEIGHT_BLACK )
4092822fc04SHerbert Dürr 			nInt = WEIGHT_BLACK;
4102822fc04SHerbert Dürr 	} else if( fWeight < 0 ) {
4112822fc04SHerbert Dürr 		nInt = rint(WEIGHT_NORMAL + fWeight * ((WEIGHT_NORMAL - WEIGHT_THIN)/0.9));
4122822fc04SHerbert Dürr 		if( nInt < WEIGHT_THIN )
4132822fc04SHerbert Dürr 			nInt = WEIGHT_THIN;
4142822fc04SHerbert Dürr 	}
4152822fc04SHerbert Dürr 	rDFA.meWeight = (FontWeight)nInt;
4162822fc04SHerbert Dürr 
4172822fc04SHerbert Dürr 	// get the font slant
4182822fc04SHerbert Dürr 	double fSlant = 0;
4192822fc04SHerbert Dürr 	CFNumberRef pSlantNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontSlantTrait );
4202822fc04SHerbert Dürr 	CFNumberGetValue( pSlantNum, kCFNumberDoubleType, &fSlant );
4212822fc04SHerbert Dürr 	if( fSlant >= 0.035 )
4222822fc04SHerbert Dürr 		rDFA.meItalic = ITALIC_NORMAL;
4232822fc04SHerbert Dürr 
4242822fc04SHerbert Dürr 	// get width trait
4252822fc04SHerbert Dürr 	double fWidth = 0;
4262822fc04SHerbert Dürr 	CFNumberRef pWidthNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontWidthTrait );
4272822fc04SHerbert Dürr 	CFNumberGetValue( pWidthNum, kCFNumberDoubleType, &fWidth );
4282822fc04SHerbert Dürr 	nInt = WIDTH_NORMAL;
4292822fc04SHerbert Dürr 	if( fWidth > 0 ) {
4302822fc04SHerbert Dürr 		nInt = rint( WIDTH_NORMAL + fWidth * ((WIDTH_ULTRA_EXPANDED - WIDTH_NORMAL)/0.4));
4312822fc04SHerbert Dürr 		if( nInt > WIDTH_ULTRA_EXPANDED )
4322822fc04SHerbert Dürr 			nInt = WIDTH_ULTRA_EXPANDED;
4332822fc04SHerbert Dürr 	} else if( fWidth < 0 ) {
4342822fc04SHerbert Dürr 		nInt = rint( WIDTH_NORMAL + fWidth * ((WIDTH_NORMAL - WIDTH_ULTRA_CONDENSED)/0.5));
4352822fc04SHerbert Dürr 		if( nInt < WIDTH_ULTRA_CONDENSED )
4362822fc04SHerbert Dürr 			nInt = WIDTH_ULTRA_CONDENSED;
4372822fc04SHerbert Dürr 	}
4382822fc04SHerbert Dürr 	rDFA.meWidthType = (FontWidth)nInt;
4392822fc04SHerbert Dürr 
4402822fc04SHerbert Dürr 	// release the attribute dict that we had copied
4412822fc04SHerbert Dürr 	CFRelease( pAttrDict );
4422822fc04SHerbert Dürr 
4432822fc04SHerbert Dürr 	// TODO? also use the HEAD table if available to get more attributes
4442822fc04SHerbert Dürr //	CFDataRef CTFontCopyTable( CTFontRef, kCTFontTableHead, /*kCTFontTableOptionNoOptions*/kCTFontTableOptionExcludeSynthetic );
4452822fc04SHerbert Dürr 
4462822fc04SHerbert Dürr #if (OSL_DEBUG_LEVEL >= 1)
4472822fc04SHerbert Dürr 	// update font attributes using the font's postscript name
4482822fc04SHerbert Dürr 	ImplDevFontAttributes rDFA2;
4492822fc04SHerbert Dürr 	CTFontRef pFont = CTFontCreateWithFontDescriptor( pFD, 0.0, NULL );
4502822fc04SHerbert Dürr 	CFStringRef pPSName = CTFontCopyPostScriptName( pFont );
4512822fc04SHerbert Dürr 	const String aPSName = GetOUString( pPSName );
4522822fc04SHerbert Dürr 
4532822fc04SHerbert Dürr 	rDFA2.mbSymbolFlag = false;
4542822fc04SHerbert Dürr 	rDFA2.mePitch      = PITCH_VARIABLE;
4552822fc04SHerbert Dürr 	rDFA2.meWidthType  = WIDTH_NORMAL;
4562822fc04SHerbert Dürr 	rDFA2.meWeight     = WEIGHT_NORMAL;
4572822fc04SHerbert Dürr 	rDFA2.meItalic     = ITALIC_NONE;
4582822fc04SHerbert Dürr 
4592822fc04SHerbert Dürr 	UpdateAttributesFromPSName( aPSName, rDFA2 );
4602822fc04SHerbert Dürr 	CFRelease( pPSName );
4612822fc04SHerbert Dürr 	CFRelease( pFont );
4622822fc04SHerbert Dürr 
4632822fc04SHerbert Dürr 	// show the font details and compare the CTFontDescriptor vs. PSName traits
4642822fc04SHerbert Dürr 	char cMatch = (rDFA.mbSymbolFlag==rDFA2.mbSymbolFlag);
4652822fc04SHerbert Dürr 	cMatch &= (rDFA.meWeight==rDFA2.meWeight);
4662822fc04SHerbert Dürr 	cMatch &= ((rDFA.meItalic==ITALIC_NONE) == (rDFA2.meItalic==ITALIC_NONE));
4672822fc04SHerbert Dürr 	cMatch &= (rDFA.meWidthType==rDFA2.meWidthType);
4682822fc04SHerbert Dürr 	cMatch = cMatch ? '.' : '#';
4692822fc04SHerbert Dürr 
4702822fc04SHerbert Dürr 	char aFN[256], aSN[256];
4712822fc04SHerbert Dürr 	CFStringGetCString( pFamilyName, aFN, sizeof(aFN), kCFStringEncodingUTF8 );
4722822fc04SHerbert Dürr 	CFStringGetCString( pStyleName, aSN, sizeof(aSN), kCFStringEncodingUTF8 );
4732822fc04SHerbert Dürr 
4742822fc04SHerbert Dürr 	const ByteString aPSCName( aPSName, RTL_TEXTENCODING_UTF8 );
4752822fc04SHerbert Dürr 	const char* aPN = aPSCName.GetBuffer();
4762822fc04SHerbert Dürr 	printf("\tCTFont_%d%x%d%d_%c_%d%x%d%d ena=%d s=%02d b=%+.2f i=%+.2f w=%+.2f (\"%s\", \"%s\", \"%s\")\n",
4772822fc04SHerbert Dürr 		(int)rDFA.mbSymbolFlag,(int)rDFA.meWeight,(int)rDFA.meItalic,(int)rDFA.meWidthType,
4782822fc04SHerbert Dürr 		cMatch,
4792822fc04SHerbert Dürr 		(int)rDFA2.mbSymbolFlag,(int)rDFA2.meWeight,(int)rDFA2.meItalic,(int)rDFA2.meWidthType,
4802822fc04SHerbert Dürr 		bFontEnabled,
4812822fc04SHerbert Dürr 		(int)(nSymbolTrait>>kCTFontClassMaskShift),fWeight,fSlant,fWidth,aFN,aSN,aPN);
4822822fc04SHerbert Dürr #endif // (OSL_DEBUG_LEVEL >= 1)
4832822fc04SHerbert Dürr 
4842822fc04SHerbert Dürr 	if( bFontEnabled)
4852822fc04SHerbert Dürr 	{
4862822fc04SHerbert Dürr 		const sal_IntPtr nFontId = (sal_IntPtr)pValue;
4872822fc04SHerbert Dürr 		CTFontData* pFontData = new CTFontData( rDFA, nFontId );
4882822fc04SHerbert Dürr 		CTFontList* pFontList = (CTFontList*)pContext;
4892822fc04SHerbert Dürr 		pFontList->AddFont( pFontData );
4902822fc04SHerbert Dürr 	}
4912822fc04SHerbert Dürr }
4922822fc04SHerbert Dürr 
4932822fc04SHerbert Dürr // =======================================================================
4942822fc04SHerbert Dürr 
CTFontList()4952822fc04SHerbert Dürr CTFontList::CTFontList()
4962822fc04SHerbert Dürr :	mpCTFontCollection( NULL )
4972822fc04SHerbert Dürr ,	mpCTFontArray( NULL )
4982822fc04SHerbert Dürr {}
4992822fc04SHerbert Dürr 
5002822fc04SHerbert Dürr // -----------------------------------------------------------------------
5012822fc04SHerbert Dürr 
~CTFontList()5022822fc04SHerbert Dürr CTFontList::~CTFontList()
5032822fc04SHerbert Dürr {
5042822fc04SHerbert Dürr 	CTFontContainer::const_iterator it = maFontContainer.begin();
5052822fc04SHerbert Dürr 	for(; it != maFontContainer.end(); ++it )
5062822fc04SHerbert Dürr 		delete (*it).second;
5072822fc04SHerbert Dürr 	maFontContainer.clear();
5082822fc04SHerbert Dürr 
5092822fc04SHerbert Dürr 	if( mpCTFontArray )
5102822fc04SHerbert Dürr 		CFRelease( mpCTFontArray );
5112822fc04SHerbert Dürr 	if( mpCTFontCollection )
5122822fc04SHerbert Dürr 		CFRelease( mpCTFontCollection );
5132822fc04SHerbert Dürr }
5142822fc04SHerbert Dürr 
5152822fc04SHerbert Dürr // -----------------------------------------------------------------------
5162822fc04SHerbert Dürr 
AddFont(CTFontData * pFontData)5172822fc04SHerbert Dürr void CTFontList::AddFont( CTFontData* pFontData )
5182822fc04SHerbert Dürr {
5192822fc04SHerbert Dürr 	sal_IntPtr nFontId = pFontData->GetFontId();
5202822fc04SHerbert Dürr 	maFontContainer[ nFontId ] = pFontData;
5212822fc04SHerbert Dürr }
5222822fc04SHerbert Dürr 
5232822fc04SHerbert Dürr // -----------------------------------------------------------------------
5242822fc04SHerbert Dürr 
AnnounceFonts(ImplDevFontList & rFontList) const5252822fc04SHerbert Dürr void CTFontList::AnnounceFonts( ImplDevFontList& rFontList ) const
5262822fc04SHerbert Dürr {
5272822fc04SHerbert Dürr 	CTFontContainer::const_iterator it = maFontContainer.begin();
5282822fc04SHerbert Dürr 	for(; it != maFontContainer.end(); ++it )
5292822fc04SHerbert Dürr 		rFontList.Add( (*it).second->Clone() );
5302822fc04SHerbert Dürr }
5312822fc04SHerbert Dürr 
5322822fc04SHerbert Dürr // -----------------------------------------------------------------------
5332822fc04SHerbert Dürr 
GetFontDataFromId(sal_IntPtr nFontId) const5342822fc04SHerbert Dürr ImplMacFontData* CTFontList::GetFontDataFromId( sal_IntPtr nFontId ) const
5352822fc04SHerbert Dürr {
5362822fc04SHerbert Dürr 	CTFontContainer::const_iterator it = maFontContainer.find( nFontId );
5372822fc04SHerbert Dürr 	if( it == maFontContainer.end() )
5382822fc04SHerbert Dürr 		return NULL;
5392822fc04SHerbert Dürr 	return (*it).second;
5402822fc04SHerbert Dürr }
5412822fc04SHerbert Dürr 
5422822fc04SHerbert Dürr // -----------------------------------------------------------------------
5432822fc04SHerbert Dürr 
Init(void)5442822fc04SHerbert Dürr bool CTFontList::Init( void )
5452822fc04SHerbert Dürr {
5462822fc04SHerbert Dürr #ifndef DISABLE_CORETEXT_DYNLOAD
5472822fc04SHerbert Dürr 	// check availability of the CoreText API
5482822fc04SHerbert Dürr 	const DynCoreTextSyms& rCT = DynCoreTextSyms::get();
5492822fc04SHerbert Dürr 	if( !rCT.IsActive() )
5502822fc04SHerbert Dürr 		return false;
5512822fc04SHerbert Dürr #endif // DISABLE_CORETEXT_DYNLOAD
5522822fc04SHerbert Dürr 
5532822fc04SHerbert Dürr 	// enumerate available system fonts
5542822fc04SHerbert Dürr 	static const int nMaxDictEntries = 8;
5552822fc04SHerbert Dürr 	CFMutableDictionaryRef pCFDict = CFDictionaryCreateMutable( NULL,
5562822fc04SHerbert Dürr 		nMaxDictEntries, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
5572822fc04SHerbert Dürr 	CFDictionaryAddValue( pCFDict, kCTFontCollectionRemoveDuplicatesOption, kCFBooleanTrue );
5582822fc04SHerbert Dürr 	mpCTFontCollection = rCT.FontCollectionCreateFromAvailableFonts( pCFDict );
5592822fc04SHerbert Dürr 	CFRelease( pCFDict );
5602822fc04SHerbert Dürr 
5612822fc04SHerbert Dürr 	mpCTFontArray = rCT.FontCollectionCreateMatchingFontDescriptors( mpCTFontCollection );
5622822fc04SHerbert Dürr 	const int nFontCount = CFArrayGetCount( mpCTFontArray );
5632822fc04SHerbert Dürr 	const CFRange aFullRange = CFRangeMake( 0, nFontCount );
5642822fc04SHerbert Dürr 	CFArrayApplyFunction( mpCTFontArray, aFullRange, CTFontEnumCallBack, this );
5652822fc04SHerbert Dürr 
5662822fc04SHerbert Dürr 	return true;
5672822fc04SHerbert Dürr }
5682822fc04SHerbert Dürr 
5692822fc04SHerbert Dürr // =======================================================================
5702822fc04SHerbert Dürr 
5712822fc04SHerbert Dürr #ifndef DISABLE_CORETEXT_DYNLOAD
5722822fc04SHerbert Dürr 
DynCoreTextSyms(void)5732822fc04SHerbert Dürr DynCoreTextSyms::DynCoreTextSyms( void )
5742822fc04SHerbert Dürr {
5752822fc04SHerbert Dürr 	mbIsActive = false;
5762822fc04SHerbert Dürr 
5772822fc04SHerbert Dürr 	// check if CoreText has been explicitely disabled
5782822fc04SHerbert Dürr 	const char* pEnvStr = getenv( "SAL_DISABLE_CORETEXT");
5792822fc04SHerbert Dürr 	if( pEnvStr && (pEnvStr[0] != '0') )
5802822fc04SHerbert Dürr 		return;
5812822fc04SHerbert Dürr 
5822822fc04SHerbert Dürr 	// check CoreText version
5832822fc04SHerbert Dürr 	GetCoreTextVersion = (uint32_t(*)(void))dlsym( RTLD_DEFAULT, "CTGetCoreTextVersion");
5842822fc04SHerbert Dürr 	if( !GetCoreTextVersion) return;
5852822fc04SHerbert Dürr 
5862822fc04SHerbert Dürr 	const uint32_t nCTVersion = GetCoreTextVersion();
5872822fc04SHerbert Dürr 	static const uint32_t mykCTVersionNumber10_5 = 0x00020000;
5882822fc04SHerbert Dürr 	if( nCTVersion < mykCTVersionNumber10_5)
5892822fc04SHerbert Dürr 		return;
5902822fc04SHerbert Dürr 
5912822fc04SHerbert Dürr 	// load CoreText symbols dynamically
5922822fc04SHerbert Dürr 	LineGetTrailingWhitespaceWidth = (double(*)(CTLineRef))dlsym( RTLD_DEFAULT, "CTLineGetTrailingWhitespaceWidth");
5932822fc04SHerbert Dürr 	if( !LineGetTrailingWhitespaceWidth) return;
5942822fc04SHerbert Dürr 
5952822fc04SHerbert Dürr 	LineCreateJustifiedLine = (CTLineRef(*)(CTLineRef,CGFloat,double))dlsym( RTLD_DEFAULT, "CTLineCreateJustifiedLine");
5962822fc04SHerbert Dürr 	if( !LineCreateJustifiedLine) return;
5972822fc04SHerbert Dürr 
5982822fc04SHerbert Dürr 	LineGetOffsetForStringIndex = (CGFloat(*)(CTLineRef,CFIndex,CGFloat*))dlsym( RTLD_DEFAULT, "CTLineGetOffsetForStringIndex");
5992822fc04SHerbert Dürr 	if( !LineGetOffsetForStringIndex) return;
6002822fc04SHerbert Dürr 
6012822fc04SHerbert Dürr 	LineGetGlyphRuns = (CFArrayRef(*)(CTLineRef))dlsym( RTLD_DEFAULT, "CTLineGetGlyphRuns");
6022822fc04SHerbert Dürr 	if( !LineGetGlyphRuns) return;
6032822fc04SHerbert Dürr 
6042822fc04SHerbert Dürr 	RunGetGlyphCount = (CFIndex(*)(CTRunRef))dlsym( RTLD_DEFAULT, "CTRunGetGlyphCount");
6052822fc04SHerbert Dürr 	if( !RunGetGlyphCount) return;
6062822fc04SHerbert Dürr 
6072822fc04SHerbert Dürr 	RunGetGlyphsPtr = (const CGGlyph*(*)(CTRunRef))dlsym( RTLD_DEFAULT, "CTRunGetGlyphsPtr");
6082822fc04SHerbert Dürr 	if( !RunGetGlyphsPtr) return;
6092822fc04SHerbert Dürr 
6102822fc04SHerbert Dürr 	RunGetPositionsPtr = (const CGPoint*(*)(CTRunRef))dlsym( RTLD_DEFAULT, "CTRunGetPositionsPtr");
6112822fc04SHerbert Dürr 	if( !RunGetPositionsPtr) return;
6122822fc04SHerbert Dürr 
6132822fc04SHerbert Dürr 	RunGetAdvancesPtr = (const CGSize*(*)(CTRunRef))dlsym( RTLD_DEFAULT, "CTRunGetAdvancesPtr");
6142822fc04SHerbert Dürr 	if( !RunGetAdvancesPtr) return;
6152822fc04SHerbert Dürr 
6162822fc04SHerbert Dürr 	RunGetStringIndicesPtr = (const CFIndex*(*)(CTRunRef))dlsym( RTLD_DEFAULT, "CTRunGetStringIndicesPtr");
6172822fc04SHerbert Dürr 	if( !RunGetStringIndicesPtr) return;
6182822fc04SHerbert Dürr 
6192822fc04SHerbert Dürr 	FontCollectionCreateFromAvailableFonts = (CTFontCollectionRef(*)(CFDictionaryRef))dlsym( RTLD_DEFAULT, "CTFontCollectionCreateFromAvailableFonts");
6202822fc04SHerbert Dürr 	if( !FontCollectionCreateFromAvailableFonts) return;
6212822fc04SHerbert Dürr 
6222822fc04SHerbert Dürr 	FontCollectionCreateMatchingFontDescriptors = (CFArrayRef(*)(CTFontCollectionRef))dlsym( RTLD_DEFAULT, "CTFontCollectionCreateMatchingFontDescriptors");
6232822fc04SHerbert Dürr 	if( !FontCollectionCreateMatchingFontDescriptors) return;
6242822fc04SHerbert Dürr 
6252822fc04SHerbert Dürr 	FontCreatePathForGlyph = (CGPathRef(*)(CTFontRef,CGGlyph,const CGAffineTransform*))dlsym( RTLD_DEFAULT, "CTFontCreatePathForGlyph");
6262822fc04SHerbert Dürr 	if( !FontCreatePathForGlyph) return;
6272822fc04SHerbert Dürr 
6282822fc04SHerbert Dürr 	FontGetBoundingRectsForGlyphs = (CGRect(*)(CTFontRef,CTFontOrientation,CGGlyph*,CGRect*,CFIndex))dlsym( RTLD_DEFAULT, "CTFontGetBoundingRectsForGlyphs");
6292822fc04SHerbert Dürr 	if( !FontGetBoundingRectsForGlyphs) return;
6302822fc04SHerbert Dürr 
6312822fc04SHerbert Dürr 	mbIsActive = true;
6322822fc04SHerbert Dürr }
6332822fc04SHerbert Dürr 
6342822fc04SHerbert Dürr // -----------------------------------------------------------------------
6352822fc04SHerbert Dürr 
get(void)6362822fc04SHerbert Dürr const DynCoreTextSyms& DynCoreTextSyms::get( void )
6372822fc04SHerbert Dürr {
6382822fc04SHerbert Dürr 	static DynCoreTextSyms aCT;
6392822fc04SHerbert Dürr 	return aCT;
6402822fc04SHerbert Dürr }
6412822fc04SHerbert Dürr 
6422822fc04SHerbert Dürr #endif // DISABLE_CORETEXT_DYNLOAD
6432822fc04SHerbert Dürr 
6442822fc04SHerbert Dürr // =======================================================================
6452822fc04SHerbert Dürr 
GetCoretextFontList(void)6462822fc04SHerbert Dürr SystemFontList* GetCoretextFontList( void )
6472822fc04SHerbert Dürr {
6482822fc04SHerbert Dürr 	CTFontList* pList = new CTFontList();
6492822fc04SHerbert Dürr 	if( !pList->Init() ) {
6502822fc04SHerbert Dürr 		delete pList;
6512822fc04SHerbert Dürr 		return NULL;
6522822fc04SHerbert Dürr 	}
6532822fc04SHerbert Dürr 
6542822fc04SHerbert Dürr 	return pList;
6552822fc04SHerbert Dürr }
6562822fc04SHerbert Dürr 
6572822fc04SHerbert Dürr // =======================================================================
6582822fc04SHerbert Dürr 
659