[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - canvas/source include/vcl vcl/headless vcl/inc vcl/qt5 vcl/source vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Tue Sep 8 08:22:51 UTC 2020
canvas/source/cairo/cairo_canvashelper_text.cxx | 4
canvas/source/cairo/cairo_textlayout.cxx | 227 +++++++++++++++++++++++-
canvas/source/cairo/cairo_textlayout.hxx | 5
include/vcl/outdev.hxx | 15 +
include/vcl/sysdata.hxx | 43 ++++
include/vcl/vcllayout.hxx | 3
vcl/headless/svptext.cxx | 10 +
vcl/inc/headless/svpgdi.hxx | 1
vcl/inc/qt5/Qt5Graphics.hxx | 1
vcl/inc/salgdi.hxx | 6
vcl/inc/sallayout.hxx | 6
vcl/inc/textrender.hxx | 5
vcl/inc/unx/freetypetextrender.hxx | 3
vcl/inc/unx/genpspgraphics.h | 2
vcl/inc/unx/glyphcache.hxx | 3
vcl/inc/unx/salgdi.h | 1
vcl/qt5/Qt5Graphics.cxx | 5
vcl/source/control/button.cxx | 1
vcl/source/gdi/sallayout.cxx | 9
vcl/source/outdev/font.cxx | 17 +
vcl/source/outdev/text.cxx | 61 ++++++
vcl/unx/generic/gdi/font.cxx | 9
vcl/unx/generic/gdi/freetypetextrender.cxx | 23 ++
vcl/unx/generic/print/genpspgraphics.cxx | 5
24 files changed, 448 insertions(+), 17 deletions(-)
New commits:
commit ee18059ed6402eb0725048b3dd406852120a9faf
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Sep 7 19:53:02 2020 +0100
Commit: Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Tue Sep 8 10:22:17 2020 +0200
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 at libreoffice.org>
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,
@@ -256,6 +261,33 @@ namespace cairocanvas
return maText;
}
+ /**
+ * 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
*
@@ -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
More information about the Libreoffice-commits
mailing list