diff options
-rw-r--r-- | vcl/inc/CommonSalLayout.hxx | 1 | ||||
-rwxr-xr-x | vcl/inc/win/winlayout.hxx | 4 | ||||
-rw-r--r-- | vcl/win/gdi/salfont.cxx | 2 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 85 |
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) |