diff options
author | Tor Lillqvist <tml@collabora.com> | 2013-12-05 22:01:05 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2013-12-06 15:05:00 +0200 |
commit | c49721950cb3d897b35f08bf871239308680b18e (patch) | |
tree | 6a76e91557328b9195960d065065b1a6914bf9be /vcl/coretext | |
parent | 693eced961a3d3014d15e0a406f4e001ee817522 (diff) |
Re-organize OS X and iOS code in vcl a bit
Now with the ATSUI code gone is a good time for some
re-organisation. Get rid of "aqua" in file names and the separate
"coretext" folders. CoreText is all we use now for OS X (and has
always been so for iOS), so no need for a "coretext" folder, we can
keep the CoreText-using code under "quartz". Keep OS X -specific code
in "osx". Ditto for headers.
Keep "Aqua" as part of class names for now, though.
This is also preparation for planned further unification between OS X
and iOS code.
Change-Id: Ic60bd73fea4ab98183e7c8a09c7d3f66b9a34223
Diffstat (limited to 'vcl/coretext')
-rw-r--r-- | vcl/coretext/ctfonts.cxx | 478 | ||||
-rw-r--r-- | vcl/coretext/ctfonts.hxx | 28 | ||||
-rw-r--r-- | vcl/coretext/ctlayout.cxx | 501 | ||||
-rw-r--r-- | vcl/coretext/salgdi.cxx | 889 |
4 files changed, 0 insertions, 1896 deletions
diff --git a/vcl/coretext/ctfonts.cxx b/vcl/coretext/ctfonts.cxx deleted file mode 100644 index fd113b892099..000000000000 --- a/vcl/coretext/ctfonts.cxx +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <boost/unordered_map.hpp> - -#include "impfont.hxx" -#include "outfont.hxx" -#include "sallayout.hxx" - -#ifdef MACOSX -#include "aqua/salinst.h" -#include "aqua/saldata.hxx" -#endif -#include "coretext/salgdi.h" -#include "quartz/utils.h" -#include "ctfonts.hxx" - -#include "basegfx/polygon/b2dpolygon.hxx" -#include "basegfx/matrix/b2dhommatrix.hxx" - -// ======================================================================= - -inline double toRadian(int nDegree) -{ - return nDegree * (M_PI / 1800.0); -} - -CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD ) -: mpFontData( (CoreTextFontData*)rFSD.mpFontData ) -, mfFontStretch( 1.0 ) -, mfFontRotation( 0.0 ) -, mpStyleDict( NULL ) -{ - mpFontData = (CoreTextFontData*)rFSD.mpFontData; - const FontSelectPattern* const pReqFont = &rFSD; - - double fScaledFontHeight = pReqFont->mfExactHeight; - - // convert font rotation to radian - mfFontRotation = toRadian(pReqFont->mnOrientation); - - // dummy matrix so we can use CGAffineTransformConcat() below - CGAffineTransform aMatrix = CGAffineTransformMakeTranslation(0, 0); - - // handle font stretching if any - if( (pReqFont->mnWidth != 0) && (pReqFont->mnWidth != pReqFont->mnHeight) ) - { - mfFontStretch = (float)pReqFont->mnWidth / pReqFont->mnHeight; - aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMakeScale(mfFontStretch, 1.0F)); - } - - // create the style object for CoreText font attributes - static const CFIndex nMaxDictSize = 16; // TODO: does this really suffice? - mpStyleDict = CFDictionaryCreateMutable( NULL, nMaxDictSize, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); - - CFBooleanRef pCFVertBool = pReqFont->mbVertical ? kCFBooleanTrue : kCFBooleanFalse; - CFDictionarySetValue( mpStyleDict, kCTVerticalFormsAttributeName, pCFVertBool ); - - // fake bold - if ((pReqFont->GetWeight() >= WEIGHT_BOLD) && (mpFontData->GetWeight() < WEIGHT_SEMIBOLD)) - { - int nStroke = -10.0; - CFNumberRef rStroke = CFNumberCreate(NULL, kCFNumberSInt32Type, &nStroke); - CFDictionarySetValue(mpStyleDict, kCTStrokeWidthAttributeName, rStroke); - } - - // fake italic - if (((pReqFont->GetSlant() == ITALIC_NORMAL) || (pReqFont->GetSlant() == ITALIC_OBLIQUE)) - && !((mpFontData->GetSlant() == ITALIC_NORMAL) || (mpFontData->GetSlant() == ITALIC_OBLIQUE))) - { - aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMake(1, 0, toRadian(120), 1, 0, 0)); - } - - CTFontDescriptorRef pFontDesc = (CTFontDescriptorRef)mpFontData->GetFontId(); - CTFontRef pNewCTFont = CTFontCreateWithFontDescriptor( pFontDesc, fScaledFontHeight, &aMatrix ); - CFDictionarySetValue( mpStyleDict, kCTFontAttributeName, pNewCTFont ); - CFRelease( pNewCTFont); - -#if 0 // LastResort is implicit in CoreText's font cascading - const void* aGFBDescriptors[] = { CTFontDescriptorCreateWithNameAndSize( CFSTR("LastResort"), 0) }; // TODO: use the full GFB list - const int nGfbCount = sizeof(aGFBDescriptors) / sizeof(*aGFBDescriptors); - CFArrayRef pGfbList = CFArrayCreate( NULL, aGFBDescriptors, nGfbCount, &kCFTypeArrayCallBacks); - CFDictionaryAddValue( mpStyleDict, kCTFontCascadeListAttribute, pGfbList); - CFRelease( pGfbList); -#endif -} - -// ----------------------------------------------------------------------- - -CoreTextStyle::~CoreTextStyle( void ) -{ - if( mpStyleDict ) - CFRelease( mpStyleDict ); -} - -// ----------------------------------------------------------------------- - -void CoreTextStyle::GetFontMetric( float fPixelSize, ImplFontMetricData& rMetric ) const -{ - // get the matching CoreText font handle - // TODO: is it worth it to cache the CTFontRef in SetFont() and reuse it here? - CTFontRef aCTFontRef = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName ); - - rMetric.mnAscent = lrint( CTFontGetAscent( aCTFontRef ) * fPixelSize); - rMetric.mnDescent = lrint( CTFontGetDescent( aCTFontRef ) * fPixelSize); - rMetric.mnExtLeading = lrint( CTFontGetLeading( aCTFontRef ) * fPixelSize); - rMetric.mnIntLeading = 0; - // since ImplFontMetricData::mnWidth is only used for stretching/squeezing fonts - // setting this width to the pixel height of the fontsize is good enough - // it also makes the calculation of the stretch factor simple - rMetric.mnWidth = lrint( CTFontGetSize( aCTFontRef ) * fPixelSize * mfFontStretch); - - // all CoreText fonts are scalable - rMetric.mbScalableFont = true; - rMetric.mbKernableFont = true; -} - -// ----------------------------------------------------------------------- - -bool CoreTextStyle::GetGlyphBoundRect( sal_GlyphId nGlyphId, Rectangle& rRect ) const -{ - CGGlyph nCGGlyph = nGlyphId & GF_IDXMASK; - // XXX: this is broken if the glyph came from fallback font - CTFontRef aCTFontRef = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName ); - - const CTFontOrientation aFontOrientation = kCTFontDefaultOrientation; // TODO: horz/vert - const CGRect aCGRect = CTFontGetBoundingRectsForGlyphs( aCTFontRef, aFontOrientation, &nCGGlyph, NULL, 1 ); - - rRect.Left() = lrint( aCGRect.origin.x ); - rRect.Top() = lrint( aCGRect.origin.y ); - rRect.Right() = lrint( aCGRect.origin.x + aCGRect.size.width ); - rRect.Bottom() = lrint( aCGRect.origin.y + aCGRect.size.height ); - return true; -} - -// ----------------------------------------------------------------------- - -// callbacks from CTFontCreatePathForGlyph+CGPathApply for GetGlyphOutline() -struct GgoData { basegfx::B2DPolygon maPolygon; basegfx::B2DPolyPolygon* mpPolyPoly; }; - -static void MyCGPathApplierFunc( void* pData, const CGPathElement* pElement ) -{ - basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon; - const int nPointCount = rPolygon.count(); - - switch( pElement->type ) - { - case kCGPathElementCloseSubpath: - case kCGPathElementMoveToPoint: - if( nPointCount > 0 ) { - static_cast<GgoData*>(pData)->mpPolyPoly->append( rPolygon ); - rPolygon.clear(); - } - // fall through for kCGPathElementMoveToPoint: - if( pElement->type != kCGPathElementMoveToPoint ) - break; - case kCGPathElementAddLineToPoint: - rPolygon.append( basegfx::B2DPoint( +pElement->points[0].x, -pElement->points[0].y ) ); - break; - case kCGPathElementAddCurveToPoint: - rPolygon.append( basegfx::B2DPoint( +pElement->points[2].x, -pElement->points[2].y ) ); - rPolygon.setNextControlPoint( nPointCount-1, basegfx::B2DPoint( pElement->points[0].x, -pElement->points[0].y ) ); - rPolygon.setPrevControlPoint( nPointCount+0, basegfx::B2DPoint( pElement->points[1].x, -pElement->points[1].y ) ); - break; - case kCGPathElementAddQuadCurveToPoint: { - const basegfx::B2DPoint aStartPt = rPolygon.getB2DPoint( nPointCount-1 ); - const basegfx::B2DPoint aCtrPt1( (aStartPt.getX() + 2* pElement->points[0].x) / 3.0, - (aStartPt.getY() - 2 * pElement->points[0].y) / 3.0 ); - const basegfx::B2DPoint aCtrPt2( (+2 * +pElement->points[0].x + pElement->points[1].x) / 3.0, - (-2 * pElement->points[0].y - pElement->points[1].y) / 3.0 ); - rPolygon.append( basegfx::B2DPoint( +pElement->points[1].x, -pElement->points[1].y ) ); - rPolygon.setNextControlPoint( nPointCount-1, aCtrPt1 ); - rPolygon.setPrevControlPoint( nPointCount+0, aCtrPt2 ); - } break; - } -} - -bool CoreTextStyle::GetGlyphOutline( sal_GlyphId nGlyphId, basegfx::B2DPolyPolygon& rResult ) const -{ - rResult.clear(); - - CGGlyph nCGGlyph = nGlyphId & GF_IDXMASK; - // XXX: this is broken if the glyph came from fallback font - CTFontRef pCTFont = (CTFontRef)CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName ); - CGPathRef xPath = CTFontCreatePathForGlyph( pCTFont, nCGGlyph, NULL ); - - GgoData aGgoData; - aGgoData.mpPolyPoly = &rResult; - CGPathApply( xPath, (void*)&aGgoData, MyCGPathApplierFunc ); -#if 0 // TODO: does OSX ensure that the last polygon is always closed? - const CGPathElement aClosingElement = { kCGPathElementCloseSubpath, NULL }; - MyCGPathApplierFunc( (void*)&aGgoData, &aClosingElement ); -#endif - - return true; -} - -// ----------------------------------------------------------------------- - -void CoreTextStyle::SetTextColor( const RGBAColor& rColor ) -{ - CGFloat aColor[] = { rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue(), rColor.GetAlpha() }; - CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); - CGColorRef pCGColor = CGColorCreate( cs, aColor ); - CGColorSpaceRelease( cs ); - CFDictionarySetValue( mpStyleDict, kCTForegroundColorAttributeName, pCGColor ); - CFRelease( pCGColor); -} - -// ======================================================================= - -PhysicalFontFace* CoreTextFontData::Clone( void ) const -{ - return new CoreTextFontData( *this); -} - -// ----------------------------------------------------------------------- - -CoreTextStyle* CoreTextFontData::CreateTextStyle( const FontSelectPattern& rFSD ) const -{ - return new CoreTextStyle( rFSD); -} - -// ----------------------------------------------------------------------- - -ImplFontEntry* CoreTextFontData::CreateFontInstance( /*const*/ FontSelectPattern& rFSD ) const -{ - return new ImplFontEntry( rFSD); -} - -// ----------------------------------------------------------------------- - -int CoreTextFontData::GetFontTable( const char pTagName[5], unsigned char* pResultBuf ) const -{ - DBG_ASSERT( pTagName[4]=='\0', "CoreTextFontData::GetFontTable with invalid tagname!\n" ); - - const CTFontTableTag nTagCode = (pTagName[0]<<24) + (pTagName[1]<<16) + (pTagName[2]<<8) + (pTagName[3]<<0); - - // get the raw table length - CTFontDescriptorRef pFontDesc = reinterpret_cast<CTFontDescriptorRef>( GetFontId()); - CTFontRef rCTFont = CTFontCreateWithFontDescriptor( pFontDesc, 0.0, NULL); -#if defined(MACOSX) && MACOSX_SDK_VERSION < 1080 - const uint32_t opts( kCTFontTableOptionExcludeSynthetic ); -#else - const uint32_t opts( kCTFontTableOptionNoOptions ); -#endif - CFDataRef pDataRef = CTFontCopyTable( rCTFont, nTagCode, opts); - CFRelease( rCTFont); - if( !pDataRef) - return 0; - - const CFIndex nByteLength = CFDataGetLength( pDataRef); - - // get the raw table data if requested - if( pResultBuf && (nByteLength > 0)) - { - const CFRange aFullRange = CFRangeMake( 0, nByteLength); - CFDataGetBytes( pDataRef, aFullRange, (UInt8*)pResultBuf); - } - - CFRelease( pDataRef); - - return (int)nByteLength; -} - -// ======================================================================= - -ImplDevFontAttributes DevFontFromCTFontDescriptor( CTFontDescriptorRef pFD, bool* bFontEnabled ) -{ - // all CoreText fonts are device fonts that can rotate just fine - ImplDevFontAttributes rDFA; - rDFA.mbOrientation = true; - rDFA.mbDevice = true; - rDFA.mnQuality = 0; - - // reset the font attributes - rDFA.SetFamilyType( FAMILY_DONTKNOW ); - rDFA.SetPitch( PITCH_VARIABLE ); - rDFA.SetWidthType( WIDTH_NORMAL ); - rDFA.SetWeight( WEIGHT_NORMAL ); - rDFA.SetItalic( ITALIC_NONE ); - rDFA.SetSymbolFlag( false ); - - // all scalable fonts on this platform are subsettable - rDFA.mbEmbeddable = false; - rDFA.mbSubsettable = true; - - // get font name - CFStringRef pFamilyName = (CFStringRef)CTFontDescriptorCopyAttribute( pFD, kCTFontFamilyNameAttribute ); - rDFA.SetFamilyName( GetOUString( pFamilyName ) ); - // get font style - CFStringRef pStyleName = (CFStringRef)CTFontDescriptorCopyAttribute( pFD, kCTFontStyleNameAttribute ); - rDFA.SetStyleName( GetOUString( pStyleName ) ); - - // get font-enabled status - if( bFontEnabled ) { - int bEnabled = FALSE; - CFNumberRef pEnabled = (CFNumberRef)CTFontDescriptorCopyAttribute( pFD, kCTFontEnabledAttribute ); - CFNumberGetValue( pEnabled, kCFNumberIntType, &bEnabled ); - *bFontEnabled = bEnabled; - } - - // get font attributes - CFDictionaryRef pAttrDict = (CFDictionaryRef)CTFontDescriptorCopyAttribute( pFD, kCTFontTraitsAttribute ); - - // get symbolic trait - // TODO: use other traits such as MonoSpace/Condensed/Expanded or Vertical too - SInt64 nSymbolTrait = 0; - CFNumberRef pSymbolNum = NULL; - if( CFDictionaryGetValueIfPresent( pAttrDict, kCTFontSymbolicTrait, (const void**)&pSymbolNum ) ) { - CFNumberGetValue( pSymbolNum, kCFNumberSInt64Type, &nSymbolTrait ); - rDFA.SetSymbolFlag( ((nSymbolTrait & kCTFontClassMaskTrait) == kCTFontSymbolicClass) ); - } - - // get the font weight - double fWeight = 0; - CFNumberRef pWeightNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontWeightTrait ); - CFNumberGetValue( pWeightNum, kCFNumberDoubleType, &fWeight ); - int nInt = WEIGHT_NORMAL; - if( fWeight > 0 ) { - nInt = rint(WEIGHT_NORMAL + fWeight * ((WEIGHT_BLACK - WEIGHT_NORMAL)/0.68)); - if( nInt > WEIGHT_BLACK ) - nInt = WEIGHT_BLACK; - } else if( fWeight < 0 ) { - nInt = rint(WEIGHT_NORMAL + fWeight * ((WEIGHT_NORMAL - WEIGHT_THIN)/0.9)); - if( nInt < WEIGHT_THIN ) - nInt = WEIGHT_THIN; - } - rDFA.SetWeight( (FontWeight)nInt ); - - // get the font slant - double fSlant = 0; - CFNumberRef pSlantNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontSlantTrait ); - CFNumberGetValue( pSlantNum, kCFNumberDoubleType, &fSlant ); - if( fSlant >= 0.035 ) - rDFA.SetItalic( ITALIC_NORMAL ); - - // get width trait - double fWidth = 0; - CFNumberRef pWidthNum = (CFNumberRef)CFDictionaryGetValue( pAttrDict, kCTFontWidthTrait ); - CFNumberGetValue( pWidthNum, kCFNumberDoubleType, &fWidth ); - nInt = WIDTH_NORMAL; - if( fWidth > 0 ) { - nInt = rint( WIDTH_NORMAL + fWidth * ((WIDTH_ULTRA_EXPANDED - WIDTH_NORMAL)/0.4)); - if( nInt > WIDTH_ULTRA_EXPANDED ) - nInt = WIDTH_ULTRA_EXPANDED; - } else if( fWidth < 0 ) { - nInt = rint( WIDTH_NORMAL + fWidth * ((WIDTH_NORMAL - WIDTH_ULTRA_CONDENSED)/0.5)); - if( nInt < WIDTH_ULTRA_CONDENSED ) - nInt = WIDTH_ULTRA_CONDENSED; - } - rDFA.SetWidthType( (FontWidth)nInt ); - - // release the attribute dict that we had copied - CFRelease( pAttrDict ); - - // TODO? also use the HEAD table if available to get more attributes -// CFDataRef CTFontCopyTable( CTFontRef, kCTFontTableHead, /*kCTFontTableOptionNoOptions*/kCTFontTableOptionExcludeSynthetic ); - - return rDFA; -} - -static void CTFontEnumCallBack( const void* pValue, void* pContext ) -{ - CTFontDescriptorRef pFD = static_cast<CTFontDescriptorRef>(pValue); - - bool bFontEnabled; - ImplDevFontAttributes rDFA = DevFontFromCTFontDescriptor( pFD, &bFontEnabled ); - - if( bFontEnabled) - { - const sal_IntPtr nFontId = (sal_IntPtr)pValue; - CoreTextFontData* pFontData = new CoreTextFontData( rDFA, nFontId ); - SystemFontList* pFontList = (SystemFontList*)pContext; - pFontList->AddFont( pFontData ); - } -} - -// ======================================================================= - -SystemFontList::SystemFontList() -: mpCTFontCollection( NULL ) -, mpCTFontArray( NULL ) -{} - -// ----------------------------------------------------------------------- - -SystemFontList::~SystemFontList() -{ - CTFontContainer::const_iterator it = maFontContainer.begin(); - for(; it != maFontContainer.end(); ++it ) - delete (*it).second; - maFontContainer.clear(); - - if( mpCTFontArray ) - CFRelease( mpCTFontArray ); - if( mpCTFontCollection ) - CFRelease( mpCTFontCollection ); -} - -// ----------------------------------------------------------------------- - -void SystemFontList::AddFont( CoreTextFontData* pFontData ) -{ - sal_IntPtr nFontId = pFontData->GetFontId(); - maFontContainer[ nFontId ] = pFontData; -} - -// ----------------------------------------------------------------------- - -void SystemFontList::AnnounceFonts( ImplDevFontList& rFontList ) const -{ - CTFontContainer::const_iterator it = maFontContainer.begin(); - for(; it != maFontContainer.end(); ++it ) - rFontList.Add( (*it).second->Clone() ); -} - -// ----------------------------------------------------------------------- - -CoreTextFontData* SystemFontList::GetFontDataFromId( sal_IntPtr nFontId ) const -{ - CTFontContainer::const_iterator it = maFontContainer.find( nFontId ); - if( it == maFontContainer.end() ) - return NULL; - return (*it).second; -} - -// ----------------------------------------------------------------------- - -bool SystemFontList::Init( void ) -{ - // enumerate available system fonts - static const int nMaxDictEntries = 8; - CFMutableDictionaryRef pCFDict = CFDictionaryCreateMutable( NULL, - nMaxDictEntries, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); - CFDictionaryAddValue( pCFDict, kCTFontCollectionRemoveDuplicatesOption, kCFBooleanTrue ); - mpCTFontCollection = CTFontCollectionCreateFromAvailableFonts( pCFDict ); - CFRelease( pCFDict ); - - mpCTFontArray = CTFontCollectionCreateMatchingFontDescriptors( mpCTFontCollection ); - const int nFontCount = CFArrayGetCount( mpCTFontArray ); - const CFRange aFullRange = CFRangeMake( 0, nFontCount ); - CFArrayApplyFunction( mpCTFontArray, aFullRange, CTFontEnumCallBack, this ); - - return true; -} - -// ======================================================================= - -SystemFontList* GetCoretextFontList( void ) -{ - SystemFontList* pList = new SystemFontList(); - if( !pList->Init() ) { - delete pList; - return NULL; - } - - return pList; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/coretext/ctfonts.hxx b/vcl/coretext/ctfonts.hxx deleted file mode 100644 index 44153115bb94..000000000000 --- a/vcl/coretext/ctfonts.hxx +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "coretext/salgdi.h" -#ifdef IOS -#include "headless/svpgdi.hxx" -#endif -#include "sallayout.hxx" - -SystemFontList* GetCoretextFontList(void); -ImplDevFontAttributes DevFontFromCTFontDescriptor( CTFontDescriptorRef, bool* ); -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/coretext/ctlayout.cxx b/vcl/coretext/ctlayout.cxx deleted file mode 100644 index 56d86967aa53..000000000000 --- a/vcl/coretext/ctlayout.cxx +++ /dev/null @@ -1,501 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "tools/debug.hxx" - -#include "ctfonts.hxx" - -class CTLayout -: public SalLayout -{ -public: - explicit CTLayout( const CoreTextStyle* ); - virtual ~CTLayout( void ); - - virtual bool LayoutText( ImplLayoutArgs& ); - virtual void AdjustLayout( ImplLayoutArgs& ); - virtual void DrawText( SalGraphics& ) const; - - virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&, - sal_Int32* pGlyphAdvances, int* pCharIndexes, - const PhysicalFontFace** pFallbackFonts ) const; - - virtual long GetTextWidth() const; - virtual long FillDXArray( sal_Int32* pDXArray ) const; - virtual sal_Int32 GetTextBreak(long nMaxWidth, long nCharExtra, int nFactor) const SAL_OVERRIDE; - virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const; - virtual bool GetGlyphOutlines( SalGraphics&, PolyPolyVector& ) const; - virtual bool GetBoundRect( SalGraphics&, Rectangle& ) const; - - virtual void InitFont( void) const; - virtual void MoveGlyph( int nStart, long nNewXPos ); - virtual void DropGlyph( int nStart ); - virtual void Simplify( bool bIsBase ); - -private: - CGPoint GetTextDrawPosition(void) const; - double GetWidth(void) const; - - const CoreTextStyle* const mpTextStyle; - - // CoreText specific objects - CFAttributedStringRef mpAttrString; - CTLineRef mpCTLine; - - int mnCharCount; // ==mnEndCharPos-mnMinCharPos - - // cached details about the resulting layout - // mutable members since these details are all lazy initialized - mutable double mfCachedWidth; // cached value of resulting typographical width - - // x-offset relative to layout origin - // currently only used in RTL-layouts - mutable double mfBaseAdv; -}; - -CTLayout::CTLayout( const CoreTextStyle* pTextStyle ) -: mpTextStyle( pTextStyle ) -, mpAttrString( NULL ) -, mpCTLine( NULL ) -, mnCharCount( 0 ) -, mfCachedWidth( -1 ) -, mfBaseAdv( 0 ) -{ -} - -CTLayout::~CTLayout() -{ - if( mpCTLine ) - CFRelease( mpCTLine ); - if( mpAttrString ) - CFRelease( mpAttrString ); -} - -bool CTLayout::LayoutText( ImplLayoutArgs& rArgs ) -{ - if( mpAttrString ) - CFRelease( mpAttrString ); - mpAttrString = NULL; - if( mpCTLine ) - CFRelease( mpCTLine ); - mpCTLine = NULL; - - SalLayout::AdjustLayout( rArgs ); - mnCharCount = mnEndCharPos - mnMinCharPos; - - // short circuit if there is nothing to do - if( mnCharCount <= 0 ) - return false; - - // create the CoreText line layout - CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, rArgs.mpStr + mnMinCharPos, mnCharCount, kCFAllocatorNull ); - // CFAttributedStringCreate copies the attribues parameter - mpAttrString = CFAttributedStringCreate( NULL, aCFText, mpTextStyle->GetStyleDict() ); - mpCTLine = CTLineCreateWithAttributedString( mpAttrString ); - CFRelease( aCFText); - - return true; -} - -void CTLayout::AdjustLayout( ImplLayoutArgs& rArgs ) -{ - if( !mpCTLine) - return; - - int nOrigWidth = GetTextWidth(); - int nPixelWidth = rArgs.mnLayoutWidth; - if( nPixelWidth ) - { - if( nPixelWidth <= 0) - return; - } - else if( rArgs.mpDXArray ) - { - // for now we are only interested in the layout width - // TODO: use all mpDXArray elements for layouting - nPixelWidth = rArgs.mpDXArray[ mnCharCount - 1 ]; - } - - float fTrailingSpace = CTLineGetTrailingWhitespaceWidth( mpCTLine ); - // in RTL-layouts trailing spaces are leftmost - // TODO: use BiDi-algorithm to thoroughly check this assumption - if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL) - mfBaseAdv = fTrailingSpace; - - // return early if there is nothing to do - if( nPixelWidth <= 0 ) - return; - - // HACK: justification requests which change the width by just one pixel are probably - // #i86038# introduced by lossy conversions between integer based coordinate system - if( (nOrigWidth >= nPixelWidth-1) && (nOrigWidth <= nPixelWidth+1) ) - return; - - CTLineRef pNewCTLine = CTLineCreateJustifiedLine( mpCTLine, 1.0, nPixelWidth - fTrailingSpace ); - if( !pNewCTLine ) { // CTLineCreateJustifiedLine can and does fail - // handle failure by keeping the unjustified layout - // TODO: a better solution such as - // - forcing glyph overlap - // - changing the font size - // - changing the CTM matrix - return; - } - CFRelease( mpCTLine ); - mpCTLine = pNewCTLine; - mfCachedWidth = nPixelWidth; -} - -// When drawing right aligned text, rounding errors in the position returned by -// GetDrawPosition() cause the right margin of the text to change whenever text -// width changes causing "jumping letters" effect. So here we calculate the -// drawing position relative to the right margin on our own to avoid the -// rounding errors. That is basically a hack, and it should go away if one day -// we managed to get rid of those rounding errors. -// -// We continue using GetDrawPosition() for non-right aligned text, to minimize -// any unforeseen side effects. -CGPoint CTLayout::GetTextDrawPosition(void) const -{ - float fPosX, fPosY; - - if (mnLayoutFlags & SAL_LAYOUT_RIGHT_ALIGN) - { - // text is always drawn at its leftmost point - const Point aPos = DrawBase(); - fPosX = aPos.X() + mfBaseAdv - GetWidth(); - fPosY = aPos.Y(); - } - else - { - const Point aPos = GetDrawPosition(Point(mfBaseAdv, 0)); - fPosX = aPos.X(); - fPosY = aPos.Y(); - } - - CGPoint aTextPos = { +fPosX, -fPosY }; - return aTextPos; -} - -void CTLayout::DrawText( SalGraphics& rGraphics ) const -{ - AquaSalGraphics& rAquaGraphics = static_cast<AquaSalGraphics&>(rGraphics); - - // short circuit if there is nothing to do - if( (mnCharCount <= 0) - || !rAquaGraphics.CheckContext() ) - return; - - // the view is vertically flipped => flipped glyphs - // so apply a temporary transformation that it flips back - // also compensate if the font was size limited - CGContextSaveGState( rAquaGraphics.mrContext ); - CGContextScaleCTM( rAquaGraphics.mrContext, 1.0, -1.0 ); - CGContextSetShouldAntialias( rAquaGraphics.mrContext, !rAquaGraphics.mbNonAntialiasedText ); - - // Draw the text - CGPoint aTextPos = GetTextDrawPosition(); - - if( mpTextStyle->mfFontRotation != 0.0 ) - { - const CGFloat fRadians = mpTextStyle->mfFontRotation; - CGContextRotateCTM( rAquaGraphics.mrContext, +fRadians ); - - const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians ); - aTextPos = CGPointApplyAffineTransform( aTextPos, aInvMatrix ); - } - - CGContextSetTextPosition( rAquaGraphics.mrContext, aTextPos.x, aTextPos.y ); - CTLineDraw( mpCTLine, rAquaGraphics.mrContext ); -#ifndef IOS - // request an update of the changed window area - if( rAquaGraphics.IsWindowGraphics() ) - { - const CGRect aInkRect = CTLineGetImageBounds( mpCTLine, rAquaGraphics.mrContext ); - const CGRect aRefreshRect = CGContextConvertRectToDeviceSpace( rAquaGraphics.mrContext, aInkRect ); - rAquaGraphics.RefreshRect( aRefreshRect ); - } -#endif - // restore the original graphic context transformations - CGContextRestoreGState( rAquaGraphics.mrContext ); -} - -int CTLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIDs, Point& rPos, int& nStart, - sal_Int32* pGlyphAdvances, int* pCharIndexes, - const PhysicalFontFace** pFallbackFonts ) const -{ - if( !mpCTLine ) - return 0; - - if( nStart < 0 ) // first glyph requested? - nStart = 0; - nLen = 1; // TODO: handle nLen>1 below - - // prepare to iterate over the glyph runs - int nCount = 0; - int nSubIndex = nStart; - - typedef std::vector<CGGlyph> CGGlyphVector; - typedef std::vector<CGPoint> CGPointVector; - typedef std::vector<CGSize> CGSizeVector; - typedef std::vector<CFIndex> CFIndexVector; - CGGlyphVector aCGGlyphVec; - CGPointVector aCGPointVec; - CGSizeVector aCGSizeVec; - CFIndexVector aCFIndexVec; - - // TODO: iterate over cached layout - CFArrayRef aGlyphRuns = CTLineGetGlyphRuns( mpCTLine ); - const int nRunCount = CFArrayGetCount( aGlyphRuns ); - for( int nRunIndex = 0; nRunIndex < nRunCount; ++nRunIndex ) { - CTRunRef pGlyphRun = (CTRunRef)CFArrayGetValueAtIndex( aGlyphRuns, nRunIndex ); - const CFIndex nGlyphsInRun = CTRunGetGlyphCount( pGlyphRun ); - // skip to the first glyph run of interest - if( nSubIndex >= nGlyphsInRun ) { - nSubIndex -= nGlyphsInRun; - continue; - } - const CFRange aFullRange = CFRangeMake( 0, nGlyphsInRun ); - - // get glyph run details - const CGGlyph* pCGGlyphIdx = CTRunGetGlyphsPtr( pGlyphRun ); - if( !pCGGlyphIdx ) { - aCGGlyphVec.reserve( nGlyphsInRun ); - CTRunGetGlyphs( pGlyphRun, aFullRange, &aCGGlyphVec[0] ); - pCGGlyphIdx = &aCGGlyphVec[0]; - } - const CGPoint* pCGGlyphPos = CTRunGetPositionsPtr( pGlyphRun ); - if( !pCGGlyphPos ) { - aCGPointVec.reserve( nGlyphsInRun ); - CTRunGetPositions( pGlyphRun, aFullRange, &aCGPointVec[0] ); - pCGGlyphPos = &aCGPointVec[0]; - } - - const CGSize* pCGGlyphAdvs = NULL; - if( pGlyphAdvances) { - pCGGlyphAdvs = CTRunGetAdvancesPtr( pGlyphRun ); - if( !pCGGlyphAdvs) { - aCGSizeVec.reserve( nGlyphsInRun ); - CTRunGetAdvances( pGlyphRun, aFullRange, &aCGSizeVec[0] ); - pCGGlyphAdvs = &aCGSizeVec[0]; - } - } - - const CFIndex* pCGGlyphStrIdx = NULL; - if( pCharIndexes) { - pCGGlyphStrIdx = CTRunGetStringIndicesPtr( pGlyphRun ); - if( !pCGGlyphStrIdx) { - aCFIndexVec.reserve( nGlyphsInRun ); - CTRunGetStringIndices( pGlyphRun, aFullRange, &aCFIndexVec[0] ); - pCGGlyphStrIdx = &aCFIndexVec[0]; - } - } - - const PhysicalFontFace* pFallbackFont = NULL; - if( pFallbackFonts ) { - CFDictionaryRef pRunAttributes = CTRunGetAttributes( pGlyphRun ); - CTFontRef pRunFont = (CTFontRef)CFDictionaryGetValue( pRunAttributes, kCTFontAttributeName ); - - CFDictionaryRef pAttributes = mpTextStyle->GetStyleDict(); - CTFontRef pFont = (CTFontRef)CFDictionaryGetValue( pAttributes, kCTFontAttributeName ); - if ( !CFEqual( pRunFont, pFont ) ) { - CTFontDescriptorRef pFontDesc = CTFontCopyFontDescriptor( pRunFont ); - ImplDevFontAttributes rDevFontAttr = DevFontFromCTFontDescriptor( pFontDesc, NULL ); - pFallbackFont = new CoreTextFontData( rDevFontAttr, (sal_IntPtr)pFontDesc ); - } - } - - // get the details for each interesting glyph - // TODO: handle nLen>1 - for(; (--nLen >= 0) && (nSubIndex < nGlyphsInRun); ++nSubIndex, ++nStart ) - { - // convert glyph details for VCL - *(pGlyphIDs++) = pCGGlyphIdx[ nSubIndex ]; - if( pGlyphAdvances ) - *(pGlyphAdvances++) = lrint(pCGGlyphAdvs[ nSubIndex ].width); - if( pCharIndexes ) - *(pCharIndexes++) = pCGGlyphStrIdx[ nSubIndex] + mnMinCharPos; - if( pFallbackFonts ) - *(pFallbackFonts++) = pFallbackFont; - if( !nCount++ ) { - const CGPoint& rCurPos = pCGGlyphPos[ nSubIndex ]; - rPos = GetDrawPosition( Point( rCurPos.x, rCurPos.y) ); - } - } - nSubIndex = 0; // prepare for the next glyph run - break; // TODO: handle nLen>1 - } - - return nCount; -} - -double CTLayout::GetWidth() const -{ - if( (mnCharCount <= 0) || !mpCTLine ) - return 0; - - if( mfCachedWidth < 0.0 ) { - mfCachedWidth = CTLineGetTypographicBounds( mpCTLine, NULL, NULL, NULL); - } - - return mfCachedWidth; -} - -long CTLayout::GetTextWidth() const -{ - return lrint(GetWidth()); -} - -long CTLayout::FillDXArray( sal_Int32* pDXArray ) const -{ - // short circuit requests which don't need full details - if( !pDXArray ) - return GetTextWidth(); - - long nPixWidth = GetTextWidth(); - if( pDXArray ) { - // initialize the result array - for( int i = 0; i < mnCharCount; ++i) - pDXArray[i] = 0; - // handle each glyph run - CFArrayRef aGlyphRuns = CTLineGetGlyphRuns( mpCTLine ); - const int nRunCount = CFArrayGetCount( aGlyphRuns ); - typedef std::vector<CGSize> CGSizeVector; - CGSizeVector aSizeVec; - typedef std::vector<CFIndex> CFIndexVector; - CFIndexVector aIndexVec; - for( int nRunIndex = 0; nRunIndex < nRunCount; ++nRunIndex ) { - CTRunRef pGlyphRun = (CTRunRef)CFArrayGetValueAtIndex( aGlyphRuns, nRunIndex ); - const CFIndex nGlyphCount = CTRunGetGlyphCount( pGlyphRun ); - const CFRange aFullRange = CFRangeMake( 0, nGlyphCount ); - aSizeVec.reserve( nGlyphCount ); - aIndexVec.reserve( nGlyphCount ); - CTRunGetAdvances( pGlyphRun, aFullRange, &aSizeVec[0] ); - CTRunGetStringIndices( pGlyphRun, aFullRange, &aIndexVec[0] ); - for( int i = 0; i != nGlyphCount; ++i ) { - const int nRelIdx = aIndexVec[i]; - pDXArray[ nRelIdx ] += lrint(aSizeVec[i].width); - } - } - } - - return nPixWidth; -} - -sal_Int32 CTLayout::GetTextBreak( long nMaxWidth, long /*nCharExtra*/, int nFactor ) const -{ - if( !mpCTLine ) - return -1; - - CTTypesetterRef aCTTypeSetter = CTTypesetterCreateWithAttributedString( mpAttrString ); - const double fCTMaxWidth = (double)nMaxWidth / nFactor; - CFIndex nIndex = CTTypesetterSuggestClusterBreak( aCTTypeSetter, 0, fCTMaxWidth ); - if( nIndex >= mnCharCount ) - return -1; - - nIndex += mnMinCharPos; - return nIndex; -} - -void CTLayout::GetCaretPositions( int nMaxIndex, sal_Int32* pCaretXArray ) const -{ - DBG_ASSERT( ((nMaxIndex>0)&&!(nMaxIndex&1)), - "CTLayout::GetCaretPositions() : invalid number of caret pairs requested"); - - // initialize the caret positions - for( int i = 0; i < nMaxIndex; ++i ) - pCaretXArray[ i ] = -1; - - for( int n = 0; n <= mnCharCount; ++n ) - { - // measure the characters cursor position - CGFloat fPos2 = -1; - const CGFloat fPos1 = CTLineGetOffsetForStringIndex( mpCTLine, n, &fPos2 ); - (void)fPos2; // TODO: split cursor at line direction change - // update previous trailing position - if( n > 0 ) - pCaretXArray[ 2*n-1 ] = lrint( fPos1 ); - // update current leading position - if( 2*n >= nMaxIndex ) - break; - pCaretXArray[ 2*n+0 ] = lrint( fPos1 ); - } -} - -bool CTLayout::GetBoundRect( SalGraphics& rGraphics, Rectangle& rVCLRect ) const -{ - // Closely mimic DrawText(), except that instead of calling - // CTLineDraw() to draw the line, we call CTLineGetImageBounds() - // to get its bounds. But all the coordinate system manipulation - // before that is the same => should be factored out? - - AquaSalGraphics& rAquaGraphics = static_cast<AquaSalGraphics&>(rGraphics); - - if( !rAquaGraphics.CheckContext() ) - return false; - - CGContextSaveGState( rAquaGraphics.mrContext ); - CGContextScaleCTM( rAquaGraphics.mrContext, 1.0, -1.0 ); - CGContextSetShouldAntialias( rAquaGraphics.mrContext, !rAquaGraphics.mbNonAntialiasedText ); - - const CGPoint aVclPos = GetTextDrawPosition(); - CGPoint aTextPos = GetTextDrawPosition(); - - if( mpTextStyle->mfFontRotation != 0.0 ) - { - const CGFloat fRadians = mpTextStyle->mfFontRotation; - CGContextRotateCTM( rAquaGraphics.mrContext, +fRadians ); - - const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians ); - aTextPos = CGPointApplyAffineTransform( aTextPos, aInvMatrix ); - } - - CGContextSetTextPosition( rAquaGraphics.mrContext, aTextPos.x, aTextPos.y ); - CGRect aMacRect = CTLineGetImageBounds( mpCTLine, rAquaGraphics.mrContext ); - - if( mpTextStyle->mfFontRotation != 0.0 ) - { - const CGFloat fRadians = mpTextStyle->mfFontRotation; - const CGAffineTransform aMatrix = CGAffineTransformMakeRotation( +fRadians ); - aMacRect = CGRectApplyAffineTransform( aMacRect, aMatrix ); - } - - CGContextRestoreGState( rAquaGraphics.mrContext ); - - rVCLRect.Left() = aVclPos.x + lrint(aMacRect.origin.x); - rVCLRect.Right() = aVclPos.x + lrint(aMacRect.origin.x + aMacRect.size.width); - rVCLRect.Bottom() = aVclPos.x - lrint(aMacRect.origin.y); - rVCLRect.Top() = aVclPos.x - lrint(aMacRect.origin.y + aMacRect.size.height); - - return true; -} - -// glyph fallback is supported directly by Aqua -// so methods used only by MultiSalLayout can be dummy implementated -bool CTLayout::GetGlyphOutlines( SalGraphics&, PolyPolyVector& ) const { return false; } -void CTLayout::InitFont() const {} -void CTLayout::MoveGlyph( int /*nStart*/, long /*nNewXPos*/ ) {} -void CTLayout::DropGlyph( int /*nStart*/ ) {} -void CTLayout::Simplify( bool /*bIsBase*/ ) {} - -SalLayout* CoreTextStyle::GetTextLayout( void ) const -{ - return new CTLayout( this); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/coretext/salgdi.cxx b/vcl/coretext/salgdi.cxx deleted file mode 100644 index ee6c834aead9..000000000000 --- a/vcl/coretext/salgdi.cxx +++ /dev/null @@ -1,889 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <config_folders.h> - -#include "sal/config.h" - -#include "osl/file.hxx" -#include "osl/process.h" - -#include "osl/mutex.hxx" - -#include "rtl/bootstrap.h" -#include "rtl/strbuf.hxx" - -#include "basegfx/range/b2drectangle.hxx" -#include "basegfx/polygon/b2dpolygon.hxx" -#include "basegfx/polygon/b2dpolygontools.hxx" -#include "basegfx/matrix/b2dhommatrix.hxx" -#include "basegfx/matrix/b2dhommatrixtools.hxx" - -#include "vcl/sysdata.hxx" -#include "vcl/svapp.hxx" - -#include "coretext/salgdi.h" - -#ifdef MACOSX -#include "aqua/salframe.h" -#endif - -#ifdef IOS -#include "saldatabasic.hxx" -#include <basebmp/scanlineformats.hxx> -#endif - -#include "ctfonts.hxx" - -#include "fontsubset.hxx" -#include "impfont.hxx" -#include "sallayout.hxx" -#include "sft.hxx" - - -using namespace vcl; - -// ======================================================================= - -CoreTextFontData::CoreTextFontData( const CoreTextFontData& rSrc ) -: PhysicalFontFace( rSrc ) -, mnFontId( rSrc.mnFontId ) -, mpCharMap( rSrc.mpCharMap ) -, mbOs2Read( rSrc.mbOs2Read ) -, mbHasOs2Table( rSrc.mbHasOs2Table ) -, mbCmapEncodingRead( rSrc.mbCmapEncodingRead ) -{ - if( mpCharMap ) - mpCharMap->AddReference(); -} - -// ----------------------------------------------------------------------- - -CoreTextFontData::CoreTextFontData( const ImplDevFontAttributes& rDFA, sal_IntPtr nFontId ) -: PhysicalFontFace( rDFA, 0 ) -, mnFontId( nFontId ) -, mpCharMap( NULL ) -, mbOs2Read( false ) -, mbHasOs2Table( false ) -, mbCmapEncodingRead( false ) -, mbFontCapabilitiesRead( false ) -{ -} - -// ----------------------------------------------------------------------- - -CoreTextFontData::~CoreTextFontData() -{ - if( mpCharMap ) - mpCharMap->DeReference(); -} - -// ----------------------------------------------------------------------- - -sal_IntPtr CoreTextFontData::GetFontId() const -{ - return (sal_IntPtr)mnFontId; -} - -// ----------------------------------------------------------------------- - -static unsigned GetUShort( const unsigned char* p ){return((p[0]<<8)+p[1]);} - -const ImplFontCharMap* CoreTextFontData::GetImplFontCharMap() const -{ - // return the cached charmap - if( mpCharMap ) - return mpCharMap; - - // set the default charmap - mpCharMap = ImplFontCharMap::GetDefaultMap(); - mpCharMap->AddReference(); - - // get the CMAP byte size - // allocate a buffer for the CMAP raw data - const int nBufSize = GetFontTable( "cmap", NULL ); - DBG_ASSERT( (nBufSize > 0), "CoreTextFontData::GetImplFontCharMap : GetFontTable1 failed!\n"); - if( nBufSize <= 0 ) - return mpCharMap; - - // get the CMAP raw data - ByteVector aBuffer( nBufSize ); - const int nRawLength = GetFontTable( "cmap", &aBuffer[0] ); - DBG_ASSERT( (nRawLength > 0), "CoreTextFontData::GetImplFontCharMap : GetFontTable2 failed!\n"); - if( nRawLength <= 0 ) - return mpCharMap; - DBG_ASSERT( (nBufSize==nRawLength), "CoreTextFontData::GetImplFontCharMap : ByteCount mismatch!\n"); - - // parse the CMAP - CmapResult aCmapResult; - if( ParseCMAP( &aBuffer[0], nRawLength, aCmapResult ) ) - { - // create the matching charmap - mpCharMap->DeReference(); - mpCharMap = new ImplFontCharMap( aCmapResult ); - mpCharMap->AddReference(); - } - - return mpCharMap; -} - -bool CoreTextFontData::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const -{ - // read this only once per font - if( mbFontCapabilitiesRead ) - { - rFontCapabilities = maFontCapabilities; - return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty(); - } - mbFontCapabilitiesRead = true; - - int nBufSize = 0; - // prepare to get the GSUB table raw data - nBufSize = GetFontTable( "GSUB", NULL ); - if( nBufSize > 0 ) - { - // allocate a buffer for the GSUB raw data - ByteVector aBuffer( nBufSize ); - // get the GSUB raw data - const int nRawLength = GetFontTable( "GSUB", &aBuffer[0] ); - if( nRawLength > 0 ) - { - const unsigned char* pGSUBTable = &aBuffer[0]; - vcl::getTTScripts(maFontCapabilities.maGSUBScriptTags, pGSUBTable, nRawLength); - } - } - nBufSize = GetFontTable( "OS/2", NULL ); - if( nBufSize > 0 ) - { - // allocate a buffer for the OS/2 raw data - ByteVector aBuffer( nBufSize ); - // get the OS/2 raw data - const int nRawLength = GetFontTable( "OS/2", &aBuffer[0] ); - if( nRawLength > 0 ) - { - const unsigned char* pOS2Table = &aBuffer[0]; - vcl::getTTCoverage( - maFontCapabilities.maUnicodeRange, - maFontCapabilities.maCodePageRange, - pOS2Table, nRawLength); - } - } - rFontCapabilities = maFontCapabilities; - return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty(); -} - -// ----------------------------------------------------------------------- - -void CoreTextFontData::ReadOs2Table( void ) const -{ - // read this only once per font - if( mbOs2Read ) - return; - mbOs2Read = true; - mbHasOs2Table = false; - - // prepare to get the OS/2 table raw data - const int nBufSize = GetFontTable( "OS/2", NULL ); - DBG_ASSERT( (nBufSize > 0), "CoreTextFontData::ReadOs2Table : GetFontTable1 failed!\n"); - if( nBufSize <= 0 ) - return; - - // get the OS/2 raw data - ByteVector aBuffer( nBufSize ); - const int nRawLength = GetFontTable( "cmap", &aBuffer[0] ); - DBG_ASSERT( (nRawLength > 0), "CoreTextFontData::ReadOs2Table : GetFontTable2 failed!\n"); - if( nRawLength <= 0 ) - return; - DBG_ASSERT( (nBufSize==nRawLength), "CoreTextFontData::ReadOs2Table : ByteCount mismatch!\n"); - mbHasOs2Table = true; - - // parse the OS/2 raw data - // TODO: also analyze panose info, etc. -} - -void CoreTextFontData::ReadMacCmapEncoding( void ) const -{ - // read this only once per font - if( mbCmapEncodingRead ) - return; - mbCmapEncodingRead = true; - - const int nBufSize = GetFontTable( "cmap", NULL ); - if( nBufSize <= 0 ) - return; - - // get the CMAP raw data - ByteVector aBuffer( nBufSize ); - const int nRawLength = GetFontTable( "cmap", &aBuffer[0] ); - if( nRawLength < 24 ) - return; - DBG_ASSERT( (nBufSize==nRawLength), "CoreTextFontData::ReadMacCmapEncoding : ByteCount mismatch!\n"); - - const unsigned char* pCmap = &aBuffer[0]; - if( GetUShort( pCmap ) != 0x0000 ) - return; -} - -// ----------------------------------------------------------------------- - -AquaSalGraphics::AquaSalGraphics() -#ifdef MACOSX - : mpFrame( NULL ) - , mxLayer( NULL ) - , mrContext( NULL ) - , mpXorEmulation( NULL ) - , mnXorMode( 0 ) - , mnWidth( 0 ) - , mnHeight( 0 ) - , mnBitmapDepth( 0 ) - , mnRealDPIX( 0 ) - , mnRealDPIY( 0 ) - , mfFakeDPIScale( 1.0 ) - , mxClipPath( NULL ) - , maLineColor( COL_WHITE ) - , maFillColor( COL_BLACK ) - , mpFontData( NULL ) - , mpTextStyle( NULL ) - , maTextColor( COL_BLACK ) - , mbNonAntialiasedText( false ) - , mbPrinter( false ) - , mbVirDev( false ) - , mbWindow( false ) -#else - : mrContext( NULL ) - , mfFakeDPIScale( 1.0 ) - , mpFontData( NULL ) - , mpTextStyle( NULL ) - , maTextColor( COL_BLACK ) - , mbNonAntialiasedText( false ) -#endif -{} - -// ----------------------------------------------------------------------- - -AquaSalGraphics::~AquaSalGraphics() -{ -#ifdef MACOSX - CGPathRelease( mxClipPath ); - delete mpTextStyle; - - if( mpXorEmulation ) - delete mpXorEmulation; - - if( mxLayer ) - CGLayerRelease( mxLayer ); - else if( mrContext && mbWindow ) - { - // destroy backbuffer bitmap context that we created ourself - CGContextRelease( mrContext ); - mrContext = NULL; - } -#endif -} - -// ======================================================================= - -void AquaSalGraphics::SetTextColor( SalColor nSalColor ) -{ - maTextColor = RGBAColor( nSalColor ); - if( mpTextStyle) - mpTextStyle->SetTextColor( maTextColor ); -} - -// ----------------------------------------------------------------------- - -void AquaSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int /*nFallbackLevel*/ ) -{ - mpTextStyle->GetFontMetric( mfFakeDPIScale, *pMetric ); -} - -// ----------------------------------------------------------------------- - -static bool AddTempDevFont(const OUString& rFontFileURL) -{ - OUString aUSytemPath; - OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFontFileURL, aUSytemPath ) ); - OString aCFileName = OUStringToOString( aUSytemPath, RTL_TEXTENCODING_UTF8 ); - - CFStringRef rFontPath = CFStringCreateWithCString(NULL, aCFileName.getStr(), kCFStringEncodingUTF8); - CFURLRef rFontURL = CFURLCreateWithFileSystemPath(NULL, rFontPath, kCFURLPOSIXPathStyle, true); - - CFErrorRef error; - bool success = CTFontManagerRegisterFontsForURL(rFontURL, kCTFontManagerScopeProcess, &error); - - if (!success) - { - CFRelease(error); - return false; - } - - return true; -} - -static void AddTempFontDir( const OUString &rFontDirUrl ) -{ - osl::Directory aFontDir( rFontDirUrl ); - osl::FileBase::RC rcOSL = aFontDir.open(); - if( rcOSL == osl::FileBase::E_None ) - { - osl::DirectoryItem aDirItem; - - while( aFontDir.getNextItem( aDirItem, 10 ) == osl::FileBase::E_None ) - { - osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileURL ); - rcOSL = aDirItem.getFileStatus( aFileStatus ); - if ( rcOSL == osl::FileBase::E_None ) - AddTempDevFont(aFileStatus.getFileURL()); - } - } -} - -static void AddLocalTempFontDirs() -{ - static bool bFirst = true; - if( !bFirst ) - return; - bFirst = false; - - // add private font files - - OUString aBrandStr( "$BRAND_BASE_DIR" ); - rtl_bootstrap_expandMacros( &aBrandStr.pData ); - AddTempFontDir( aBrandStr + "/" LIBO_SHARE_FOLDER "/fonts/truetype/" ); -} - -void AquaSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) -{ - DBG_ASSERT( pFontList, "AquaSalGraphics::GetDevFontList(NULL) !"); - - AddLocalTempFontDirs(); - - // The idea is to cache the list of system fonts once it has been generated. - // SalData seems to be a good place for this caching. However we have to - // carefully make the access to the font list thread-safe. If we register - // a font-change event handler to update the font list in case fonts have - // changed on the system we have to lock access to the list. The right - // way to do that is the solar mutex since GetDevFontList is protected - // through it as should be all event handlers - - SalData* pSalData = GetSalData(); - if( !pSalData->mpFontList ) - pSalData->mpFontList = GetCoretextFontList(); - - // Copy all PhysicalFontFace objects contained in the SystemFontList - pSalData->mpFontList->AnnounceFonts( *pFontList ); -} - -void AquaSalGraphics::ClearDevFontCache() -{ - SalData* pSalData = GetSalData(); - delete pSalData->mpFontList; - pSalData->mpFontList = NULL; -} - -// ----------------------------------------------------------------------- - -bool AquaSalGraphics::AddTempDevFont( ImplDevFontList*, - const OUString& rFontFileURL, const OUString& /*rFontName*/ ) -{ - return ::AddTempDevFont(rFontFileURL); -} - -// ----------------------------------------------------------------------- - -sal_Bool AquaSalGraphics::GetGlyphOutline( sal_GlyphId nGlyphId, basegfx::B2DPolyPolygon& rPolyPoly ) -{ - const bool bRC = mpTextStyle->GetGlyphOutline( nGlyphId, rPolyPoly ); - return bRC; -} - -// ----------------------------------------------------------------------- - -sal_Bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphId, Rectangle& rRect ) -{ - const bool bRC = mpTextStyle->GetGlyphBoundRect( nGlyphId, rRect ); - return bRC; -} - -// ----------------------------------------------------------------------- - -void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& ) -{ -} - -// ----------------------------------------------------------------------- - -sal_uInt16 AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ ) -{ - // release the text style - delete mpTextStyle; - mpTextStyle = NULL; - - // handle NULL request meaning: release-font-resources request - if( !pReqFont ) - { - mpFontData = NULL; - return 0; - } - - // update the text style - mpFontData = static_cast<const CoreTextFontData*>( pReqFont->mpFontData ); - mpTextStyle = mpFontData->CreateTextStyle( *pReqFont ); - mpTextStyle->SetTextColor( maTextColor ); - - SAL_INFO("vcl.coretext", - "SetFont" - << " to " << mpFontData->GetFamilyName() - << ", " << mpFontData->GetStyleName() - << " fontid=" << mpFontData->GetFontId() - << " for " << pReqFont->GetFamilyName() - << ", " << pReqFont->GetStyleName() - << " weight=" << pReqFont->GetWeight() - << " slant=" << pReqFont->GetSlant() - << " size=" << pReqFont->mnHeight << "x" << pReqFont->mnWidth - << " orientation=" << pReqFont->mnOrientation - ); - - return 0; -} - -// ----------------------------------------------------------------------- - -SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs& /*rArgs*/, int /*nFallbackLevel*/ ) -{ - SalLayout* pSalLayout = mpTextStyle->GetTextLayout(); - return pSalLayout; -} - -// ----------------------------------------------------------------------- - -const ImplFontCharMap* AquaSalGraphics::GetImplFontCharMap() const -{ - if( !mpFontData ) - return ImplFontCharMap::GetDefaultMap(); - - return mpFontData->GetImplFontCharMap(); -} - -bool AquaSalGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const -{ - if( !mpFontData ) - return false; - - return mpFontData->GetImplFontCapabilities(rFontCapabilities); -} - -// ----------------------------------------------------------------------- - -// fake a SFNT font directory entry for a font table -// see http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html#Directory -static void FakeDirEntry( const char aTag[5], ByteCount nOfs, ByteCount nLen, - const unsigned char* /*pData*/, unsigned char*& rpDest ) -{ - // write entry tag - rpDest[ 0] = aTag[0]; - rpDest[ 1] = aTag[1]; - rpDest[ 2] = aTag[2]; - rpDest[ 3] = aTag[3]; - // TODO: get entry checksum and write it - // not too important since the subsetter doesn't care currently - // for( pData+nOfs ... pData+nOfs+nLen ) - // write entry offset - rpDest[ 8] = (char)(nOfs >> 24); - rpDest[ 9] = (char)(nOfs >> 16); - rpDest[10] = (char)(nOfs >> 8); - rpDest[11] = (char)(nOfs >> 0); - // write entry length - rpDest[12] = (char)(nLen >> 24); - rpDest[13] = (char)(nLen >> 16); - rpDest[14] = (char)(nLen >> 8); - rpDest[15] = (char)(nLen >> 0); - // advance to next entry - rpDest += 16; -} - -// fake a TTF or CFF font as directly accessing font file is not possible -// when only the fontid is known. This approach also handles *.dfont fonts. -bool AquaSalGraphics::GetRawFontData( const PhysicalFontFace* pFontData, - ByteVector& rBuffer, bool* pJustCFF ) -{ - const CoreTextFontData* pMacFont = static_cast<const CoreTextFontData*>(pFontData); - - // short circuit for CFF-only fonts - const int nCffSize = pMacFont->GetFontTable( "CFF ", NULL); - if( pJustCFF != NULL ) - { - *pJustCFF = (nCffSize > 0); - if( *pJustCFF) - { - rBuffer.resize( nCffSize); - const int nCffRead = pMacFont->GetFontTable( "CFF ", &rBuffer[0]); - if( nCffRead != nCffSize) - return false; - return true; - } - } - - // get font table availability and size in bytes - const int nHeadSize = pMacFont->GetFontTable( "head", NULL); - if( nHeadSize <= 0) - return false; - const int nMaxpSize = pMacFont->GetFontTable( "maxp", NULL); - if( nMaxpSize <= 0) - return false; - const int nCmapSize = pMacFont->GetFontTable( "cmap", NULL); - if( nCmapSize <= 0) - return false; - const int nNameSize = pMacFont->GetFontTable( "name", NULL); - if( nNameSize <= 0) - return false; - const int nHheaSize = pMacFont->GetFontTable( "hhea", NULL); - if( nHheaSize <= 0) - return false; - const int nHmtxSize = pMacFont->GetFontTable( "hmtx", NULL); - if( nHmtxSize <= 0) - return false; - - // get the ttf-glyf outline tables - int nLocaSize = 0; - int nGlyfSize = 0; - if( nCffSize <= 0) - { - nLocaSize = pMacFont->GetFontTable( "loca", NULL); - if( nLocaSize <= 0) - return false; - nGlyfSize = pMacFont->GetFontTable( "glyf", NULL); - if( nGlyfSize <= 0) - return false; - } - - int nPrepSize = 0, nCvtSize = 0, nFpgmSize = 0; - if( nGlyfSize) // TODO: reduce PDF size by making hint subsetting optional - { - nPrepSize = pMacFont->GetFontTable( "prep", NULL); - nCvtSize = pMacFont->GetFontTable( "cvt ", NULL); - nFpgmSize = pMacFont->GetFontTable( "fpgm", NULL); - } - - // prepare a byte buffer for a fake font - int nTableCount = 7; - nTableCount += (nPrepSize>0) + (nCvtSize>0) + (nFpgmSize>0) + (nGlyfSize>0); - const ByteCount nFdirSize = 12 + 16*nTableCount; - ByteCount nTotalSize = nFdirSize; - nTotalSize += nHeadSize + nMaxpSize + nNameSize + nCmapSize; - if( nGlyfSize ) - nTotalSize += nLocaSize + nGlyfSize; - else - nTotalSize += nCffSize; - nTotalSize += nHheaSize + nHmtxSize; - nTotalSize += nPrepSize + nCvtSize + nFpgmSize; - rBuffer.resize( nTotalSize ); - - // fake a SFNT font directory header - if( nTableCount < 16 ) - { - int nLog2 = 0; - while( (nTableCount >> nLog2) > 1 ) ++nLog2; - rBuffer[ 1] = 1; // Win-TTF style scaler - rBuffer[ 5] = nTableCount; // table count - rBuffer[ 7] = nLog2*16; // searchRange - rBuffer[ 9] = nLog2; // entrySelector - rBuffer[11] = (nTableCount-nLog2)*16; // rangeShift - } - - // get font table raw data and update the fake directory entries - ByteCount nOfs = nFdirSize; - unsigned char* pFakeEntry = &rBuffer[12]; - if( nCmapSize != pMacFont->GetFontTable( "cmap", &rBuffer[nOfs])) - return false; - FakeDirEntry( "cmap", nOfs, nCmapSize, &rBuffer[0], pFakeEntry ); - nOfs += nCmapSize; - if( nCvtSize ) { - if( nCvtSize != pMacFont->GetFontTable( "cvt ", &rBuffer[nOfs])) - return false; - FakeDirEntry( "cvt ", nOfs, nCvtSize, &rBuffer[0], pFakeEntry ); - nOfs += nCvtSize; - } - if( nFpgmSize ) { - if( nFpgmSize != pMacFont->GetFontTable( "fpgm", &rBuffer[nOfs])) - return false; - FakeDirEntry( "fpgm", nOfs, nFpgmSize, &rBuffer[0], pFakeEntry ); - nOfs += nFpgmSize; - } - if( nCffSize ) { - if( nCffSize != pMacFont->GetFontTable( "CFF ", &rBuffer[nOfs])) - return false; - FakeDirEntry( "CFF ", nOfs, nCffSize, &rBuffer[0], pFakeEntry ); - nOfs += nGlyfSize; - } else { - if( nGlyfSize != pMacFont->GetFontTable( "glyf", &rBuffer[nOfs])) - return false; - FakeDirEntry( "glyf", nOfs, nGlyfSize, &rBuffer[0], pFakeEntry ); - nOfs += nGlyfSize; - if( nLocaSize != pMacFont->GetFontTable( "loca", &rBuffer[nOfs])) - return false; - FakeDirEntry( "loca", nOfs, nLocaSize, &rBuffer[0], pFakeEntry ); - nOfs += nLocaSize; - } - if( nHeadSize != pMacFont->GetFontTable( "head", &rBuffer[nOfs])) - return false; - FakeDirEntry( "head", nOfs, nHeadSize, &rBuffer[0], pFakeEntry ); - nOfs += nHeadSize; - if( nHheaSize != pMacFont->GetFontTable( "hhea", &rBuffer[nOfs])) - return false; - FakeDirEntry( "hhea", nOfs, nHheaSize, &rBuffer[0], pFakeEntry ); - nOfs += nHheaSize; - if( nHmtxSize != pMacFont->GetFontTable( "hmtx", &rBuffer[nOfs])) - return false; - FakeDirEntry( "hmtx", nOfs, nHmtxSize, &rBuffer[0], pFakeEntry ); - nOfs += nHmtxSize; - if( nMaxpSize != pMacFont->GetFontTable( "maxp", &rBuffer[nOfs])) - return false; - FakeDirEntry( "maxp", nOfs, nMaxpSize, &rBuffer[0], pFakeEntry ); - nOfs += nMaxpSize; - if( nNameSize != pMacFont->GetFontTable( "name", &rBuffer[nOfs])) - return false; - FakeDirEntry( "name", nOfs, nNameSize, &rBuffer[0], pFakeEntry ); - nOfs += nNameSize; - if( nPrepSize ) { - if( nPrepSize != pMacFont->GetFontTable( "prep", &rBuffer[nOfs])) - return false; - FakeDirEntry( "prep", nOfs, nPrepSize, &rBuffer[0], pFakeEntry ); - nOfs += nPrepSize; - } - - DBG_ASSERT( (nOfs==nTotalSize), "AquaSalGraphics::CreateFontSubset (nOfs!=nTotalSize)"); - - return true; -} - -// ----------------------------------------------------------------------- - -void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bVertical, - Int32Vector& rGlyphWidths, Ucs2UIntMap& rUnicodeEnc ) -{ - rGlyphWidths.clear(); - rUnicodeEnc.clear(); - - if( pFontData->IsSubsettable() ) - { - ByteVector aBuffer; - if( !GetRawFontData( pFontData, aBuffer, NULL ) ) - return; - - // TODO: modernize psprint's horrible fontsubset C-API - // this probably only makes sense after the switch to another SCM - // that can preserve change history after file renames - - // use the font subsetter to get the widths - TrueTypeFont* pSftFont = NULL; - int nRC = ::OpenTTFontBuffer( (void*)&aBuffer[0], aBuffer.size(), 0, &pSftFont); - if( nRC != SF_OK ) - return; - - const int nGlyphCount = ::GetTTGlyphCount( pSftFont ); - if( nGlyphCount > 0 ) - { - // get glyph metrics - rGlyphWidths.resize(nGlyphCount); - std::vector<sal_uInt16> aGlyphIds(nGlyphCount); - for( int i = 0; i < nGlyphCount; i++ ) - aGlyphIds[i] = static_cast<sal_uInt16>(i); - const TTSimpleGlyphMetrics* pGlyphMetrics = ::GetTTSimpleGlyphMetrics( - pSftFont, &aGlyphIds[0], nGlyphCount, bVertical ); - if( pGlyphMetrics ) - { - for( int i = 0; i < nGlyphCount; ++i ) - rGlyphWidths[i] = pGlyphMetrics[i].adv; - free( (void*)pGlyphMetrics ); - } - - const ImplFontCharMap* pMap = mpFontData->GetImplFontCharMap(); - DBG_ASSERT( pMap && pMap->GetCharCount(), "no charmap" ); - pMap->AddReference(); // TODO: add and use RAII object instead - - // get unicode<->glyph encoding - // TODO? avoid sft mapping by using the pMap itself - int nCharCount = pMap->GetCharCount(); - sal_uInt32 nChar = pMap->GetFirstChar(); - for(; --nCharCount >= 0; nChar = pMap->GetNextChar( nChar ) ) - { - if( nChar > 0xFFFF ) // TODO: allow UTF-32 chars - break; - sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar); - sal_uInt32 nGlyph = ::MapChar( pSftFont, nUcsChar, bVertical ); - if( nGlyph > 0 ) - rUnicodeEnc[ nUcsChar ] = nGlyph; - } - - pMap->DeReference(); // TODO: add and use RAII object instead - } - - ::CloseTTFont( pSftFont ); - } - else if( pFontData->IsEmbeddable() ) - { - // get individual character widths - OSL_FAIL("not implemented for non-subsettable fonts!\n"); - } -} - -// ----------------------------------------------------------------------- - -const Ucs2SIntMap* AquaSalGraphics::GetFontEncodingVector( - const PhysicalFontFace*, const Ucs2OStrMap** /*ppNonEncoded*/ ) -{ - return NULL; -} - -// ----------------------------------------------------------------------- - -const void* AquaSalGraphics::GetEmbedFontData( const PhysicalFontFace*, - const sal_Ucs* /*pUnicodes*/, - sal_Int32* /*pWidths*/, - FontSubsetInfo&, - long* /*pDataLen*/ ) -{ - return NULL; -} - -// ----------------------------------------------------------------------- - -void AquaSalGraphics::FreeEmbedFontData( const void* pData, long /*nDataLen*/ ) -{ - // TODO: implementing this only makes sense when the implementation of - // AquaSalGraphics::GetEmbedFontData() returns non-NULL - (void)pData; - DBG_ASSERT( (pData!=NULL), "AquaSalGraphics::FreeEmbedFontData() is not implemented\n"); -} - -// ----------------------------------------------------------------------- - -SystemFontData AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const -{ - SystemFontData aSysFontData; - aSysFontData.nSize = sizeof( SystemFontData ); - - aSysFontData.bAntialias = !mbNonAntialiasedText; - - return aSysFontData; -} - -#ifdef IOS - -// Note that "SvpSalGraphics" is actually called AquaSalGraphics for iOS - -bool SvpSalGraphics::CheckContext() -{ - const basegfx::B2IVector size = m_aDevice->getSize(); - const basegfx::B2IVector bufferSize = m_aDevice->getBufferSize(); - const sal_Int32 scanlineStride = m_aDevice->getScanlineStride(); - basebmp::RawMemorySharedArray pixelBuffer = m_aDevice->getBuffer(); - bool warned = false; - - SAL_INFO( "vcl.ios", - "CheckContext: device=" << m_aDevice.get() << - " size=" << size.getX() << "x" << size.getY() << - (m_aDevice->isTopDown() ? " top-down" : " bottom-up") << - " stride=" << scanlineStride << - " bufferSize=(" << bufferSize.getX() << "," << bufferSize.getY() << ")" ); - - switch( m_aDevice->getScanlineFormat() ) { - case basebmp::FORMAT_EIGHT_BIT_PAL: - mrContext = CGBitmapContextCreate(pixelBuffer.get(), - bufferSize.getX(), bufferSize.getY(), - 8, scanlineStride, - CGColorSpaceCreateDeviceGray(), - kCGImageAlphaNone); - break; - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA: - mrContext = CGBitmapContextCreate(pixelBuffer.get(), - bufferSize.getX(), bufferSize.getY(), - 8, scanlineStride, - CGColorSpaceCreateDeviceRGB(), - kCGImageAlphaNoneSkipLast); - break; - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA: - mrContext = CGBitmapContextCreate(pixelBuffer.get(), - bufferSize.getX(), bufferSize.getY(), - 8, scanlineStride, - CGColorSpaceCreateDeviceRGB(), - kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little); - break; - default: - SAL_WARN( "vcl.ios", "CheckContext: unsupported color format " << basebmp::formatName( m_aDevice->getScanlineFormat() ) ); - warned = true; - } - - SAL_WARN_IF( mrContext == NULL && !warned, "vcl.ios", "CheckContext: CGBitmapContextCreate() failed" ); - - // Should we also clip the context? (Then we need to add a - // getBounds() function to BitmapDevice.) - - if( mrContext != NULL && m_aDevice->isTopDown() ) - { - CGContextTranslateCTM( mrContext, 0, bufferSize.getY() ); - CGContextScaleCTM( mrContext, 1, -1 ); - } - - - if (mrContext) - { - RectangleVector aRectangles; - m_aClipRegion.GetRegionRectangles(aRectangles); - - CGContextBeginPath( mrContext ); - - for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter) - { - const long nW(aRectIter->Right() - aRectIter->Left() + 1); // uses +1 logic in original - - if(nW) - { - const long nH(aRectIter->Bottom() - aRectIter->Top() + 1); // uses +1 logic in original - - if(nH) - { - CGRect aRect = {{ (CGFloat) aRectIter->Left(), (CGFloat) aRectIter->Top() }, { (CGFloat) nW, (CGFloat) nH }}; - CGContextAddRect( mrContext, aRect ); - } - } - } - - if (!CGContextIsPathEmpty(mrContext)) - CGContextClip(mrContext); - } - - - SAL_INFO( "vcl.ios", "CheckContext: context=" << mrContext ); - - return ( mrContext != NULL ); -} - -CGContextRef SvpSalGraphics::GetContext() -{ - if ( !mrContext ) - CheckContext(); - - return mrContext; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |