1
0
Fork 0
libreoffice/vcl/inc/quartz/salgdi.h
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

479 lines
17 KiB
C++

/* -*- 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 .
*/
#pragma once
#include <sal/config.h>
#include <vector>
#include <tools/long.hxx>
#include <premac.h>
#ifdef MACOSX
#include <ApplicationServices/ApplicationServices.h>
#include <osx/osxvcltypes.h>
#include <osx/salframe.h>
#else
#include <CoreGraphics/CoreGraphics.h>
#include <CoreText/CoreText.h>
#endif
#include <postmac.h>
#ifdef IOS
// iOS defines a different Point class so include salgeom.hxx after postmac.h
// so that it will use the Point class in tools/gen.hxx
#include "salgeom.hxx"
#endif
#include <vcl/fontcapabilities.hxx>
#include <vcl/metric.hxx>
#include <font/LogicalFontInstance.hxx>
#include <font/FontMetricData.hxx>
#include <salgdi.hxx>
#include <quartz/salgdicommon.hxx>
#include <quartz/CGHelpers.hxx>
class AquaSalFrame;
class XorEmulation;
class CoreTextFont;
namespace sal::aqua
{
#ifdef MACOSX
NSRect getTotalScreenBounds();
void resetTotalScreenBounds();
#endif
float getWindowScaling();
void resetWindowScaling();
}
struct AquaSharedAttributes
{
/// path representing current clip region
CGMutablePathRef mxClipPath;
/// Drawing colors
/// pen color RGBA
RGBAColor maLineColor;
/// brush color RGBA
RGBAColor maFillColor;
// Graphics types
#ifdef MACOSX
AquaSalFrame* mpFrame;
/// is this a window graphics
bool mbWindow;
#else // IOS
// mirror AquaSalVirtualDevice::mbForeignContext for SvpSalGraphics objects related to such
bool mbForeignContext;
#endif
/// is this a printer graphics
bool mbPrinter;
/// is this a virtual device graphics
bool mbVirDev;
CGLayerHolder maLayer; // Quartz graphics layer
CGContextHolder maContextHolder; // Quartz drawing context
CGContextHolder maBGContextHolder; // Quartz drawing context for CGLayer
CGContextHolder maCSContextHolder; // Quartz drawing context considering the color space
int mnWidth;
int mnHeight;
int mnXorMode; // 0: off 1: on 2: invert only
int mnBitmapDepth; // zero unless bitmap
Color maTextColor;
/// allows text to be rendered without antialiasing
bool mbNonAntialiasedText;
std::unique_ptr<XorEmulation> mpXorEmulation;
AquaSharedAttributes()
: mxClipPath(nullptr)
, maLineColor(COL_WHITE)
, maFillColor(COL_BLACK)
#ifdef MACOSX
, mpFrame(nullptr)
, mbWindow(false)
#else
, mbForeignContext(false)
#endif
, mbPrinter(false)
, mbVirDev(false)
, mnWidth(0)
, mnHeight(0)
, mnXorMode(0)
, mnBitmapDepth(0)
, maTextColor( COL_BLACK )
, mbNonAntialiasedText( false )
{}
void unsetClipPath()
{
if (mxClipPath)
{
CGPathRelease(mxClipPath);
mxClipPath = nullptr;
}
}
void unsetState()
{
unsetClipPath();
}
bool checkContext();
void setState();
bool isPenVisible() const
{
return maLineColor.IsVisible();
}
bool isBrushVisible() const
{
return maFillColor.IsVisible();
}
void refreshRect(float lX, float lY, float lWidth, float lHeight)
{
#ifdef MACOSX
if (!mbWindow) // view only on Window graphics
return;
if (mpFrame)
{
// update a little more around the designated rectangle
// this helps with antialiased rendering
// Rounding down x and width can accumulate a rounding error of up to 2
// The decrementing of x, the rounding error and the antialiasing border
// require that the width and the height need to be increased by four
const tools::Rectangle aVclRect(
Point(tools::Long(lX - 1), tools::Long(lY - 1)),
Size(tools::Long(lWidth + 4), tools::Long(lHeight + 4)));
mpFrame->maInvalidRect.Union(aVclRect);
}
#else
(void) lX;
(void) lY;
(void) lWidth;
(void) lHeight;
return;
#endif
}
// apply the XOR mask to the target context if active and dirty
void applyXorContext()
{
if (!mpXorEmulation)
return;
if (mpXorEmulation->UpdateTarget())
{
refreshRect(0, 0, mnWidth, mnHeight); // TODO: refresh minimal changerect
}
}
// differences between VCL, Quartz and kHiThemeOrientation coordinate systems
// make some graphics seem to be vertically-mirrored from a VCL perspective
bool isFlipped() const
{
#ifdef MACOSX
return mbWindow;
#else
return false;
#endif
}
};
class AquaGraphicsBackendBase
{
public:
virtual ~AquaGraphicsBackendBase() = 0;
AquaSharedAttributes& GetShared() { return mrShared; }
SalGraphicsImpl* GetImpl()
{
return mpImpl;
}
virtual void UpdateGeometryProvider(SalGeometryProvider*) {};
virtual bool drawNativeControl(ControlType nType,
ControlPart nPart,
const tools::Rectangle &rControlRegion,
ControlState nState,
const ImplControlValue &aValue) = 0;
virtual void drawTextLayout(const GenericSalLayout& layout) = 0;
virtual void Flush() {}
virtual void Flush( const tools::Rectangle& ) {}
virtual void WindowBackingPropertiesChanged() {};
protected:
AquaGraphicsBackendBase(AquaSharedAttributes& rShared, SalGraphicsImpl * impl)
: mrShared( rShared ), mpImpl(impl)
{}
static bool performDrawNativeControl(ControlType nType,
ControlPart nPart,
const tools::Rectangle &rControlRegion,
ControlState nState,
const ImplControlValue &aValue,
CGContextRef context,
AquaSalFrame* mpFrame);
AquaSharedAttributes& mrShared;
private:
SalGraphicsImpl* mpImpl;
};
inline AquaGraphicsBackendBase::~AquaGraphicsBackendBase() {}
class AquaGraphicsBackend final : public SalGraphicsImpl, public AquaGraphicsBackendBase
{
private:
void drawPixelImpl( tools::Long nX, tools::Long nY, const RGBAColor& rColor); // helper to draw single pixels
#ifdef MACOSX
void refreshRect(const NSRect& rRect)
{
mrShared.refreshRect(rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height);
}
#else
void refreshRect(const CGRect& /*rRect*/)
{}
#endif
void pattern50Fill();
#ifdef MACOSX
void copyScaledArea(tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY,
tools::Long nSrcWidth, tools::Long nSrcHeight, AquaSharedAttributes* pSrcShared);
#endif
public:
AquaGraphicsBackend(AquaSharedAttributes & rShared);
~AquaGraphicsBackend() override;
OUString getRenderBackendName() const override
{
return "aqua";
}
void setClipRegion(vcl::Region const& rRegion) override;
void ResetClipRegion() override;
sal_uInt16 GetBitCount() const override;
tools::Long GetGraphicsWidth() const override;
void SetLineColor() override;
void SetLineColor(Color nColor) override;
void SetFillColor() override;
void SetFillColor(Color nColor) override;
void SetXORMode(bool bSet, bool bInvertOnly) override;
void SetROPLineColor(SalROPColor nROPColor) override;
void SetROPFillColor(SalROPColor nROPColor) override;
void drawPixel(tools::Long nX, tools::Long nY) override;
void drawPixel(tools::Long nX, tools::Long nY, Color nColor) override;
void drawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2) override;
void drawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight) override;
void drawPolyLine(sal_uInt32 nPoints, const Point* pPointArray) override;
void drawPolygon(sal_uInt32 nPoints, const Point* pPointArray) override;
void drawPolyPolygon(sal_uInt32 nPoly, const sal_uInt32* pPoints,
const Point** pPointArray) override;
void drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectToDevice,
const basegfx::B2DPolyPolygon&, double fTransparency) override;
bool drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDevice, const basegfx::B2DPolygon&,
double fTransparency, double fLineWidth, const std::vector<double>* pStroke,
basegfx::B2DLineJoin, css::drawing::LineCap, double fMiterMinimumAngle,
bool bPixelSnapHairline) override;
bool drawPolyLineBezier(sal_uInt32 nPoints, const Point* pPointArray,
const PolyFlags* pFlagArray) override;
bool drawPolygonBezier(sal_uInt32 nPoints, const Point* pPointArray,
const PolyFlags* pFlagArray) override;
bool drawPolyPolygonBezier(sal_uInt32 nPoly, const sal_uInt32* pPoints,
const Point* const* pPointArray,
const PolyFlags* const* pFlagArray) override;
void copyArea(tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY,
tools::Long nSrcWidth, tools::Long nSrcHeight, bool bWindowInvalidate) override;
void copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics) override;
void drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) override;
void drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,
const SalBitmap& rMaskBitmap) override;
void drawMask(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,
Color nMaskColor) override;
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
Color getPixel(tools::Long nX, tools::Long nY) override;
void invert(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight,
SalInvert nFlags) override;
void invert(sal_uInt32 nPoints, const Point* pPtAry, SalInvert nFlags) override;
bool drawEPS(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight,
void* pPtr, sal_uInt32 nSize) override;
bool blendBitmap(const SalTwoRect&, const SalBitmap& rBitmap) override;
bool blendAlphaBitmap(const SalTwoRect&, const SalBitmap& rSrcBitmap,
const SalBitmap& rMaskBitmap, const SalBitmap& rAlphaBitmap) override;
bool drawAlphaBitmap(const SalTwoRect&, const SalBitmap& rSourceBitmap,
const SalBitmap& rAlphaBitmap) override;
bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX,
const basegfx::B2DPoint& rY, const SalBitmap& rSourceBitmap,
const SalBitmap* pAlphaBitmap, double fAlpha) override;
bool drawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight,
sal_uInt8 nTransparency) override;
bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
bool implDrawGradient(basegfx::B2DPolyPolygon const& rPolyPolygon,
SalGradient const& rGradient) override;
virtual bool drawNativeControl(ControlType nType,
ControlPart nPart,
const tools::Rectangle &rControlRegion,
ControlState nState,
const ImplControlValue &aValue) override;
virtual void drawTextLayout(const GenericSalLayout& layout) override;
bool supportsOperation(OutDevSupportType eType) const override;
};
class AquaSalGraphics : public SalGraphicsAutoDelegateToImpl
{
AquaSharedAttributes maShared;
std::unique_ptr<AquaGraphicsBackendBase> mpBackend;
/// device resolution of this graphics
sal_Int32 mnRealDPIX;
sal_Int32 mnRealDPIY;
// Device Font settings
rtl::Reference<CoreTextFont> mpFont[MAX_FALLBACK];
public:
AquaSalGraphics(bool bPrinter = false);
virtual ~AquaSalGraphics() override;
void SetVirDevGraphics(SalVirtualDevice* pVirDev,CGLayerHolder const &rLayer, CGContextRef, int nBitDepth = 0);
#ifdef MACOSX
void initResolution( NSWindow* );
void copyResolution( AquaSalGraphics& );
void updateResolution();
void SetWindowGraphics( AquaSalFrame* pFrame );
bool IsWindowGraphics() const { return maShared.mbWindow; }
void SetPrinterGraphics(CGContextRef, sal_Int32 nRealDPIX, sal_Int32 nRealDPIY);
AquaSalFrame* getGraphicsFrame() const { return maShared.mpFrame; }
void setGraphicsFrame( AquaSalFrame* pFrame ) { maShared.mpFrame = pFrame; }
#endif
#ifdef MACOSX
void UpdateWindow( NSRect& ); // delivered in NSView coordinates
void RefreshRect(const NSRect& rRect)
{
maShared.refreshRect(rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height);
}
#else
void RefreshRect( const CGRect& ) {}
#endif
void Flush();
void Flush( const tools::Rectangle& );
void WindowBackingPropertiesChanged();
void UnsetState();
// InvalidateContext does an UnsetState and sets mrContext to 0
void InvalidateContext();
AquaGraphicsBackendBase* getAquaGraphicsBackend() const
{
return mpBackend.get();
}
virtual SalGraphicsImpl* GetImpl() const override;
#ifdef MACOSX
protected:
// native widget rendering methods that require mirroring
virtual bool isNativeControlSupported( ControlType nType, ControlPart nPart ) override;
virtual bool hitTestNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
const Point& aPos, bool& rIsInside ) override;
virtual bool drawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
ControlState nState, const ImplControlValue& aValue,
const OUString& aCaption, const Color& rBackgroundColor ) override;
public:
virtual bool getNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState nState,
const ImplControlValue& aValue, const OUString& aCaption,
tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion ) override;
#endif
public:
// get device resolution
virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) override;
// set the text color to a specific color
virtual void SetTextColor( Color nColor ) override;
// set the font
virtual void SetFont( LogicalFontInstance*, int nFallbackLevel ) override;
// get the current font's metrics
virtual void GetFontMetric( FontMetricDataRef&, int nFallbackLevel ) override;
// get the repertoire of the current font
virtual FontCharMapRef GetFontCharMap() const override;
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const override;
// graphics must fill supplied font list
virtual void GetDevFontList( vcl::font::PhysicalFontCollection* ) override;
// graphics must drop any cached font info
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
virtual void DrawTextLayout( const GenericSalLayout& ) override;
#ifdef MACOSX
virtual bool ShouldDownscaleIconsAtSurface(double& rScaleOut) const override;
#endif
virtual SystemGraphicsData
GetGraphicsData() const override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */