include/vcl/outdev.hxx                  |    5 +++++
 vcl/inc/salgdi.hxx                      |   11 +++++++++++
 vcl/inc/win/DWriteTextRenderer.hxx      |   16 ++++++++++------
 vcl/inc/win/salgdi.h                    |    2 +-
 vcl/inc/win/winlayout.hxx               |    8 +++++---
 vcl/qt5/QtGraphics_Text.cxx             |   17 ++++++++++++++++-
 vcl/skia/win/gdiimpl.cxx                |    8 +++++++-
 vcl/skia/x11/textrender.cxx             |   18 ++++++++++++++++--
 vcl/source/gdi/salgdilayout.cxx         |    3 ++-
 vcl/source/gdi/virdev.cxx               |    2 ++
 vcl/source/outdev/outdev.cxx            |   19 ++++++++++++++++---
 vcl/unx/generic/gdi/cairotextrender.cxx |   16 ++++++++++++++--
 vcl/win/gdi/DWriteTextRenderer.cxx      |   27 ++++++++++++++++-----------
 vcl/win/gdi/winlayout.cxx               |   25 +++++++++++++++++--------
 14 files changed, 138 insertions(+), 39 deletions(-)

New commits:
commit 99c51ce0e44bf03ddea0efd7612389faa636b658
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Wed Dec 22 15:49:52 2021 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu Jan 13 18:32:05 2022 +0100

    allow selecting text rendering mode suitable for natural glyph positions
    
    Change-Id: I6b8c815fda3a48917467719432071c0716e3e9ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127338
    Tested-by: Caolán McNamara <caol...@redhat.com>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 02faeb1477fb..ddeafe9f8599 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -242,6 +242,7 @@ private:
     Point                           maRefPoint;
     AntialiasingFlags               mnAntialiasing;
     LanguageType                    meTextLanguage;
+    bool mbTextRenderModeForResolutionIndependentLayout;
 
     mutable bool                    mbMap : 1;
     mutable bool                    mbClipRegion : 1;
@@ -486,6 +487,10 @@ public:
     void                        SetAntialiasing( AntialiasingFlags nMode );
     AntialiasingFlags           GetAntialiasing() const { return 
mnAntialiasing; }
 
+    // Render glyphs with a mode suitable for rendering of 
resolution-independent layout positions.
+    void                        
SetTextRenderModeForResolutionIndependentLayout(bool bMode);
+    bool                        
GetTextRenderModeForResolutionIndependentLayout() const { return 
mbTextRenderModeForResolutionIndependentLayout; }
+
     void                        SetDrawMode( DrawModeFlags nDrawMode );
     DrawModeFlags               GetDrawMode() const { return mnDrawMode; }
 
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index db3ed6806f7e..eed8ab7160ac 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -96,6 +96,16 @@ public:
         return m_bAntiAlias;
     }
 
+    void setTextRenderModeForResolutionIndependentLayout(bool bNew)
+    {
+        m_bTextRenderModeForResolutionIndependentLayout = bNew;
+    }
+
+    bool getTextRenderModeForResolutionIndependentLayoutEnabled() const
+    {
+        return m_bTextRenderModeForResolutionIndependentLayout;
+    }
+
     // public SalGraphics methods, the interface to the independent vcl part
 
     // get device resolution
@@ -636,6 +646,7 @@ private:
 protected:
     /// flags which hold the SetAntialiasing() value from OutputDevice
     bool                        m_bAntiAlias : 1;
+    bool                        
m_bTextRenderModeForResolutionIndependentLayout : 1;
 
     inline tools::Long GetDeviceWidth(const OutputDevice& rOutDev) const;
 
diff --git a/vcl/inc/win/DWriteTextRenderer.hxx 
b/vcl/inc/win/DWriteTextRenderer.hxx
index 77d26e750e5a..b64cc48a1c6a 100644
--- a/vcl/inc/win/DWriteTextRenderer.hxx
+++ b/vcl/inc/win/DWriteTextRenderer.hxx
@@ -37,12 +37,13 @@ enum class D2DTextAntiAliasMode
 class D2DWriteTextOutRenderer : public TextOutRenderer
 {
 public:
-    explicit D2DWriteTextOutRenderer();
+    explicit D2DWriteTextOutRenderer(bool bRenderingModeNatural);
     virtual ~D2DWriteTextOutRenderer() override;
 
-    bool operator ()(GenericSalLayout const &rLayout,
+    bool operator()(GenericSalLayout const &rLayout,
         SalGraphics &rGraphics,
-        HDC hDC) override;
+        HDC hDC,
+        bool bRenderingModeNatural) override;
 
     HRESULT BindDC(HDC hDC, tools::Rectangle const & rRect = 
tools::Rectangle(0, 0, 1, 1));
 
@@ -54,11 +55,13 @@ public:
     IDWriteFontFace   * GetFontFace() const { return mpFontFace; }
     float               GetEmHeight() const { return mlfEmHeight; }
 
-    HRESULT CreateRenderTarget();
+    HRESULT CreateRenderTarget(bool bRenderingModeNatural);
 
     bool Ready() const;
 
-    void applyTextAntiAliasMode();
+    void applyTextAntiAliasMode(bool bRenderingModeNatural);
+
+    bool GetRenderingModeNatural() const { return mbRenderingModeNatural; }
 
 private:
     // This is a singleton object disable copy ctor and assignment operator
@@ -66,7 +69,7 @@ private:
     D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = 
delete;
 
     bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * 
lfSize) const;
-    bool performRender(GenericSalLayout const &rLayout, SalGraphics 
&rGraphics, HDC hDC, bool& bRetry);
+    bool performRender(GenericSalLayout const &rLayout, SalGraphics 
&rGraphics, HDC hDC, bool& bRetry, bool bRenderingModeNatural);
 
     ID2D1Factory        * mpD2DFactory;
     IDWriteFactory      * mpDWriteFactory;
@@ -77,6 +80,7 @@ private:
     IDWriteFontFace * mpFontFace;
     float             mlfEmHeight;
     HDC               mhDC;
+    bool mbRenderingModeNatural;
     D2DTextAntiAliasMode meTextAntiAliasMode;
 };
 
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index b472ece0a256..7833f988bd18 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -316,7 +316,7 @@ public:
 private:
     // local helpers
 
-    void                    DrawTextLayout(const GenericSalLayout&, HDC, bool 
bUseDWrite);
+    void DrawTextLayout(const GenericSalLayout&, HDC, bool bUseDWrite, bool 
bRenderingModeNatural);
 
 public:
     // public SalGraphics methods, the interface to the independent vcl part
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 0b43ef4eeca1..5f56fe6b0c5e 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -75,13 +75,14 @@ protected:
     TextOutRenderer & operator = (const TextOutRenderer &) = delete;
 
 public:
-    static TextOutRenderer & get(bool bUseDWrite);
+    static TextOutRenderer & get(bool bUseDWrite, bool bRenderingModeNatural);
 
     virtual ~TextOutRenderer() = default;
 
     virtual bool operator ()(GenericSalLayout const &rLayout,
         SalGraphics &rGraphics,
-        HDC hDC) = 0;
+        HDC hDC,
+        bool bRenderingModeNatural) = 0;
 };
 
 class ExTextOutRenderer : public TextOutRenderer
@@ -94,7 +95,8 @@ public:
 
     bool operator ()(GenericSalLayout const &rLayout,
         SalGraphics &rGraphics,
-        HDC hDC) override;
+        HDC hDC,
+        bool bRenderingModeNatural) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtGraphics_Text.cxx b/vcl/qt5/QtGraphics_Text.cxx
index 37825c970327..02158fca29db 100644
--- a/vcl/qt5/QtGraphics_Text.cxx
+++ b/vcl/qt5/QtGraphics_Text.cxx
@@ -294,11 +294,26 @@ std::unique_ptr<GenericSalLayout> 
QtGraphics::GetTextLayout(int nFallbackLevel)
     return std::make_unique<QtCommonSalLayout>(*m_pTextStyle[nFallbackLevel]);
 }
 
+static QRawFont GetRawFont(const QFont& rFont, bool 
bWithoutHintingInTextDirection)
+{
+    QFont::HintingPreference eHinting = rFont.hintingPreference();
+    bool bAllowedHintStyle
+        = !bWithoutHintingInTextDirection
+          || (eHinting == QFont::PreferNoHinting || eHinting == 
QFont::PreferVerticalHinting);
+    if (bWithoutHintingInTextDirection && !bAllowedHintStyle)
+    {
+        QFont aFont(rFont);
+        aFont.setHintingPreference(QFont::PreferVerticalHinting);
+        return QRawFont::fromFont(aFont);
+    }
+    return QRawFont::fromFont(rFont);
+}
+
 void QtGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
 {
     const QtFont* pFont = static_cast<const QtFont*>(&rLayout.GetFont());
     assert(pFont);
-    QRawFont aRawFont(QRawFont::fromFont(*pFont));
+    QRawFont aRawFont(GetRawFont(*pFont, 
getTextRenderModeForResolutionIndependentLayoutEnabled()));
 
     QVector<quint32> glyphIndexes;
     QVector<QPointF> positions;
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 6686ecd0e8ed..e9074340e66e 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -287,8 +287,14 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const 
GenericSalLayout& rLayout)
     }
 
     SkFont font(typeface);
+
+    bool bSubpixelPositioning = 
mWinParent.getTextRenderModeForResolutionIndependentLayoutEnabled();
+    SkFont::Edging ePreferredAliasing
+        = bSubpixelPositioning ? SkFont::Edging::kSubpixelAntiAlias : 
fontEdging;
+    if (bSubpixelPositioning)
+        font.setSubpixel(true);
     font.setEdging(logFont.lfQuality == NONANTIALIASED_QUALITY ? 
SkFont::Edging::kAlias
-                                                               : fontEdging);
+                                                               : 
ePreferredAliasing);
 
     const vcl::font::FontSelectPattern& rFSD = 
pWinFont->GetFontSelectPattern();
     int nHeight = rFSD.mnHeight;
diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx
index a2d0dcbb36f6..9fda8ba6601c 100644
--- a/vcl/skia/x11/textrender.cxx
+++ b/vcl/skia/x11/textrender.cxx
@@ -57,8 +57,22 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& 
rLayout, const SalGr
         font.setSkewX(1.0 * -0x4000L / 0x10000L);
     if (rFont.NeedsArtificialBold())
         font.setEmbolden(true);
-    font.setEdging(rFont.GetAntialiasAdvice() ? SkFont::Edging::kAntiAlias
-                                              : SkFont::Edging::kAlias);
+
+    bool bSubpixelPositioning = 
rGraphics.getTextRenderModeForResolutionIndependentLayoutEnabled();
+    SkFont::Edging ePreferredAliasing
+        = bSubpixelPositioning ? SkFont::Edging::kSubpixelAntiAlias : 
SkFont::Edging::kAntiAlias;
+    if (bSubpixelPositioning)
+    {
+        font.setSubpixel(true);
+
+        SkFontHinting eHinting = font.getHinting();
+        bool bAllowedHintStyle
+            = eHinting == SkFontHinting::kNone || eHinting == 
SkFontHinting::kSlight;
+        if (!bAllowedHintStyle)
+            font.setHinting(SkFontHinting::kSlight);
+    }
+
+    font.setEdging(rFont.GetAntialiasAdvice() ? ePreferredAliasing : 
SkFont::Edging::kAlias);
 
     // Vertical font, use width as "height".
     SkFont verticalFont(font);
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index aafa8f157e70..b22d4594cafe 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -54,7 +54,8 @@ SalGraphics::SalGraphics()
     m_aLastMirrorW(0),
     m_nLastMirrorDeviceLTRButBiDiRtlTranslate(0),
     m_bLastMirrorDeviceLTRButBiDiRtlSet(false),
-    m_bAntiAlias(false)
+    m_bAntiAlias(false),
+    m_bTextRenderModeForResolutionIndependentLayout(false)
 {
     // read global RTL settings
     if( AllSettings::GetLayoutRTL() )
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
index 6a44cc1cd136..87721c683d77 100644
--- a/vcl/source/gdi/virdev.cxx
+++ b/vcl/source/gdi/virdev.cxx
@@ -379,6 +379,8 @@ bool VirtualDevice::ImplSetOutputSizePixel( const Size& 
rNewSize, bool bErase,
             mpAlphaVDev->SetMapMode( GetMapMode() );
 
             mpAlphaVDev->SetAntialiasing( GetAntialiasing() );
+
+            
mpAlphaVDev->SetTextRenderModeForResolutionIndependentLayout(GetTextRenderModeForResolutionIndependentLayout());
         }
 
         return true;
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 1083ff9b0d04..7f8167b5180b 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -105,6 +105,7 @@ OutputDevice::OutputDevice(OutDevType eOutDevType) :
     meRasterOp                      = RasterOp::OverPaint;
     mnAntialiasing                  = AntialiasingFlags::NONE;
     meTextLanguage                  = LANGUAGE_SYSTEM;  // TODO: get default 
from configuration?
+    mbTextRenderModeForResolutionIndependentLayout = false;
     mbLineColor                     = true;
     mbFillColor                     = true;
     mbInitLineColor                 = true;
@@ -345,16 +346,28 @@ void OutputDevice::SetAntialiasing( AntialiasingFlags 
nMode )
         mnAntialiasing = nMode;
         mbInitFont = true;
 
-        if(mpGraphics)
-        {
+        if (mpGraphics)
             mpGraphics->setAntiAlias(bool(mnAntialiasing & 
AntialiasingFlags::Enable));
-        }
     }
 
     if( mpAlphaVDev )
         mpAlphaVDev->SetAntialiasing( nMode );
 }
 
+void OutputDevice::SetTextRenderModeForResolutionIndependentLayout(bool bMode)
+{
+    if (mbTextRenderModeForResolutionIndependentLayout!= bMode)
+    {
+        mbTextRenderModeForResolutionIndependentLayout = bMode;
+
+        if (mpGraphics)
+            mpGraphics->setTextRenderModeForResolutionIndependentLayout(bMode);
+    }
+
+    if (mpAlphaVDev)
+        mpAlphaVDev->SetTextRenderModeForResolutionIndependentLayout(bMode);
+}
+
 void OutputDevice::SetDrawMode(DrawModeFlags nDrawMode)
 {
     mnDrawMode = nDrawMode;
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx 
b/vcl/unx/generic/gdi/cairotextrender.cxx
index 721528bc3683..7d24dce1e09f 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -172,12 +172,24 @@ void CairoTextRender::DrawTextLayout(const 
GenericSalLayout& rLayout, const SalG
     if (const cairo_font_options_t* pFontOptions = 
pSVData->mpDefInst->GetCairoFontOptions())
     {
         const StyleSettings& rStyleSettings = 
Application::GetSettings().GetStyleSettings();
-        if (!rStyleSettings.GetUseFontAAFromSystem() && 
!rGraphics.getAntiAlias())
+        bool bDisableAA = !rStyleSettings.GetUseFontAAFromSystem() && 
!rGraphics.getAntiAlias();
+
+        bool bWithoutHintingInTextDirection = 
rGraphics.getTextRenderModeForResolutionIndependentLayoutEnabled();
+        cairo_hint_style_t eHintStyle = 
cairo_font_options_get_hint_style(pFontOptions);
+        bool bAllowedHintStyle = !bWithoutHintingInTextDirection || 
(eHintStyle == CAIRO_HINT_STYLE_NONE || eHintStyle == CAIRO_HINT_STYLE_SLIGHT);
+
+        if (bDisableAA || !bAllowedHintStyle)
         {
             // Disable font AA in case global AA setting is supposed to affect
             // font rendering (not the default) and AA is disabled.
             cairo_font_options_t* pOptions = 
cairo_font_options_copy(pFontOptions);
-            cairo_font_options_set_antialias(pOptions, CAIRO_ANTIALIAS_NONE);
+            if (bDisableAA)
+                cairo_font_options_set_antialias(pOptions, 
CAIRO_ANTIALIAS_NONE);
+            if (!bAllowedHintStyle)
+            {
+                cairo_font_options_set_hint_style(pOptions, 
CAIRO_HINT_STYLE_SLIGHT);
+                cairo_font_options_set_hint_metrics(pOptions, 
CAIRO_HINT_METRICS_OFF);
+            }
             cairo_set_font_options(cr, pOptions);
             cairo_font_options_destroy(pOptions);
         }
diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx 
b/vcl/win/gdi/DWriteTextRenderer.cxx
index fbed3d28eddf..1ec441b00592 100644
--- a/vcl/win/gdi/DWriteTextRenderer.cxx
+++ b/vcl/win/gdi/DWriteTextRenderer.cxx
@@ -99,7 +99,7 @@ HRESULT checkResult(HRESULT hr, const char* file, size_t line)
 
 } // end anonymous namespace
 
-D2DWriteTextOutRenderer::D2DWriteTextOutRenderer()
+D2DWriteTextOutRenderer::D2DWriteTextOutRenderer(bool bRenderingModeNatural)
     : mpD2DFactory(nullptr),
     mpDWriteFactory(nullptr),
     mpGdiInterop(nullptr),
@@ -110,6 +110,7 @@ D2DWriteTextOutRenderer::D2DWriteTextOutRenderer()
     mpFontFace(nullptr),
     mlfEmHeight(0.0f),
     mhDC(nullptr),
+    mbRenderingModeNatural(bRenderingModeNatural),
     meTextAntiAliasMode(D2DTextAntiAliasMode::Default)
 {
     HRESULT hr = S_OK;
@@ -118,7 +119,7 @@ D2DWriteTextOutRenderer::D2DWriteTextOutRenderer()
     if (SUCCEEDED(hr))
     {
         hr = mpDWriteFactory->GetGdiInterop(&mpGdiInterop);
-        hr = CreateRenderTarget();
+        hr = CreateRenderTarget(bRenderingModeNatural);
     }
     meTextAntiAliasMode = lclGetSystemTextAntiAliasMode();
 }
@@ -135,7 +136,7 @@ D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer()
         mpD2DFactory->Release();
 }
 
-void D2DWriteTextOutRenderer::applyTextAntiAliasMode()
+void D2DWriteTextOutRenderer::applyTextAntiAliasMode(bool 
bRenderingModeNatural)
 {
     D2D1_TEXT_ANTIALIAS_MODE eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
     DWRITE_RENDERING_MODE eRenderingMode = DWRITE_RENDERING_MODE_DEFAULT;
@@ -160,11 +161,15 @@ void D2DWriteTextOutRenderer::applyTextAntiAliasMode()
         default:
             break;
     }
+
+    if (bRenderingModeNatural)
+        eRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
+
     mpRT->SetTextRenderingParams(lclSetRenderingMode(mpDWriteFactory, 
eRenderingMode));
     mpRT->SetTextAntialiasMode(eTextAAMode);
 }
 
-HRESULT D2DWriteTextOutRenderer::CreateRenderTarget()
+HRESULT D2DWriteTextOutRenderer::CreateRenderTarget(bool bRenderingModeNatural)
 {
     if (mpRT)
     {
@@ -173,7 +178,7 @@ HRESULT D2DWriteTextOutRenderer::CreateRenderTarget()
     }
     HRESULT hr = CHECKHR(mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT));
     if (SUCCEEDED(hr))
-        applyTextAntiAliasMode();
+        applyTextAntiAliasMode(bRenderingModeNatural);
     return hr;
 }
 
@@ -190,7 +195,7 @@ HRESULT D2DWriteTextOutRenderer::BindDC(HDC hDC, 
tools::Rectangle const & rRect)
     return CHECKHR(mpRT->BindDC(hDC, &rc));
 }
 
-bool D2DWriteTextOutRenderer::operator ()(GenericSalLayout const & rLayout, 
SalGraphics& rGraphics, HDC hDC)
+bool D2DWriteTextOutRenderer::operator()(GenericSalLayout const & rLayout, 
SalGraphics& rGraphics, HDC hDC, bool bRenderingModeNatural)
 {
     bool bRetry = false;
     bool bResult = false;
@@ -198,13 +203,13 @@ bool D2DWriteTextOutRenderer::operator 
()(GenericSalLayout const & rLayout, SalG
     do
     {
        bRetry = false;
-       bResult = performRender(rLayout, rGraphics, hDC, bRetry);
+       bResult = performRender(rLayout, rGraphics, hDC, bRetry, 
bRenderingModeNatural);
        nCount++;
     } while (bRetry && nCount < 3);
     return bResult;
 }
 
-bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, 
SalGraphics& rGraphics, HDC hDC, bool& bRetry)
+bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, 
SalGraphics& rGraphics, HDC hDC, bool& bRetry, bool bRenderingModeNatural)
 {
     if (!Ready())
         return false;
@@ -214,14 +219,14 @@ bool 
D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
 
     if (hr == D2DERR_RECREATE_TARGET)
     {
-        CreateRenderTarget();
+        CreateRenderTarget(bRenderingModeNatural);
         bRetry = true;
         return false;
     }
     if (FAILED(hr))
     {
         // If for any reason we can't bind fallback to legacy APIs.
-        return ExTextOutRenderer()(rLayout, rGraphics, hDC);
+        return ExTextOutRenderer()(rLayout, rGraphics, hDC, 
bRenderingModeNatural);
     }
 
     mlfEmHeight = 0;
@@ -286,7 +291,7 @@ bool 
D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
 
     if (hr == D2DERR_RECREATE_TARGET)
     {
-        CreateRenderTarget();
+        CreateRenderTarget(bRenderingModeNatural);
         bRetry = true;
     }
 
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index cb9bcc6a29da..673b223a263f 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -52,7 +52,7 @@
 #include <shlwapi.h>
 #include <winver.h>
 
-TextOutRenderer& TextOutRenderer::get(bool bUseDWrite)
+TextOutRenderer& TextOutRenderer::get(bool bUseDWrite, bool 
bRenderingModeNatural)
 {
     SalData* const pSalData = GetSalData();
 
@@ -64,9 +64,13 @@ TextOutRenderer& TextOutRenderer::get(bool bUseDWrite)
 
     if (bUseDWrite)
     {
-        if (!pSalData->m_pD2DWriteTextOutRenderer)
+        if (!pSalData->m_pD2DWriteTextOutRenderer
+            || 
static_cast<D2DWriteTextOutRenderer*>(pSalData->m_pD2DWriteTextOutRenderer.get())
+                       ->GetRenderingModeNatural()
+                   != bRenderingModeNatural)
         {
-            pSalData->m_pD2DWriteTextOutRenderer.reset(new 
D2DWriteTextOutRenderer());
+            pSalData->m_pD2DWriteTextOutRenderer.reset(
+                new D2DWriteTextOutRenderer(bRenderingModeNatural));
         }
         return *pSalData->m_pD2DWriteTextOutRenderer;
     }
@@ -78,7 +82,7 @@ TextOutRenderer& TextOutRenderer::get(bool bUseDWrite)
 }
 
 bool ExTextOutRenderer::operator()(GenericSalLayout const& rLayout, 
SalGraphics& /*rGraphics*/,
-                                   HDC hDC)
+                                   HDC hDC, bool /*bRenderingModeNatural*/)
 {
     int nStart = 0;
     DevicePoint aPos;
@@ -293,10 +297,11 @@ void WinFontInstance::SetGraphics(WinSalGraphics* 
pGraphics)
     SelectObject(hDC, hOrigFont);
 }
 
