diff options
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r-- | win32/PlatWin.cxx | 121 |
1 files changed, 60 insertions, 61 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index f60f79d5c..645decb35 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -369,6 +369,22 @@ struct FontDirectWrite : public FontWin { lf.lfHeight = -static_cast<int>(pTextFormat->GetFontSize()); return ::CreateFontIndirectW(&lf); } + + int CodePageText(int codePage) const noexcept { + if (!(codePage == CpUtf8) && (characterSet != CharacterSet::Ansi)) { + codePage = CodePageFromCharSet(characterSet, codePage); + } + return codePage; + } + + static const FontDirectWrite *Cast(const Font *font_) { + const FontDirectWrite *pfm = dynamic_cast<const FontDirectWrite *>(font_); + PLATFORM_ASSERT(pfm); + if (!pfm) { + throw std::runtime_error("SurfaceD2D::SetFont: wrong Font type."); + } + return pfm; + } }; #endif @@ -1292,24 +1308,18 @@ class BlobInline; class SurfaceD2D : public Surface { SurfaceMode mode; - int codePageText = 0; - ID2D1RenderTarget *pRenderTarget = nullptr; ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr; bool ownRenderTarget = false; int clipsActive = 0; - IDWriteTextFormat *pTextFormat = nullptr; - FLOAT yAscent = 2; - FLOAT yDescent = 1; - FLOAT yInternalLeading = 0; - ID2D1SolidColorBrush *pBrush = nullptr; + FontQuality fontQuality = FontQuality::QualityMask; int logPixelsY = USER_DEFAULT_SCREEN_DPI; void Clear() noexcept; - void SetFont(const Font *font_); + void SetFontQuality(FontQuality extraFontFlag); HRESULT GetBitmap(ID2D1Bitmap **ppBitmap); public: @@ -1431,6 +1441,7 @@ void SurfaceD2D::Release() noexcept { } void SurfaceD2D::SetScale(WindowID wid) noexcept { + fontQuality = FontQuality::QualityMask; logPixelsY = DpiForWindow(wid); } @@ -1484,23 +1495,10 @@ void SurfaceD2D::D2DPenColourAlpha(ColourRGBA fore) noexcept { } } -void SurfaceD2D::SetFont(const Font *font_) { - const FontDirectWrite *pfm = dynamic_cast<const FontDirectWrite *>(font_); - PLATFORM_ASSERT(pfm); - if (!pfm) { - throw std::runtime_error("SurfaceD2D::SetFont: wrong Font type."); - } - pTextFormat = pfm->pTextFormat; - yAscent = pfm->yAscent; - yDescent = pfm->yDescent; - yInternalLeading = pfm->yInternalLeading; - codePageText = mode.codePage; - if (!(mode.codePage == CpUtf8) && (pfm->characterSet != CharacterSet::Ansi)) { - codePageText = CodePageFromCharSet(pfm->characterSet, mode.codePage); - } - if (pRenderTarget) { - D2D1_TEXT_ANTIALIAS_MODE aaMode; - aaMode = DWriteMapFontQuality(pfm->extraFontFlag); +void SurfaceD2D::SetFontQuality(FontQuality extraFontFlag) { + if (fontQuality != extraFontFlag) { + fontQuality = extraFontFlag; + const D2D1_TEXT_ANTIALIAS_MODE aaMode = DWriteMapFontQuality(extraFontFlag); if (aaMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE && customClearTypeRenderingParams) pRenderTarget->SetTextRenderingParams(customClearTypeRenderingParams); @@ -2143,9 +2141,8 @@ ScreenLineLayout::ScreenLineLayout(const IScreenLine *screenLine) { text = screenLine->Text(); // Get textFormat - const FontDirectWrite *pfm = dynamic_cast<const FontDirectWrite *>(screenLine->FontOfPosition(0)); - - if (!pfm || !pfm->pTextFormat) { + const FontDirectWrite *pfm = FontDirectWrite::Cast(screenLine->FontOfPosition(0)); + if (!pfm->pTextFormat) { return; } @@ -2315,12 +2312,13 @@ std::unique_ptr<IScreenLineLayout> SurfaceD2D::Layout(const IScreenLine *screenL } void SurfaceD2D::DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, int codePageOverride, UINT fuOptions) { - SetFont(font_); + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (pfm->pTextFormat && pRenderTarget && pBrush) { + // Use Unicode calls + const int codePageDraw = codePageOverride ? codePageOverride : pfm->CodePageText(mode.codePage); + const TextWide tbuf(text, codePageDraw); - // Use Unicode calls - const int codePageDraw = codePageOverride ? codePageOverride : codePageText; - const TextWide tbuf(text, codePageDraw); - if (pRenderTarget && pTextFormat && pBrush) { + SetFontQuality(pfm->extraFontFlag); if (fuOptions & ETO_CLIPPED) { const D2D1_RECT_F rcClip = RectangleFromPRectangle(rc); pRenderTarget->PushAxisAlignedClip(rcClip, D2D1_ANTIALIAS_MODE_ALIASED); @@ -2331,12 +2329,12 @@ void SurfaceD2D::DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION yba const HRESULT hr = pIDWriteFactory->CreateTextLayout( tbuf.buffer, tbuf.tlen, - pTextFormat, + pfm->pTextFormat, static_cast<FLOAT>(rc.Width()), static_cast<FLOAT>(rc.Height()), &pTextLayout); if (SUCCEEDED(hr)) { - const D2D1_POINT_2F origin = DPointFromPoint(Point(rc.left, ybase-yAscent)); + const D2D1_POINT_2F origin = DPointFromPoint(Point(rc.left, ybase - pfm->yAscent)); pRenderTarget->DrawTextLayout(origin, pTextLayout, pBrush, d2dDrawTextOptions); ReleaseUnknown(pTextLayout); } @@ -2380,18 +2378,19 @@ void SurfaceD2D::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITIO } void SurfaceD2D::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) { - SetFont(font_); - if (!pTextFormat) { + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (!pfm->pTextFormat) { // SetFont failed or no access to DirectWrite so give up. return; } + const int codePageText = pfm->CodePageText(mode.codePage); const TextWide tbuf(text, codePageText); TextPositions poses(tbuf.tlen); // Initialize poses for safety. std::fill(poses.buffer, poses.buffer + tbuf.tlen, 0.0f); // Create a layout IDWriteTextLayout *pTextLayout = nullptr; - const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout); + const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pfm->pTextFormat, 10000.0, 1000.0, &pTextLayout); if (!SUCCEEDED(hrCreate) || !pTextLayout) { return; } @@ -2413,7 +2412,7 @@ void SurfaceD2D::MeasureWidths(const Font *font_, std::string_view text, XYPOSIT position += clusterMetrics[ci].width; } PLATFORM_ASSERT(ti == tbuf.tlen); - if (mode.codePage == CpUtf8) { + if (codePageText == CpUtf8) { // Map the widths given for UTF-16 characters back onto the UTF-8 input string size_t i = 0; for (int ui = 0; ui < tbuf.tlen; ui++) { @@ -2458,12 +2457,12 @@ void SurfaceD2D::MeasureWidths(const Font *font_, std::string_view text, XYPOSIT XYPOSITION SurfaceD2D::WidthText(const Font *font_, std::string_view text) { FLOAT width = 1.0; - SetFont(font_); - const TextWide tbuf(text, codePageText); - if (pTextFormat) { + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (pfm->pTextFormat) { + const TextWide tbuf(text, pfm->CodePageText(mode.codePage)); // Create a layout IDWriteTextLayout *pTextLayout = nullptr; - const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 1000.0, 1000.0, &pTextLayout); + const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pfm->pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr) && pTextLayout) { DWRITE_TEXT_METRICS textMetrics; if (SUCCEEDED(pTextLayout->GetMetrics(&textMetrics))) @@ -2507,9 +2506,8 @@ void SurfaceD2D::DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOS } void SurfaceD2D::MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) { - SetFont(font_); - if (!pTextFormat) { - // SetFont failed or no access to DirectWrite so give up. + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (!pfm->pTextFormat) { return; } const TextWide tbuf(text, CpUtf8); @@ -2518,7 +2516,7 @@ void SurfaceD2D::MeasureWidthsUTF8(const Font *font_, std::string_view text, XYP std::fill(poses.buffer, poses.buffer + tbuf.tlen, 0.0f); // Create a layout IDWriteTextLayout *pTextLayout = nullptr; - const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout); + const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pfm->pTextFormat, 10000.0, 1000.0, &pTextLayout); if (!SUCCEEDED(hrCreate) || !pTextLayout) { return; } @@ -2561,12 +2559,12 @@ void SurfaceD2D::MeasureWidthsUTF8(const Font *font_, std::string_view text, XYP XYPOSITION SurfaceD2D::WidthTextUTF8(const Font * font_, std::string_view text) { FLOAT width = 1.0; - SetFont(font_); - const TextWide tbuf(text, CpUtf8); - if (pTextFormat) { + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (pfm->pTextFormat) { + const TextWide tbuf(text, CpUtf8); // Create a layout IDWriteTextLayout *pTextLayout = nullptr; - const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 1000.0, 1000.0, &pTextLayout); + const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pfm->pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr)) { DWRITE_TEXT_METRICS textMetrics; if (SUCCEEDED(pTextLayout->GetMetrics(&textMetrics))) @@ -2578,34 +2576,35 @@ XYPOSITION SurfaceD2D::WidthTextUTF8(const Font * font_, std::string_view text) } XYPOSITION SurfaceD2D::Ascent(const Font *font_) { - SetFont(font_); - return std::ceil(yAscent); + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + return std::ceil(pfm->yAscent); } XYPOSITION SurfaceD2D::Descent(const Font *font_) { - SetFont(font_); - return std::ceil(yDescent); + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + return std::ceil(pfm->yDescent); } XYPOSITION SurfaceD2D::InternalLeading(const Font *font_) { - SetFont(font_); - return std::floor(yInternalLeading); + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + return std::floor(pfm->yInternalLeading); } XYPOSITION SurfaceD2D::Height(const Font *font_) { - return Ascent(font_) + Descent(font_); + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + return std::ceil(pfm->yAscent) + std::ceil(pfm->yDescent); } XYPOSITION SurfaceD2D::AverageCharWidth(const Font *font_) { FLOAT width = 1.0; - SetFont(font_); - if (pTextFormat) { + const FontDirectWrite *pfm = FontDirectWrite::Cast(font_); + if (pfm->pTextFormat) { // Create a layout IDWriteTextLayout *pTextLayout = nullptr; static constexpr WCHAR wszAllAlpha[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const size_t lenAllAlpha = wcslen(wszAllAlpha); const HRESULT hr = pIDWriteFactory->CreateTextLayout(wszAllAlpha, static_cast<UINT32>(lenAllAlpha), - pTextFormat, 1000.0, 1000.0, &pTextLayout); + pfm->pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr) && pTextLayout) { DWRITE_TEXT_METRICS textMetrics; if (SUCCEEDED(pTextLayout->GetMetrics(&textMetrics))) |