summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/win/DWriteTextRenderer.hxx12
-rw-r--r--vcl/inc/win/winlayout.hxx1
-rw-r--r--vcl/win/gdi/DWriteTextRenderer.cxx21
-rw-r--r--vcl/win/gdi/winlayout.cxx19
4 files changed, 47 insertions, 6 deletions
diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx
index 92e0825bb8b3..a84cf81b9b66 100644
--- a/vcl/inc/win/DWriteTextRenderer.hxx
+++ b/vcl/inc/win/DWriteTextRenderer.hxx
@@ -81,6 +81,18 @@ private:
D2DTextAntiAliasMode meTextAntiAliasMode;
};
+/// Sets and unsets the needed DirectWrite transform to support the font's horizontal scaling.
+class WinFontStretchGuard
+{
+public:
+ WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale);
+ ~WinFontStretchGuard();
+
+private:
+ ID2D1RenderTarget* mpRenderTarget;
+ D2D1::Matrix3x2F maTransform;
+};
+
#endif // INCLUDED_VCL_INC_WIN_DWRITERENDERER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 279c155b0a97..257c92e1a672 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -151,6 +151,7 @@ public:
~WinFontInstance() override;
bool hasHScale() const;
+ float getHScale() const;
void SetGraphics(WinSalGraphics*);
WinSalGraphics* GetGraphics() const { return m_pGraphics; }
diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx
index 117b35989b1c..dac6452a41a5 100644
--- a/vcl/win/gdi/DWriteTextRenderer.cxx
+++ b/vcl/win/gdi/DWriteTextRenderer.cxx
@@ -232,6 +232,10 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
if (!GetDWriteFaceFromHDC(hDC, &mpFontFace, &mlfEmHeight))
return false;
+ const WinFontInstance& rWinFont = static_cast<const WinFontInstance&>(rLayout.GetFont());
+ float fHScale = rWinFont.getHScale();
+ WinFontStretchGuard aStretchGuard(mpRT, fHScale);
+
tools::Rectangle bounds;
bool succeeded = rLayout.GetBoundRect(bounds);
if (succeeded)
@@ -258,9 +262,10 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart))
{
UINT16 glyphIndices[] = { pGlyph->m_aGlyphId };
- FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->m_nNewWidth) };
+ FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->m_nNewWidth) / fHScale };
DWRITE_GLYPH_OFFSET glyphOffsets[] = { { 0.0f, 0.0f }, };
- D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.X() - bounds.Left()), static_cast<FLOAT>(aPos.Y() - bounds.Top()) };
+ D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.X() - bounds.Left()) / fHScale,
+ static_cast<FLOAT>(aPos.Y() - bounds.Top()) };
DWRITE_GLYPH_RUN glyphs = {
mpFontFace,
mlfEmHeight,
@@ -379,6 +384,18 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p
return succeeded;
}
+WinFontStretchGuard::WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale)
+ : mpRenderTarget(pRenderTarget)
+{
+ pRenderTarget->GetTransform(&maTransform);
+ if (fHScale == 1.0f)
+ return;
+
+ D2D1::Matrix3x2F aTransform
+ = maTransform * D2D1::Matrix3x2F::Scale(D2D1::Size(fHScale, 1.0f), D2D1::Point2F(0, 0));
+ mpRenderTarget->SetTransform(aTransform);
+}
+WinFontStretchGuard::~WinFontStretchGuard() { mpRenderTarget->SetTransform(maTransform); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index b3fe0132b7df..1d804fcd08d1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -116,10 +116,11 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S
std::vector<float> aGlyphAdv(1); // offsets between glyphs
std::vector<DWRITE_GLYPH_OFFSET> aGlyphOffset(1, {0.0f, 0.0f});
std::vector<int> aEnds(1); // end of each glyph box
+ float fHScale = getHScale();
float totWidth = 0;
{
int overhang = aInkBoxes[0].Left();
- int blackWidth = aInkBoxes[0].getWidth(); // width of non-AA pixels
+ int blackWidth = aInkBoxes[0].getWidth() * fHScale; // width of non-AA pixels
aElement.maLeftOverhangs = overhang;
aGlyphAdv[0] = blackWidth + aElement.getExtraSpace();
@@ -170,6 +171,7 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S
0
};
+ WinFontStretchGuard aStretchGuard(pRT, fHScale);
pRT->BeginDraw();
pRT->DrawGlyphRun(baseline, &glyphs, pBrush);
HRESULT hResult = pRT->EndDraw();
@@ -314,6 +316,16 @@ bool WinFontInstance::hasHScale() const
return nWidth != nHeight;
}
+float WinFontInstance::getHScale() const
+{
+ const FontSelectPattern& rPattern = GetFontSelectPattern();
+ int nHeight(rPattern.mnHeight);
+ if (!nHeight)
+ return 1.0;
+ float nWidth(rPattern.mnWidth ? rPattern.mnWidth * GetAverageWidthFactor() : nHeight);
+ return nWidth / nHeight;
+}
+
static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
{
sal_uLong nLength = 0;
@@ -460,9 +472,8 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
const HFONT hLayoutFont = pWinFont->GetHFONT();
bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
- // Our DirectWrite renderer is incomplete, skip it for non-horizontal or
- // stretched text.
- bool bForceGDI = rLayout.GetOrientation() || (pWinFont->hasHScale() && !bUseOpenGL);
+ // Our DirectWrite renderer is incomplete, skip it for non-horizontal text.
+ bool bForceGDI = rLayout.GetOrientation();
if (!bUseOpenGL)
{