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 <sal/config.h>
21 #include <sal/log.hxx>
22 #include <config_folders.h>
24 #include <basegfx/matrix/b2dhommatrix.hxx>
25 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <basegfx/polygon/b2dpolygon.hxx>
27 #include <basegfx/polygon/b2dpolygontools.hxx>
28 #include <basegfx/range/b2drectangle.hxx>
29 #include <osl/file.hxx>
30 #include <osl/process.h>
31 #include <rtl/bootstrap.h>
32 #include <rtl/strbuf.hxx>
33 #include <tools/long.hxx>
34 #include <comphelper/lok.hxx>
36 #include <vcl/metric.hxx>
37 #include <vcl/fontcharmap.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/sysdata.hxx>
41 #include <quartz/ctfonts.hxx>
42 #include <fontsubset.hxx>
43 #include <impfont.hxx>
44 #include <impfontcharmap.hxx>
45 #include <impfontmetricdata.hxx>
47 #include <PhysicalFontCollection.hxx>
50 #include <osx/salframe.h>
52 #include <quartz/utils.h>
54 #include "saldatabasic.hxx"
56 #include <sallayout.hxx>
63 class CoreTextGlyphFallbackSubstititution
64 : public ImplGlyphFallbackFontSubstitution
67 bool FindFontSubstitute(FontSelectPattern
&, LogicalFontInstance
* pLogicalFont
, OUString
&) const override
;
72 bool CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern
& rPattern
, LogicalFontInstance
* pLogicalFont
,
73 OUString
& rMissingChars
) const
76 CoreTextStyle
* pStyle
= static_cast<CoreTextStyle
*>(pLogicalFont
);
77 CTFontRef pFont
= static_cast<CTFontRef
>(CFDictionaryGetValue(pStyle
->GetStyleDict(), kCTFontAttributeName
));
78 CFStringRef pStr
= CreateCFString(rMissingChars
);
81 CTFontRef pFallback
= CTFontCreateForString(pFont
, pStr
, CFRangeMake(0, CFStringGetLength(pStr
)));
86 CTFontDescriptorRef pDesc
= CTFontCopyFontDescriptor(pFallback
);
87 FontAttributes rAttr
= DevFontFromCTFontDescriptor(pDesc
, nullptr);
89 rPattern
.maSearchName
= rAttr
.GetFamilyName();
91 rPattern
.SetWeight(rAttr
.GetWeight());
92 rPattern
.SetItalic(rAttr
.GetItalic());
93 rPattern
.SetPitch(rAttr
.GetPitch());
94 rPattern
.SetWidthType(rAttr
.GetWidthType());
105 CoreTextFontFace::CoreTextFontFace( const FontAttributes
& rDFA
, sal_IntPtr nFontId
)
106 : PhysicalFontFace( rDFA
)
107 , mnFontId( nFontId
)
108 , mbFontCapabilitiesRead( false )
112 CoreTextFontFace::~CoreTextFontFace()
116 sal_IntPtr
CoreTextFontFace::GetFontId() const
121 FontCharMapRef
CoreTextFontFace::GetFontCharMap() const
123 // return the cached charmap
127 // set the default charmap
128 FontCharMapRef
pCharMap( new FontCharMap() );
129 mxCharMap
= pCharMap
;
131 // get the CMAP byte size
132 // allocate a buffer for the CMAP raw data
133 const int nBufSize
= GetFontTable( "cmap", nullptr );
134 SAL_WARN_IF( (nBufSize
<= 0), "vcl", "CoreTextFontFace::GetFontCharMap : GetFontTable1 failed!");
138 // get the CMAP raw data
139 std::vector
<unsigned char> aBuffer( nBufSize
);
140 const int nRawLength
= GetFontTable( "cmap", aBuffer
.data() );
141 SAL_WARN_IF( (nRawLength
<= 0), "vcl", "CoreTextFontFace::GetFontCharMap : GetFontTable2 failed!");
142 if( nRawLength
<= 0 )
145 SAL_WARN_IF( (nBufSize
!=nRawLength
), "vcl", "CoreTextFontFace::GetFontCharMap : ByteCount mismatch!");
148 CmapResult aCmapResult
;
149 if( ParseCMAP( aBuffer
.data(), nRawLength
, aCmapResult
) )
151 FontCharMapRef
xDefFontCharMap( new FontCharMap(aCmapResult
) );
152 // create the matching charmap
153 mxCharMap
= xDefFontCharMap
;
159 bool CoreTextFontFace::GetFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const
161 // read this only once per font
162 if( mbFontCapabilitiesRead
)
164 rFontCapabilities
= maFontCapabilities
;
165 return rFontCapabilities
.oUnicodeRange
|| rFontCapabilities
.oCodePageRange
;
167 mbFontCapabilitiesRead
= true;
169 int nBufSize
= GetFontTable( "OS/2", nullptr );
172 // allocate a buffer for the OS/2 raw data
173 std::vector
<unsigned char> aBuffer( nBufSize
);
174 // get the OS/2 raw data
175 const int nRawLength
= GetFontTable( "OS/2", aBuffer
.data() );
178 const unsigned char* pOS2Table
= aBuffer
.data();
179 vcl::getTTCoverage( maFontCapabilities
.oUnicodeRange
,
180 maFontCapabilities
.oCodePageRange
,
181 pOS2Table
, nRawLength
);
184 rFontCapabilities
= maFontCapabilities
;
185 return rFontCapabilities
.oUnicodeRange
|| rFontCapabilities
.oCodePageRange
;
188 AquaSalGraphics::AquaSalGraphics()
189 : mpBackend(new AquaGraphicsBackend(maShared
))
192 , maTextColor( COL_BLACK
)
193 , mbNonAntialiasedText( false )
195 SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this );
197 for (int i
= 0; i
< MAX_FALLBACK
; ++i
)
198 mpTextStyle
[i
] = nullptr;
200 if (comphelper::LibreOfficeKit::isActive())
201 initWidgetDrawBackends(true);
204 AquaSalGraphics::~AquaSalGraphics()
206 SAL_INFO( "vcl.quartz", "AquaSalGraphics::~AquaSalGraphics() this=" << this );
208 maShared
.unsetClipPath();
212 maShared
.mpXorEmulation
.reset();
215 if (maShared
.mbForeignContext
)
218 if (maShared
.maLayer
.isSet())
220 CGLayerRelease(maShared
.maLayer
.get());
222 else if (maShared
.maContextHolder
.isSet()
228 // destroy backbuffer bitmap context that we created ourself
229 CGContextRelease(maShared
.maContextHolder
.get());
230 maShared
.maContextHolder
.set(nullptr);
234 SalGraphicsImpl
* AquaSalGraphics::GetImpl() const
236 return mpBackend
.get();
239 void AquaSalGraphics::SetTextColor( Color nColor
)
241 maTextColor
= RGBAColor( nColor
);
242 // SAL_ DEBUG(std::hex << nColor << std::dec << "={" << maTextColor.GetRed() << ", " << maTextColor.GetGreen() << ", " << maTextColor.GetBlue() << ", " << maTextColor.GetAlpha() << "}");
245 void AquaSalGraphics::GetFontMetric(ImplFontMetricDataRef
& rxFontMetric
, int nFallbackLevel
)
247 if (nFallbackLevel
< MAX_FALLBACK
&& mpTextStyle
[nFallbackLevel
])
249 mpTextStyle
[nFallbackLevel
]->GetFontMetric(rxFontMetric
);
253 static bool AddTempDevFont(const OUString
& rFontFileURL
)
255 OUString aUSystemPath
;
256 OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFontFileURL
, aUSystemPath
) );
257 OString aCFileName
= OUStringToOString( aUSystemPath
, RTL_TEXTENCODING_UTF8
);
259 CFStringRef rFontPath
= CFStringCreateWithCString(nullptr, aCFileName
.getStr(), kCFStringEncodingUTF8
);
260 CFURLRef rFontURL
= CFURLCreateWithFileSystemPath(nullptr, rFontPath
, kCFURLPOSIXPathStyle
, true);
263 bool success
= CTFontManagerRegisterFontsForURL(rFontURL
, kCTFontManagerScopeProcess
, &error
);
268 CFRelease(rFontPath
);
274 static void AddTempFontDir( const OUString
&rFontDirUrl
)
276 osl::Directory
aFontDir( rFontDirUrl
);
277 osl::FileBase::RC rcOSL
= aFontDir
.open();
278 if( rcOSL
== osl::FileBase::E_None
)
280 osl::DirectoryItem aDirItem
;
282 while( aFontDir
.getNextItem( aDirItem
, 10 ) == osl::FileBase::E_None
)
284 osl::FileStatus
aFileStatus( osl_FileStatus_Mask_FileURL
);
285 rcOSL
= aDirItem
.getFileStatus( aFileStatus
);
286 if ( rcOSL
== osl::FileBase::E_None
)
288 AddTempDevFont(aFileStatus
.getFileURL());
294 static void AddLocalTempFontDirs()
296 static bool bFirst
= true;
302 // add private font files
304 OUString
aBrandStr( "$BRAND_BASE_DIR" );
305 rtl_bootstrap_expandMacros( &aBrandStr
.pData
);
307 // internal font resources, required for normal operation, like OpenSymbol
308 AddTempFontDir( aBrandStr
+ "/" LIBO_SHARE_RESOURCE_FOLDER
"/common/fonts/" );
310 AddTempFontDir( aBrandStr
+ "/" LIBO_SHARE_FOLDER
"/fonts/truetype/" );
313 void AquaSalGraphics::GetDevFontList( PhysicalFontCollection
* pFontCollection
)
315 SAL_WARN_IF( !pFontCollection
, "vcl", "AquaSalGraphics::GetDevFontList(NULL) !");
317 AddLocalTempFontDirs();
319 // The idea is to cache the list of system fonts once it has been generated.
320 // SalData seems to be a good place for this caching. However we have to
321 // carefully make the access to the font list thread-safe. If we register
322 // a font-change event handler to update the font list in case fonts have
323 // changed on the system we have to lock access to the list. The right
324 // way to do that is the solar mutex since GetDevFontList is protected
325 // through it as should be all event handlers
327 SalData
* pSalData
= GetSalData();
328 if( !pSalData
->mpFontList
)
329 pSalData
->mpFontList
= GetCoretextFontList();
331 // Copy all PhysicalFontFace objects contained in the SystemFontList
332 pSalData
->mpFontList
->AnnounceFonts( *pFontCollection
);
334 static CoreTextGlyphFallbackSubstititution aSubstFallback
;
335 pFontCollection
->SetFallbackHook(&aSubstFallback
);
338 void AquaSalGraphics::ClearDevFontCache()
340 SalData
* pSalData
= GetSalData();
341 delete pSalData
->mpFontList
;
342 pSalData
->mpFontList
= nullptr;
345 bool AquaSalGraphics::AddTempDevFont( PhysicalFontCollection
*,
346 const OUString
& rFontFileURL
, const OUString
& /*rFontName*/ )
348 return ::AddTempDevFont(rFontFileURL
);
351 void AquaSalGraphics::DrawTextLayout(const GenericSalLayout
& rLayout
)
354 if (!maShared
.checkContext())
356 SAL_WARN("vcl.quartz", "AquaSalGraphics::DrawTextLayout() without context");
361 const CoreTextStyle
& rStyle
= *static_cast<const CoreTextStyle
*>(&rLayout
.GetFont());
362 const FontSelectPattern
& rFontSelect
= rStyle
.GetFontSelectPattern();
363 if (rFontSelect
.mnHeight
== 0)
365 SAL_WARN("vcl.quartz", "AquaSalGraphics::DrawTextLayout(): rFontSelect.mnHeight is zero!?");
369 CTFontRef pFont
= static_cast<CTFontRef
>(CFDictionaryGetValue(rStyle
.GetStyleDict(), kCTFontAttributeName
));
370 CGAffineTransform aRotMatrix
= CGAffineTransformMakeRotation(-rStyle
.mfFontRotation
);
373 const GlyphItem
* pGlyph
;
374 std::vector
<CGGlyph
> aGlyphIds
;
375 std::vector
<CGPoint
> aGlyphPos
;
376 std::vector
<bool> aGlyphOrientation
;
378 while (rLayout
.GetNextGlyph(&pGlyph
, aPos
, nStart
))
380 CGPoint aGCPos
= CGPointMake(aPos
.X(), -aPos
.Y());
382 // Whether the glyph should be upright in vertical mode or not
383 bool bUprightGlyph
= false;
385 if (rStyle
.mfFontRotation
)
387 if (pGlyph
->IsVertical())
389 bUprightGlyph
= true;
390 // Adjust the position of upright (vertical) glyphs.
391 aGCPos
.y
-= CTFontGetAscent(pFont
) - CTFontGetDescent(pFont
);
395 // Transform the position of rotated glyphs.
396 aGCPos
= CGPointApplyAffineTransform(aGCPos
, aRotMatrix
);
400 aGlyphIds
.push_back(pGlyph
->glyphId());
401 aGlyphPos
.push_back(aGCPos
);
402 aGlyphOrientation
.push_back(bUprightGlyph
);
405 if (aGlyphIds
.empty())
408 assert(aGlyphIds
.size() == aGlyphPos
.size());
410 std::cerr
<< "aGlyphIds:[";
411 for (unsigned i
= 0; i
< aGlyphIds
.size(); i
++)
415 std::cerr
<< aGlyphIds
[i
];
418 std::cerr
<< "aGlyphPos:[";
419 for (unsigned i
= 0; i
< aGlyphPos
.size(); i
++)
423 std::cerr
<< aGlyphPos
[i
];
428 maShared
.maContextHolder
.saveState();
430 // The view is vertically flipped (no idea why), flip it back.
431 CGContextScaleCTM(maShared
.maContextHolder
.get(), 1.0, -1.0);
432 CGContextSetShouldAntialias(maShared
.maContextHolder
.get(), !mbNonAntialiasedText
);
433 CGContextSetFillColor(maShared
.maContextHolder
.get(), maTextColor
.AsArray());
435 if (rStyle
.mbFauxBold
)
438 float fSize
= rFontSelect
.mnHeight
/ 23.0f
;
439 CGContextSetStrokeColor(maShared
.maContextHolder
.get(), maTextColor
.AsArray());
440 CGContextSetLineWidth(maShared
.maContextHolder
.get(), fSize
);
441 CGContextSetTextDrawingMode(maShared
.maContextHolder
.get(), kCGTextFillStroke
);
444 auto aIt
= aGlyphOrientation
.cbegin();
445 while (aIt
!= aGlyphOrientation
.cend())
447 bool bUprightGlyph
= *aIt
;
448 // Find the boundary of the run of glyphs with the same rotation, to be
450 auto aNext
= std::find(aIt
, aGlyphOrientation
.cend(), !bUprightGlyph
);
451 size_t nStartIndex
= std::distance(aGlyphOrientation
.cbegin(), aIt
);
452 size_t nLen
= std::distance(aIt
, aNext
);
454 maShared
.maContextHolder
.saveState();
455 if (rStyle
.mfFontRotation
&& !bUprightGlyph
)
457 CGContextRotateCTM(maShared
.maContextHolder
.get(), rStyle
.mfFontRotation
);
459 CTFontDrawGlyphs(pFont
, &aGlyphIds
[nStartIndex
], &aGlyphPos
[nStartIndex
], nLen
, maShared
.maContextHolder
.get());
460 maShared
.maContextHolder
.restoreState();
465 maShared
.maContextHolder
.restoreState();
468 void AquaSalGraphics::SetFont(LogicalFontInstance
* pReqFont
, int nFallbackLevel
)
470 // release the text style
471 for (int i
= nFallbackLevel
; i
< MAX_FALLBACK
; ++i
)
475 mpTextStyle
[i
].clear();
481 // update the text style
482 mpTextStyle
[nFallbackLevel
] = static_cast<CoreTextStyle
*>(pReqFont
);
485 std::unique_ptr
<GenericSalLayout
> AquaSalGraphics::GetTextLayout(int nFallbackLevel
)
487 assert(mpTextStyle
[nFallbackLevel
]);
488 if (!mpTextStyle
[nFallbackLevel
])
490 return std::make_unique
<GenericSalLayout
>(*mpTextStyle
[nFallbackLevel
]);
493 FontCharMapRef
AquaSalGraphics::GetFontCharMap() const
497 return FontCharMapRef( new FontCharMap() );
500 return static_cast<const CoreTextFontFace
*>(mpTextStyle
[0]->GetFontFace())->GetFontCharMap();
503 bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const
508 return static_cast<const CoreTextFontFace
*>(mpTextStyle
[0]->GetFontFace())->GetFontCapabilities(rFontCapabilities
);
511 // fake a SFNT font directory entry for a font table
512 // see http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html#Directory
513 static void FakeDirEntry( const char aTag
[5], ByteCount nOfs
, ByteCount nLen
,
514 const unsigned char* /*pData*/, unsigned char*& rpDest
)
517 rpDest
[ 0] = aTag
[0];
518 rpDest
[ 1] = aTag
[1];
519 rpDest
[ 2] = aTag
[2];
520 rpDest
[ 3] = aTag
[3];
521 // TODO: get entry checksum and write it
522 // not too important since the subsetter doesn't care currently
523 // for( pData+nOfs ... pData+nOfs+nLen )
524 // write entry offset
525 rpDest
[ 8] = static_cast<char>(nOfs
>> 24);
526 rpDest
[ 9] = static_cast<char>(nOfs
>> 16);
527 rpDest
[10] = static_cast<char>(nOfs
>> 8);
528 rpDest
[11] = static_cast<char>(nOfs
>> 0);
529 // write entry length
530 rpDest
[12] = static_cast<char>(nLen
>> 24);
531 rpDest
[13] = static_cast<char>(nLen
>> 16);
532 rpDest
[14] = static_cast<char>(nLen
>> 8);
533 rpDest
[15] = static_cast<char>(nLen
>> 0);
534 // advance to next entry
538 // fake a TTF or CFF font as directly accessing font file is not possible
539 // when only the fontid is known. This approach also handles *.font fonts.
540 bool AquaSalGraphics::GetRawFontData( const PhysicalFontFace
* pFontData
,
541 std::vector
<unsigned char>& rBuffer
, bool* pJustCFF
)
543 const CoreTextFontFace
* pMacFont
= static_cast<const CoreTextFontFace
*>(pFontData
);
545 // short circuit for CFF-only fonts
546 const int nCffSize
= pMacFont
->GetFontTable( "CFF ", nullptr);
547 if( pJustCFF
!= nullptr )
549 *pJustCFF
= (nCffSize
> 0);
552 rBuffer
.resize( nCffSize
);
553 const int nCffRead
= pMacFont
->GetFontTable( "CFF ", rBuffer
.data());
554 if( nCffRead
!= nCffSize
)
562 // get font table availability and size in bytes
563 const int nHeadSize
= pMacFont
->GetFontTable( "head", nullptr);
567 const int nMaxpSize
= pMacFont
->GetFontTable( "maxp", nullptr);
571 const int nCmapSize
= pMacFont
->GetFontTable( "cmap", nullptr);
575 const int nNameSize
= pMacFont
->GetFontTable( "name", nullptr);
579 const int nHheaSize
= pMacFont
->GetFontTable( "hhea", nullptr);
583 const int nHmtxSize
= pMacFont
->GetFontTable( "hmtx", nullptr);
587 // get the ttf-glyf outline tables
592 nLocaSize
= pMacFont
->GetFontTable( "loca", nullptr);
596 nGlyfSize
= pMacFont
->GetFontTable( "glyf", nullptr);
601 int nPrepSize
= 0, nCvtSize
= 0, nFpgmSize
= 0;
602 if( nGlyfSize
) // TODO: reduce PDF size by making hint subsetting optional
604 nPrepSize
= pMacFont
->GetFontTable( "prep", nullptr);
605 nCvtSize
= pMacFont
->GetFontTable( "cvt ", nullptr);
606 nFpgmSize
= pMacFont
->GetFontTable( "fpgm", nullptr);
609 // prepare a byte buffer for a fake font
611 nTableCount
+= (nPrepSize
>0?1:0) + (nCvtSize
>0?1:0) + (nFpgmSize
>0?1:0) + (nGlyfSize
>0?1:0);
612 const ByteCount nFdirSize
= 12 + 16*nTableCount
;
613 ByteCount nTotalSize
= nFdirSize
;
614 nTotalSize
+= nHeadSize
+ nMaxpSize
+ nNameSize
+ nCmapSize
;
618 nTotalSize
+= nLocaSize
+ nGlyfSize
;
622 nTotalSize
+= nCffSize
;
624 nTotalSize
+= nHheaSize
+ nHmtxSize
;
625 nTotalSize
+= nPrepSize
+ nCvtSize
+ nFpgmSize
;
626 rBuffer
.resize( nTotalSize
);
628 // fake a SFNT font directory header
629 if( nTableCount
< 16 )
632 while( (nTableCount
>> nLog2
) > 1 ) ++nLog2
;
633 rBuffer
[ 1] = 1; // Win-TTF style scaler
634 rBuffer
[ 5] = nTableCount
; // table count
635 rBuffer
[ 7] = nLog2
*16; // searchRange
636 rBuffer
[ 9] = nLog2
; // entrySelector
637 rBuffer
[11] = (nTableCount
-nLog2
)*16; // rangeShift
640 // get font table raw data and update the fake directory entries
641 ByteCount nOfs
= nFdirSize
;
642 unsigned char* pFakeEntry
= &rBuffer
[12];
643 if( nCmapSize
!= pMacFont
->GetFontTable( "cmap", &rBuffer
[nOfs
]))
646 FakeDirEntry( "cmap", nOfs
, nCmapSize
, rBuffer
.data(), pFakeEntry
);
650 if( nCvtSize
!= pMacFont
->GetFontTable( "cvt ", &rBuffer
[nOfs
]))
653 FakeDirEntry( "cvt ", nOfs
, nCvtSize
, rBuffer
.data(), pFakeEntry
);
658 if( nFpgmSize
!= pMacFont
->GetFontTable( "fpgm", &rBuffer
[nOfs
]))
661 FakeDirEntry( "fpgm", nOfs
, nFpgmSize
, rBuffer
.data(), pFakeEntry
);
666 if( nCffSize
!= pMacFont
->GetFontTable( "CFF ", &rBuffer
[nOfs
]))
669 FakeDirEntry( "CFF ", nOfs
, nCffSize
, rBuffer
.data(), pFakeEntry
);
674 if( nGlyfSize
!= pMacFont
->GetFontTable( "glyf", &rBuffer
[nOfs
]))
677 FakeDirEntry( "glyf", nOfs
, nGlyfSize
, rBuffer
.data(), pFakeEntry
);
680 if( nLocaSize
!= pMacFont
->GetFontTable( "loca", &rBuffer
[nOfs
]))
683 FakeDirEntry( "loca", nOfs
, nLocaSize
, rBuffer
.data(), pFakeEntry
);
686 if( nHeadSize
!= pMacFont
->GetFontTable( "head", &rBuffer
[nOfs
]))
689 FakeDirEntry( "head", nOfs
, nHeadSize
, rBuffer
.data(), pFakeEntry
);
692 if( nHheaSize
!= pMacFont
->GetFontTable( "hhea", &rBuffer
[nOfs
]))
695 FakeDirEntry( "hhea", nOfs
, nHheaSize
, rBuffer
.data(), pFakeEntry
);
697 if( nHmtxSize
!= pMacFont
->GetFontTable( "hmtx", &rBuffer
[nOfs
]))
700 FakeDirEntry( "hmtx", nOfs
, nHmtxSize
, rBuffer
.data(), pFakeEntry
);
702 if( nMaxpSize
!= pMacFont
->GetFontTable( "maxp", &rBuffer
[nOfs
]))
705 FakeDirEntry( "maxp", nOfs
, nMaxpSize
, rBuffer
.data(), pFakeEntry
);
707 if( nNameSize
!= pMacFont
->GetFontTable( "name", &rBuffer
[nOfs
]))
710 FakeDirEntry( "name", nOfs
, nNameSize
, rBuffer
.data(), pFakeEntry
);
714 if( nPrepSize
!= pMacFont
->GetFontTable( "prep", &rBuffer
[nOfs
]))
717 FakeDirEntry( "prep", nOfs
, nPrepSize
, rBuffer
.data(), pFakeEntry
);
721 SAL_WARN_IF( (nOfs
!=nTotalSize
), "vcl", "AquaSalGraphics::GetRawFontData (nOfs!=nTotalSize)");
726 void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace
* pFontData
, bool bVertical
,
727 std::vector
< sal_Int32
>& rGlyphWidths
, Ucs2UIntMap
& rUnicodeEnc
)
729 rGlyphWidths
.clear();
732 std::vector
<unsigned char> aBuffer
;
733 if( !GetRawFontData( pFontData
, aBuffer
, nullptr ) )
736 // TODO: modernize psprint's horrible fontsubset C-API
737 // this probably only makes sense after the switch to another SCM
738 // that can preserve change history after file renames
740 // use the font subsetter to get the widths
741 TrueTypeFont
* pSftFont
= nullptr;
742 SFErrCodes nRC
= ::OpenTTFontBuffer(static_cast<void*>(aBuffer
.data()), aBuffer
.size(), 0, &pSftFont
,
743 pFontData
->GetFontCharMap());
744 if( nRC
!= SFErrCodes::Ok
)
747 SalGraphics::GetGlyphWidths(*pSftFont
, *pFontData
, bVertical
, rGlyphWidths
, rUnicodeEnc
);
749 ::CloseTTFont( pSftFont
);
752 const void* AquaSalGraphics::GetEmbedFontData(const PhysicalFontFace
*, tools::Long
* /*pDataLen*/)
757 void AquaSalGraphics::FreeEmbedFontData( const void* pData
, tools::Long
/*nDataLen*/ )
759 // TODO: implementing this only makes sense when the implementation of
760 // AquaSalGraphics::GetEmbedFontData() returns non-NULL
761 SAL_WARN_IF( (pData
==nullptr), "vcl", "AquaSalGraphics::FreeEmbedFontData() is not implemented");
766 bool AquaSharedAttributes::checkContext()
768 if (mbForeignContext
)
770 SAL_INFO("vcl.ios", "CheckContext() this=" << this << ", mbForeignContext, return true");
774 SAL_INFO( "vcl.ios", "CheckContext() this=" << this << ", not foreign, return false");
780 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */