vcl/inc/skia/gdiimpl.hxx | 2 +- vcl/skia/gdiimpl.cxx | 42 ++++++++++++++++++++++++++++++++---------- vcl/skia/win/gdiimpl.cxx | 2 +- vcl/skia/x11/textrender.cxx | 10 ++++++++-- 4 files changed, 42 insertions(+), 14 deletions(-)
New commits: commit d3772e26c077686fc5ca0a8ba526df7d104ada5c Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Wed May 5 18:21:21 2021 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Mon May 24 10:58:18 2021 +0200 fix font scale width handling for Skia/X11 (tdf#136081) We get width+height, for vertical text width is the font "height". This means we need to use two different fonts, one for "normal" glyphs and one for vertical glyphs. Change-Id: I9d190fc28286055a18c3d5c3ec75515c7c1d4373 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115618 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx index 2eb2ffd26136..08d9f6ee64cc 100644 --- a/vcl/inc/skia/gdiimpl.hxx +++ b/vcl/inc/skia/gdiimpl.hxx @@ -223,7 +223,7 @@ public: Ignore }; void drawGenericLayout(const GenericSalLayout& layout, Color textColor, const SkFont& font, - GlyphOrientation glyphOrientation); + const SkFont& verticalFont, GlyphOrientation glyphOrientation); protected: // To be called before any drawing. diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 2e15d8dbb45f..b559231cd906 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -2060,13 +2060,16 @@ static double toCos(Degree10 degree10th) { return SkScalarCos(toRadian(degree10t static double toSin(Degree10 degree10th) { return SkScalarSin(toRadian(degree10th)); } void SkiaSalGraphicsImpl::drawGenericLayout(const GenericSalLayout& layout, Color textColor, - const SkFont& font, GlyphOrientation glyphOrientation) + const SkFont& font, const SkFont& verticalFont, + GlyphOrientation glyphOrientation) { SkiaZone zone; std::vector<SkGlyphID> glyphIds; std::vector<SkRSXform> glyphForms; + std::vector<bool> verticals; glyphIds.reserve(256); glyphForms.reserve(256); + verticals.reserve(256); Point aPos; const GlyphItem* pGlyph; int nStart = 0; @@ -2082,19 +2085,38 @@ void SkiaSalGraphicsImpl::drawGenericLayout(const GenericSalLayout& layout, Colo } SkRSXform form = SkRSXform::Make(toCos(angle), toSin(angle), aPos.X(), aPos.Y()); glyphForms.emplace_back(std::move(form)); + verticals.emplace_back(pGlyph->IsVertical()); } if (glyphIds.empty()) return; - sk_sp<SkTextBlob> textBlob - = SkTextBlob::MakeFromRSXform(glyphIds.data(), glyphIds.size() * sizeof(SkGlyphID), - glyphForms.data(), font, SkTextEncoding::kGlyphID); + preDraw(); - SAL_INFO("vcl.skia.trace", - "drawtextblob(" << this << "): " << textBlob->bounds() << ":" << textColor); - addUpdateRegion(textBlob->bounds()); - SkPaint paint; - paint.setColor(toSkColor(textColor)); - getDrawCanvas()->drawTextBlob(textBlob, 0, 0, paint); + auto getBoundRect = [&layout]() { + tools::Rectangle rect; + layout.GetBoundRect(rect); + return rect; + }; + SAL_INFO("vcl.skia.trace", "drawtextblob(" << this << "): " << getBoundRect() << ", " + << glyphIds.size() << " glyphs, " << textColor); + + // Vertical glyphs need a different font, so each run draw only consecutive horizontal or vertical glyphs. + std::vector<bool>::const_iterator pos = verticals.cbegin(); + std::vector<bool>::const_iterator end = verticals.cend(); + while (pos != end) + { + bool verticalRun = *pos; + std::vector<bool>::const_iterator rangeEnd = std::find(pos + 1, end, !verticalRun); + size_t index = pos - verticals.cbegin(); + size_t count = rangeEnd - pos; + sk_sp<SkTextBlob> textBlob = SkTextBlob::MakeFromRSXform( + glyphIds.data() + index, count * sizeof(SkGlyphID), glyphForms.data() + index, + verticalRun ? verticalFont : font, SkTextEncoding::kGlyphID); + addUpdateRegion(textBlob->bounds()); + SkPaint paint; + paint.setColor(toSkColor(textColor)); + getDrawCanvas()->drawTextBlob(textBlob, 0, 0, paint); + pos = rangeEnd; + } postDraw(); } diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index 5f7e1fe3538a..24daf1fc8b7c 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -240,7 +240,7 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(mWinParent.GetImpl()); COLORREF color = ::GetTextColor(mWinParent.getHDC()); Color salColor(GetRValue(color), GetGValue(color), GetBValue(color)); - impl->drawGenericLayout(rLayout, salColor, font, + impl->drawGenericLayout(rLayout, salColor, font, font, pWinFont->GetSkiaDWrite() ? GlyphOrientation::Apply : GlyphOrientation::Ignore); return true; diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx index 7021d9794f5e..c1086b57545a 100644 --- a/vcl/skia/x11/textrender.cxx +++ b/vcl/skia/x11/textrender.cxx @@ -48,7 +48,8 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr } sk_sp<SkTypeface> typeface = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()); - SkFont font(typeface, nHeight); + SkFont font(typeface); + font.setSize(nHeight); font.setScaleX(1.0 * nWidth / nHeight); if (rFont.NeedsArtificialItalic()) font.setSkewX(1.0 * -0x4000L / 0x10000L); @@ -57,9 +58,14 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr font.setEdging(rFont.GetAntialiasAdvice() ? SkFont::Edging::kAntiAlias : SkFont::Edging::kAlias); + // Vertical font, use width as "height". + SkFont verticalFont(font); + verticalFont.setSize(nWidth); + verticalFont.setScaleX(1.0 * nHeight / nWidth); + assert(dynamic_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl())); SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl()); - impl->drawGenericLayout(rLayout, mnTextColor, font, + impl->drawGenericLayout(rLayout, mnTextColor, font, verticalFont, SkiaSalGraphicsImpl::GlyphOrientation::Apply); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits