summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-05-23 20:21:59 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-05-24 20:20:54 +0200
commit770892a387361067d23ab08ed38690c50b8b9395 (patch)
tree099d1cc78a6dd1a896f6855bb95ebe345ef3b9e4
parentde01c1978216373a9aa7cd01e28186d2752e6cc4 (diff)
platforms using the cairo canvas use cairo for text rendering already
this wasn't true at the time the canvas text rendering was written but it is true now so its better now to just simplify this to using the vcl text rendering to render the text through cairo Change-Id: I1e63496e03e2cedc3e36e2bf10b0eab90a549629 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94736 Tested-by: Caolán McNamara <caolanm@redhat.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--canvas/source/cairo/cairo_canvashelper_text.cxx4
-rw-r--r--canvas/source/cairo/cairo_textlayout.cxx200
-rw-r--r--canvas/source/cairo/cairo_textlayout.hxx3
3 files changed, 12 insertions, 195 deletions
diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx
index fc0d70947b26..b7c101ef3956 100644
--- a/canvas/source/cairo/cairo_canvashelper_text.cxx
+++ b/canvas/source/cairo/cairo_canvashelper_text.cxx
@@ -276,7 +276,7 @@ namespace cairocanvas
clip_cairo_from_dev(*mpVirtualDevice);
rtl::Reference pTextLayout( new TextLayout(text, textDirection, 0, CanvasFont::Reference(dynamic_cast< CanvasFont* >( xFont.get() )), mpSurfaceProvider) );
- pTextLayout->draw(mpCairo, *mpVirtualDevice, aOutpos, viewState, renderState);
+ pTextLayout->draw(*mpVirtualDevice, aOutpos, viewState, renderState);
}
return uno::Reference< rendering::XCachedPrimitive >(nullptr);
@@ -318,7 +318,7 @@ namespace cairocanvas
clip_cairo_from_dev(*mpVirtualDevice);
// TODO(F2): What about the offset scalings?
- pTextLayout->draw(mpCairo, *mpVirtualDevice, aOutpos, viewState, renderState);
+ pTextLayout->draw(*mpVirtualDevice, aOutpos, viewState, renderState);
}
}
else
diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx
index 32a62c5ea790..04db33135578 100644
--- a/canvas/source/cairo/cairo_textlayout.cxx
+++ b/canvas/source/cairo/cairo_textlayout.cxx
@@ -77,11 +77,6 @@ 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,
@@ -297,207 +292,30 @@ 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( CairoSharedPtr const & pSCairo,
- OutputDevice& rOutDev,
+ void TextLayout::draw( 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 );
- // 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)
+ if (maLogicalAdvancements.hasElements())
{
- 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;
- }
- }
+ rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(),
+ ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition),
+ ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) );
}
-
- // 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)
+ else
{
- 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);
+ rOutDev.DrawText( rOutpos, maText.Text,
+ ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition),
+ ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) );
}
}
diff --git a/canvas/source/cairo/cairo_textlayout.hxx b/canvas/source/cairo/cairo_textlayout.hxx
index b5ba2d84bb21..c7dd023af1bf 100644
--- a/canvas/source/cairo/cairo_textlayout.hxx
+++ b/canvas/source/cairo/cairo_textlayout.hxx
@@ -82,8 +82,7 @@ namespace cairocanvas
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
- void draw( ::cairo::CairoSharedPtr const & pSCairo,
- OutputDevice& rOutDev,
+ void draw( OutputDevice& rOutDev,
const Point& rOutpos,
const css::rendering::ViewState& viewState,
const css::rendering::RenderState& renderState ) const;