aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/PlatWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r--win32/PlatWin.cxx121
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)))