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>
diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx
index 8303887..3b4d161 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 d81a739..32a62c5 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())
{
rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(),
::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition),
::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) );
// TODO(F3): ensure correct length and termination for DX
// array (last entry _must_ contain the overall width)
}
else
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.DrawText( rOutpos, maText.Text,
::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;
}
}
}
// 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
{
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 6254108..b5ba2d8 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 372d1a7..26a2920 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 1be73fe..3152fa3 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 1d6aa9f..9988401 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 f44373f..e4b625b 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 3cffdcd..3d1617d 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 1515783..bc4870ee 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 d2b92c6..8d8e4c9 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 9ab5263..e94b4c2 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 f1cbfd8..1aec8fb 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 9c4960e..ccc1db0 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 c02d6aa..b696618 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 993a0cf..983a6ec 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 caef46a..4216b70 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 257e0f4..34f6108 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 1f9e257..7e0a1bf 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 55aa1450..eaa016ed 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 b7d8bfe..59ce4ef 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 b11e1e4..34db8e6 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 5a6f04f..ede4d95 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 b364406..3d94da3 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 03319d1..235f45e 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