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

Reply via email to