-void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout, HDC hDC, 
bool bUseDWrite)
+void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout, HDC hDC, 
bool bUseDWrite,
+                                    bool bRenderingModeNatural)
 {
-    TextOutRenderer& render = TextOutRenderer::get(bUseDWrite);
-    render(rLayout, *this, hDC);
+    TextOutRenderer& render = TextOutRenderer::get(bUseDWrite, 
bRenderingModeNatural);
+    render(rLayout, *this, hDC, bRenderingModeNatural);
 }
 
 void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
@@ -312,7 +317,11 @@ void WinSalGraphics::DrawTextLayout(const 
GenericSalLayout& rLayout)
     const HFONT hOrigFont = ::SelectFont(hDC, hLayoutFont);
 
     // DWrite text renderer performs vertical writing better except printing.
-    DrawTextLayout(rLayout, hDC, !mbPrinter && 
rLayout.GetFont().GetFontSelectPattern().mbVertical);
+    const bool bVerticalScreenText
+        = !mbPrinter && rLayout.GetFont().GetFontSelectPattern().mbVertical;
+    const bool bRenderingModeNatural = 
getTextRenderModeForResolutionIndependentLayoutEnabled();
+    const bool bUseDWrite = bVerticalScreenText || bRenderingModeNatural;
+    DrawTextLayout(rLayout, hDC, bUseDWrite, bRenderingModeNatural);
 
     ::SelectFont(hDC, hOrigFont);
 }

Reply via email to