aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cocoa/PlatCocoa.h20
-rw-r--r--cocoa/PlatCocoa.mm140
-rw-r--r--cocoa/QuartzTextLayout.h4
-rw-r--r--cocoa/QuartzTextStyle.h10
-rwxr-xr-xgtk/PlatGTK.cxx305
-rw-r--r--qt/ScintillaEditBase/PlatQt.cpp122
-rw-r--r--qt/ScintillaEditBase/PlatQt.h24
-rw-r--r--src/CallTip.cxx15
-rw-r--r--src/CallTip.h2
-rw-r--r--src/EditView.cxx30
-rw-r--r--src/Editor.cxx2
-rw-r--r--src/LineMarker.cxx2
-rw-r--r--src/LineMarker.h4
-rw-r--r--src/MarginView.cxx2
-rw-r--r--src/Platform.h40
-rw-r--r--src/PositionCache.cxx4
-rw-r--r--src/PositionCache.h2
-rw-r--r--src/ScintillaBase.cxx2
-rw-r--r--src/Style.cxx31
-rw-r--r--src/Style.h18
-rw-r--r--src/ViewStyle.cxx15
-rw-r--r--src/ViewStyle.h2
-rw-r--r--win32/PlatWin.cxx310
23 files changed, 485 insertions, 621 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h
index c19ac8bca..f140295c5 100644
--- a/cocoa/PlatCocoa.h
+++ b/cocoa/PlatCocoa.h
@@ -101,18 +101,18 @@ public:
void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) override;
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
- void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore,
+ void DrawTextNoClip(PRectangle rc, const 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,
+ void DrawTextClipped(PRectangle rc, const 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 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;
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm
index be9ee23cd..149949048 100644
--- a/cocoa/PlatCocoa.mm
+++ b/cocoa/PlatCocoa.mm
@@ -75,27 +75,33 @@ inline CGRect PRectangleToCGRect(PRectangle &rc) {
return CGRectMake(rc.left, rc.top, rc.Width(), rc.Height());
}
-//----------------- Font ---------------------------------------------------------------------------
+//----------------- FontQuartz ---------------------------------------------------------------------
-Font::Font() noexcept : fid(0) {
-}
-
-//--------------------------------------------------------------------------------------------------
-
-Font::~Font() {
- Release();
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static QuartzTextStyle *TextStyleFromFont(const Font &f) {
- return static_cast<QuartzTextStyle *>(f.GetID());
-}
+class FontQuartz : public Font {
+public:
+ std::unique_ptr<QuartzTextStyle> style;
+ FontQuartz(const FontParameters &fp) {
+ style = std::make_unique<QuartzTextStyle>();
+ // Create the font with attributes
+ QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.italic);
+ CTFontRef fontRef = font.getFontID();
+ style->setFontRef(fontRef, fp.characterSet);
+ }
+ FontQuartz(const QuartzTextStyle *style_) {
+ style = std::make_unique<QuartzTextStyle>(style_);
+ }
+};
//--------------------------------------------------------------------------------------------------
-static int FontCharacterSet(Font &f) {
- return TextStyleFromFont(f)->getCharacterSet();
+static QuartzTextStyle *TextStyleFromFont(const Font *f) noexcept {
+ if (f) {
+ const FontQuartz *pfq = dynamic_cast<const FontQuartz *>(f);
+ if (pfq) {
+ return pfq->style.get();
+ }
+ }
+ return nullptr;
}
//--------------------------------------------------------------------------------------------------
@@ -103,24 +109,8 @@ static int FontCharacterSet(Font &f) {
/**
* Creates a CTFontRef with the given properties.
*/
-void Font::Create(const FontParameters &fp) {
- Release();
-
- QuartzTextStyle *style = new QuartzTextStyle();
- fid = style;
-
- // Create the font with attributes
- QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.italic);
- CTFontRef fontRef = font.getFontID();
- style->setFontRef(fontRef, fp.characterSet);
-}
-
-//--------------------------------------------------------------------------------------------------
-
-void Font::Release() {
- if (fid)
- delete static_cast<QuartzTextStyle *>(fid);
- fid = 0;
+std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) {
+ return std::make_shared<FontQuartz>(fp);
}
//--------------------------------------------------------------------------------------------------
@@ -202,7 +192,7 @@ ScreenLineLayout::ScreenLineLayout(const IScreenLine *screenLine) : text(screenL
byteCount,
kCFStringEncodingUTF8,
false);
- QuartzTextStyle *qts = static_cast<QuartzTextStyle *>(screenLine->FontOfPosition(bp)->GetID());
+ const QuartzTextStyle *qts = TextStyleFromFont(screenLine->FontOfPosition(bp));
CFMutableDictionaryRef pieceAttributes = qts->getCTStyle();
as = CFAttributedStringCreate(NULL, piece, pieceAttributes);
CFRelease(piece);
@@ -1037,7 +1027,7 @@ std::unique_ptr<IScreenLineLayout> SurfaceImpl::Layout(const IScreenLine *screen
//--------------------------------------------------------------------------------------------------
-void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
FillRectangle(rc, back);
DrawTextTransparent(rc, font_, ybase, text, fore);
@@ -1045,7 +1035,7 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, s
//--------------------------------------------------------------------------------------------------
-void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
CGContextSaveGState(gc);
CGContextClipToRect(gc, PRectangleToCGRect(rc));
@@ -1110,27 +1100,34 @@ CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet) {
}
}
-void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore) {
- CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_));
+ QuartzTextStyle *style = TextStyleFromFont(font_);
+ if (!style) {
+ return;
+ }
+ CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, style->getCharacterSet());
ColourDesired colour(fore.AsInteger());
CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0, colour.GetGreen()/255.0, colour.GetBlue()/255.0, 1.0);
- QuartzTextStyle *style = TextStyleFromFont(font_);
style->setCTStyleColour(color);
CGColorRelease(color);
- textLayout->setText(text, encoding, *style);
+ textLayout->setText(text, encoding, style);
textLayout->draw(gc, rc.left, ybase);
}
//--------------------------------------------------------------------------------------------------
-void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
- CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_));
+void SurfaceImpl::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) {
+ const QuartzTextStyle *style = TextStyleFromFont(font_);
+ if (!style) {
+ return;
+ }
+ CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, style->getCharacterSet());
const CFStringEncoding encodingUsed =
- textLayout->setText(text, encoding, *TextStyleFromFont(font_));
+ textLayout->setText(text, encoding, style);
CTLineRef mLine = textLayout->getCTLine();
assert(mLine);
@@ -1186,51 +1183,53 @@ void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *
}
-XYPOSITION SurfaceImpl::WidthText(Font &font_, std::string_view text) {
- if (font_.GetID()) {
- CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_));
- textLayout->setText(text, encoding, *TextStyleFromFont(font_));
-
- return static_cast<XYPOSITION>(textLayout->MeasureStringWidth());
+XYPOSITION SurfaceImpl::WidthText(const Font *font_, std::string_view text) {
+ const QuartzTextStyle *style = TextStyleFromFont(font_);
+ if (!style) {
+ return 1;
}
- return 1;
+ CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, style->getCharacterSet());
+ textLayout->setText(text, encoding, style);
+
+ return static_cast<XYPOSITION>(textLayout->MeasureStringWidth());
}
// This string contains a good range of characters to test for size.
const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-XYPOSITION SurfaceImpl::Ascent(Font &font_) {
- if (!font_.GetID())
+XYPOSITION SurfaceImpl::Ascent(const Font *font_) {
+ const QuartzTextStyle *style = TextStyleFromFont(font_);
+ if (!style) {
return 1;
+ }
- float ascent = TextStyleFromFont(font_)->getAscent();
+ float ascent = style->getAscent();
return ascent + 0.5f;
}
-XYPOSITION SurfaceImpl::Descent(Font &font_) {
- if (!font_.GetID())
+XYPOSITION SurfaceImpl::Descent(const Font *font_) {
+ const QuartzTextStyle *style = TextStyleFromFont(font_);
+ if (!style) {
return 1;
+ }
- float descent = TextStyleFromFont(font_)->getDescent();
+ float descent = style->getDescent();
return descent + 0.5f;
}
-XYPOSITION SurfaceImpl::InternalLeading(Font &) {
+XYPOSITION SurfaceImpl::InternalLeading(const Font *) {
return 0;
}
-XYPOSITION SurfaceImpl::Height(Font &font_) {
+XYPOSITION SurfaceImpl::Height(const Font *font_) {
return Ascent(font_) + Descent(font_);
}
-XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) {
-
- if (!font_.GetID())
- return 1;
+XYPOSITION SurfaceImpl::AverageCharWidth(const Font *font_) {
XYPOSITION width = WidthText(font_, sizeString);
@@ -1407,7 +1406,7 @@ void Window::InvalidateRectangle(PRectangle rc) {
//--------------------------------------------------------------------------------------------------
-void Window::SetFont(Font &) {
+void Window::SetFont(const Font *) {
// Implemented on list subclass on Cocoa.
}
@@ -1630,7 +1629,7 @@ private:
XYPOSITION maxItemWidth;
unsigned int aveCharWidth;
XYPOSITION maxIconWidth;
- Font font;
+ std::unique_ptr<Font> font;
int maxWidth;
NSTableView *table;
@@ -1666,7 +1665,7 @@ public:
}
// ListBox methods
- void SetFont(Font &font) override;
+ void SetFont(const Font *font_) override;
void Create(Window &parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int technology_) override;
void SetAverageCharWidth(int width) override;
void SetVisibleRows(int rows) override;
@@ -1744,12 +1743,11 @@ void ListBoxImpl::Create(Window & /*parent*/, int /*ctrlID*/, Scintilla::Point p
wid = (__bridge_retained WindowID)winLB;
}
-void ListBoxImpl::SetFont(Font &font_) {
+void ListBoxImpl::SetFont(const Font *font_) {
// NSCell setFont takes an NSFont* rather than a CTFontRef but they
// are the same thing toll-free bridged.
QuartzTextStyle *style = TextStyleFromFont(font_);
- font.Release();
- font.SetID(new QuartzTextStyle(*style));
+ font = std::make_unique<FontQuartz>(style);
NSFont *pfont = (__bridge NSFont *)style->getFontRef();
[colText.dataCell setFont: pfont];
CGFloat itemHeight = std::ceil(pfont.boundingRectForFont.size.height);
@@ -1831,7 +1829,7 @@ void ListBoxImpl::Append(char *s, int type) {
ld.Add(count, type, s);
Scintilla::SurfaceImpl surface;
- XYPOSITION width = surface.WidthText(font, s);
+ XYPOSITION width = surface.WidthText(font.get(), s);
if (width > maxItemWidth) {
maxItemWidth = width;
colText.width = maxItemWidth;
diff --git a/cocoa/QuartzTextLayout.h b/cocoa/QuartzTextLayout.h
index 0c6eb08dd..0c234fe39 100644
--- a/cocoa/QuartzTextLayout.h
+++ b/cocoa/QuartzTextLayout.h
@@ -33,7 +33,7 @@ public:
}
}
- CFStringEncoding setText(std::string_view sv, CFStringEncoding encoding, const QuartzTextStyle &r) {
+ CFStringEncoding setText(std::string_view sv, CFStringEncoding encoding, const QuartzTextStyle *r) {
// First clear current values in case of failure.
if (mString) {
CFRelease(mString);
@@ -58,7 +58,7 @@ public:
stringLength = CFStringGetLength(str);
- CFMutableDictionaryRef stringAttribs = r.getCTStyle();
+ CFMutableDictionaryRef stringAttribs = r->getCTStyle();
mString = ::CFAttributedStringCreate(NULL, str, stringAttribs);
diff --git a/cocoa/QuartzTextStyle.h b/cocoa/QuartzTextStyle.h
index 3c5684685..f8d50ebe9 100644
--- a/cocoa/QuartzTextStyle.h
+++ b/cocoa/QuartzTextStyle.h
@@ -21,14 +21,14 @@ public:
characterSet = 0;
}
- QuartzTextStyle(const QuartzTextStyle &other) {
+ QuartzTextStyle(const QuartzTextStyle *other) {
// Does not copy font colour attribute
- fontRef = static_cast<CTFontRef>(CFRetain(other.fontRef));
+ fontRef = static_cast<CTFontRef>(CFRetain(other->fontRef));
styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef);
- characterSet = other.characterSet;
+ characterSet = other->characterSet;
}
~QuartzTextStyle() {
@@ -77,11 +77,11 @@ public:
CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef);
}
- CTFontRef getFontRef() {
+ CTFontRef getFontRef() const noexcept {
return fontRef;
}
- int getCharacterSet() {
+ int getCharacterSet() const noexcept {
return characterSet;
}
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index b9b9ab029..5471a7289 100755
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -71,9 +71,9 @@ GtkWidget *PWidget(WindowID wid) noexcept {
enum encodingType { singleByte, UTF8, dbcs };
// Holds a PangoFontDescription*.
-class FontHandle {
+class FontHandle : public Font {
public:
- PangoFontDescription *pfd;
+ PangoFontDescription *pfd = nullptr;
int characterSet;
FontHandle() noexcept : pfd(nullptr), characterSet(-1) {
}
@@ -81,6 +81,17 @@ public:
pfd = pfd_;
characterSet = characterSet_;
}
+ FontHandle(const FontParameters &fp) {
+ pfd = pango_font_description_new();
+ if (pfd) {
+ pango_font_description_set_family(pfd,
+ (fp.faceName[0] == '!') ? fp.faceName + 1 : fp.faceName);
+ pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size));
+ pango_font_description_set_weight(pfd, static_cast<PangoWeight>(fp.weight));
+ pango_font_description_set_style(pfd, fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
+ }
+ characterSet = fp.characterSet;
+ }
// Deleted so FontHandle objects can not be copied.
FontHandle(const FontHandle &) = delete;
FontHandle(FontHandle &&) = delete;
@@ -91,45 +102,19 @@ public:
pango_font_description_free(pfd);
pfd = nullptr;
}
- static FontHandle *CreateNewFont(const FontParameters &fp);
};
-FontHandle *FontHandle::CreateNewFont(const FontParameters &fp) {
- PangoFontDescription *pfd = pango_font_description_new();
- if (pfd) {
- pango_font_description_set_family(pfd,
- (fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName);
- pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size));
- pango_font_description_set_weight(pfd, static_cast<PangoWeight>(fp.weight));
- pango_font_description_set_style(pfd, fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
- return new FontHandle(pfd, fp.characterSet);
- }
-
- return nullptr;
-}
-
// X has a 16 bit coordinate space, so stop drawing here to avoid wrapping
constexpr int maxCoordinate = 32000;
-FontHandle *PFont(const Font &f) noexcept {
- return static_cast<FontHandle *>(f.GetID());
+const FontHandle *PFont(const Font *f) noexcept {
+ return dynamic_cast<const FontHandle *>(f);
}
}
-Font::Font() noexcept : fid(nullptr) {}
-
-Font::~Font() {}
-
-void Font::Create(const FontParameters &fp) {
- Release();
- fid = FontHandle::CreateNewFont(fp);
-}
-
-void Font::Release() {
- if (fid)
- delete static_cast<FontHandle *>(fid);
- fid = nullptr;
+std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) {
+ return std::make_shared<FontHandle>(fp);
}
// Required on OS X
@@ -184,17 +169,17 @@ public:
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
- void DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore);
- 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 DrawTextBase(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore);
+ 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;
@@ -684,7 +669,7 @@ size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) n
}
-void SurfaceImpl::DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextBase(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore) {
PenColour(fore);
if (context) {
@@ -710,20 +695,20 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybas
}
}
-void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
FillRectangle(rc, back);
DrawTextBase(rc, font_, ybase, text, fore);
}
// On GTK+, exactly same as DrawTextNoClip
-void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore, ColourDesired back) {
FillRectangle(rc, back);
DrawTextBase(rc, font_, ybase, text, fore);
}
-void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text,
ColourDesired fore) {
// Avoid drawing spaces in transparent mode
for (size_t i=0; i<text.length(); i++) {
@@ -774,102 +759,100 @@ public:
}
};
-void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
- if (font_.GetID()) {
- if (PFont(font_)->pfd) {
- pango_layout_set_font_description(layout, PFont(font_)->pfd);
- if (et == UTF8) {
- // Simple and direct as UTF-8 is native Pango encoding
- int i = 0;
- pango_layout_set_text(layout, text.data(), text.length());
- ClusterIterator iti(layout, text.length());
- while (!iti.finished) {
- iti.Next();
- const int places = iti.curIndex - i;
- while (i < iti.curIndex) {
- // Evenly distribute space among bytes of this cluster.
- // Would be better to find number of characters and then
- // divide evenly between characters with each byte of a character
- // being at the same position.
- positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places;
- i++;
- }
- }
- PLATFORM_ASSERT(static_cast<size_t>(i) == text.length());
- } else {
- int positionsCalculated = 0;
- if (et == dbcs) {
- SetConverter(PFont(font_)->characterSet);
- std::string utfForm = UTF8FromIconv(conv, text);
- if (!utfForm.empty()) {
- // Convert to UTF-8 so can ask Pango for widths, then
- // Loop through UTF-8 and DBCS forms, taking account of different
- // character byte lengths.
- Converter convMeasure("UCS-2", CharacterSetID(characterSet), false);
- pango_layout_set_text(layout, utfForm.c_str(), strlen(utfForm.c_str()));
- int i = 0;
- int clusterStart = 0;
- ClusterIterator iti(layout, strlen(utfForm.c_str()));
- while (!iti.finished) {
- iti.Next();
- const int clusterEnd = iti.curIndex;
- const int places = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart);
- int place = 1;
- while (clusterStart < clusterEnd) {
- size_t lenChar = MultiByteLenFromIconv(convMeasure, text.data()+i, text.length()-i);
- while (lenChar--) {
- positions[i++] = iti.position - (places - place) * iti.distance / places;
- positionsCalculated++;
- }
- clusterStart += UTF8BytesOfLead[static_cast<unsigned char>(utfForm[clusterStart])];
- place++;
- }
- }
- PLATFORM_ASSERT(static_cast<size_t>(i) == text.length());
- }
+void SurfaceImpl::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) {
+ if (PFont(font_)->pfd) {
+ pango_layout_set_font_description(layout, PFont(font_)->pfd);
+ if (et == UTF8) {
+ // Simple and direct as UTF-8 is native Pango encoding
+ int i = 0;
+ pango_layout_set_text(layout, text.data(), text.length());
+ ClusterIterator iti(layout, text.length());
+ while (!iti.finished) {
+ iti.Next();
+ const int places = iti.curIndex - i;
+ while (i < iti.curIndex) {
+ // Evenly distribute space among bytes of this cluster.
+ // Would be better to find number of characters and then
+ // divide evenly between characters with each byte of a character
+ // being at the same position.
+ positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places;
+ i++;
}
- if (positionsCalculated < 1) {
- const size_t lenPositions = text.length();
- // Either 8-bit or DBCS conversion failed so treat as 8-bit.
- SetConverter(PFont(font_)->characterSet);
- const bool rtlCheck = PFont(font_)->characterSet == SC_CHARSET_HEBREW ||
- PFont(font_)->characterSet == SC_CHARSET_ARABIC;
- std::string utfForm = UTF8FromIconv(conv, text);
- if (utfForm.empty()) {
- utfForm = UTF8FromLatin1(text);
- }
- pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
- size_t i = 0;
+ }
+ PLATFORM_ASSERT(static_cast<size_t>(i) == text.length());
+ } else {
+ int positionsCalculated = 0;
+ if (et == dbcs) {
+ SetConverter(PFont(font_)->characterSet);
+ std::string utfForm = UTF8FromIconv(conv, text);
+ if (!utfForm.empty()) {
+ // Convert to UTF-8 so can ask Pango for widths, then
+ // Loop through UTF-8 and DBCS forms, taking account of different
+ // character byte lengths.
+ Converter convMeasure("UCS-2", CharacterSetID(characterSet), false);
+ pango_layout_set_text(layout, utfForm.c_str(), strlen(utfForm.c_str()));
+ int i = 0;
int clusterStart = 0;
- // Each 8-bit input character may take 1 or 2 bytes in UTF-8
- // and groups of up to 3 may be represented as ligatures.
- ClusterIterator iti(layout, utfForm.length());
+ ClusterIterator iti(layout, strlen(utfForm.c_str()));
while (!iti.finished) {
iti.Next();
const int clusterEnd = iti.curIndex;
- const int ligatureLength = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart);
- if (rtlCheck && ((clusterEnd <= clusterStart) || (ligatureLength == 0) || (ligatureLength > 3))) {
- // Something has gone wrong: exit quickly but pretend all the characters are equally spaced:
- int widthLayout = 0;
- pango_layout_get_size(layout, &widthLayout, nullptr);
- const XYPOSITION widthTotal = floatFromPangoUnits(widthLayout);
- for (size_t bytePos=0; bytePos<lenPositions; bytePos++) {
- positions[bytePos] = widthTotal / lenPositions * (bytePos + 1);
+ const int places = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart);
+ int place = 1;
+ while (clusterStart < clusterEnd) {
+ size_t lenChar = MultiByteLenFromIconv(convMeasure, text.data()+i, text.length()-i);
+ while (lenChar--) {
+ positions[i++] = iti.position - (places - place) * iti.distance / places;
+ positionsCalculated++;
}
- return;
+ clusterStart += UTF8BytesOfLead[static_cast<unsigned char>(utfForm[clusterStart])];
+ place++;
}
- PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3);
- for (int charInLig=0; charInLig<ligatureLength; charInLig++) {
- positions[i++] = iti.position - (ligatureLength - 1 - charInLig) * iti.distance / ligatureLength;
+ }
+ PLATFORM_ASSERT(static_cast<size_t>(i) == text.length());
+ }
+ }
+ if (positionsCalculated < 1) {
+ const size_t lenPositions = text.length();
+ // Either 8-bit or DBCS conversion failed so treat as 8-bit.
+ SetConverter(PFont(font_)->characterSet);
+ const bool rtlCheck = PFont(font_)->characterSet == SC_CHARSET_HEBREW ||
+ PFont(font_)->characterSet == SC_CHARSET_ARABIC;
+ std::string utfForm = UTF8FromIconv(conv, text);
+ if (utfForm.empty()) {
+ utfForm = UTF8FromLatin1(text);
+ }
+ pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
+ size_t i = 0;
+ int clusterStart = 0;
+ // Each 8-bit input character may take 1 or 2 bytes in UTF-8
+ // and groups of up to 3 may be represented as ligatures.
+ ClusterIterator iti(layout, utfForm.length());
+ while (!iti.finished) {
+ iti.Next();
+ const int clusterEnd = iti.curIndex;
+ const int ligatureLength = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart);
+ if (rtlCheck && ((clusterEnd <= clusterStart) || (ligatureLength == 0) || (ligatureLength > 3))) {
+ // Something has gone wrong: exit quickly but pretend all the characters are equally spaced:
+ int widthLayout = 0;
+ pango_layout_get_size(layout, &widthLayout, nullptr);
+ const XYPOSITION widthTotal = floatFromPangoUnits(widthLayout);
+ for (size_t bytePos=0; bytePos<lenPositions; bytePos++) {
+ positions[bytePos] = widthTotal / lenPositions * (bytePos + 1);
}
- clusterStart = clusterEnd;
+ return;
}
- while (i < lenPositions) {
- // If something failed, fill in rest of the positions
- positions[i++] = clusterStart;
+ PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3);
+ for (int charInLig=0; charInLig<ligatureLength; charInLig++) {
+ positions[i++] = iti.position - (ligatureLength - 1 - charInLig) * iti.distance / ligatureLength;
}
- PLATFORM_ASSERT(i == text.length());
+ clusterStart = clusterEnd;
}
+ while (i < lenPositions) {
+ // If something failed, fill in rest of the positions
+ positions[i++] = clusterStart;
+ }
+ PLATFORM_ASSERT(i == text.length());
}
}
} else {
@@ -880,37 +863,31 @@ void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *
}
}
-XYPOSITION SurfaceImpl::WidthText(Font &font_, std::string_view text) {
- if (font_.GetID()) {
- if (PFont(font_)->pfd) {
- std::string utfForm;
- pango_layout_set_font_description(layout, PFont(font_)->pfd);
- if (et == UTF8) {
- pango_layout_set_text(layout, text.data(), text.length());
- } else {
- SetConverter(PFont(font_)->characterSet);
- utfForm = UTF8FromIconv(conv, text);
- if (utfForm.empty()) { // iconv failed so treat as Latin1
- utfForm = UTF8FromLatin1(text);
- }
- pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
+XYPOSITION SurfaceImpl::WidthText(const Font *font_, std::string_view text) {
+ if (PFont(font_)->pfd) {
+ std::string utfForm;
+ pango_layout_set_font_description(layout, PFont(font_)->pfd);
+ if (et == UTF8) {
+ pango_layout_set_text(layout, text.data(), text.length());
+ } else {
+ SetConverter(PFont(font_)->characterSet);
+ utfForm = UTF8FromIconv(conv, text);
+ if (utfForm.empty()) { // iconv failed so treat as Latin1
+ utfForm = UTF8FromLatin1(text);
}
- PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0);
- PangoRectangle pos {};
- pango_layout_line_get_extents(pangoLine, nullptr, &pos);
- return floatFromPangoUnits(pos.width);
+ pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
}
- return 1;
- } else {
- return 1;
+ PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0);
+ PangoRectangle pos {};
+ pango_layout_line_get_extents(pangoLine, nullptr, &pos);
+ return floatFromPangoUnits(pos.width);
}
+ return 1;
}
// Ascent and descent determined by Pango font metrics.
-XYPOSITION SurfaceImpl::Ascent(Font &font_) {
- if (!(font_.GetID()))
- return 1;
+XYPOSITION SurfaceImpl::Ascent(const Font *font_) {
XYPOSITION ascent = 0;
if (PFont(font_)->pfd) {
PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
@@ -925,9 +902,7 @@ XYPOSITION SurfaceImpl::Ascent(Font &font_) {
return ascent;
}
-XYPOSITION SurfaceImpl::Descent(Font &font_) {
- if (!(font_.GetID()))
- return 1;
+XYPOSITION SurfaceImpl::Descent(const Font *font_) {
if (PFont(font_)->pfd) {
PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
PFont(font_)->pfd, pango_context_get_language(pcontext));
@@ -939,15 +914,15 @@ XYPOSITION SurfaceImpl::Descent(Font &font_) {
return 0;
}
-XYPOSITION SurfaceImpl::InternalLeading(Font &) {
+XYPOSITION SurfaceImpl::InternalLeading(const Font *) {
return 0;
}
-XYPOSITION SurfaceImpl::Height(Font &font_) {
+XYPOSITION SurfaceImpl::Height(const Font *font_) {
return Ascent(font_) + Descent(font_);
}
-XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) {
+XYPOSITION SurfaceImpl::AverageCharWidth(const Font *font_) {
return WidthText(font_, "n");
}
@@ -1092,7 +1067,7 @@ void Window::InvalidateRectangle(PRectangle rc) {
}
}
-void Window::SetFont(Font &) {
+void Window::SetFont(const Font *) {
// Can not be done generically but only needed for ListBox
}
@@ -1240,7 +1215,7 @@ public:
}
#endif
}
- 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;
@@ -1508,7 +1483,7 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) {
GTK_WINDOW(top));
}
-void ListBoxX::SetFont(Font &font) {
+void ListBoxX::SetFont(const Font *font) {
// Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(font)->pfd) {
// Current font is Pango font
diff --git a/qt/ScintillaEditBase/PlatQt.cpp b/qt/ScintillaEditBase/PlatQt.cpp
index 9ea1d88f5..ee17bf0f7 100644
--- a/qt/ScintillaEditBase/PlatQt.cpp
+++ b/qt/ScintillaEditBase/PlatQt.cpp
@@ -100,12 +100,30 @@ QString UnicodeFromText(QTextCodec *codec, std::string_view text) {
return codec->toUnicode(text.data(), static_cast<int>(text.length()));
}
-class FontAndCharacterSet {
+static QFont::StyleStrategy ChooseStrategy(int eff)
+{
+ switch (eff) {
+ case SC_EFF_QUALITY_DEFAULT: return QFont::PreferDefault;
+ case SC_EFF_QUALITY_NON_ANTIALIASED: return QFont::NoAntialias;
+ case SC_EFF_QUALITY_ANTIALIASED: return QFont::PreferAntialias;
+ case SC_EFF_QUALITY_LCD_OPTIMIZED: return QFont::PreferAntialias;
+ default: return QFont::PreferDefault;
+ }
+}
+
+class FontAndCharacterSet : public Font {
public:
- int characterSet;
- QFont *pfont;
- FontAndCharacterSet(int characterSet_, QFont *pfont):
- characterSet(characterSet_), pfont(pfont) {
+ int characterSet = 0;
+ QFont *pfont = nullptr;
+ FontAndCharacterSet(const FontParameters &fp) {
+ pfont = new QFont;
+ pfont->setStyleStrategy(ChooseStrategy(fp.extraFontFlag));
+ pfont->setFamily(QString::fromUtf8(fp.faceName));
+ pfont->setPointSizeF(fp.size);
+ pfont->setBold(fp.weight > 500);
+ pfont->setItalic(fp.italic);
+
+ characterSet = fp.characterSet;
}
~FontAndCharacterSet() {
delete pfont;
@@ -115,59 +133,22 @@ public:
namespace {
-FontAndCharacterSet *AsFontAndCharacterSet(const Font &f) {
- return reinterpret_cast<FontAndCharacterSet *>(f.GetID());
-}
-
-int FontCharacterSet(const Font &f)
-{
- return AsFontAndCharacterSet(f)->characterSet;
+const FontAndCharacterSet *AsFontAndCharacterSet(const Font *f) {
+ return dynamic_cast<const FontAndCharacterSet *>(f);
}
-QFont *FontPointer(const Font &f)
+QFont *FontPointer(const Font *f)
{
return AsFontAndCharacterSet(f)->pfont;
}
}
-Font::Font() noexcept : fid(nullptr) {}
-Font::~Font()
+std::shared_ptr<Font> Font::Allocate(const FontParameters &fp)
{
- delete reinterpret_cast<FontAndCharacterSet *>(fid);
- fid = nullptr;
-}
-static QFont::StyleStrategy ChooseStrategy(int eff)
-{
- switch (eff) {
- case SC_EFF_QUALITY_DEFAULT: return QFont::PreferDefault;
- case SC_EFF_QUALITY_NON_ANTIALIASED: return QFont::NoAntialias;
- case SC_EFF_QUALITY_ANTIALIASED: return QFont::PreferAntialias;
- case SC_EFF_QUALITY_LCD_OPTIMIZED: return QFont::PreferAntialias;
- default: return QFont::PreferDefault;
- }
-}
-
-void Font::Create(const FontParameters &fp)
-{
- Release();
-
- QFont *font = new QFont;
- font->setStyleStrategy(ChooseStrategy(fp.extraFontFlag));
- font->setFamily(QString::fromUtf8(fp.faceName));
- font->setPointSizeF(fp.size);
- font->setBold(fp.weight > 500);
- font->setItalic(fp.italic);
-
- fid = new FontAndCharacterSet(fp.characterSet, font);
+ return std::make_shared<FontAndCharacterSet>(fp);
}
-void Font::Release()
-{
- if (fid)
- delete reinterpret_cast<FontAndCharacterSet *>(fid);
- fid = nullptr;
-}
SurfaceImpl::SurfaceImpl()
: device(nullptr), painter(nullptr), deviceOwned(false), painterOwned(false), x(0), y(0),
unicodeMode(false), codePage(0), codecName(nullptr), codec(nullptr)
@@ -241,12 +222,13 @@ void SurfaceImpl::BrushColour(ColourDesired back)
GetPainter()->setBrush(QBrush(QColorFromCA(back)));
}
-void SurfaceImpl::SetCodec(const Font &font)
+void SurfaceImpl::SetCodec(const Font *font)
{
- if (font.GetID()) {
+ const FontAndCharacterSet *pfacs = AsFontAndCharacterSet(font);
+ if (pfacs && pfacs->pfont) {
const char *csid = "UTF-8";
if (!unicodeMode)
- csid = CharacterSetID(FontCharacterSet(font));
+ csid = CharacterSetID(pfacs->characterSet);
if (csid != codecName) {
codecName = csid;
codec = QTextCodec::codecForName(csid);
@@ -254,10 +236,11 @@ void SurfaceImpl::SetCodec(const Font &font)
}
}
-void SurfaceImpl::SetFont(const Font &font)
+void SurfaceImpl::SetFont(const Font *font)
{
- if (font.GetID()) {
- GetPainter()->setFont(*FontPointer(font));
+ const FontAndCharacterSet *pfacs = AsFontAndCharacterSet(font);
+ if (pfacs && pfacs->pfont) {
+ GetPainter()->setFont(*(pfacs->pfont));
SetCodec(font);
}
}
@@ -444,7 +427,7 @@ std::unique_ptr<IScreenLineLayout> SurfaceImpl::Layout(const IScreenLine *)
}
void SurfaceImpl::DrawTextNoClip(PRectangle rc,
- Font &font,
+ const Font *font,
XYPOSITION ybase,
std::string_view text,
ColourDesired fore,
@@ -460,7 +443,7 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc,
}
void SurfaceImpl::DrawTextClipped(PRectangle rc,
- Font &font,
+ const Font *font,
XYPOSITION ybase,
std::string_view text,
ColourDesired fore,
@@ -472,7 +455,7 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc,
}
void SurfaceImpl::DrawTextTransparent(PRectangle rc,
- Font &font,
+ const Font *font,
XYPOSITION ybase,
std::string_view text,
ColourDesired fore)
@@ -490,11 +473,11 @@ void SurfaceImpl::SetClip(PRectangle rc)
GetPainter()->setClipRect(QRectFFromPRect(rc));
}
-void SurfaceImpl::MeasureWidths(Font &font,
+void SurfaceImpl::MeasureWidths(const Font *font,
std::string_view text,
XYPOSITION *positions)
{
- if (!font.GetID())
+ if (!font)
return;
SetCodec(font);
QString su = UnicodeFromText(codec, text);
@@ -541,7 +524,7 @@ void SurfaceImpl::MeasureWidths(Font &font,
}
}
-XYPOSITION SurfaceImpl::WidthText(Font &font, std::string_view text)
+XYPOSITION SurfaceImpl::WidthText(const Font *font, std::string_view text)
{
QFontMetricsF metrics(*FontPointer(font), device);
SetCodec(font);
@@ -549,13 +532,13 @@ XYPOSITION SurfaceImpl::WidthText(Font &font, std::string_view text)
return metrics.width(su);
}
-XYPOSITION SurfaceImpl::Ascent(Font &font)
+XYPOSITION SurfaceImpl::Ascent(const Font *font)
{
QFontMetricsF metrics(*FontPointer(font), device);
return metrics.ascent();
}
-XYPOSITION SurfaceImpl::Descent(Font &font)
+XYPOSITION SurfaceImpl::Descent(const Font *font)
{
QFontMetricsF metrics(*FontPointer(font), device);
// Qt returns 1 less than true descent
@@ -565,18 +548,18 @@ XYPOSITION SurfaceImpl::Descent(Font &font)
return metrics.descent() + 1;
}
-XYPOSITION SurfaceImpl::InternalLeading(Font & /* font */)
+XYPOSITION SurfaceImpl::InternalLeading(const Font * /* font */)
{
return 0;
}
-XYPOSITION SurfaceImpl::Height(Font &font)
+XYPOSITION SurfaceImpl::Height(const Font *font)
{
QFontMetricsF metrics(*FontPointer(font), device);
return metrics.height();
}
-XYPOSITION SurfaceImpl::AverageCharWidth(Font &font)
+XYPOSITION SurfaceImpl::AverageCharWidth(const Font *font)
{
QFontMetricsF metrics(*FontPointer(font), device);
return metrics.averageCharWidth();
@@ -727,7 +710,7 @@ void Window::InvalidateRectangle(PRectangle rc)
window(wid)->update(QRectFromPRect(rc));
}
-void Window::SetFont(Font &font)
+void Window::SetFont(const Font *font)
{
if (wid)
window(wid)->setFont(*FontPointer(font));
@@ -793,7 +776,7 @@ public:
ListBoxImpl();
~ListBoxImpl();
- 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;
@@ -874,10 +857,13 @@ void ListBoxImpl::Create(Window &parent,
wid = list;
}
-void ListBoxImpl::SetFont(Font &font)
+void ListBoxImpl::SetFont(const Font *font)
{
ListWidget *list = GetWidget();
- list->setFont(*FontPointer(font));
+ const FontAndCharacterSet *pfacs = AsFontAndCharacterSet(font);
+ if (pfacs && pfacs->pfont) {
+ list->setFont(*(pfacs->pfont));
+ }
}
void ListBoxImpl::SetAverageCharWidth(int /*width*/) {}
diff --git a/qt/ScintillaEditBase/PlatQt.h b/qt/ScintillaEditBase/PlatQt.h
index 63364a3d7..2860e1397 100644
--- a/qt/ScintillaEditBase/PlatQt.h
+++ b/qt/ScintillaEditBase/PlatQt.h
@@ -113,20 +113,20 @@ public:
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
- void DrawTextNoClip(PRectangle rc, Font &font, XYPOSITION ybase,
+ void DrawTextNoClip(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextClipped(PRectangle rc, Font &font, XYPOSITION ybase,
+ void DrawTextClipped(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourDesired fore, ColourDesired back) override;
- void DrawTextTransparent(PRectangle rc, Font &font, XYPOSITION ybase,
+ void DrawTextTransparent(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourDesired fore) override;
- void MeasureWidths(Font &font, std::string_view text,
+ void MeasureWidths(const 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;
+ 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;
@@ -136,8 +136,8 @@ public:
void SetBidiR2L(bool bidiR2L_) override;
void BrushColour(ColourDesired back);
- void SetCodec(const Font &font);
- void SetFont(const Font &font);
+ void SetCodec(const Font *font);
+ void SetFont(const Font *font);
QPaintDevice *GetPaintDevice();
void SetPainter(QPainter *painter);
diff --git a/src/CallTip.cxx b/src/CallTip.cxx
index 667e41c96..e6bfc2b7e 100644
--- a/src/CallTip.cxx
+++ b/src/CallTip.cxx
@@ -67,7 +67,6 @@ CallTip::CallTip() noexcept {
}
CallTip::~CallTip() {
- font.Release();
wCallTip.Destroy();
}
@@ -168,11 +167,11 @@ int CallTip::DrawChunk(Surface *surface, int x, std::string_view sv,
xEnd = NextTabPos(x);
} else {
const std::string_view segText = sv.substr(startSeg, endSeg - startSeg);
- xEnd = x + static_cast<int>(std::lround(surface->WidthText(font, segText)));
+ xEnd = x + static_cast<int>(std::lround(surface->WidthText(font.get(), segText)));
if (draw) {
rcClient.left = static_cast<XYPOSITION>(x);
rcClient.right = static_cast<XYPOSITION>(xEnd);
- surface->DrawTextTransparent(rcClient, font, static_cast<XYPOSITION>(ytext),
+ surface->DrawTextTransparent(rcClient, font.get(), static_cast<XYPOSITION>(ytext),
segText, asHighlight ? colourSel : colourUnSel);
}
}
@@ -189,12 +188,12 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1);
// To make a nice small call tip window, it is only sized to fit most normal characters without accents
- const int ascent = static_cast<int>(std::round(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font)));
+ const int ascent = static_cast<int>(std::round(surfaceWindow->Ascent(font.get()) - surfaceWindow->InternalLeading(font.get())));
// For each line...
// Draw the definition in three parts: before highlight, highlighted, after highlight
int ytext = static_cast<int>(rcClient.top) + ascent + 1;
- rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
+ rcClient.bottom = ytext + surfaceWindow->Descent(font.get()) + 1;
std::string_view remaining(val);
int maxWidth = 0;
size_t lineStart = 0;
@@ -286,7 +285,7 @@ PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, co
posStartCallTip = pos;
const XYPOSITION deviceHeight = static_cast<XYPOSITION>(surfaceMeasure->DeviceHeightFont(size));
const FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet);
- font.Create(fp);
+ font = Font::Allocate(fp);
// Look for multiple lines in the text
// Only support \n here - simply means container must avoid \r!
const int numLines = 1 + static_cast<int>(std::count(val.begin(), val.end(), '\n'));
@@ -294,12 +293,12 @@ PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, co
rectDown = PRectangle(0,0,0,0);
offsetMain = insetX; // changed to right edge of any arrows
const int width = PaintContents(surfaceMeasure.get(), false) + insetX;
- lineHeight = static_cast<int>(std::lround(surfaceMeasure->Height(font)));
+ lineHeight = static_cast<int>(std::lround(surfaceMeasure->Height(font.get())));
// The returned
// rectangle is aligned to the right edge of the last arrow encountered in
// the tip text, else to the tip text left edge.
- const int height = lineHeight * numLines - static_cast<int>(surfaceMeasure->InternalLeading(font)) + borderHeight * 2;
+ const int height = lineHeight * numLines - static_cast<int>(surfaceMeasure->InternalLeading(font.get())) + borderHeight * 2;
if (above) {
return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width - offsetMain, pt.y - verticalOffset);
} else {
diff --git a/src/CallTip.h b/src/CallTip.h
index 562b24f9d..6cc89d3a5 100644
--- a/src/CallTip.h
+++ b/src/CallTip.h
@@ -24,7 +24,7 @@ struct Chunk {
class CallTip {
Chunk highlight; // character offset to start and end of highlighted text
std::string val;
- Font font;
+ std::shared_ptr<Font> font;
PRectangle rectUp; // rectangle of last up angle in the tip
PRectangle rectDown; // rectangle of last down arrow in the tip
int lineHeight; // vertical line spacing
diff --git a/src/EditView.cxx b/src/EditView.cxx
index 87d8134c6..fcb747d21 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -90,7 +90,7 @@ static int WidthStyledText(Surface *surface, const ViewStyle &vs, int styleOffse
size_t endSegment = start;
while ((endSegment + 1 < len) && (styles[endSegment + 1] == style))
endSegment++;
- FontAlias fontText = vs.styles[style + styleOffset].font;
+ const Font *fontText = vs.styles[style + styleOffset].font.get();
const std::string_view sv(text + start, endSegment - start + 1);
width += static_cast<int>(surface->WidthText(fontText, sv));
start = endSegment + 1;
@@ -107,7 +107,7 @@ int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, cons
if (st.multipleStyles) {
widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine);
} else {
- FontAlias fontText = vs.styles[styleOffset + st.style].font;
+ const Font *fontText = vs.styles[styleOffset + st.style].font.get();
const std::string_view text(st.text + start, lenLine);
widthSubLine = static_cast<int>(surface->WidthText(fontText, text));
}
@@ -120,7 +120,7 @@ int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, cons
void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase,
std::string_view text, DrawPhase phase) {
- FontAlias fontText = style.font;
+ const Font *fontText = style.font.get();
if (phase & drawBack) {
if (phase & drawText) {
// Drawing both
@@ -146,7 +146,7 @@ void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRec
while (end < length - 1 && st.styles[start + end + 1] == style)
end++;
style += styleOffset;
- FontAlias fontText = vs.styles[style].font;
+ const Font *fontText = vs.styles[style].font.get();
const std::string_view text(st.text + start + i, end - i + 1);
const int width = static_cast<int>(surface->WidthText(fontText, text));
PRectangle rcSegment = rcText;
@@ -601,9 +601,9 @@ void EditView::UpdateBidiData(const EditModel &model, const ViewStyle &vstyle, L
if (model.BidirectionalEnabled()) {
ll->EnsureBidiData();
for (int stylesInLine = 0; stylesInLine < ll->numCharsInLine; stylesInLine++) {
- ll->bidiData->stylesFonts[stylesInLine].MakeAlias(vstyle.styles[ll->styles[stylesInLine]].font);
+ ll->bidiData->stylesFonts[stylesInLine] = vstyle.styles[ll->styles[stylesInLine]].font;
}
- ll->bidiData->stylesFonts[ll->numCharsInLine].ClearFont();
+ ll->bidiData->stylesFonts[ll->numCharsInLine].reset();
for (int charsInLine = 0; charsInLine < ll->numCharsInLine; charsInLine++) {
const int charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(&ll->chars[charsInLine]), ll->numCharsInLine - charsInLine);
@@ -877,7 +877,7 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r
if (fillBackground) {
surface->FillRectangle(rcSegment, textBack);
}
- FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
+ const Font *ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font.get();
const int normalCharHeight = static_cast<int>(std::ceil(vsDraw.styles[STYLE_CONTROLCHAR].capitalHeight));
PRectangle rcCChar = rcSegment;
rcCChar.left = rcCChar.left + 1;
@@ -1202,7 +1202,7 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con
PRectangle rcSegment = rcLine;
const std::string_view foldDisplayText(text);
- FontAlias fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font;
+ const Font *fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font.get();
const int widthFoldDisplayText = static_cast<int>(surface->WidthText(fontText, foldDisplayText));
int eolInSelection = 0;
@@ -1300,7 +1300,7 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c
const size_t style = stEOLAnnotation.style + vsDraw.eolAnnotationStyleOffset;
PRectangle rcSegment = rcLine;
- FontAlias fontText = vsDraw.styles[style].font;
+ const Font *fontText = vsDraw.styles[style].font.get();
const int widthEOLAnnotationText = static_cast<int>(surface->WidthText(fontText, eolAnnotationText));
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
@@ -1493,7 +1493,7 @@ static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewS
// This character is where the caret block is, we override the colours
// (inversed) for drawing the caret here.
const int styleMain = ll->styles[offsetFirstChar];
- FontAlias fontText = vsDraw.styles[styleMain].font;
+ const Font *fontText = vsDraw.styles[styleMain].font.get();
const std::string_view text(&ll->chars[offsetFirstChar], numCharsToDraw);
surface->DrawTextClipped(rcCaret, fontText,
rcCaret.top + vsDraw.maxAscent, text, vsDraw.styles[styleMain].back,
@@ -1883,7 +1883,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
if (rcSegment.Intersects(rcLine)) {
const int styleMain = ll->styles[i];
ColourDesired textFore = vsDraw.styles[styleMain].fore;
- FontAlias textFont = vsDraw.styles[styleMain].font;
+ const Font *textFont = vsDraw.styles[styleMain].font.get();
//hotspot foreground
const bool inHotspot = (ll->hotspot.Valid()) && ll->hotspot.ContainsCharacter(iDoc);
if (inHotspot) {
@@ -1961,7 +1961,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
// Using one font for all control characters so it can be controlled independently to ensure
// the box goes around the characters tightly. Seems to be no way to work out what height
// is taken by an individual character - internal leading gives varying results.
- FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
+ const Font *ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font.get();
const char cc[2] = { static_cast<char>(vsDraw.controlCharSymbol), '\0' };
surface->DrawTextNoClip(rcSegment, ctrlCharsFont,
rcSegment.top + vsDraw.maxAscent,
@@ -2509,7 +2509,7 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur
// Determining width must happen after fonts have been realised in Refresh
int lineNumberWidth = 0;
if (lineNumberIndex >= 0) {
- lineNumberWidth = static_cast<int>(surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,
+ lineNumberWidth = static_cast<int>(surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font.get(),
"99999" lineNumberPrintSpace));
vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); // Recalculate fixedColumnWidth
@@ -2589,9 +2589,9 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur
rcNumber.right = rcNumber.left + lineNumberWidth;
// Right justify
rcNumber.left = rcNumber.right - surfaceMeasure->WidthText(
- vsPrint.styles[STYLE_LINENUMBER].font, number);
+ vsPrint.styles[STYLE_LINENUMBER].font.get(), number);
surface->FlushCachedState();
- surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
+ surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font.get(),
static_cast<XYPOSITION>(ypos + vsPrint.maxAscent), number,
vsPrint.styles[STYLE_LINENUMBER].fore,
vsPrint.styles[STYLE_LINENUMBER].back);
diff --git a/src/Editor.cxx b/src/Editor.cxx
index f9bf5a582..7fa790469 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -1829,7 +1829,7 @@ long Editor::TextWidth(uptr_t style, const char *text) {
RefreshStyleData();
AutoSurface surface(this);
if (surface) {
- return std::lround(surface->WidthText(vs.styles[style].font, text));
+ return std::lround(surface->WidthText(vs.styles[style].font.get(), text));
} else {
return 1;
}
diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx
index 286f334f5..861ae58aa 100644
--- a/src/LineMarker.cxx
+++ b/src/LineMarker.cxx
@@ -111,7 +111,7 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore);
}
-void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const {
+void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, int marginStyle) const {
if (customDraw) {
customDraw(surface, rcWhole, fontForCharacter, static_cast<int>(part), marginStyle, this);
return;
diff --git a/src/LineMarker.h b/src/LineMarker.h
index 4173f065e..468c53f13 100644
--- a/src/LineMarker.h
+++ b/src/LineMarker.h
@@ -13,7 +13,7 @@ namespace Scintilla {
class XPM;
class RGBAImage;
-typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, int tFold, int marginStyle, const void *lineMarker);
+typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, const Font *fontForCharacter, int tFold, int marginStyle, const void *lineMarker);
/**
*/
@@ -44,7 +44,7 @@ public:
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage);
- void Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const;
+ void Draw(Surface *surface, PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, int marginStyle) const;
};
}
diff --git a/src/MarginView.cxx b/src/MarginView.cxx
index d2fb5f77d..27b057bd4 100644
--- a/src/MarginView.cxx
+++ b/src/MarginView.cxx
@@ -188,7 +188,7 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc,
rcSelMargin.bottom = rc.bottom;
const Point ptOrigin = model.GetVisibleOriginInMain();
- FontAlias fontLineNumber = vs.styles[STYLE_LINENUMBER].font;
+ const Font *fontLineNumber = vs.styles[STYLE_LINENUMBER].font.get();
for (size_t margin = 0; margin < vs.ms.size(); margin++) {
if (vs.ms[margin].width > 0) {
diff --git a/src/Platform.h b/src/Platform.h
index 778c9a810..cd096af6b 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -81,7 +81,6 @@ namespace Scintilla {
// Underlying the implementation of the platform classes are platform specific types.
// Sometimes these need to be passed around by client code so they are defined here
-typedef void *FontID;
typedef void *SurfaceID;
typedef void *WindowID;
typedef void *MenuID;
@@ -124,25 +123,16 @@ struct FontParameters {
};
class Font {
-protected:
- FontID fid;
public:
- Font() noexcept;
+ Font() noexcept=default;
// Deleted so Font objects can not be copied
Font(const Font &) = delete;
Font(Font &&) = delete;
Font &operator=(const Font &) = delete;
Font &operator=(Font &&) = delete;
- virtual ~Font();
-
- virtual void Create(const FontParameters &fp);
- virtual void Release();
+ virtual ~Font()=default;
- FontID GetID() const noexcept { return fid; }
- // Alias another font - caller guarantees not to Release
- void SetID(FontID fid_) noexcept { fid = fid_; }
- friend class Surface;
- friend class SurfaceImpl;
+ static std::shared_ptr<Font> Allocate(const FontParameters &fp);
};
class IScreenLine {
@@ -206,16 +196,16 @@ public:
virtual std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) = 0;
- virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
- virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
- virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) = 0;
- virtual void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) = 0;
- virtual XYPOSITION WidthText(Font &font_, std::string_view text) = 0;
- virtual XYPOSITION Ascent(Font &font_)=0;
- virtual XYPOSITION Descent(Font &font_)=0;
- virtual XYPOSITION InternalLeading(Font &font_)=0;
- virtual XYPOSITION Height(Font &font_)=0;
- virtual XYPOSITION AverageCharWidth(Font &font_)=0;
+ virtual void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
+ virtual void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
+ virtual void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) = 0;
+ virtual void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) = 0;
+ virtual XYPOSITION WidthText(const Font *font_, std::string_view text) = 0;
+ virtual XYPOSITION Ascent(const Font *font_)=0;
+ virtual XYPOSITION Descent(const Font *font_)=0;
+ virtual XYPOSITION InternalLeading(const Font *font_)=0;
+ virtual XYPOSITION Height(const Font *font_)=0;
+ virtual XYPOSITION AverageCharWidth(const Font *font_)=0;
virtual void SetClip(PRectangle rc)=0;
virtual void FlushCachedState()=0;
@@ -255,7 +245,7 @@ public:
void Show(bool show=true);
void InvalidateAll();
void InvalidateRectangle(PRectangle rc);
- virtual void SetFont(Font &font);
+ virtual void SetFont(const Font *font);
enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
void SetCursor(Cursor curs);
PRectangle GetMonitorRect(Point pt);
@@ -286,7 +276,7 @@ public:
~ListBox() override;
static ListBox *Allocate();
- void SetFont(Font &font) override =0;
+ void SetFont(const Font *font) override =0;
virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index 55af2dabb..8665c19be 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -342,7 +342,7 @@ XYPOSITION ScreenLine::TabWidthMinimumPixels() const {
}
const Font *ScreenLine::FontOfPosition(size_t position) const {
- return &ll->bidiData->stylesFonts[start + position];
+ return ll->bidiData->stylesFonts[start + position].get();
}
XYPOSITION ScreenLine::RepresentationWidth(size_t position) const {
@@ -795,7 +795,7 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
probe = probe2;
}
}
- FontAlias fontStyle = vstyle.styles[styleNumber].font;
+ const Font *fontStyle = vstyle.styles[styleNumber].font.get();
if (len > BreakFinder::lengthStartSubdivision) {
// Break up into segments
unsigned int startSegment = 0;
diff --git a/src/PositionCache.h b/src/PositionCache.h
index 7573a2dc3..8968092e7 100644
--- a/src/PositionCache.h
+++ b/src/PositionCache.h
@@ -46,7 +46,7 @@ enum PointEnd {
class BidiData {
public:
- std::vector<FontAlias> stylesFonts;
+ std::vector<std::shared_ptr<Font>> stylesFonts;
std::vector<XYPOSITION> widthReprs;
void Resize(size_t maxLineLength_);
};
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 4830357ed..b46a2207a 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -289,7 +289,7 @@ void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list
rcac.right = rcac.left + widthLB;
rcac.bottom = static_cast<XYPOSITION>(std::min(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
ac.lb->SetPositionRelative(rcac, &wMain);
- ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
+ ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font.get());
const unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
ac.lb->SetAverageCharWidth(aveCharWidth);
ac.lb->SetDelegate(this);
diff --git a/src/Style.cxx b/src/Style.cxx
index 5a3628e8f..85ac58738 100644
--- a/src/Style.cxx
+++ b/src/Style.cxx
@@ -18,31 +18,6 @@
using namespace Scintilla;
-FontAlias::FontAlias() noexcept {
-}
-
-FontAlias::FontAlias(const FontAlias &other) noexcept : Font() {
- SetID(other.fid);
-}
-
-FontAlias::FontAlias(FontAlias &&other) noexcept : Font() {
- SetID(other.fid);
- other.ClearFont();
-}
-
-FontAlias::~FontAlias() {
- SetID(FontID{});
- // ~Font will not release the actual font resource since it is now 0
-}
-
-void FontAlias::MakeAlias(const Font &fontOrigin) noexcept {
- SetID(fontOrigin.GetID());
-}
-
-void FontAlias::ClearFont() noexcept {
- SetID(FontID{});
-}
-
bool FontSpecification::operator==(const FontSpecification &other) const noexcept {
return fontName == other.fontName &&
weight == other.weight &&
@@ -148,7 +123,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
- font.ClearFont();
+ font.reset();
FontMeasurements::ClearMeasurements();
}
@@ -169,7 +144,7 @@ void Style::ClearTo(const Style &source) noexcept {
source.hotspot);
}
-void Style::Copy(const Font &font_, const FontMeasurements &fm_) noexcept {
- font.MakeAlias(font_);
+void Style::Copy(std::shared_ptr<Font> font_, const FontMeasurements &fm_) noexcept {
+ font = std::move(font_);
(FontMeasurements &)(*this) = fm_;
}
diff --git a/src/Style.h b/src/Style.h
index 071d752ca..769386359 100644
--- a/src/Style.h
+++ b/src/Style.h
@@ -29,20 +29,6 @@ struct FontSpecification {
bool operator<(const FontSpecification &other) const noexcept;
};
-// Just like Font but only has a copy of the FontID so should not delete it
-class FontAlias : public Font {
-public:
- FontAlias() noexcept;
- // FontAlias objects can be copy or move constructed but not be assigned
- FontAlias(const FontAlias &) noexcept;
- FontAlias(FontAlias &&) noexcept;
- FontAlias &operator=(const FontAlias &) = delete;
- FontAlias &operator=(FontAlias &&) = delete;
- ~FontAlias() override;
- void MakeAlias(const Font &fontOrigin) noexcept;
- void ClearFont() noexcept;
-};
-
struct FontMeasurements {
unsigned int ascent;
unsigned int descent;
@@ -68,7 +54,7 @@ public:
bool changeable;
bool hotspot;
- FontAlias font;
+ std::shared_ptr<Font> font;
Style();
Style(const Style &source) noexcept;
@@ -83,7 +69,7 @@ public:
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) noexcept;
void ClearTo(const Style &source) noexcept;
- void Copy(const Font &font_, const FontMeasurements &fm_) noexcept;
+ void Copy(std::shared_ptr<Font> font_, const FontMeasurements &fm_) noexcept;
bool IsProtected() const noexcept { return !(changeable && visible);}
};
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index d05e82749..0a3451026 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -37,7 +37,6 @@ MarginStyle::MarginStyle(int style_, int width_, int mask_) noexcept :
FontRealised::FontRealised() noexcept = default;
FontRealised::~FontRealised() {
- font.Release();
}
void FontRealised::Realise(Surface &surface, int zoomLevel, int technology, const FontSpecification &fs) {
@@ -48,13 +47,13 @@ void FontRealised::Realise(Surface &surface, int zoomLevel, int technology, cons
const float deviceHeight = static_cast<float>(surface.DeviceHeightFont(sizeZoomed));
const FontParameters fp(fs.fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, fs.weight, fs.italic, fs.extraFontFlag, technology, fs.characterSet);
- font.Create(fp);
+ font = Font::Allocate(fp);
- ascent = static_cast<unsigned int>(surface.Ascent(font));
- descent = static_cast<unsigned int>(surface.Descent(font));
- capitalHeight = surface.Ascent(font) - surface.InternalLeading(font);
- aveCharWidth = surface.AverageCharWidth(font);
- spaceWidth = surface.WidthText(font, " ");
+ ascent = static_cast<unsigned int>(surface.Ascent(font.get()));
+ descent = static_cast<unsigned int>(surface.Descent(font.get()));
+ capitalHeight = surface.Ascent(font.get()) - surface.InternalLeading(font.get());
+ aveCharWidth = surface.AverageCharWidth(font.get());
+ spaceWidth = surface.WidthText(font.get(), " ");
}
ViewStyle::ViewStyle() : markers(MARKER_MAX + 1), indicators(INDICATOR_MAX + 1) {
@@ -345,7 +344,7 @@ void ViewStyle::Refresh(Surface &surface, int tabInChars) {
controlCharWidth = 0.0;
if (controlCharSymbol >= 32) {
const char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
- controlCharWidth = surface.WidthText(styles[STYLE_CONTROLCHAR].font, cc);
+ controlCharWidth = surface.WidthText(styles[STYLE_CONTROLCHAR].font.get(), cc);
}
CalculateMarginWidthAndMask();
diff --git a/src/ViewStyle.h b/src/ViewStyle.h
index dc47ed380..b07c34a08 100644
--- a/src/ViewStyle.h
+++ b/src/ViewStyle.h
@@ -29,7 +29,7 @@ public:
class FontRealised : public FontMeasurements {
public:
- Font font;
+ std::shared_ptr<Font> font;
FontRealised() noexcept;
// FontRealised objects can not be copied.
FontRealised(const FontRealised &) = delete;
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);
}