diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-09-07 19:53:02 +0100 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2020-09-08 10:22:17 +0200 |
commit | ee18059ed6402eb0725048b3dd406852120a9faf (patch) | |
tree | 4cd998be7703475227b19508d2dfc0abc82f8a06 | |
parent | 72549d97c220d63d5fd5f6f38ae14f13c3e3d919 (diff) |
tdf#136545 revert cairo canvas uses cairo for text rendering already
This was the fallback path, so the problem must already exist in the uncommon
fallback case. I think I know the best approach to take, but for the 7-0 case
be conservative and restore the historic state.
this reverts 770892a387361067d23ab08ed38690c50b8b9395 and associated
code removal
Change-Id: I0e61d934e4dae03442ca5910f802199a1d3d53f4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102197
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r-- | canvas/source/cairo/cairo_canvashelper_text.cxx | 4 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_textlayout.cxx | 227 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_textlayout.hxx | 5 | ||||
-rw-r--r-- | include/vcl/outdev.hxx | 15 | ||||
-rw-r--r-- | include/vcl/sysdata.hxx | 43 | ||||
-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/qt5/Qt5Graphics.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 6 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 6 | ||||
-rw-r--r-- | vcl/inc/textrender.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/unx/freetypetextrender.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/unx/genpspgraphics.h | 2 | ||||
-rw-r--r-- | vcl/inc/unx/glyphcache.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 1 | ||||
-rw-r--r-- | vcl/qt5/Qt5Graphics.cxx | 5 | ||||
-rw-r--r-- | vcl/source/control/button.cxx | 1 | ||||
-rw-r--r-- | vcl/source/gdi/sallayout.cxx | 9 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 17 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 61 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/font.cxx | 9 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/freetypetextrender.cxx | 23 | ||||
-rw-r--r-- | vcl/unx/generic/print/genpspgraphics.cxx | 5 |
24 files changed, 448 insertions, 17 deletions
diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx index 830388775670..3b4d161417bd 100644 --- a/canvas/source/cairo/cairo_canvashelper_text.cxx +++ b/canvas/source/cairo/cairo_canvashelper_text.cxx @@ -254,7 +254,7 @@ namespace cairocanvas mpVirtualDevice->SetLayoutMode( nLayoutMode ); rtl::Reference pTextLayout( new TextLayout(text, textDirection, 0, CanvasFont::Reference(dynamic_cast< CanvasFont* >( xFont.get() )), mpSurfaceProvider) ); - pTextLayout->draw(*mpVirtualDevice, aOutpos, viewState, renderState); + pTextLayout->draw(mpCairo, *mpVirtualDevice, aOutpos, viewState, renderState); } return uno::Reference< rendering::XCachedPrimitive >(nullptr); @@ -289,7 +289,7 @@ namespace cairocanvas return uno::Reference< rendering::XCachedPrimitive >(nullptr); // no output necessary // TODO(F2): What about the offset scalings? - pTextLayout->draw(*mpVirtualDevice, aOutpos, viewState, renderState); + pTextLayout->draw(mpCairo, *mpVirtualDevice, aOutpos, viewState, renderState); } } else diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx index d81a739b4956..32a62c5ea790 100644 --- a/canvas/source/cairo/cairo_textlayout.cxx +++ b/canvas/source/cairo/cairo_textlayout.cxx @@ -77,6 +77,11 @@ namespace cairocanvas // as required at the API spec rOutDev.SetLayoutMode( nLayoutMode | ComplexTextLayoutFlags::TextOriginLeft ); } + + bool compareFallbacks(const SystemGlyphData&rA, const SystemGlyphData &rB) + { + return rA.fallbacklevel < rB.fallbacklevel; + } } TextLayout::TextLayout( const rendering::StringContext& aText, @@ -257,6 +262,33 @@ namespace cairocanvas } /** + * TextLayout::isCairoRenderable + * + * Features currently not supported by Cairo (VCL rendering is used as fallback): + * - vertical glyphs + * + * @return true, if text/font can be rendered with cairo + **/ + bool TextLayout::isCairoRenderable(SystemFontData aSysFontData) const + { +#if defined CAIRO_HAS_FT_FONT + // is font usable? + if (!aSysFontData.nFontId) + return false; +#endif + + // vertical glyph rendering is not supported in cairo for now + if (aSysFontData.bVerticalCharacterType) + { + SAL_WARN("canvas.cairo", ":cairocanvas::TextLayout::isCairoRenderable(): Vertical Character Style not supported"); + return false; + } + + return true; + } + + + /** * TextLayout::draw * * Cairo-based text rendering. Draw text directly on the cairo surface with cairo fonts. @@ -265,30 +297,207 @@ namespace cairocanvas * Note: some text effects are not rendered due to lacking generic canvas or cairo canvas * implementation. See issues 92657, 92658, 92659, 92660, 97529 **/ - void TextLayout::draw( OutputDevice& rOutDev, + void TextLayout::draw( CairoSharedPtr const & pSCairo, + OutputDevice& rOutDev, const Point& rOutpos, const rendering::ViewState& viewState, const rendering::RenderState& renderState ) const { ::osl::MutexGuard aGuard( m_aMutex ); + SystemTextLayoutData aSysLayoutData; setupLayoutMode( rOutDev, mnTextDirection ); + // TODO(P2): cache that std::unique_ptr< long []> aOffsets(new long[maLogicalAdvancements.getLength()]); if( maLogicalAdvancements.hasElements() ) + { setupTextOffsets( aOffsets.get(), maLogicalAdvancements, viewState, renderState ); - if (maLogicalAdvancements.hasElements()) + // TODO(F3): ensure correct length and termination for DX + // array (last entry _must_ contain the overall width) + } + + aSysLayoutData = rOutDev.GetSysTextLayoutData(rOutpos, maText.Text, + ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), + ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length), + maLogicalAdvancements.hasElements() ? aOffsets.get() : nullptr); + + // Sort them so that all glyphs on the same glyph fallback level are consecutive + std::sort(aSysLayoutData.rGlyphData.begin(), aSysLayoutData.rGlyphData.end(), compareFallbacks); + bool bCairoRenderable = true; + + //Pull all the fonts we need to render the text + typedef std::pair<SystemFontData,int> FontLevel; + std::vector<FontLevel> aFontData; + for (auto const& glyph : aSysLayoutData.rGlyphData) { - rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(), - ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), - ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); + if( aFontData.empty() || glyph.fallbacklevel != aFontData.back().second ) + { + aFontData.emplace_back(rOutDev.GetSysFontData(glyph.fallbacklevel), + glyph.fallbacklevel); + if( !isCairoRenderable(aFontData.back().first) ) + { + bCairoRenderable = false; + SAL_INFO("canvas.cairo", ":cairocanvas::TextLayout::draw(S,O,p,v,r): VCL FALLBACK " << + (maLogicalAdvancements.hasElements() ? "ADV " : "") << + (aFontData.back().first.bAntialias ? "AA " : "") << + (aFontData.back().first.bFakeBold ? "FB " : "") << + (aFontData.back().first.bFakeItalic ? "FI " : "") << + " - " << + maText.Text.copy( maText.StartPosition, maText.Length)); + break; + } + } } - else + + // The ::GetSysTextLayoutData(), i.e. layouting of text to glyphs can change the font being used. + // The fallback checks need to be done after final font is known. + if (!bCairoRenderable) // VCL FALLBACKS { - rOutDev.DrawText( rOutpos, maText.Text, - ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), - ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); + if (maLogicalAdvancements.hasElements()) // VCL FALLBACK - with glyph advances + { + rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(), + ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), + ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); + return; + } + else // VCL FALLBACK - without advances + { + rOutDev.DrawText( rOutpos, maText.Text, + ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), + ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); + return; + } + } + + if (aSysLayoutData.rGlyphData.empty()) + return; //??? false? + + /** + * Setup platform independent glyph vector into cairo-based glyphs vector. + **/ + + // Loop through the fonts used and render the matching glyphs for each + for (auto const& elemFontData : aFontData) + { + const SystemFontData &rSysFontData = elemFontData.first; + + // setup glyphs + std::vector<cairo_glyph_t> cairo_glyphs; + cairo_glyphs.reserve( 256 ); + + for (auto const& systemGlyph : aSysLayoutData.rGlyphData) + { + if( systemGlyph.fallbacklevel != elemFontData.second ) + continue; + + cairo_glyph_t aGlyph; + aGlyph.index = systemGlyph.index; + aGlyph.x = systemGlyph.x; + aGlyph.y = systemGlyph.y; + cairo_glyphs.push_back(aGlyph); + } + + if (cairo_glyphs.empty()) + continue; + + const vcl::Font& aFont = rOutDev.GetFont(); + long nWidth = aFont.GetAverageFontWidth(); + long nHeight = aFont.GetFontHeight(); + if (nWidth == 0) + nWidth = nHeight; + if (nWidth == 0 || nHeight == 0) + continue; + + /** + * Setup font + **/ + cairo_font_face_t* font_face = nullptr; + +#if defined CAIRO_HAS_FT_FONT + font_face = cairo_ft_font_face_create_for_ft_face(static_cast<FT_Face>(rSysFontData.nFontId), + rSysFontData.nFontFlags); +#else +# error Native API needed. +#endif + + cairo_set_font_face( pSCairo.get(), font_face); + + // create default font options. cairo_get_font_options() does not retrieve the surface defaults, + // only what has been set before with cairo_set_font_options() + cairo_font_options_t* options = cairo_font_options_create(); + if (rSysFontData.bAntialias) + { + // CAIRO_ANTIALIAS_GRAY provides more similar result to VCL Canvas, + // so we're not using CAIRO_ANTIALIAS_SUBPIXEL + cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY); + } + cairo_set_font_options( pSCairo.get(), options); + + // Font color + Color aTextColor = rOutDev.GetTextColor(); + cairo_set_source_rgb(pSCairo.get(), + aTextColor.GetRed()/255.0, + aTextColor.GetGreen()/255.0, + aTextColor.GetBlue()/255.0); + + // Font rotation and scaling + cairo_matrix_t m; + + cairo_matrix_init_identity(&m); + + if (aSysLayoutData.orientation) + cairo_matrix_rotate(&m, (3600 - aSysLayoutData.orientation) * M_PI / 1800.0); + + cairo_matrix_scale(&m, nWidth, nHeight); + + //faux italics + if (rSysFontData.bFakeItalic) + m.xy = -m.xx * 0x6000 / 0x10000; + + cairo_set_font_matrix(pSCairo.get(), &m); + + SAL_INFO( + "canvas.cairo", + "Size:(" << aFont.GetAverageFontWidth() << "," << aFont.GetFontHeight() + << "), Pos (" << rOutpos.X() << "," << rOutpos.Y() + << "), G(" + << (!cairo_glyphs.empty() ? cairo_glyphs[0].index : -1) + << "," + << (cairo_glyphs.size() > 1 ? cairo_glyphs[1].index : -1) + << "," + << (cairo_glyphs.size() > 2 ? cairo_glyphs[2].index : -1) + << ") " << (maLogicalAdvancements.hasElements() ? "ADV " : "") + << (rSysFontData.bAntialias ? "AA " : "") + << (rSysFontData.bFakeBold ? "FB " : "") + << (rSysFontData.bFakeItalic ? "FI " : "") << " || Name:" + << aFont.GetFamilyName() << " - " + << maText.Text.copy(maText.StartPosition, maText.Length)); + + cairo_show_glyphs(pSCairo.get(), cairo_glyphs.data(), cairo_glyphs.size()); + + //faux bold + if (rSysFontData.bFakeBold) + { + double bold_dx = 0.5 * sqrt( 0.7 * aFont.GetFontHeight() ); + int total_steps = 1 * static_cast<int>(bold_dx + 0.5); + + // loop to draw the text for every half pixel of displacement + for (int nSteps = 0; nSteps < total_steps; nSteps++) + { + for(cairo_glyph_t & cairo_glyph : cairo_glyphs) + { + cairo_glyph.x += (bold_dx * nSteps / total_steps) / 4; + cairo_glyph.y -= (bold_dx * nSteps / total_steps) / 4; + } + cairo_show_glyphs(pSCairo.get(), cairo_glyphs.data(), cairo_glyphs.size()); + } + SAL_INFO("canvas.cairo",":cairocanvas::TextLayout::draw(S,O,p,v,r): FAKEBOLD - dx:" << static_cast<int>(bold_dx)); + } + + cairo_font_face_destroy(font_face); + cairo_font_options_destroy(options); } } diff --git a/canvas/source/cairo/cairo_textlayout.hxx b/canvas/source/cairo/cairo_textlayout.hxx index 6254108a50ad..b5ba2d84bb21 100644 --- a/canvas/source/cairo/cairo_textlayout.hxx +++ b/canvas/source/cairo/cairo_textlayout.hxx @@ -82,7 +82,8 @@ namespace cairocanvas virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; - void draw( OutputDevice& rOutDev, + void draw( ::cairo::CairoSharedPtr const & pSCairo, + OutputDevice& rOutDev, const Point& rOutpos, const css::rendering::ViewState& viewState, const css::rendering::RenderState& renderState ) const; @@ -101,6 +102,8 @@ namespace cairocanvas CanvasFont::Reference mpFont; SurfaceProviderRef mpRefDevice; sal_Int8 mnTextDirection; + + bool isCairoRenderable(SystemFontData aSysFontData) const; }; } diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 372d1a7e4830..26a2920b86e1 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -55,6 +55,8 @@ struct ImplOutDevData; class LogicalFontInstance; struct SystemGraphicsData; +struct SystemFontData; +struct SystemTextLayoutData; class ImplFontCache; class PhysicalFontCollection; class ImplDeviceFontList; @@ -1231,6 +1233,15 @@ public: bool GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const; + + /** Retrieve detailed font information in platform independent structure + + @param nFallbacklevel Fallback font level (0 = best matching font) + + @return SystemFontData + */ + SystemFontData GetSysFontData( int nFallbacklevel ) const; + SAL_DLLPRIVATE void ImplGetEmphasisMark( tools::PolyPolygon& rPolyPoly, bool& rPolyLine, tools::Rectangle& rRect1, tools::Rectangle& rRect2, long& rYOff, long& rWidth, FontEmphasisMark eEmphasis, long nHeight ); SAL_DLLPRIVATE static FontEmphasisMark @@ -1320,6 +1331,10 @@ private: public: + SystemTextLayoutData GetSysTextLayoutData( const Point& rStartPt, const OUString& rStr, + sal_Int32 nIndex, sal_Int32 nLen, + const long* pDXAry ) const; + // tells whether this output device is RTL in an LTR UI or LTR in a RTL UI SAL_DLLPRIVATE bool ImplIsAntiparallel() const ; SAL_DLLPRIVATE void ReMirror( Point &rPoint ) const; diff --git a/include/vcl/sysdata.hxx b/include/vcl/sysdata.hxx index 1be73fef8856..3152fa3bed56 100644 --- a/include/vcl/sysdata.hxx +++ b/include/vcl/sysdata.hxx @@ -185,6 +185,49 @@ struct SystemWindowData #endif }; +struct SystemGlyphData +{ + sal_uInt32 index; + double x; + double y; + int fallbacklevel; +}; + +#if ENABLE_CAIRO_CANVAS + +struct SystemFontData +{ +#if defined( UNX ) + void* nFontId; // native font id + int nFontFlags; // native font flags +#endif + bool bFakeBold; // Does this font need faking the bold style + bool bFakeItalic; // Does this font need faking the italic style + bool bAntialias; // Should this font be antialiased + bool bVerticalCharacterType; // Is the font using vertical character type + + SystemFontData() + : +#if defined( UNX ) + nFontId( nullptr ), + nFontFlags( 0 ), +#endif + bFakeBold( false ), + bFakeItalic( false ), + bAntialias( true ), + bVerticalCharacterType( false ) + { + } +}; + +#endif // ENABLE_CAIRO_CANVAS + +struct SystemTextLayoutData +{ + std::vector<SystemGlyphData> rGlyphData; // glyph data + int orientation; // Text orientation +}; + #endif // INCLUDED_VCL_SYSDATA_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx index 1d6aa9f174f5..99884011e928 100644 --- a/include/vcl/vcllayout.hxx +++ b/include/vcl/vcllayout.hxx @@ -89,7 +89,8 @@ public: // methods using glyph indexing virtual bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, - const PhysicalFontFace** pFallbackFont = nullptr) const = 0; + const PhysicalFontFace** pFallbackFont = nullptr, + int* const pFallbackLevel = nullptr) const = 0; virtual bool GetOutline(basegfx::B2DPolyPolygonVector&) const; bool GetBoundRect(tools::Rectangle&) const; diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index f44373f5acc1..e4b625b365cb 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -22,6 +22,7 @@ #include <vcl/fontcharmap.hxx> #include <basegfx/range/b2ibox.hxx> #include <headless/svpgdi.hxx> +#include <config_cairo_canvas.h> #include <impfontmetricdata.hxx> #include <sallayout.hxx> @@ -108,4 +109,13 @@ void SvpSalGraphics::SetTextColor( Color nColor ) m_aTextRenderImpl.SetTextColor(nColor); } +#if ENABLE_CAIRO_CANVAS + +SystemFontData SvpSalGraphics::GetSysFontData( int nFallbacklevel ) const +{ + return m_aTextRenderImpl.GetSysFontData(nFallbacklevel); +} + +#endif // ENABLE_CAIRO_CANVAS + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 3cffdcd2a1c0..3d1617d07100 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -273,6 +273,7 @@ public: virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const override; virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const override; virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override; + virtual SystemFontData GetSysFontData( int nFallbacklevel ) const override; #endif // ENABLE_CAIRO_CANVAS cairo_t* getCairoContext(bool bXorModeAllowed) const; diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx index 1515783f6076..bc4870ee7e18 100644 --- a/vcl/inc/qt5/Qt5Graphics.hxx +++ b/vcl/inc/qt5/Qt5Graphics.hxx @@ -92,6 +92,7 @@ public: const Size& rSize) const override; virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override; + virtual SystemFontData GetSysFontData(int nFallbacklevel) const override; #endif // ENABLE_CAIRO_CANVAS // GDI diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index d2b92c65110f..8d8e4c96dbf3 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -48,6 +48,10 @@ class OutputDevice; class FreetypeFont; struct SystemGraphicsData; +#if ENABLE_CAIRO_CANVAS +struct SystemFontData; +#endif // ENABLE_CAIRO_CANVAS + namespace basegfx { class B2DVector; class B2DPolygon; @@ -431,6 +435,8 @@ public: virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const = 0; virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const = 0; + virtual SystemFontData GetSysFontData( int nFallbacklevel ) const = 0; + #endif // ENABLE_CAIRO_CANVAS protected: diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index 9ab526365ea7..e94b4c20531e 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -130,7 +130,8 @@ public: DeviceCoordinate FillDXArray(DeviceCoordinate* pDXArray) const override; void GetCaretPositions(int nArraySize, long* pCaretXArray) const override; bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, - const PhysicalFontFace** pFallbackFont = nullptr) const override; + const PhysicalFontFace** pFallbackFont = nullptr, + int* const pFallbackLevel = nullptr) const override; bool GetOutline(basegfx::B2DPolyPolygonVector&) const override; bool IsKashidaPosValid(int nCharPos) const override; @@ -183,7 +184,8 @@ public: { return m_GlyphItems.Impl()->GetFont(); } bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, - const PhysicalFontFace** pFallbackFont = nullptr) const override; + const PhysicalFontFace** pFallbackFont = nullptr, + int* const pFallbackLevel = nullptr) const override; private: // for glyph+font+script fallback diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx index f1cbfd8990b5..1aec8fba2301 100644 --- a/vcl/inc/textrender.hxx +++ b/vcl/inc/textrender.hxx @@ -22,6 +22,8 @@ #include "salgdi.hxx" +#include <config_cairo_canvas.h> + class ImplLayoutArgs; class ImplFontMetricData; class PhysicalFontCollection; @@ -62,6 +64,9 @@ public: virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) = 0; virtual void DrawTextLayout(const GenericSalLayout&, const SalGraphics&) = 0; +#if ENABLE_CAIRO_CANVAS + virtual SystemFontData GetSysFontData( int nFallbackLevel ) const = 0; +#endif // ENABLE_CAIRO_CANVAS }; #endif diff --git a/vcl/inc/unx/freetypetextrender.hxx b/vcl/inc/unx/freetypetextrender.hxx index 9c4960e0f36c..ccc1db0157d2 100644 --- a/vcl/inc/unx/freetypetextrender.hxx +++ b/vcl/inc/unx/freetypetextrender.hxx @@ -65,6 +65,9 @@ public: virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; +#if ENABLE_CAIRO_CANVAS + virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override; +#endif }; #endif diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h index c02d6aa21fe3..b696618c75ca 100644 --- a/vcl/inc/unx/genpspgraphics.h +++ b/vcl/inc/unx/genpspgraphics.h @@ -203,6 +203,8 @@ public: virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const override; virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const override; virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override; + + virtual SystemFontData GetSysFontData( int nFallbacklevel ) const override; #endif // ENABLE_CAIRO_CANVAS }; diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index 993a0cf49a22..983a6ec0382e 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -116,6 +116,7 @@ public: int GetFontFaceVariation() const; bool TestFont() const { return mbFaceOk;} FT_Face GetFtFace() const; + int GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); } const FontConfigFontOptions* GetFontOptions() const; bool NeedsArtificialBold() const { return mbArtBold; } bool NeedsArtificialItalic() const { return mbArtItalic; } @@ -129,6 +130,8 @@ public: bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const; bool GetAntialiasAdvice() const; + FreetypeFontInstance& GetFontInstance() const { return mrFontInstance; } + void SetFontVariationsOnHBFont(hb_font_t* pHbFace) const; // tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal brace glyphs diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index caef46a1a2e8..4216b703c14e 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -264,6 +264,7 @@ public: virtual cairo::SurfaceSharedPtr CreateSurface(const OutputDevice& rRefDevice, int x, int y, int width, int height) const override; virtual cairo::SurfaceSharedPtr CreateBitmapSurface(const OutputDevice& rRefDevice, const BitmapSystemData& rData, const Size& rSize) const override; virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override; + virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override; void clipRegion(cairo_t* cr); #endif // ENABLE_CAIRO_CANVAS diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx index 257e0f436334..34f610812d45 100644 --- a/vcl/qt5/Qt5Graphics.cxx +++ b/vcl/qt5/Qt5Graphics.cxx @@ -104,6 +104,11 @@ css::uno::Any Qt5Graphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& /*rSu return css::uno::Any(); } +SystemFontData Qt5Graphics::GetSysFontData(int /*nFallbacklevel*/) const +{ + return SystemFontData(); +} + #endif void Qt5Graphics::handleDamage(const tools::Rectangle& rDamagedRegion) diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index 1f9e2573e144..7e0a1bfa81fa 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -1528,6 +1528,7 @@ void PushButton::SetState( TriState eState ) void PushButton::statusChanged(const css::frame::FeatureStateEvent& rEvent) { Button::statusChanged(rEvent); + fprintf(stderr, "State is %d\n", rEvent.State.has<bool>()); if (rEvent.State.has<bool>()) SetPressed(rEvent.State.get<bool>()); } diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index 55aa145095be..eaa016ed1927 100644 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -895,7 +895,7 @@ sal_Int32 GenericSalLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoor bool GenericSalLayout::GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, - const PhysicalFontFace**) const + const PhysicalFontFace**, int* const pFallbackLevel) const { std::vector<GlyphItem>::const_iterator pGlyphIter = m_GlyphItems.Impl()->begin(); std::vector<GlyphItem>::const_iterator pGlyphIterEnd = m_GlyphItems.Impl()->end(); @@ -918,6 +918,8 @@ bool GenericSalLayout::GetNextGlyph(const GlyphItem** pGlyph, // update return data with glyph info *pGlyph = &(*pGlyphIter); + if (pFallbackLevel) + *pFallbackLevel = 0; ++nStart; // calculate absolute position in pixel units @@ -1504,7 +1506,8 @@ void MultiSalLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) cons bool MultiSalLayout::GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, - const PhysicalFontFace** pFallbackFont) const + const PhysicalFontFace** pFallbackFont, + int* const pFallbackLevel) const { // NOTE: nStart is tagged with current font index int nLevel = static_cast<unsigned>(nStart) >> GF_FONTSHIFT; @@ -1520,6 +1523,8 @@ bool MultiSalLayout::GetNextGlyph(const GlyphItem** pGlyph, nStart |= nFontTag; if (pFallbackFont) *pFallbackFont = pFontFace; + if (pFallbackLevel) + *pFallbackLevel = nLevel; rPos += maDrawBase; rPos += maDrawOffset; return true; diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index b7d8bfeeba7c..59ce4ef52a99 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -278,6 +278,23 @@ bool OutputDevice::GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities return mpGraphics->GetFontCapabilities(rFontCapabilities); } +#if ENABLE_CAIRO_CANVAS + +SystemFontData OutputDevice::GetSysFontData(int nFallbacklevel) const +{ + SystemFontData aSysFontData; + + if (!mpGraphics) + (void) AcquireGraphics(); + + if (mpGraphics) + aSysFontData = mpGraphics->GetSysFontData(nFallbacklevel); + + return aSysFontData; +} + +#endif // ENABLE_CAIRO_CANVAS + void OutputDevice::ImplGetEmphasisMark( tools::PolyPolygon& rPolyPoly, bool& rPolyLine, tools::Rectangle& rRect1, tools::Rectangle& rRect2, long& rYOff, long& rWidth, diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index b11e1e480503..34db8e6299c1 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -2254,6 +2254,67 @@ OUString OutputDevice::GetNonMnemonicString( const OUString& rStr, sal_Int32& rM return aStr; } +/** OutputDevice::GetSysTextLayoutData + * + * @param rStartPt Start point of the text + * @param rStr Text string that will be transformed into layout of glyphs + * @param nIndex Position in the string from where layout will be done + * @param nLen Length of the string + * @param pDXAry Custom layout adjustment data + * + * Export finalized glyph layout data as platform independent SystemTextLayoutData + * (see vcl/inc/vcl/sysdata.hxx) + * + * Only parameters rStartPt and rStr are mandatory, the rest is optional + * (default values will be used) + * + * @return SystemTextLayoutData + **/ +SystemTextLayoutData OutputDevice::GetSysTextLayoutData(const Point& rStartPt, const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen, + const long* pDXAry) const +{ + if( (nLen < 0) || (nIndex + nLen >= rStr.getLength())) + { + nLen = rStr.getLength() - nIndex; + } + + SystemTextLayoutData aSysLayoutData; + aSysLayoutData.rGlyphData.reserve( 256 ); + aSysLayoutData.orientation = 0; + + if ( mpMetaFile ) + { + if (pDXAry) + mpMetaFile->AddAction( new MetaTextArrayAction( rStartPt, rStr, pDXAry, nIndex, nLen ) ); + else + mpMetaFile->AddAction( new MetaTextAction( rStartPt, rStr, nIndex, nLen ) ); + } + + if ( !IsDeviceOutputNecessary() ) return aSysLayoutData; + + std::unique_ptr<SalLayout> pLayout = ImplLayout(rStr, nIndex, nLen, rStartPt, 0, pDXAry); + + if ( !pLayout ) return aSysLayoutData; + + // setup glyphs + Point aPos; + const GlyphItem* pGlyph; + int nStart = 0; + SystemGlyphData aSystemGlyph; + while (pLayout->GetNextGlyph(&pGlyph, aPos, nStart, nullptr, &aSystemGlyph.fallbacklevel)) + { + aSystemGlyph.index = pGlyph->glyphId(); + aSystemGlyph.x = aPos.X(); + aSystemGlyph.y = aPos.Y(); + aSysLayoutData.rGlyphData.push_back(aSystemGlyph); + } + + // Get font data + aSysLayoutData.orientation = pLayout->GetOrientation(); + + return aSysLayoutData; +} + bool OutputDevice::GetTextBoundRect( tools::Rectangle& rRect, const OUString& rStr, sal_Int32 nBase, sal_Int32 nIndex, sal_Int32 nLen, diff --git a/vcl/unx/generic/gdi/font.cxx b/vcl/unx/generic/gdi/font.cxx index 5a6f04fd856f..ede4d953c48e 100644 --- a/vcl/unx/generic/gdi/font.cxx +++ b/vcl/unx/generic/gdi/font.cxx @@ -80,6 +80,15 @@ std::unique_ptr<GenericSalLayout> X11SalGraphics::GetTextLayout(int nFallbackLev return mxTextRenderImpl->GetTextLayout(nFallbackLevel); } +#if ENABLE_CAIRO_CANVAS + +SystemFontData X11SalGraphics::GetSysFontData( int nFallbackLevel ) const +{ + return mxTextRenderImpl->GetSysFontData(nFallbackLevel); +} + +#endif + bool X11SalGraphics::CreateFontSubset( const OUString& rToFile, const PhysicalFontFace* pFont, diff --git a/vcl/unx/generic/gdi/freetypetextrender.cxx b/vcl/unx/generic/gdi/freetypetextrender.cxx index b364406f1e1d..3d94da30440a 100644 --- a/vcl/unx/generic/gdi/freetypetextrender.cxx +++ b/vcl/unx/generic/gdi/freetypetextrender.cxx @@ -153,6 +153,29 @@ std::unique_ptr<GenericSalLayout> FreeTypeTextRenderImpl::GetTextLayout(int nFal return std::make_unique<GenericSalLayout>(*mpFreetypeFont[nFallbackLevel]); } +#if ENABLE_CAIRO_CANVAS +SystemFontData FreeTypeTextRenderImpl::GetSysFontData( int nFallbackLevel ) const +{ + SystemFontData aSysFontData; + + if (nFallbackLevel >= MAX_FALLBACK) nFallbackLevel = MAX_FALLBACK - 1; + if (nFallbackLevel < 0 ) nFallbackLevel = 0; + + if (mpFreetypeFont[nFallbackLevel]) + { + FreetypeFont& rFreetypeFont = mpFreetypeFont[nFallbackLevel]->GetFreetypeFont(); + aSysFontData.nFontId = rFreetypeFont.GetFtFace(); + aSysFontData.nFontFlags = rFreetypeFont.GetLoadFlags(); + aSysFontData.bFakeBold = rFreetypeFont.NeedsArtificialBold(); + aSysFontData.bFakeItalic = rFreetypeFont.NeedsArtificialItalic(); + aSysFontData.bAntialias = rFreetypeFont.GetAntialiasAdvice(); + aSysFontData.bVerticalCharacterType = mpFreetypeFont[nFallbackLevel]->GetFontSelectPattern().mbVertical; + } + + return aSysFontData; +} +#endif + bool FreeTypeTextRenderImpl::CreateFontSubset( const OUString& rToFile, const PhysicalFontFace* pFont, diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 03319d1acf53..235f45eb83a4 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -944,6 +944,11 @@ css::uno::Any GenPspGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& /* return css::uno::Any(); } +SystemFontData GenPspGraphics::GetSysFontData( int /* nFallbacklevel */ ) const +{ + return SystemFontData(); +} + #endif // ENABLE_CAIRO_CANVAS bool GenPspGraphics::supportsOperation( OutDevSupportType ) const |