summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/CommonSalLayout.hxx1
-rwxr-xr-xvcl/inc/win/winlayout.hxx4
-rw-r--r--vcl/win/gdi/salfont.cxx2
-rw-r--r--vcl/win/gdi/winlayout.cxx85
4 files changed, 67 insertions, 25 deletions
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 0dd44b2a1545..86fe5d0a857d 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -56,6 +56,7 @@ class CommonSalLayout : public GenericSalLayout
public:
#if defined(_WIN32)
explicit CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&);
+ const FontSelectPattern& getFontSelData() const { return mrFontSelData; };
#elif defined(MACOSX) || defined(IOS)
explicit CommonSalLayout(const CoreTextStyle&);
const CoreTextStyle& getFontData() const { return mrCoreTextStyle; };
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 1f0425133e83..b137a4bc20f9 100755
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -455,11 +455,15 @@ class D2DWriteTextOutRenderer : public TextOutRenderer
typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
REFIID, const D2D1_FACTORY_OPTIONS *, void **);
+ typedef HRESULT(WINAPI *pD2D1MakeRotateMatrix_t)(float, D2D1_POINT_2F,
+ D2D1_MATRIX_3X2_F*);
+
typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
REFIID, IUnknown **);
static HINSTANCE mmD2d1, mmDWrite;
static pD2D1CreateFactory_t D2D1CreateFactory;
+ static pD2D1MakeRotateMatrix_t D2D1MakeRotateMatrix;
static pDWriteCreateFactory_t DWriteCreateFactory;
public:
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index d3e4e5ec39df..b4341848d43d 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1219,7 +1219,7 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
rLogFont.lfQuality = NONANTIALIASED_QUALITY;
// select vertical mode if requested and available
- if( pFont->mbVertical && nNameLen )
+ if (!SalLayout::UseCommonLayout() && pFont->mbVertical && nNameLen )
{
// vertical fonts start with an '@'
memmove( &rLogFont.lfFaceName[1], &rLogFont.lfFaceName[0],
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index d82f86daa401..83db103657e1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -3339,6 +3339,7 @@ sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth)
HINSTANCE D2DWriteTextOutRenderer::mmD2d1 = nullptr,
D2DWriteTextOutRenderer::mmDWrite = nullptr;
D2DWriteTextOutRenderer::pD2D1CreateFactory_t D2DWriteTextOutRenderer::D2D1CreateFactory = nullptr;
+D2DWriteTextOutRenderer::pD2D1MakeRotateMatrix_t D2DWriteTextOutRenderer::D2D1MakeRotateMatrix = nullptr;
D2DWriteTextOutRenderer::pDWriteCreateFactory_t D2DWriteTextOutRenderer::DWriteCreateFactory = nullptr;
bool D2DWriteTextOutRenderer::InitModules()
@@ -3348,10 +3349,11 @@ bool D2DWriteTextOutRenderer::InitModules()
if (mmD2d1 && mmDWrite)
{
D2D1CreateFactory = pD2D1CreateFactory_t(GetProcAddress(mmD2d1, "D2D1CreateFactory"));
+ D2D1MakeRotateMatrix = pD2D1MakeRotateMatrix_t(GetProcAddress(mmD2d1, "D2D1MakeRotateMatrix"));
DWriteCreateFactory = pDWriteCreateFactory_t(GetProcAddress(mmDWrite, "DWriteCreateFactory"));
}
- if (!D2D1CreateFactory || !DWriteCreateFactory)
+ if (!D2D1CreateFactory || !DWriteCreateFactory || !D2D1MakeRotateMatrix)
{
CleanupModules();
return false;
@@ -3370,6 +3372,7 @@ void D2DWriteTextOutRenderer::CleanupModules()
mmD2d1 = nullptr;
mmDWrite = nullptr;
D2D1CreateFactory = nullptr;
+ D2D1MakeRotateMatrix = nullptr;
DWriteCreateFactory = nullptr;
}
#endif // ENABLE_GRAPHITE_DWRITE
@@ -3479,7 +3482,24 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
FLOAT glyphAdvances[MAX_GLYPHS];
DWRITE_GLYPH_OFFSET glyphOffsets[MAX_GLYPHS] = { { 0.0f, 0.0f }, };
+ bool bVertical = false;
+ double nYDiff = 0.0f;
+ const CommonSalLayout* pCSL = dynamic_cast<const CommonSalLayout*>(&rLayout);
+ if (pCSL)
+ bVertical = pCSL->getFontSelData().mbVertical;
+
+ if (bVertical)
+ {
+ DWRITE_FONT_METRICS aFM;
+ mpFontFace->GetMetrics(&aFM);
+ nYDiff = (aFM.ascent - aFM.descent) * mlfEmHeight / aFM.designUnitsPerEm;
+ }
+
mpRT->BeginDraw();
+
+ D2D1_MATRIX_3X2_F aOrigTrans, aRotTrans;
+ mpRT->GetTransform(&aOrigTrans);
+
do
{
nGlyphs = rLayout.GetNextGlyphs(1, glyphIntStr, *pPos, *pGetNextGlypInfo, glyphIntAdv);
@@ -3501,7 +3521,17 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
0
};
- mpRT->DrawGlyphRun(baseline, &glyphs, pBrush);
+ if (bVertical && (glyphIntStr[0] & GF_ROTMASK) != GF_ROTL)
+ {
+ D2D1MakeRotateMatrix(90.0f, baseline, &aRotTrans);
+ mpRT->SetTransform(aOrigTrans * aRotTrans);
+ mpRT->DrawGlyphRun(baseline, &glyphs, pBrush);
+ mpRT->SetTransform(aOrigTrans);
+ }
+ else
+ {
+ mpRT->DrawGlyphRun({ baseline.x, baseline.y + nYDiff }, &glyphs, pBrush);
+ }
} while (!pRectToErase);
hr = mpRT->EndDraw();
@@ -3641,21 +3671,45 @@ bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLa
Point aPos;
sal_GlyphId nLGlyph;
std::vector<uint16_t> indices;
+ std::vector<sal_GlyphId> gids;
std::vector<Point> positions;
int nStart = 0;
while (rLayout.GetNextGlyphs(1, &nLGlyph, aPos, nStart) == 1)
{
positions.push_back(aPos);
indices.push_back(nLGlyph);
+ gids.push_back(nLGlyph);
}
auto aBoxes = GetGlyphInkBoxes(indices.data(), indices.data() + indices.size());
if (aBoxes.empty())
return false;
+ bool bVertical = false;
+ double nYDiff = 0.0f;
+ const CommonSalLayout* pCSL = dynamic_cast<const CommonSalLayout*>(&rLayout);
+ if (pCSL)
+ bVertical = pCSL->getFontSelData().mbVertical;
+
+ if (bVertical)
+ {
+ DWRITE_FONT_METRICS aFM;
+ rFontFace.GetMetrics(&aFM);
+ nYDiff = (aFM.ascent - aFM.descent) * mlfEmHeight / aFM.designUnitsPerEm;
+ }
+
auto p = positions.begin();
+ auto gid = gids.begin();
for (auto &b:aBoxes)
{
+ if (bVertical)
+ {
+ if ((*gid++ & GF_ROTMASK) != GF_ROTL)
+ // FIXME: Hack, should rotate the box here instead.
+ b.expand(std::max(b.getHeight(), b.getWidth()));
+ else
+ b += Point(0, nYDiff);
+ }
b += *p++;
rOut.Union(b);
}
@@ -4006,28 +4060,11 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
void WinSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout, HDC hDC)
{
- if (getenv("SAL_DWRITE_COMMON_LAYOUT"))
- {
- Point aPos(0, 0);
- int nGlyphCount(0);
- TextOutRenderer &render = TextOutRenderer::get();
- bool result = render(rLayout, hDC, nullptr, &aPos, &nGlyphCount);
- assert(!result);
- }
- else
- {
- Point aPos;
- sal_GlyphId aGlyphId;
- int nFetchedGlyphs = 0;
- UINT oldTa = GetTextAlign(hDC);
- SetTextAlign(hDC, (oldTa & ~TA_NOUPDATECP));
- while (rLayout.GetNextGlyphs(1, &aGlyphId, aPos, nFetchedGlyphs))
- {
- ExtTextOutW(hDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>(&aGlyphId),
- 1, nullptr);
- }
- SetTextAlign(hDC, oldTa);
- }
+ Point aPos(0, 0);
+ int nGlyphCount(0);
+ TextOutRenderer &render = TextOutRenderer::get();
+ bool result = render(rLayout, hDC, nullptr, &aPos, &nGlyphCount);
+ assert(!result);
}
void WinSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)