diff options
author | Armin Le Grand (Collabora) <Armin.Le.Grand@me.com> | 2024-08-02 15:56:52 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2024-08-05 12:29:02 +0200 |
commit | bf9e8d5ffd3f29fa027f0009a70f27d3456b648b (patch) | |
tree | 90a472d181b256d0571c603c7494a326cf89a2f5 | |
parent | e6d470293243f1a8dd3dbcb42258dd22e408e127 (diff) |
CairoSDPR: direct text rendering using Cairo
I have added basic support for the text primitives
(TextSimplePortionPrimitive2D) to the SDPR Cairo
renderer. It can now basically render Text using
a fallback to the already existing CairoTextRender.
NOTE: This is not yet complete, but for discussion.
Change-Id: I9b0c7b6bb4892905576593ef4e2b4071c7663c63
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171429
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
-rw-r--r-- | drawinglayer/source/primitive2d/textlayoutdevice.cxx | 32 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/cairopixelprocessor2d.cxx | 158 | ||||
-rw-r--r-- | include/drawinglayer/primitive2d/textlayoutdevice.hxx | 19 | ||||
-rw-r--r-- | include/drawinglayer/processor2d/cairopixelprocessor2d.hxx | 11 | ||||
-rw-r--r-- | include/vcl/vcllayout.hxx | 3 | ||||
-rw-r--r-- | vcl/headless/svptext.cxx | 10 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/unx/cairotextrender.hxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/cairotextrender.cxx | 37 |
12 files changed, 265 insertions, 21 deletions
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx index 3daecb4bec62..3a6667d0461f 100644 --- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx +++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx @@ -38,6 +38,8 @@ #include <vcl/metric.hxx> #include <i18nlangtag/languagetag.hxx> #include <vcl/svapp.hxx> +#include <vcl/vcllayout.hxx> +#include <vcl/glyphitemcache.hxx> namespace drawinglayer::primitive2d { @@ -192,6 +194,21 @@ void TextLayouterDevice::setFontAttribute(const attribute::FontAttribute& rFontA } } +void TextLayouterDevice::setLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode) +{ + mrDevice.SetLayoutMode(nTextLayoutMode); +} + +vcl::text::ComplexTextLayoutFlags TextLayouterDevice::getLayoutMode() const +{ + return mrDevice.GetLayoutMode(); +} + +void TextLayouterDevice::setTextColor(const basegfx::BColor& rColor) +{ + mrDevice.SetTextColor(Color(rColor)); +} + double TextLayouterDevice::getOverlineOffset() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); @@ -348,6 +365,21 @@ std::vector<double> TextLayouterDevice::getTextArray(const OUString& rText, sal_ return aRetval; } +std::unique_ptr<SalLayout> TextLayouterDevice::getSalLayout(const OUString& rText, + sal_uInt32 nIndex, sal_uInt32 nLength, + const basegfx::B2DPoint& rStartPoint, + const KernArray& rDXArray, + std::span<const sal_Bool> pKashidaAry) +{ + const SalLayoutGlyphs* pGlyphs( + SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&mrDevice, rText, nIndex, nLength)); + const Point aStartPoint(basegfx::fround<tools::Long>(rStartPoint.getX()), + basegfx::fround<tools::Long>(rStartPoint.getY())); + KernArraySpan aKernArraySpan(rDXArray); + return mrDevice.ImplLayout(rText, nIndex, nLength, aStartPoint, 0, aKernArraySpan, pKashidaAry, + SalLayoutFlags::NONE, nullptr, pGlyphs); +} + // helper methods for vcl font handling vcl::Font getVclFontFromFontAttribute(const attribute::FontAttribute& rFontAttribute, diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx index f6483e4a795e..baea016068c1 100644 --- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx @@ -39,12 +39,17 @@ #include <drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx> #include <drawinglayer/primitive2d/PolyPolygonRGBAPrimitive2D.hxx> #include <drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> #include <drawinglayer/converters.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <basegfx/curve/b2dcubicbezier.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <basegfx/utils/systemdependentdata.hxx> #include <basegfx/utils/bgradient.hxx> #include <vcl/BitmapReadAccess.hxx> +#include <officecfg/Office/Common.hxx> +#include <vcl/vcllayout.hxx> #include <unordered_map> #include <dlfcn.h> @@ -285,7 +290,7 @@ void checkAndDoPixelSnap(cairo_t* pRT, // with the comments above at CairoPathHelper we cannot do PixelSnap // at path construction time, so it needs to be done *after* the path - // data is added to the cairo context. ADvantage is that all general + // data is added to the cairo context. Advantage is that all general // path data can be buffered, though, but needs view-dependent manipulation // here after being added. // For now, just snap all points - no real need to identify hor/ver lines @@ -807,6 +812,10 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D& : BaseProcessor2D(rViewInformation) , maBColorModifierStack() , mpRT(nullptr) + , mbRenderSimpleTextDirect( + officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get()) + , mbRenderDecoratedTextDirect( + officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get()) { if (pTarget) { @@ -2793,6 +2802,141 @@ void CairoPixelProcessor2D::processBitmapAlphaPrimitive2D( rBitmapAlphaPrimitive2D.getTransparency()); } +void CairoPixelProcessor2D::processTextSimplePortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rCandidate) +{ + if (SAL_LIKELY(mbRenderSimpleTextDirect)) + { + renderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate); + } + else + { + process(rCandidate); + } +} + +void CairoPixelProcessor2D::processTextDecoratedPortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rCandidate) +{ + if (SAL_LIKELY(mbRenderDecoratedTextDirect)) + { + renderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate); + } + else + { + process(rCandidate); + } +} + +void CairoPixelProcessor2D::renderTextSimpleOrDecoratedPortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate) +{ + // decompose matrix to have global position and scale of text + const basegfx::B2DHomMatrix aGlobalFontTransform( + getViewInformation2D().getObjectToViewTransformation() * rTextCandidate.getTextTransform()); + basegfx::B2DVector aGlobalFontScaling, aGlobalFontTranslate; + double fGlobalFontRotate, fGlobalFontShearX; + aGlobalFontTransform.decompose(aGlobalFontScaling, aGlobalFontTranslate, fGlobalFontRotate, + fGlobalFontShearX); + + // decompose primitive-local matrix to get local font scaling + double fLocalFontRotate, fLocalFontShearX; + basegfx::B2DVector aLocalFontSize, aLocalFontTranslate; + rTextCandidate.getTextTransform().decompose(aLocalFontSize, aLocalFontTranslate, + fLocalFontRotate, fLocalFontShearX); + + // Get the VCL font from existing processor tooling. Do not use + // rotation, for Cairo we can transform the whole text render and + // thus handle the xext in it's local coordinate system untransformed + vcl::Font aFont(primitive2d::getVclFontFromFontAttribute( + rTextCandidate.getFontAttribute(), aGlobalFontScaling.getX(), aGlobalFontScaling.getY(), + 0.0, rTextCandidate.getLocale())); + + if (aFont.GetFontSize().Height() <= 0) + { + // Don't draw fonts without height, error. use decompose as fallback + process(rTextCandidate); + return; + } + + // set FillColor Attribute at Font + Color aFillColor( + maBColorModifierStack.getModifiedColor(rTextCandidate.getTextFillColor().getBColor())); + aFont.SetTransparent(rTextCandidate.getTextFillColor().IsTransparent()); + if (rTextCandidate.getTextFillColor().IsTransparent()) + aFillColor.SetAlpha(rTextCandidate.getTextFillColor().GetAlpha()); + aFont.SetFillColor(aFillColor); + + // create integer DXArray. As mentioned above we can act in the + // Text's local coordinate system without transformation at all + const ::std::vector<double>& rDXArray(rTextCandidate.getDXArray()); + KernArray aDXArray; + + if (!rDXArray.empty()) + { + aDXArray.reserve(rDXArray.size()); + for (auto const& elem : rDXArray) + aDXArray.push_back(basegfx::fround(elem)); + } + + // set parameters and paint text snippet + const basegfx::BColor aRGBFontColor( + maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor())); + + // create a TextLayouter to access encapsulated VCL Text/Font related tooling + primitive2d::TextLayouterDevice aTextLayouter; + aTextLayouter.setFontAttribute(rTextCandidate.getFontAttribute(), aLocalFontSize.getX(), + aLocalFontSize.getY(), rTextCandidate.getLocale()); + aTextLayouter.setTextColor(aRGBFontColor); + + if (rTextCandidate.getFontAttribute().getRTL()) + { + vcl::text::ComplexTextLayoutFlags nRTLLayoutMode( + aTextLayouter.getLayoutMode() & ~vcl::text::ComplexTextLayoutFlags::BiDiStrong); + nRTLLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl + | vcl::text::ComplexTextLayoutFlags::TextOriginLeft; + aTextLayouter.setLayoutMode(nRTLLayoutMode); + } + else + { + // tdf#101686: This is LTR text, but the output device may have RTL state. + vcl::text::ComplexTextLayoutFlags nLTRLayoutMode(aTextLayouter.getLayoutMode()); + nLTRLayoutMode = nLTRLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiRtl; + nLTRLayoutMode = nLTRLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiStrong; + aTextLayouter.setLayoutMode(nLTRLayoutMode); + } + + // create SalLayout. No need for a position, as mentioned text can work + // without transformations, so start point is always 0,0 + std::unique_ptr<SalLayout> pSalLayout(aTextLayouter.getSalLayout( + rTextCandidate.getText(), rTextCandidate.getTextPosition(), rTextCandidate.getTextLength(), + basegfx::B2DPoint(0.0, 0.0), aDXArray, rTextCandidate.getKashidaArray())); + + if (!pSalLayout) + { + // got no layout, error. use decompose as fallback + process(rTextCandidate); + return; + } + + // draw using Cairo, use existing tooling (this tunnels to + // CairoTextRender::ImplDrawTextLayout) + cairo_save(mpRT); + const basegfx::B2DHomMatrix aObjTransformWithoutScale( + basegfx::utils::createShearXRotateTranslateB2DHomMatrix(fLocalFontShearX, fLocalFontRotate, + aLocalFontTranslate)); + const basegfx::B2DHomMatrix aFullTextTransform( + getViewInformation2D().getObjectToViewTransformation() * aObjTransformWithoutScale); + + cairo_matrix_t aMatrix; + cairo_matrix_init(&aMatrix, aFullTextTransform.a(), aFullTextTransform.b(), + aFullTextTransform.c(), aFullTextTransform.d(), aFullTextTransform.e(), + aFullTextTransform.f()); + cairo_set_matrix(mpRT, &aMatrix); + pSalLayout->drawSalLayout(mpRT, aRGBFontColor, getViewInformation2D().getUseAntiAliasing()); + cairo_restore(mpRT); +} + void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch (rCandidate.getPrimitive2DID()) @@ -2921,6 +3065,18 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimit static_cast<const primitive2d::BitmapAlphaPrimitive2D&>(rCandidate)); break; } + case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D: + { + processTextSimplePortionPrimitive2D( + static_cast<const primitive2d::TextSimplePortionPrimitive2D&>(rCandidate)); + break; + } + case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D: + { + processTextDecoratedPortionPrimitive2D( + static_cast<const primitive2d::TextSimplePortionPrimitive2D&>(rCandidate)); + break; + } // continue with decompose default: diff --git a/include/drawinglayer/primitive2d/textlayoutdevice.hxx b/include/drawinglayer/primitive2d/textlayoutdevice.hxx index db019494a8c0..de7a1e214a2a 100644 --- a/include/drawinglayer/primitive2d/textlayoutdevice.hxx +++ b/include/drawinglayer/primitive2d/textlayoutdevice.hxx @@ -25,11 +25,14 @@ #include <vector> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <vcl/svapp.hxx> +#include <span> // predefines class VirtualDevice; class GDIMetaFile; enum class DrawTextFlags; +class SalLayout; +class KernArray; namespace vcl { class Font; @@ -46,6 +49,14 @@ namespace com::sun::star::lang { struct Locale; } +namespace vcl::text +{ +enum class ComplexTextLayoutFlags : sal_uInt8; +} +namespace basegfx +{ +class BColor; +} // access to one global impTimedRefDev incarnation in namespace drawinglayer::primitive @@ -75,6 +86,9 @@ public: void setFont(const vcl::Font& rFont); void setFontAttribute(const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, const css::lang::Locale& rLocale); + void setLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode); + vcl::text::ComplexTextLayoutFlags getLayoutMode() const; + void setTextColor(const basegfx::BColor& rColor); double getTextHeight() const; double getOverlineHeight() const; @@ -100,6 +114,11 @@ public: ::std::vector<double> getTextArray(const OUString& rText, sal_uInt32 nIndex, sal_uInt32 nLength, bool bCaret = false) const; + std::unique_ptr<SalLayout> getSalLayout(const OUString& rText, sal_uInt32 nIndex, + sal_uInt32 nLength, + const basegfx::B2DPoint& rStartPoint, + const KernArray& rDXArray, + std::span<const sal_Bool> pKashidaAry); }; // helper methods for vcl font handling diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx index 129daaef86fa..21cffda24e7c 100644 --- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx +++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx @@ -39,6 +39,7 @@ class PolyPolygonRGBAGradientPrimitive2D; class FillGraphicPrimitive2D; class PolyPolygonRGBAPrimitive2D; class BitmapAlphaPrimitive2D; +class TextSimplePortionPrimitive2D; } namespace basegfx @@ -58,6 +59,10 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub // cairo specific data cairo_t* mpRT; + // get text render config settings + bool mbRenderSimpleTextDirect; + bool mbRenderDecoratedTextDirect; + // helpers for direct paints void paintPolyPoylgonRGBA(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rColor, double fTransparency = 0.0); @@ -99,6 +104,12 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub double fTransparency = 0.0); void processBitmapAlphaPrimitive2D( const primitive2d::BitmapAlphaPrimitive2D& rBitmapAlphaPrimitive2D); + void processTextSimplePortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rCandidate); + void processTextDecoratedPortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rCandidate); + void renderTextSimpleOrDecoratedPortionPrimitive2D( + const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate); /* the local processor for BasePrimitive2D-Implementation based primitives, called from the common process()-implementation diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx index dd0747eae3ec..9c84d7453a3c 100644 --- a/include/vcl/vcllayout.hxx +++ b/include/vcl/vcllayout.hxx @@ -32,6 +32,7 @@ class LogicalFontInstance; namespace vcl::text { class ImplLayoutArgs; } namespace vcl::font { class PhysicalFontFace; } +namespace basegfx { class BColor; } class SalGraphics; class GlyphItem; @@ -120,6 +121,8 @@ public: virtual SalLayoutGlyphs GetGlyphs() const; + virtual void drawSalLayout(void* /*pSurface*/, const basegfx::BColor& /*rTextColor*/, bool /*bAntiAliased*/) const {} + protected: // used by layout engines SalLayout(); diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index ff9653aa6f6d..22b7b37c5507 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -69,6 +69,16 @@ void SvpSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout) m_aTextRenderImpl.DrawTextLayout(rLayout, *this); } +void SvpSalGraphics::DrawSalLayout(const GenericSalLayout& rLayout, void* pSurface, const basegfx::BColor& rTextColor, bool bAntiAliased) const +{ + CairoTextRender::ImplDrawTextLayout( + static_cast<cairo_t*>(pSurface), + Color(rTextColor), + rLayout, + nullptr, + bAntiAliased); +} + void SvpSalGraphics::SetTextColor( Color nColor ) { m_aTextRenderImpl.SetTextColor(nColor); diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 78d04d753ac4..0c4476e9aa5b 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -78,6 +78,7 @@ public: virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout( const GenericSalLayout& ) override; + virtual void DrawSalLayout(const GenericSalLayout& rLayout, void* pSurface, const basegfx::BColor& rTextColor, bool bAntiAliased) const override; virtual bool ShouldDownscaleIconsAtSurface(double* pScaleOut) const override; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index d592bc10daea..4296cb4e3e51 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -162,6 +162,7 @@ public: virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) = 0; virtual void DrawTextLayout( const GenericSalLayout& ) = 0; + virtual void DrawSalLayout(const GenericSalLayout&, void*, const basegfx::BColor&, bool ) const {} virtual bool supportsOperation( OutDevSupportType ) const = 0; diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index 0b10629fcb3e..fdb5151bc2a5 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -136,6 +136,8 @@ public: const SalLayoutGlyphsImpl& GlyphsImpl() const { return m_GlyphItems; } + virtual void drawSalLayout(void* /*pSurface*/, const basegfx::BColor& /*rTextColor*/, bool /*bAntiAliased*/) const override; + private: // for glyph+font+script fallback SAL_DLLPRIVATE void MoveGlyph(int nStart, double nNewXPos); diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx index 50848ed19fa6..e98d12bf207e 100644 --- a/vcl/inc/unx/cairotextrender.hxx +++ b/vcl/inc/unx/cairotextrender.hxx @@ -34,10 +34,13 @@ private: protected: cairo_t* getCairoContext(); void releaseCairoContext(cairo_t* cr); - void clipRegion(cairo_t* cr); public: - virtual void DrawTextLayout(const GenericSalLayout&, const SalGraphics&) override; + // helper to call DrawTextLayout with already setup cairo_t context, + // so no CairoCommon is needed. + static void ImplDrawTextLayout(cairo_t* cr, const Color& rTextColor, const GenericSalLayout& rLayout, CairoCommon* pCairoCommon, bool bAntiAlias); + + virtual void DrawTextLayout(const GenericSalLayout&, const SalGraphics&) override; CairoTextRender(CairoCommon& rCairoCommon); virtual ~CairoTextRender(); }; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index e11fcbacd35a..2463301a4d05 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -1029,4 +1029,9 @@ bool GenericSalLayout::IsKashidaPosValid(int nCharPos, int nNextCharPos) const return rNextGlyph->IsSafeToInsertKashida(); } +void GenericSalLayout::drawSalLayout(void* pSurface, const basegfx::BColor& rTextColor, bool bAntiAliased) const +{ + Application::GetDefaultDevice()->GetGraphics()->DrawSalLayout(*this, pSurface, rTextColor, bAntiAliased); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 7e7ce9ca700f..9c201a2cc1ec 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -240,10 +240,6 @@ static CairoFontsCache::CacheId makeCacheId(const GenericSalLayout& rLayout) void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGraphics& rGraphics) { - const LogicalFontInstance& rInstance = rLayout.GetFont(); - - const bool bSubpixelPositioning = rLayout.GetSubpixelPositioning(); - /* * It might be ideal to cache surface and cairo context between calls and * only destroy it when the drawable changes, but to do that we need to at @@ -258,6 +254,15 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG } comphelper::ScopeGuard releaseContext([this, cr]() { releaseCairoContext(cr); }); + // void CairoCommon::clipRegion(cairo_t* cr) { CairoCommon::clipRegion(cr, m_aClipRegion); } + ImplDrawTextLayout(cr, mnTextColor, rLayout, &mrCairoCommon, rGraphics.getAntiAlias()); +} + +void CairoTextRender::ImplDrawTextLayout(cairo_t* cr, const Color& rTextColor, const GenericSalLayout& rLayout, CairoCommon* pCairoCommon, bool bAntiAlias) +{ + const LogicalFontInstance& rInstance = rLayout.GetFont(); + const bool bSubpixelPositioning = rLayout.GetSubpixelPositioning(); + std::vector<cairo_glyph_t> cairo_glyphs; std::vector<int> glyph_extrarotation; cairo_glyphs.reserve( 256 ); @@ -342,13 +347,14 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG } #endif - clipRegion(cr); + if (nullptr != pCairoCommon) + pCairoCommon->clipRegion(cr); cairo_set_source_rgba(cr, - mnTextColor.GetRed()/255.0, - mnTextColor.GetGreen()/255.0, - mnTextColor.GetBlue()/255.0, - mnTextColor.GetAlpha()/255.0); + rTextColor.GetRed()/255.0, + rTextColor.GetGreen()/255.0, + rTextColor.GetBlue()/255.0, + rTextColor.GetAlpha()/255.0); int nRatio = nWidth * 10 / nHeight; @@ -381,9 +387,9 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG ApplyFont(temp_cr, aId, nHeight, nHeight, 0, rLayout); cairo_set_source_rgb(temp_cr, - mnTextColor.GetRed()/255.0, - mnTextColor.GetGreen()/255.0, - mnTextColor.GetBlue()/255.0); + rTextColor.GetRed()/255.0, + rTextColor.GetGreen()/255.0, + rTextColor.GetBlue()/255.0); cairo_show_glyphs(temp_cr, &glyph, 1); cairo_destroy(temp_cr); @@ -417,7 +423,7 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG #endif const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); - const bool bDisableAA = !rStyleSettings.GetUseFontAAFromSystem() && !rGraphics.getAntiAlias(); + const bool bDisableAA = !rStyleSettings.GetUseFontAAFromSystem() && !bAntiAlias; static bool bAllowDefaultHinting = getenv("SAL_ALLOW_DEFAULT_HINTING") != nullptr; const cairo_font_options_t* pFontOptions = GetSalInstance()->GetCairoFontOptions(); @@ -505,11 +511,6 @@ cairo_t* CairoTextRender::getCairoContext() return mrCairoCommon.getCairoContext(/*bXorModeAllowed*/false, /*bAntiAlias*/true); } -void CairoTextRender::clipRegion(cairo_t* cr) -{ - mrCairoCommon.clipRegion(cr); -} - void CairoTextRender::releaseCairoContext(cairo_t* cr) { mrCairoCommon.releaseCairoContext(cr, /*bXorModeAllowed*/false, basegfx::B2DRange()); |