aboutsummaryrefslogtreecommitdiffhomepage
path: root/qt/ScintillaEditBase/PlatQt.cpp
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 /qt/ScintillaEditBase/PlatQt.cpp
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 'qt/ScintillaEditBase/PlatQt.cpp')
-rw-r--r--qt/ScintillaEditBase/PlatQt.cpp122
1 files changed, 54 insertions, 68 deletions
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*/) {}