aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/PlatWin.cxx
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-03-17 14:58:11 +1100
committerNeil <nyamatongwe@gmail.com>2021-03-17 14:58:11 +1100
commit1b5dd62b71d8d9b657b0cd7c138c9dc523a07cc4 (patch)
treef25f7353ad23c041da607b07b5ddd247214ba90c /win32/PlatWin.cxx
parent7fbe52f835688967a6079582ed8839cb55d0f9ea (diff)
downloadscintilla-mirror-1b5dd62b71d8d9b657b0cd7c138c9dc523a07cc4.tar.gz
Change Font to an interface and stop using FontID. Fonts are shared and
reference counted using std::shared_ptr. This optimizes memory and reduces potential for allocation bugs.
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r--win32/PlatWin.cxx310
1 files changed, 133 insertions, 177 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 63c5a30ab..f63262cfe 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -152,85 +152,6 @@ bool LoadD2D() {
#endif
-struct FormatAndMetrics {
- int technology;
- HFONT hfont;
-#if defined(USE_D2D)
- IDWriteTextFormat *pTextFormat;
-#endif
- int extraFontFlag;
- int characterSet;
- FLOAT yAscent;
- FLOAT yDescent;
- FLOAT yInternalLeading;
- FormatAndMetrics(HFONT hfont_, int extraFontFlag_, int characterSet_) noexcept :
- technology(SCWIN_TECH_GDI), hfont(hfont_),
-#if defined(USE_D2D)
- pTextFormat(nullptr),
-#endif
- extraFontFlag(extraFontFlag_), characterSet(characterSet_), yAscent(2), yDescent(1), yInternalLeading(0) {
- }
-#if defined(USE_D2D)
- FormatAndMetrics(IDWriteTextFormat *pTextFormat_,
- int extraFontFlag_,
- int characterSet_,
- FLOAT yAscent_,
- FLOAT yDescent_,
- FLOAT yInternalLeading_) noexcept :
- technology(SCWIN_TECH_DIRECTWRITE),
- hfont{},
- pTextFormat(pTextFormat_),
- extraFontFlag(extraFontFlag_),
- characterSet(characterSet_),
- yAscent(yAscent_),
- yDescent(yDescent_),
- yInternalLeading(yInternalLeading_) {
- }
-#endif
- FormatAndMetrics(const FormatAndMetrics &) = delete;
- FormatAndMetrics(FormatAndMetrics &&) = delete;
- FormatAndMetrics &operator=(const FormatAndMetrics &) = delete;
- FormatAndMetrics &operator=(FormatAndMetrics &&) = delete;
-
- ~FormatAndMetrics() {
- if (hfont)
- ::DeleteObject(hfont);
-#if defined(USE_D2D)
- ReleaseUnknown(pTextFormat);
-#endif
- extraFontFlag = 0;
- characterSet = 0;
- yAscent = 2;
- yDescent = 1;
- yInternalLeading = 0;
- }
- HFONT HFont() noexcept;
-};
-
-HFONT FormatAndMetrics::HFont() noexcept {
- LOGFONTW lf = {};
-#if defined(USE_D2D)
- if (technology == SCWIN_TECH_GDI) {
- if (0 == ::GetObjectW(hfont, sizeof(lf), &lf)) {
- return {};
- }
- } else {
- const HRESULT hr = pTextFormat->GetFontFamilyName(lf.lfFaceName, LF_FACESIZE);
- if (!SUCCEEDED(hr)) {
- return {};
- }
- lf.lfWeight = pTextFormat->GetFontWeight();
- lf.lfItalic = pTextFormat->GetFontStyle() == DWRITE_FONT_STYLE_ITALIC;
- lf.lfHeight = -static_cast<int>(pTextFormat->GetFontSize());
- }
-#else
- if (0 == ::GetObjectW(hfont, sizeof(lf), &lf)) {
- return {};
- }
-#endif
- return ::CreateFontIndirectW(&lf);
-}
-
#ifndef CLEARTYPE_QUALITY
#define CLEARTYPE_QUALITY 5
#endif
@@ -287,10 +208,6 @@ void LoadDpiForWindow() noexcept {
HINSTANCE hinstPlatformRes {};
-FormatAndMetrics *FamFromFontID(void *fid) noexcept {
- return static_cast<FormatAndMetrics *>(fid);
-}
-
constexpr BYTE Win32MapFontQuality(int extraFontFlag) noexcept {
switch (extraFontFlag & SC_EFF_QUALITY_MASK) {
@@ -327,6 +244,11 @@ constexpr D2D1_TEXT_ANTIALIAS_MODE DWriteMapFontQuality(int extraFontFlag) noexc
}
#endif
+// Both GDI and DirectWrite can produce a HFONT for use in list boxes
+struct FontWin : public Font {
+ virtual HFONT HFont() const noexcept = 0;
+};
+
void SetLogFont(LOGFONTW &lf, const char *faceName, int characterSet, float size, int weight, bool italic, int extraFontFlag) {
lf = LOGFONTW();
// The negative is to allow for leading
@@ -338,16 +260,44 @@ void SetLogFont(LOGFONTW &lf, const char *faceName, int characterSet, float size
UTF16FromUTF8(faceName, lf.lfFaceName, LF_FACESIZE);
}
-FontID CreateFontFromParameters(const FontParameters &fp) {
- LOGFONTW lf;
- SetLogFont(lf, fp.faceName, fp.characterSet, fp.size, fp.weight, fp.italic, fp.extraFontFlag);
- FontID fid = nullptr;
- if (fp.technology == SCWIN_TECH_GDI) {
- HFONT hfont = ::CreateFontIndirectW(&lf);
- fid = new FormatAndMetrics(hfont, fp.extraFontFlag, fp.characterSet);
- } else {
+struct FontGDI : public FontWin {
+ HFONT hfont = {};
+ FontGDI(const FontParameters &fp) {
+ LOGFONTW lf;
+ SetLogFont(lf, fp.faceName, fp.characterSet, fp.size, fp.weight, fp.italic, fp.extraFontFlag);
+ hfont = ::CreateFontIndirectW(&lf);
+ }
+ // Deleted so FontGDI objects can not be copied.
+ FontGDI(const FontGDI &) = delete;
+ FontGDI(FontGDI &&) = delete;
+ FontGDI &operator=(const FontGDI &) = delete;
+ FontGDI &operator=(FontGDI &&) = delete;
+ ~FontGDI() {
+ if (hfont)
+ ::DeleteObject(hfont);
+ }
+ HFONT HFont() const noexcept override {
+ // Duplicating hfont
+ LOGFONTW lf = {};
+ if (0 == ::GetObjectW(hfont, sizeof(lf), &lf)) {
+ return {};
+ }
+ return ::CreateFontIndirectW(&lf);
+ }
+};
+
#if defined(USE_D2D)
- IDWriteTextFormat *pTextFormat = nullptr;
+struct FontDirectWrite : public FontWin {
+ IDWriteTextFormat *pTextFormat = nullptr;
+ int extraFontFlag = SC_EFF_QUALITY_DEFAULT;
+ int characterSet = 0;
+ FLOAT yAscent = 2.0f;
+ FLOAT yDescent = 1.0f;
+ FLOAT yInternalLeading = 0.0f;
+
+ FontDirectWrite(const FontParameters &fp) :
+ extraFontFlag(fp.extraFontFlag),
+ characterSet(fp.characterSet) {
const std::wstring wsFace = WStringFromUTF8(fp.faceName);
const FLOAT fHeight = fp.size;
const DWRITE_FONT_STYLE style = fp.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
@@ -358,9 +308,6 @@ FontID CreateFontFromParameters(const FontParameters &fp) {
if (SUCCEEDED(hr)) {
pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
- FLOAT yAscent = 1.0f;
- FLOAT yDescent = 1.0f;
- FLOAT yInternalLeading = 0.0f;
IDWriteTextLayout *pTextLayout = nullptr;
hr = pIDWriteFactory->CreateTextLayout(L"X", 1, pTextFormat,
100.0f, 100.0f, &pTextLayout);
@@ -382,31 +329,39 @@ FontID CreateFontFromParameters(const FontParameters &fp) {
ReleaseUnknown(pTextLayout);
pTextFormat->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_UNIFORM, lineMetrics[0].height, lineMetrics[0].baseline);
}
- fid = new FormatAndMetrics(pTextFormat, fp.extraFontFlag, fp.characterSet, yAscent, yDescent, yInternalLeading);
}
-#endif
}
- return fid;
-}
-
-}
-
-Font::Font() noexcept : fid{} {
-}
-
-Font::~Font() {
-}
+ // Deleted so FontDirectWrite objects can not be copied.
+ FontDirectWrite(const FontDirectWrite &) = delete;
+ FontDirectWrite(FontDirectWrite &&) = delete;
+ FontDirectWrite &operator=(const FontDirectWrite &) = delete;
+ FontDirectWrite &operator=(FontDirectWrite &&) = delete;
+ ~FontDirectWrite() {
+ ReleaseUnknown(pTextFormat);
+ }
+ HFONT HFont() const noexcept override {
+ LOGFONTW lf = {};
+ const HRESULT hr = pTextFormat->GetFontFamilyName(lf.lfFaceName, LF_FACESIZE);
+ if (!SUCCEEDED(hr)) {
+ return {};
+ }
+ lf.lfWeight = pTextFormat->GetFontWeight();
+ lf.lfItalic = pTextFormat->GetFontStyle() == DWRITE_FONT_STYLE_ITALIC;
+ lf.lfHeight = -static_cast<int>(pTextFormat->GetFontSize());
+ return ::CreateFontIndirectW(&lf);
+ }
+};
+#endif
-void Font::Create(const FontParameters &fp) {
- Release();
- if (fp.faceName)
- fid = CreateFontFromParameters(fp);
}
-void Font::Release() {
- if (fid)
- delete FamFromFontID(fid);
- fid = nullptr;
+std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) {
+#if defined(USE_D2D)
+ if (fp.technology == SCWIN_TECH_DIRECTWRITE) {
+ return std::make_shared<FontDirectWrite>(fp);
+ }
+#endif
+ return std::make_shared<FontGDI>(fp);
}
// Buffer to hold strings and string position arrays without always allocating on heap.
@@ -501,7 +456,7 @@ class SurfaceGDI : public Surface {
int codePage = 0;
void BrushColour(ColourDesired back) noexcept;
- void SetFont(const Font &font_) noexcept;
+ void SetFont(const Font *font_) noexcept;
void Clear() noexcept;
public:
@@ -539,17 +494,17 @@ public:
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
- void DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
- void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
- void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) override;
- XYPOSITION WidthText(Font &font_, std::string_view text) override;
- XYPOSITION Ascent(Font &font_) override;
- XYPOSITION Descent(Font &font_) override;
- XYPOSITION InternalLeading(Font &font_) override;
- XYPOSITION Height(Font &font_) override;
- XYPOSITION AverageCharWidth(Font &font_) override;
+ void DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
+ void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+ void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+ void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
+ void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) override;
+ XYPOSITION WidthText(const Font *font_, std::string_view text) override;
+ XYPOSITION Ascent(const Font *font_) override;
+ XYPOSITION Descent(const Font *font_) override;
+ XYPOSITION InternalLeading(const Font *font_) override;
+ XYPOSITION Height(const Font *font_) override;
+ XYPOSITION AverageCharWidth(const Font *font_) override;
void SetClip(PRectangle rc) override;
void FlushCachedState() override;
@@ -659,9 +614,9 @@ void SurfaceGDI::BrushColour(ColourDesired back) noexcept {
brushOld = SelectBrush(hdc, brush);
}
-void SurfaceGDI::SetFont(const Font &font_) noexcept {
- const FormatAndMetrics *pfm = FamFromFontID(font_.GetID());
- PLATFORM_ASSERT(pfm->technology == SCWIN_TECH_GDI);
+void SurfaceGDI::SetFont(const Font *font_) noexcept {
+ const FontGDI *pfm = dynamic_cast<const FontGDI *>(font_);
+ PLATFORM_ASSERT(pfm);
if (fontOld) {
SelectFont(hdc, pfm->hfont);
} else {
@@ -989,7 +944,7 @@ std::unique_ptr<IScreenLineLayout> SurfaceGDI::Layout(const IScreenLine *) {
typedef VarBuffer<int, stackBufferLength> TextPositionsI;
-void SurfaceGDI::DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
+void SurfaceGDI::DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
SetFont(font_);
const RECT rcw = RectFromPRectangle(rc);
const int x = static_cast<int>(rc.left);
@@ -1003,21 +958,21 @@ void SurfaceGDI::DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION yba
}
}
-void SurfaceGDI::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceGDI::DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
::SetTextColor(hdc, fore.AsInteger());
::SetBkColor(hdc, back.AsInteger());
DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE);
}
-void SurfaceGDI::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceGDI::DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
::SetTextColor(hdc, fore.AsInteger());
::SetBkColor(hdc, back.AsInteger());
DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE | ETO_CLIPPED);
}
-void SurfaceGDI::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceGDI::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore) {
// Avoid drawing spaces in transparent mode
for (const char ch : text) {
@@ -1031,7 +986,7 @@ void SurfaceGDI::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybas
}
}
-XYPOSITION SurfaceGDI::WidthText(Font &font_, std::string_view text) {
+XYPOSITION SurfaceGDI::WidthText(const Font *font_, std::string_view text) {
SetFont(font_);
SIZE sz={0,0};
if (!unicodeMode) {
@@ -1043,7 +998,7 @@ XYPOSITION SurfaceGDI::WidthText(Font &font_, std::string_view text) {
return static_cast<XYPOSITION>(sz.cx);
}
-void SurfaceGDI::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
+void SurfaceGDI::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) {
// Zero positions to avoid random behaviour on failure.
std::fill(positions, positions + text.length(), 0.0f);
SetFont(font_);
@@ -1085,35 +1040,35 @@ void SurfaceGDI::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *p
std::fill(positions+i, positions + text.length(), lastPos);
}
-XYPOSITION SurfaceGDI::Ascent(Font &font_) {
+XYPOSITION SurfaceGDI::Ascent(const Font *font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return static_cast<XYPOSITION>(tm.tmAscent);
}
-XYPOSITION SurfaceGDI::Descent(Font &font_) {
+XYPOSITION SurfaceGDI::Descent(const Font *font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return static_cast<XYPOSITION>(tm.tmDescent);
}
-XYPOSITION SurfaceGDI::InternalLeading(Font &font_) {
+XYPOSITION SurfaceGDI::InternalLeading(const Font *font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return static_cast<XYPOSITION>(tm.tmInternalLeading);
}
-XYPOSITION SurfaceGDI::Height(Font &font_) {
+XYPOSITION SurfaceGDI::Height(const Font *font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return static_cast<XYPOSITION>(tm.tmHeight);
}
-XYPOSITION SurfaceGDI::AverageCharWidth(Font &font_) {
+XYPOSITION SurfaceGDI::AverageCharWidth(const Font *font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
@@ -1176,7 +1131,7 @@ class SurfaceD2D : public Surface {
int logPixelsY;
void Clear() noexcept;
- void SetFont(const Font &font_) noexcept;
+ void SetFont(const Font *font_) noexcept;
HRESULT GetBitmap(ID2D1Bitmap **ppBitmap);
public:
@@ -1218,17 +1173,17 @@ public:
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
- void DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
- void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
- void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) override;
- XYPOSITION WidthText(Font &font_, std::string_view text) override;
- XYPOSITION Ascent(Font &font_) override;
- XYPOSITION Descent(Font &font_) override;
- XYPOSITION InternalLeading(Font &font_) override;
- XYPOSITION Height(Font &font_) override;
- XYPOSITION AverageCharWidth(Font &font_) override;
+ void DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
+ void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+ void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+ void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
+ void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) override;
+ XYPOSITION WidthText(const Font *font_, std::string_view text) override;
+ XYPOSITION Ascent(const Font *font_) override;
+ XYPOSITION Descent(const Font *font_) override;
+ XYPOSITION InternalLeading(const Font *font_) override;
+ XYPOSITION Height(const Font *font_) override;
+ XYPOSITION AverageCharWidth(const Font *font_) override;
void SetClip(PRectangle rc) override;
void FlushCachedState() override;
@@ -1361,9 +1316,9 @@ void SurfaceD2D::D2DPenColour(ColourDesired fore, int alpha) {
}
}
-void SurfaceD2D::SetFont(const Font &font_) noexcept {
- const FormatAndMetrics *pfm = FamFromFontID(font_.GetID());
- PLATFORM_ASSERT(pfm->technology == SCWIN_TECH_DIRECTWRITE);
+void SurfaceD2D::SetFont(const Font *font_) noexcept {
+ const FontDirectWrite *pfm = dynamic_cast<const FontDirectWrite *>(font_);
+ PLATFORM_ASSERT(pfm);
pTextFormat = pfm->pTextFormat;
yAscent = pfm->yAscent;
yDescent = pfm->yDescent;
@@ -1830,8 +1785,8 @@ void ScreenLineLayout::FillTextLayoutFormats(const IScreenLine *screenLine, IDWr
textLayout->SetInlineObject(&blobs.back(), textRange);
};
- FormatAndMetrics *pfm =
- static_cast<FormatAndMetrics *>(screenLine->FontOfPosition(bytePosition)->GetID());
+ const FontDirectWrite *pfm =
+ dynamic_cast<const FontDirectWrite *>(screenLine->FontOfPosition(bytePosition));
const unsigned int fontFamilyNameSize = pfm->pTextFormat->GetFontFamilyNameLength();
std::wstring fontFamilyName(fontFamilyNameSize, 0);
@@ -1888,7 +1843,7 @@ ScreenLineLayout::ScreenLineLayout(const IScreenLine *screenLine) {
text = screenLine->Text();
// Get textFormat
- FormatAndMetrics *pfm = static_cast<FormatAndMetrics *>(screenLine->FontOfPosition(0)->GetID());
+ const FontDirectWrite *pfm = dynamic_cast<const FontDirectWrite *>(screenLine->FontOfPosition(0));
if (!pIDWriteFactory || !pfm->pTextFormat) {
return;
@@ -2058,7 +2013,7 @@ std::unique_ptr<IScreenLineLayout> SurfaceD2D::Layout(const IScreenLine *screenL
return std::make_unique<ScreenLineLayout>(screenLine);
}
-void SurfaceD2D::DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
+void SurfaceD2D::DrawTextCommon(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
SetFont(font_);
// Use Unicode calls
@@ -2085,7 +2040,7 @@ void SurfaceD2D::DrawTextCommon(PRectangle rc, const Font &font_, XYPOSITION yba
}
}
-void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceD2D::DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
if (pRenderTarget) {
FillRectangle(rc, back);
@@ -2094,7 +2049,7 @@ void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, st
}
}
-void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceD2D::DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
if (pRenderTarget) {
FillRectangle(rc, back);
@@ -2103,7 +2058,7 @@ void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, s
}
}
-void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceD2D::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore) {
// Avoid drawing spaces in transparent mode
for (const char ch : text) {
@@ -2117,7 +2072,7 @@ void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybas
}
}
-XYPOSITION SurfaceD2D::WidthText(Font &font_, std::string_view text) {
+XYPOSITION SurfaceD2D::WidthText(const Font *font_, std::string_view text) {
FLOAT width = 1.0;
SetFont(font_);
const TextWide tbuf(text, unicodeMode, codePageText);
@@ -2135,7 +2090,7 @@ XYPOSITION SurfaceD2D::WidthText(Font &font_, std::string_view text) {
return width;
}
-void SurfaceD2D::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
+void SurfaceD2D::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) {
SetFont(font_);
if (!pIDWriteFactory || !pTextFormat) {
// SetFont failed or no access to DirectWrite so give up.
@@ -2216,26 +2171,26 @@ void SurfaceD2D::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *p
}
}
-XYPOSITION SurfaceD2D::Ascent(Font &font_) {
+XYPOSITION SurfaceD2D::Ascent(const Font *font_) {
SetFont(font_);
return std::ceil(yAscent);
}
-XYPOSITION SurfaceD2D::Descent(Font &font_) {
+XYPOSITION SurfaceD2D::Descent(const Font *font_) {
SetFont(font_);
return std::ceil(yDescent);
}
-XYPOSITION SurfaceD2D::InternalLeading(Font &font_) {
+XYPOSITION SurfaceD2D::InternalLeading(const Font *font_) {
SetFont(font_);
return std::floor(yInternalLeading);
}
-XYPOSITION SurfaceD2D::Height(Font &font_) {
+XYPOSITION SurfaceD2D::Height(const Font *font_) {
return Ascent(font_) + Descent(font_);
}
-XYPOSITION SurfaceD2D::AverageCharWidth(Font &font_) {
+XYPOSITION SurfaceD2D::AverageCharWidth(const Font *font_) {
FLOAT width = 1.0;
SetFont(font_);
if (pIDWriteFactory && pTextFormat) {
@@ -2386,8 +2341,9 @@ void Window::InvalidateRectangle(PRectangle rc) {
::InvalidateRect(HwndFromWindowID(wid), &rcw, FALSE);
}
-void Window::SetFont(Font &font) {
- SetWindowFont(HwndFromWindowID(wid), font.GetID(), 0);
+void Window::SetFont(const Font *font) {
+ const FontWin *pfm = dynamic_cast<const FontWin *>(font);
+ SetWindowFont(HwndFromWindowID(wid), pfm->HFont(), 0);
}
namespace {
@@ -2541,7 +2497,7 @@ ListBox::~ListBox() {
class ListBoxX : public ListBox {
int lineHeight;
- FontID fontCopy;
+ HFONT fontCopy;
int technology;
RGBAImageSet images;
LineToItem lti;
@@ -2598,7 +2554,7 @@ public:
fontCopy = 0;
}
}
- void SetFont(Font &font) override;
+ void SetFont(const Font *font) override;
void Create(Window &parent_, int ctrlID_, Point location_, int lineHeight_, bool unicodeMode_, int technology_) override;
void SetAverageCharWidth(int width) override;
void SetVisibleRows(int rows) override;
@@ -2651,13 +2607,13 @@ void ListBoxX::Create(Window &parent_, int ctrlID_, Point location_, int lineHei
location = PointFromPOINT(locationw);
}
-void ListBoxX::SetFont(Font &font) {
- if (font.GetID()) {
+void ListBoxX::SetFont(const Font *font) {
+ const FontWin *pfm = dynamic_cast<const FontWin *>(font);
+ if (pfm) {
if (fontCopy) {
::DeleteObject(fontCopy);
fontCopy = 0;
}
- FormatAndMetrics *pfm = static_cast<FormatAndMetrics *>(font.GetID());
fontCopy = pfm->HFont();
SetWindowFont(lb, fontCopy, 0);
}