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 #ifndef INCLUDED_VCL_INC_QUARTZ_SALGDI_H
21 #define INCLUDED_VCL_INC_QUARTZ_SALGDI_H
25 #include <basegfx/polygon/b2dpolypolygon.hxx>
26 #include <tools/long.hxx>
30 #include <ApplicationServices/ApplicationServices.h>
31 #include <osx/osxvcltypes.h>
32 #include <osx/salframe.h>
34 #include <CoreGraphics/CoreGraphics.h>
35 #include <CoreText/CoreText.h>
39 #include <vcl/fontcapabilities.hxx>
40 #include <vcl/metric.hxx>
43 #include <fontinstance.hxx>
44 #include <impfontmetricdata.hxx>
45 #include <PhysicalFontFace.hxx>
48 #include <quartz/salgdicommon.hxx>
49 #include <unordered_map>
52 #include <quartz/CGHelpers.hxx>
58 // CoreText-specific physically available font face
59 class CoreTextFontFace
: public PhysicalFontFace
62 CoreTextFontFace( const FontAttributes
&, sal_IntPtr nFontID
);
63 virtual ~CoreTextFontFace() override
;
65 sal_IntPtr
GetFontId() const override
;
67 int GetFontTable( uint32_t nTagCode
, unsigned char* ) const;
68 int GetFontTable( const char pTagName
[5], unsigned char* ) const;
70 FontCharMapRef
GetFontCharMap() const override
;
71 bool GetFontCapabilities(vcl::FontCapabilities
&) const override
;
72 bool HasChar( sal_uInt32 cChar
) const;
74 rtl::Reference
<LogicalFontInstance
> CreateFontInstance(const FontSelectPattern
&) const override
;
77 const sal_IntPtr mnFontId
;
78 mutable FontCharMapRef mxCharMap
;
79 mutable vcl::FontCapabilities maFontCapabilities
;
80 mutable bool mbFontCapabilitiesRead
;
83 class CoreTextStyle final
: public LogicalFontInstance
85 friend rtl::Reference
<LogicalFontInstance
> CoreTextFontFace::CreateFontInstance(const FontSelectPattern
&) const;
88 ~CoreTextStyle() override
;
90 void GetFontMetric( ImplFontMetricDataRef
const & );
91 bool GetGlyphOutline(sal_GlyphId
, basegfx::B2DPolyPolygon
&, bool) const override
;
93 CFMutableDictionaryRef
GetStyleDict( void ) const { return mpStyleDict
; }
95 /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
97 /// text rotation in radian
99 /// faux bold - true, if font doesn't have proper bold variants
103 explicit CoreTextStyle(const PhysicalFontFace
&, const FontSelectPattern
&);
105 hb_font_t
* ImplInitHbFont() override
;
106 bool ImplGetGlyphBoundRect(sal_GlyphId
, tools::Rectangle
&, bool) const override
;
108 /// CoreText text style object
109 CFMutableDictionaryRef mpStyleDict
;
112 // TODO: move into cross-platform headers
117 SystemFontList( void );
118 ~SystemFontList( void );
121 void AddFont( CoreTextFontFace
* );
123 void AnnounceFonts( PhysicalFontCollection
& ) const;
124 CoreTextFontFace
* GetFontDataFromId( sal_IntPtr nFontId
) const;
127 CTFontCollectionRef mpCTFontCollection
;
128 CFArrayRef mpCTFontArray
;
130 std::unordered_map
<sal_IntPtr
, rtl::Reference
<CoreTextFontFace
>> maFontContainer
;
135 float getWindowScaling();
138 struct AquaSharedAttributes
140 /// path representing current clip region
141 CGMutablePathRef mxClipPath
;
145 RGBAColor maLineColor
;
148 RGBAColor maFillColor
;
152 AquaSalFrame
* mpFrame
;
153 /// is this a window graphics
156 // mirror AquaSalVirtualDevice::mbForeignContext for SvpSalGraphics objects related to such
157 bool mbForeignContext
;
159 /// is this a printer graphics
161 /// is this a virtual device graphics
164 CGLayerHolder maLayer
; // Quartz graphics layer
165 CGContextHolder maContextHolder
; // Quartz drawing context
166 CGContextHolder maBGContextHolder
; // Quartz drawing context for CGLayer
167 CGContextHolder maCSContextHolder
; // Quartz drawing context considering the color space
170 int mnXorMode
; // 0: off 1: on 2: invert only
171 int mnBitmapDepth
; // zero unless bitmap
173 std::unique_ptr
<XorEmulation
> mpXorEmulation
;
175 AquaSharedAttributes()
176 : mxClipPath(nullptr)
177 , maLineColor(COL_WHITE
)
178 , maFillColor(COL_BLACK
)
183 , mbForeignContext(false)
197 CGPathRelease(mxClipPath
);
198 mxClipPath
= nullptr;
210 bool isPenVisible() const
212 return maLineColor
.IsVisible();
214 bool isBrushVisible() const
216 return maFillColor
.IsVisible();
219 void refreshRect(float lX
, float lY
, float lWidth
, float lHeight
)
222 if (!mbWindow
) // view only on Window graphics
227 // update a little more around the designated rectangle
228 // this helps with antialiased rendering
229 // Rounding down x and width can accumulate a rounding error of up to 2
230 // The decrementing of x, the rounding error and the antialiasing border
231 // require that the width and the height need to be increased by four
232 const tools::Rectangle
aVclRect(
233 Point(tools::Long(lX
- 1), tools::Long(lY
- 1)),
234 Size(tools::Long(lWidth
+ 4), tools::Long(lHeight
+ 4)));
236 mpFrame
->maInvalidRect
.Union(aVclRect
);
247 // apply the XOR mask to the target context if active and dirty
248 void applyXorContext()
252 if (mpXorEmulation
->UpdateTarget())
254 refreshRect(0, 0, mnWidth
, mnHeight
); // TODO: refresh minimal changerect
258 // differences between VCL, Quartz and kHiThemeOrientation coordinate systems
259 // make some graphics seem to be vertically-mirrored from a VCL perspective
260 bool isFlipped() const
270 class AquaGraphicsBackend final
: public SalGraphicsImpl
273 AquaSharedAttributes
& mrShared
;
275 void drawPixelImpl( tools::Long nX
, tools::Long nY
, const RGBAColor
& rColor
); // helper to draw single pixels
278 void refreshRect(const NSRect
& rRect
)
280 mrShared
.refreshRect(rRect
.origin
.x
, rRect
.origin
.y
, rRect
.size
.width
, rRect
.size
.height
);
283 void refreshRect(const CGRect
& /*rRect*/)
287 void pattern50Fill();
290 void copyScaledArea(tools::Long nDestX
, tools::Long nDestY
, tools::Long nSrcX
, tools::Long nSrcY
,
291 tools::Long nSrcWidth
, tools::Long nSrcHeight
, AquaSharedAttributes
* pSrcShared
);
295 AquaGraphicsBackend(AquaSharedAttributes
& rShared
);
296 ~AquaGraphicsBackend() override
;
298 void Init() override
;
300 void freeResources() override
;
302 OUString
getRenderBackendName() const override
307 bool setClipRegion(vcl::Region
const& rRegion
) override
;
308 void ResetClipRegion() override
;
310 sal_uInt16
GetBitCount() const override
;
312 tools::Long
GetGraphicsWidth() const override
;
314 void SetLineColor() override
;
315 void SetLineColor(Color nColor
) override
;
316 void SetFillColor() override
;
317 void SetFillColor(Color nColor
) override
;
318 void SetXORMode(bool bSet
, bool bInvertOnly
) override
;
319 void SetROPLineColor(SalROPColor nROPColor
) override
;
320 void SetROPFillColor(SalROPColor nROPColor
) override
;
322 void drawPixel(tools::Long nX
, tools::Long nY
) override
;
323 void drawPixel(tools::Long nX
, tools::Long nY
, Color nColor
) override
;
325 void drawLine(tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
) override
;
326 void drawRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
) override
;
327 void drawPolyLine(sal_uInt32 nPoints
, const Point
* pPointArray
) override
;
328 void drawPolygon(sal_uInt32 nPoints
, const Point
* pPointArray
) override
;
329 void drawPolyPolygon(sal_uInt32 nPoly
, const sal_uInt32
* pPoints
,
330 const Point
** pPointArray
) override
;
332 bool drawPolyPolygon(const basegfx::B2DHomMatrix
& rObjectToDevice
,
333 const basegfx::B2DPolyPolygon
&, double fTransparency
) override
;
335 bool drawPolyLine(const basegfx::B2DHomMatrix
& rObjectToDevice
, const basegfx::B2DPolygon
&,
336 double fTransparency
, double fLineWidth
, const std::vector
<double>* pStroke
,
337 basegfx::B2DLineJoin
, css::drawing::LineCap
, double fMiterMinimumAngle
,
338 bool bPixelSnapHairline
) override
;
340 bool drawPolyLineBezier(sal_uInt32 nPoints
, const Point
* pPointArray
,
341 const PolyFlags
* pFlagArray
) override
;
343 bool drawPolygonBezier(sal_uInt32 nPoints
, const Point
* pPointArray
,
344 const PolyFlags
* pFlagArray
) override
;
346 bool drawPolyPolygonBezier(sal_uInt32 nPoly
, const sal_uInt32
* pPoints
,
347 const Point
* const* pPointArray
,
348 const PolyFlags
* const* pFlagArray
) override
;
350 void copyArea(tools::Long nDestX
, tools::Long nDestY
, tools::Long nSrcX
, tools::Long nSrcY
,
351 tools::Long nSrcWidth
, tools::Long nSrcHeight
, bool bWindowInvalidate
) override
;
353 void copyBits(const SalTwoRect
& rPosAry
, SalGraphics
* pSrcGraphics
) override
;
355 void drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
) override
;
357 void drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
,
358 const SalBitmap
& rMaskBitmap
) override
;
360 void drawMask(const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
,
361 Color nMaskColor
) override
;
363 std::shared_ptr
<SalBitmap
> getBitmap(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
364 tools::Long nHeight
) override
;
366 Color
getPixel(tools::Long nX
, tools::Long nY
) override
;
368 void invert(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
,
369 SalInvert nFlags
) override
;
371 void invert(sal_uInt32 nPoints
, const Point
* pPtAry
, SalInvert nFlags
) override
;
373 bool drawEPS(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
,
374 void* pPtr
, sal_uInt32 nSize
) override
;
376 bool blendBitmap(const SalTwoRect
&, const SalBitmap
& rBitmap
) override
;
378 bool blendAlphaBitmap(const SalTwoRect
&, const SalBitmap
& rSrcBitmap
,
379 const SalBitmap
& rMaskBitmap
, const SalBitmap
& rAlphaBitmap
) override
;
381 bool drawAlphaBitmap(const SalTwoRect
&, const SalBitmap
& rSourceBitmap
,
382 const SalBitmap
& rAlphaBitmap
) override
;
384 bool drawTransformedBitmap(const basegfx::B2DPoint
& rNull
, const basegfx::B2DPoint
& rX
,
385 const basegfx::B2DPoint
& rY
, const SalBitmap
& rSourceBitmap
,
386 const SalBitmap
* pAlphaBitmap
, double fAlpha
) override
;
388 bool hasFastDrawTransformedBitmap() const override
;
390 bool drawAlphaRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
,
391 sal_uInt8 nTransparency
) override
;
393 bool drawGradient(const tools::PolyPolygon
& rPolygon
, const Gradient
& rGradient
) override
;
394 bool implDrawGradient(basegfx::B2DPolyPolygon
const& rPolyPolygon
,
395 SalGradient
const& rGradient
) override
;
397 bool supportsOperation(OutDevSupportType eType
) const override
;
400 class AquaSalGraphics
: public SalGraphicsAutoDelegateToImpl
402 AquaSharedAttributes maShared
;
403 std::unique_ptr
<AquaGraphicsBackend
> mpBackend
;
405 /// device resolution of this graphics
406 sal_Int32 mnRealDPIX
;
407 sal_Int32 mnRealDPIY
;
409 // Device Font settings
410 rtl::Reference
<CoreTextStyle
> mpTextStyle
[MAX_FALLBACK
];
411 RGBAColor maTextColor
;
412 /// allows text to be rendered without antialiasing
413 bool mbNonAntialiasedText
;
417 virtual ~AquaSalGraphics() override
;
419 void SetVirDevGraphics(CGLayerHolder
const &rLayer
, CGContextRef
, int nBitDepth
= 0);
421 void initResolution( NSWindow
* );
422 void copyResolution( AquaSalGraphics
& );
423 void updateResolution();
425 void SetWindowGraphics( AquaSalFrame
* pFrame
);
426 bool IsWindowGraphics() const { return maShared
.mbWindow
; }
427 void SetPrinterGraphics(CGContextRef
, sal_Int32 nRealDPIX
, sal_Int32 nRealDPIY
);
428 AquaSalFrame
* getGraphicsFrame() const { return maShared
.mpFrame
; }
429 void setGraphicsFrame( AquaSalFrame
* pFrame
) { maShared
.mpFrame
= pFrame
; }
433 void UpdateWindow( NSRect
& ); // delivered in NSView coordinates
434 void RefreshRect(const NSRect
& rRect
)
436 maShared
.refreshRect(rRect
.origin
.x
, rRect
.origin
.y
, rRect
.size
.width
, rRect
.size
.height
);
439 void RefreshRect( const CGRect
& ) {}
443 // InvalidateContext does an UnsetState and sets mrContext to 0
444 void InvalidateContext();
446 AquaGraphicsBackend
* getAquaGraphicsBackend() const
448 return mpBackend
.get();
451 virtual SalGraphicsImpl
* GetImpl() const override
;
457 // native widget rendering methods that require mirroring
459 virtual bool isNativeControlSupported( ControlType nType
, ControlPart nPart
) override
;
461 virtual bool hitTestNativeControl( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
,
462 const Point
& aPos
, bool& rIsInside
) override
;
463 virtual bool drawNativeControl( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
,
464 ControlState nState
, const ImplControlValue
& aValue
,
465 const OUString
& aCaption
, const Color
& rBackgroundColor
) override
;
466 virtual bool getNativeControlRegion( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
, ControlState nState
,
467 const ImplControlValue
& aValue
, const OUString
& aCaption
,
468 tools::Rectangle
&rNativeBoundingRegion
, tools::Rectangle
&rNativeContentRegion
) override
;
472 // get device resolution
473 virtual void GetResolution( sal_Int32
& rDPIX
, sal_Int32
& rDPIY
) override
;
474 // set the text color to a specific color
475 virtual void SetTextColor( Color nColor
) override
;
477 virtual void SetFont( LogicalFontInstance
*, int nFallbackLevel
) override
;
478 // get the current font's metrics
479 virtual void GetFontMetric( ImplFontMetricDataRef
&, int nFallbackLevel
) override
;
480 // get the repertoire of the current font
481 virtual FontCharMapRef
GetFontCharMap() const override
;
482 virtual bool GetFontCapabilities(vcl::FontCapabilities
&rFontCapabilities
) const override
;
483 // graphics must fill supplied font list
484 virtual void GetDevFontList( PhysicalFontCollection
* ) override
;
485 // graphics must drop any cached font info
486 virtual void ClearDevFontCache() override
;
487 virtual bool AddTempDevFont( PhysicalFontCollection
*, const OUString
& rFileURL
, const OUString
& rFontName
) override
;
488 // CreateFontSubset: a method to get a subset of glyhps of a font
489 // inside a new valid font file
490 // returns TRUE if creation of subset was successful
491 // parameters: rToFile: contains an osl file URL to write the subset to
492 // pFont: describes from which font to create a subset
493 // pGlyphIDs: the glyph ids to be extracted
494 // pEncoding: the character code corresponding to each glyph
495 // pWidths: the advance widths of the corresponding glyphs (in PS font units)
496 // nGlyphs: the number of glyphs
497 // rInfo: additional outgoing information
498 // implementation note: encoding 0 with glyph id 0 should be added implicitly
499 // as "undefined character"
500 virtual bool CreateFontSubset( const OUString
& rToFile
,
501 const PhysicalFontFace
* pFont
,
502 const sal_GlyphId
* pGlyphIds
,
503 const sal_uInt8
* pEncoding
,
506 FontSubsetInfo
& rInfo
// out parameter
509 // GetEmbedFontData: gets the font data for a font marked
510 // embeddable by GetDevFontList or NULL in case of error
511 // parameters: pFont: describes the font in question
512 // pDataLen: out parameter, contains the byte length of the returned buffer
513 virtual const void* GetEmbedFontData(const PhysicalFontFace
*, tools::Long
* pDataLen
)
515 // frees the font data again
516 virtual void FreeEmbedFontData( const void* pData
, tools::Long nDataLen
) override
;
518 virtual void GetGlyphWidths( const PhysicalFontFace
*,
520 std::vector
< sal_Int32
>& rWidths
,
521 Ucs2UIntMap
& rUnicodeEnc
) override
;
523 virtual std::unique_ptr
<GenericSalLayout
>
524 GetTextLayout(int nFallbackLevel
) override
;
525 virtual void DrawTextLayout( const GenericSalLayout
& ) override
;
527 virtual SystemGraphicsData
528 GetGraphicsData() const override
;
531 UInt32
getState( ControlState nState
);
532 UInt32
getTrackState( ControlState nState
);
533 static bool GetRawFontData( const PhysicalFontFace
* pFontData
,
534 std::vector
<unsigned char>& rBuffer
,
539 #endif // INCLUDED_VCL_INC_QUARTZ_SALGDI_H
541 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */