1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_folders.h>
22 #include "sal/config.h"
24 #include "osl/file.hxx"
25 #include "osl/process.h"
27 #include "osl/mutex.hxx"
29 #include "rtl/bootstrap.h"
30 #include "rtl/strbuf.hxx"
32 #include "basegfx/range/b2drectangle.hxx"
33 #include "basegfx/polygon/b2dpolygon.hxx"
34 #include "basegfx/polygon/b2dpolygontools.hxx"
35 #include "basegfx/matrix/b2dhommatrix.hxx"
36 #include "basegfx/matrix/b2dhommatrixtools.hxx"
38 #include "vcl/sysdata.hxx"
39 #include "vcl/svapp.hxx"
40 #include "vcl/metric.hxx"
42 #include "impfont.hxx"
44 #include "quartz/salgdi.h"
45 #include "quartz/utils.h"
48 #include "osx/salframe.h"
52 #include "saldatabasic.hxx"
53 #include <basebmp/scanlineformats.hxx>
56 #include "ctfonts.hxx"
58 #include "fontsubset.hxx"
59 #include "sallayout.hxx"
64 CoreTextFontData::CoreTextFontData( const CoreTextFontData
& rSrc
)
65 : PhysicalFontFace( rSrc
)
66 , mnFontId( rSrc
.mnFontId
)
67 , mbOs2Read( rSrc
.mbOs2Read
)
68 , mbHasOs2Table( rSrc
.mbHasOs2Table
)
69 , mbCmapEncodingRead( rSrc
.mbCmapEncodingRead
)
72 mpCharMap
= rSrc
.mpCharMap
;
75 CoreTextFontData::CoreTextFontData( const ImplDevFontAttributes
& rDFA
, sal_IntPtr nFontId
)
76 : PhysicalFontFace( rDFA
, 0 )
79 , mbHasOs2Table( false )
80 , mbCmapEncodingRead( false )
81 , mbFontCapabilitiesRead( false )
85 CoreTextFontData::~CoreTextFontData()
91 sal_IntPtr
CoreTextFontData::GetFontId() const
93 return (sal_IntPtr
)mnFontId
;
96 static unsigned GetUShort( const unsigned char* p
){return((p
[0]<<8)+p
[1]);}
98 const FontCharMapPtr
CoreTextFontData::GetFontCharMap() const
100 // return the cached charmap
104 // set the default charmap
105 FontCharMapPtr
pCharMap( new FontCharMap() );
106 mpCharMap
= pCharMap
;
108 // get the CMAP byte size
109 // allocate a buffer for the CMAP raw data
110 const int nBufSize
= GetFontTable( "cmap", NULL
);
111 DBG_ASSERT( (nBufSize
> 0), "CoreTextFontData::GetFontCharMap : GetFontTable1 failed!\n");
115 // get the CMAP raw data
116 ByteVector
aBuffer( nBufSize
);
117 const int nRawLength
= GetFontTable( "cmap", &aBuffer
[0] );
118 DBG_ASSERT( (nRawLength
> 0), "CoreTextFontData::GetFontCharMap : GetFontTable2 failed!\n");
119 if( nRawLength
<= 0 )
121 DBG_ASSERT( (nBufSize
==nRawLength
), "CoreTextFontData::GetFontCharMap : ByteCount mismatch!\n");
124 CmapResult aCmapResult
;
125 if( ParseCMAP( &aBuffer
[0], nRawLength
, aCmapResult
) )
127 FontCharMapPtr
pDefFontCharMap( new FontCharMap(aCmapResult
) );
128 // create the matching charmap
129 mpCharMap
= pDefFontCharMap
;
135 bool CoreTextFontData::GetFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const
137 // read this only once per font
138 if( mbFontCapabilitiesRead
)
140 rFontCapabilities
= maFontCapabilities
;
141 return !rFontCapabilities
.maUnicodeRange
.empty() || !rFontCapabilities
.maCodePageRange
.empty();
143 mbFontCapabilitiesRead
= true;
146 // prepare to get the GSUB table raw data
147 nBufSize
= GetFontTable( "GSUB", NULL
);
150 // allocate a buffer for the GSUB raw data
151 ByteVector
aBuffer( nBufSize
);
152 // get the GSUB raw data
153 const int nRawLength
= GetFontTable( "GSUB", &aBuffer
[0] );
156 const unsigned char* pGSUBTable
= &aBuffer
[0];
157 vcl::getTTScripts(maFontCapabilities
.maGSUBScriptTags
, pGSUBTable
, nRawLength
);
160 nBufSize
= GetFontTable( "OS/2", NULL
);
163 // allocate a buffer for the OS/2 raw data
164 ByteVector
aBuffer( nBufSize
);
165 // get the OS/2 raw data
166 const int nRawLength
= GetFontTable( "OS/2", &aBuffer
[0] );
169 const unsigned char* pOS2Table
= &aBuffer
[0];
171 maFontCapabilities
.maUnicodeRange
,
172 maFontCapabilities
.maCodePageRange
,
173 pOS2Table
, nRawLength
);
176 rFontCapabilities
= maFontCapabilities
;
177 return !rFontCapabilities
.maUnicodeRange
.empty() || !rFontCapabilities
.maCodePageRange
.empty();
180 void CoreTextFontData::ReadOs2Table() const
182 // read this only once per font
186 mbHasOs2Table
= false;
188 // prepare to get the OS/2 table raw data
189 const int nBufSize
= GetFontTable( "OS/2", NULL
);
190 DBG_ASSERT( (nBufSize
> 0), "CoreTextFontData::ReadOs2Table : GetFontTable1 failed!\n");
194 // get the OS/2 raw data
195 ByteVector
aBuffer( nBufSize
);
196 const int nRawLength
= GetFontTable( "cmap", &aBuffer
[0] );
197 DBG_ASSERT( (nRawLength
> 0), "CoreTextFontData::ReadOs2Table : GetFontTable2 failed!\n");
198 if( nRawLength
<= 0 )
200 DBG_ASSERT( (nBufSize
==nRawLength
), "CoreTextFontData::ReadOs2Table : ByteCount mismatch!\n");
201 mbHasOs2Table
= true;
203 // parse the OS/2 raw data
204 // TODO: also analyze panose info, etc.
207 void CoreTextFontData::ReadMacCmapEncoding() const
209 // read this only once per font
210 if( mbCmapEncodingRead
)
212 mbCmapEncodingRead
= true;
214 const int nBufSize
= GetFontTable( "cmap", NULL
);
218 // get the CMAP raw data
219 ByteVector
aBuffer( nBufSize
);
220 const int nRawLength
= GetFontTable( "cmap", &aBuffer
[0] );
221 if( nRawLength
< 24 )
223 DBG_ASSERT( (nBufSize
==nRawLength
), "CoreTextFontData::ReadMacCmapEncoding : ByteCount mismatch!\n");
225 const unsigned char* pCmap
= &aBuffer
[0];
226 if( GetUShort( pCmap
) != 0x0000 )
230 AquaSalGraphics::AquaSalGraphics():
236 #if OSL_DEBUG_LEVEL > 0
237 , mnContextStackDepth( 0 )
239 , mpXorEmulation( NULL
)
247 , maLineColor( COL_WHITE
)
248 , maFillColor( COL_BLACK
)
250 , mpTextStyle( NULL
)
251 , maTextColor( COL_BLACK
)
252 , mbNonAntialiasedText( false )
258 , mbForeignContext( false )
261 SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this );
264 AquaSalGraphics::~AquaSalGraphics()
266 SAL_INFO( "vcl.quartz", "AquaSalGraphics::~AquaSalGraphics() this=" << this );
270 CG_TRACE( "CGPathRelease(" << mxClipPath
<< ")" );
271 CGPathRelease( mxClipPath
);
277 delete mpXorEmulation
;
280 if (mbForeignContext
)
285 CG_TRACE( "CGLayerRelease(" << mxLayer
<< ")" );
286 CGLayerRelease( mxLayer
);
294 // destroy backbuffer bitmap context that we created ourself
295 CG_TRACE( "CGContextRelease(" << mrContext
<< ")" );
296 CGContextRelease( mrContext
);
301 SalGraphicsImpl
* AquaSalGraphics::GetImpl() const
306 void AquaSalGraphics::SetTextColor( SalColor nSalColor
)
308 maTextColor
= RGBAColor( nSalColor
);
309 // SAL_ DEBUG(std::hex << nSalColor << std::dec << "={" << maTextColor.GetRed() << ", " << maTextColor.GetGreen() << ", " << maTextColor.GetBlue() << ", " << maTextColor.GetAlpha() << "}");
312 void AquaSalGraphics::GetFontMetric( ImplFontMetricData
* pMetric
, int /*nFallbackLevel*/ )
314 mpTextStyle
->GetFontMetric( *pMetric
);
317 static bool AddTempDevFont(const OUString
& rFontFileURL
)
319 OUString aUSytemPath
;
320 OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFontFileURL
, aUSytemPath
) );
321 OString aCFileName
= OUStringToOString( aUSytemPath
, RTL_TEXTENCODING_UTF8
);
323 CFStringRef rFontPath
= CFStringCreateWithCString(NULL
, aCFileName
.getStr(), kCFStringEncodingUTF8
);
324 CFURLRef rFontURL
= CFURLCreateWithFileSystemPath(NULL
, rFontPath
, kCFURLPOSIXPathStyle
, true);
326 bool success
= false;
329 success
= CTFontManagerRegisterFontsForURL(rFontURL
, kCTFontManagerScopeProcess
, &error
);
338 static void AddTempFontDir( const OUString
&rFontDirUrl
)
340 osl::Directory
aFontDir( rFontDirUrl
);
341 osl::FileBase::RC rcOSL
= aFontDir
.open();
342 if( rcOSL
== osl::FileBase::E_None
)
344 osl::DirectoryItem aDirItem
;
346 while( aFontDir
.getNextItem( aDirItem
, 10 ) == osl::FileBase::E_None
)
348 osl::FileStatus
aFileStatus( osl_FileStatus_Mask_FileURL
);
349 rcOSL
= aDirItem
.getFileStatus( aFileStatus
);
350 if ( rcOSL
== osl::FileBase::E_None
)
351 AddTempDevFont(aFileStatus
.getFileURL());
356 static void AddLocalTempFontDirs()
358 static bool bFirst
= true;
363 // add private font files
365 OUString
aBrandStr( "$BRAND_BASE_DIR" );
366 rtl_bootstrap_expandMacros( &aBrandStr
.pData
);
367 AddTempFontDir( aBrandStr
+ "/" LIBO_SHARE_FOLDER
"/fonts/truetype/" );
370 void AquaSalGraphics::GetDevFontList( PhysicalFontCollection
* pFontCollection
)
372 DBG_ASSERT( pFontCollection
, "AquaSalGraphics::GetDevFontList(NULL) !");
374 AddLocalTempFontDirs();
376 // The idea is to cache the list of system fonts once it has been generated.
377 // SalData seems to be a good place for this caching. However we have to
378 // carefully make the access to the font list thread-safe. If we register
379 // a font-change event handler to update the font list in case fonts have
380 // changed on the system we have to lock access to the list. The right
381 // way to do that is the solar mutex since GetDevFontList is protected
382 // through it as should be all event handlers
384 SalData
* pSalData
= GetSalData();
385 if( !pSalData
->mpFontList
)
386 pSalData
->mpFontList
= GetCoretextFontList();
388 // Copy all PhysicalFontFace objects contained in the SystemFontList
389 pSalData
->mpFontList
->AnnounceFonts( *pFontCollection
);
392 void AquaSalGraphics::ClearDevFontCache()
394 SalData
* pSalData
= GetSalData();
395 delete pSalData
->mpFontList
;
396 pSalData
->mpFontList
= NULL
;
399 bool AquaSalGraphics::AddTempDevFont( PhysicalFontCollection
*,
400 const OUString
& rFontFileURL
, const OUString
& /*rFontName*/ )
402 return ::AddTempDevFont(rFontFileURL
);
405 bool AquaSalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId
, basegfx::B2DPolyPolygon
& rPolyPoly
)
407 const bool bRC
= mpTextStyle
->GetGlyphOutline( aGlyphId
, rPolyPoly
);
411 bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId
, Rectangle
& rRect
)
413 const bool bRC
= mpTextStyle
->GetGlyphBoundRect( aGlyphId
, rRect
);
417 void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout
& )
421 sal_uInt16
AquaSalGraphics::SetFont( FontSelectPattern
* pReqFont
, int /*nFallbackLevel*/ )
423 // release the text style
427 // handle NULL request meaning: release-font-resources request
434 // update the text style
435 mpFontData
= static_cast<const CoreTextFontData
*>( pReqFont
->mpFontData
);
436 mpTextStyle
= new CoreTextStyle( *pReqFont
);
440 " to " << mpFontData
->GetFamilyName()
441 << ", " << mpFontData
->GetStyleName()
442 << " fontid=" << mpFontData
->GetFontId()
443 << " for " << pReqFont
->GetFamilyName()
444 << ", " << pReqFont
->GetStyleName()
445 << " weight=" << pReqFont
->GetWeight()
446 << " slant=" << pReqFont
->GetSlant()
447 << " size=" << pReqFont
->mnHeight
<< "x" << pReqFont
->mnWidth
448 << " orientation=" << pReqFont
->mnOrientation
454 SalLayout
* AquaSalGraphics::GetTextLayout( ImplLayoutArgs
& /*rArgs*/, int /*nFallbackLevel*/ )
456 SalLayout
* pSalLayout
= mpTextStyle
->GetTextLayout();
460 const FontCharMapPtr
AquaSalGraphics::GetFontCharMap() const
464 FontCharMapPtr
pFontCharMap( new FontCharMap() );
468 return mpFontData
->GetFontCharMap();
471 bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const
476 return mpFontData
->GetFontCapabilities(rFontCapabilities
);
479 // fake a SFNT font directory entry for a font table
480 // see http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html#Directory
481 static void FakeDirEntry( const char aTag
[5], ByteCount nOfs
, ByteCount nLen
,
482 const unsigned char* /*pData*/, unsigned char*& rpDest
)
485 rpDest
[ 0] = aTag
[0];
486 rpDest
[ 1] = aTag
[1];
487 rpDest
[ 2] = aTag
[2];
488 rpDest
[ 3] = aTag
[3];
489 // TODO: get entry checksum and write it
490 // not too important since the subsetter doesn't care currently
491 // for( pData+nOfs ... pData+nOfs+nLen )
492 // write entry offset
493 rpDest
[ 8] = (char)(nOfs
>> 24);
494 rpDest
[ 9] = (char)(nOfs
>> 16);
495 rpDest
[10] = (char)(nOfs
>> 8);
496 rpDest
[11] = (char)(nOfs
>> 0);
497 // write entry length
498 rpDest
[12] = (char)(nLen
>> 24);
499 rpDest
[13] = (char)(nLen
>> 16);
500 rpDest
[14] = (char)(nLen
>> 8);
501 rpDest
[15] = (char)(nLen
>> 0);
502 // advance to next entry
506 // fake a TTF or CFF font as directly accessing font file is not possible
507 // when only the fontid is known. This approach also handles *.dfont fonts.
508 bool AquaSalGraphics::GetRawFontData( const PhysicalFontFace
* pFontData
,
509 ByteVector
& rBuffer
, bool* pJustCFF
)
511 const CoreTextFontData
* pMacFont
= static_cast<const CoreTextFontData
*>(pFontData
);
513 // short circuit for CFF-only fonts
514 const int nCffSize
= pMacFont
->GetFontTable( "CFF ", NULL
);
515 if( pJustCFF
!= NULL
)
517 *pJustCFF
= (nCffSize
> 0);
520 rBuffer
.resize( nCffSize
);
521 const int nCffRead
= pMacFont
->GetFontTable( "CFF ", &rBuffer
[0]);
522 if( nCffRead
!= nCffSize
)
528 // get font table availability and size in bytes
529 const int nHeadSize
= pMacFont
->GetFontTable( "head", NULL
);
532 const int nMaxpSize
= pMacFont
->GetFontTable( "maxp", NULL
);
535 const int nCmapSize
= pMacFont
->GetFontTable( "cmap", NULL
);
538 const int nNameSize
= pMacFont
->GetFontTable( "name", NULL
);
541 const int nHheaSize
= pMacFont
->GetFontTable( "hhea", NULL
);
544 const int nHmtxSize
= pMacFont
->GetFontTable( "hmtx", NULL
);
548 // get the ttf-glyf outline tables
553 nLocaSize
= pMacFont
->GetFontTable( "loca", NULL
);
556 nGlyfSize
= pMacFont
->GetFontTable( "glyf", NULL
);
561 int nPrepSize
= 0, nCvtSize
= 0, nFpgmSize
= 0;
562 if( nGlyfSize
) // TODO: reduce PDF size by making hint subsetting optional
564 nPrepSize
= pMacFont
->GetFontTable( "prep", NULL
);
565 nCvtSize
= pMacFont
->GetFontTable( "cvt ", NULL
);
566 nFpgmSize
= pMacFont
->GetFontTable( "fpgm", NULL
);
569 // prepare a byte buffer for a fake font
571 nTableCount
+= (nPrepSize
>0?1:0) + (nCvtSize
>0?1:0) + (nFpgmSize
>0?1:0) + (nGlyfSize
>0?1:0);
572 const ByteCount nFdirSize
= 12 + 16*nTableCount
;
573 ByteCount nTotalSize
= nFdirSize
;
574 nTotalSize
+= nHeadSize
+ nMaxpSize
+ nNameSize
+ nCmapSize
;
576 nTotalSize
+= nLocaSize
+ nGlyfSize
;
578 nTotalSize
+= nCffSize
;
579 nTotalSize
+= nHheaSize
+ nHmtxSize
;
580 nTotalSize
+= nPrepSize
+ nCvtSize
+ nFpgmSize
;
581 rBuffer
.resize( nTotalSize
);
583 // fake a SFNT font directory header
584 if( nTableCount
< 16 )
587 while( (nTableCount
>> nLog2
) > 1 ) ++nLog2
;
588 rBuffer
[ 1] = 1; // Win-TTF style scaler
589 rBuffer
[ 5] = nTableCount
; // table count
590 rBuffer
[ 7] = nLog2
*16; // searchRange
591 rBuffer
[ 9] = nLog2
; // entrySelector
592 rBuffer
[11] = (nTableCount
-nLog2
)*16; // rangeShift
595 // get font table raw data and update the fake directory entries
596 ByteCount nOfs
= nFdirSize
;
597 unsigned char* pFakeEntry
= &rBuffer
[12];
598 if( nCmapSize
!= pMacFont
->GetFontTable( "cmap", &rBuffer
[nOfs
]))
600 FakeDirEntry( "cmap", nOfs
, nCmapSize
, &rBuffer
[0], pFakeEntry
);
603 if( nCvtSize
!= pMacFont
->GetFontTable( "cvt ", &rBuffer
[nOfs
]))
605 FakeDirEntry( "cvt ", nOfs
, nCvtSize
, &rBuffer
[0], pFakeEntry
);
609 if( nFpgmSize
!= pMacFont
->GetFontTable( "fpgm", &rBuffer
[nOfs
]))
611 FakeDirEntry( "fpgm", nOfs
, nFpgmSize
, &rBuffer
[0], pFakeEntry
);
615 if( nCffSize
!= pMacFont
->GetFontTable( "CFF ", &rBuffer
[nOfs
]))
617 FakeDirEntry( "CFF ", nOfs
, nCffSize
, &rBuffer
[0], pFakeEntry
);
620 if( nGlyfSize
!= pMacFont
->GetFontTable( "glyf", &rBuffer
[nOfs
]))
622 FakeDirEntry( "glyf", nOfs
, nGlyfSize
, &rBuffer
[0], pFakeEntry
);
624 if( nLocaSize
!= pMacFont
->GetFontTable( "loca", &rBuffer
[nOfs
]))
626 FakeDirEntry( "loca", nOfs
, nLocaSize
, &rBuffer
[0], pFakeEntry
);
629 if( nHeadSize
!= pMacFont
->GetFontTable( "head", &rBuffer
[nOfs
]))
631 FakeDirEntry( "head", nOfs
, nHeadSize
, &rBuffer
[0], pFakeEntry
);
633 if( nHheaSize
!= pMacFont
->GetFontTable( "hhea", &rBuffer
[nOfs
]))
635 FakeDirEntry( "hhea", nOfs
, nHheaSize
, &rBuffer
[0], pFakeEntry
);
637 if( nHmtxSize
!= pMacFont
->GetFontTable( "hmtx", &rBuffer
[nOfs
]))
639 FakeDirEntry( "hmtx", nOfs
, nHmtxSize
, &rBuffer
[0], pFakeEntry
);
641 if( nMaxpSize
!= pMacFont
->GetFontTable( "maxp", &rBuffer
[nOfs
]))
643 FakeDirEntry( "maxp", nOfs
, nMaxpSize
, &rBuffer
[0], pFakeEntry
);
645 if( nNameSize
!= pMacFont
->GetFontTable( "name", &rBuffer
[nOfs
]))
647 FakeDirEntry( "name", nOfs
, nNameSize
, &rBuffer
[0], pFakeEntry
);
650 if( nPrepSize
!= pMacFont
->GetFontTable( "prep", &rBuffer
[nOfs
]))
652 FakeDirEntry( "prep", nOfs
, nPrepSize
, &rBuffer
[0], pFakeEntry
);
656 DBG_ASSERT( (nOfs
==nTotalSize
), "AquaSalGraphics::CreateFontSubset (nOfs!=nTotalSize)");
661 void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace
* pFontData
, bool bVertical
,
662 Int32Vector
& rGlyphWidths
, Ucs2UIntMap
& rUnicodeEnc
)
664 rGlyphWidths
.clear();
667 if( pFontData
->IsSubsettable() )
670 if( !GetRawFontData( pFontData
, aBuffer
, NULL
) )
673 // TODO: modernize psprint's horrible fontsubset C-API
674 // this probably only makes sense after the switch to another SCM
675 // that can preserve change history after file renames
677 // use the font subsetter to get the widths
678 TrueTypeFont
* pSftFont
= NULL
;
679 int nRC
= ::OpenTTFontBuffer( (void*)&aBuffer
[0], aBuffer
.size(), 0, &pSftFont
);
683 const int nGlyphCount
= ::GetTTGlyphCount( pSftFont
);
684 if( nGlyphCount
> 0 )
687 rGlyphWidths
.resize(nGlyphCount
);
688 std::vector
<sal_uInt16
> aGlyphIds(nGlyphCount
);
689 for( int i
= 0; i
< nGlyphCount
; i
++ )
690 aGlyphIds
[i
] = static_cast<sal_uInt16
>(i
);
691 const TTSimpleGlyphMetrics
* pGlyphMetrics
= ::GetTTSimpleGlyphMetrics(
692 pSftFont
, &aGlyphIds
[0], nGlyphCount
, bVertical
);
695 for( int i
= 0; i
< nGlyphCount
; ++i
)
696 rGlyphWidths
[i
] = pGlyphMetrics
[i
].adv
;
697 free( (void*)pGlyphMetrics
);
700 FontCharMapPtr pMap
= mpFontData
->GetFontCharMap();
701 DBG_ASSERT( pMap
&& pMap
->GetCharCount(), "no charmap" );
703 // get unicode<->glyph encoding
704 // TODO? avoid sft mapping by using the pMap itself
705 int nCharCount
= pMap
->GetCharCount();
706 sal_uInt32 nChar
= pMap
->GetFirstChar();
707 for(; --nCharCount
>= 0; nChar
= pMap
->GetNextChar( nChar
) )
709 if( nChar
> 0xFFFF ) // TODO: allow UTF-32 chars
711 sal_Ucs nUcsChar
= static_cast<sal_Ucs
>(nChar
);
712 sal_uInt32 nGlyph
= ::MapChar( pSftFont
, nUcsChar
, bVertical
);
714 rUnicodeEnc
[ nUcsChar
] = nGlyph
;
720 ::CloseTTFont( pSftFont
);
722 else if( pFontData
->IsEmbeddable() )
724 // get individual character widths
725 OSL_FAIL("not implemented for non-subsettable fonts!\n");
729 const Ucs2SIntMap
* AquaSalGraphics::GetFontEncodingVector(
730 const PhysicalFontFace
*, const Ucs2OStrMap
** /*ppNonEncoded*/, std::set
<sal_Unicode
> const** )
735 const void* AquaSalGraphics::GetEmbedFontData( const PhysicalFontFace
*,
736 const sal_Ucs
* /*pUnicodes*/,
737 sal_Int32
* /*pWidths*/,
745 void AquaSalGraphics::FreeEmbedFontData( const void* pData
, long /*nDataLen*/ )
747 // TODO: implementing this only makes sense when the implementation of
748 // AquaSalGraphics::GetEmbedFontData() returns non-NULL
750 DBG_ASSERT( (pData
!=NULL
), "AquaSalGraphics::FreeEmbedFontData() is not implemented\n");
753 SystemFontData
AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
755 SystemFontData aSysFontData
;
756 aSysFontData
.nSize
= sizeof( SystemFontData
);
758 aSysFontData
.bAntialias
= !mbNonAntialiasedText
;
763 bool AquaSalGraphics::IsFlipped() const
772 void AquaSalGraphics::RefreshRect(float lX
, float lY
, float lWidth
, float lHeight
)
775 if( ! mbWindow
) // view only on Window graphics
780 // update a little more around the designated rectangle
781 // this helps with antialiased rendering
782 // Rounding down x and width can accumulate a rounding error of up to 2
783 // The decrementing of x, the rounding error and the antialiasing border
784 // require that the width and the height need to be increased by four
785 const Rectangle
aVclRect(Point(static_cast<long int>(lX
-1),
786 static_cast<long int>(lY
-1) ),
787 Size( static_cast<long int>(lWidth
+4),
788 static_cast<long int>(lHeight
+4) ) );
789 mpFrame
->maInvalidRect
.Union( aVclRect
);
802 bool AquaSalGraphics::CheckContext()
804 if (mbForeignContext
)
806 SAL_INFO("vcl.ios", "CheckContext() this=" << this << ", mbForeignContext, return true");
810 SAL_INFO( "vcl.ios", "CheckContext() this=" << this << ", not foreign, return false");
814 CGContextRef
AquaSalGraphics::GetContext()
824 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */