diff options
author | Neil <nyamatongwe@gmail.com> | 2021-03-17 14:58:11 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2021-03-17 14:58:11 +1100 |
commit | 1b5dd62b71d8d9b657b0cd7c138c9dc523a07cc4 (patch) | |
tree | f25f7353ad23c041da607b07b5ddd247214ba90c /src | |
parent | 7fbe52f835688967a6079582ed8839cb55d0f9ea (diff) | |
download | scintilla-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 'src')
-rw-r--r-- | src/CallTip.cxx | 15 | ||||
-rw-r--r-- | src/CallTip.h | 2 | ||||
-rw-r--r-- | src/EditView.cxx | 30 | ||||
-rw-r--r-- | src/Editor.cxx | 2 | ||||
-rw-r--r-- | src/LineMarker.cxx | 2 | ||||
-rw-r--r-- | src/LineMarker.h | 4 | ||||
-rw-r--r-- | src/MarginView.cxx | 2 | ||||
-rw-r--r-- | src/Platform.h | 40 | ||||
-rw-r--r-- | src/PositionCache.cxx | 4 | ||||
-rw-r--r-- | src/PositionCache.h | 2 | ||||
-rw-r--r-- | src/ScintillaBase.cxx | 2 | ||||
-rw-r--r-- | src/Style.cxx | 31 | ||||
-rw-r--r-- | src/Style.h | 18 | ||||
-rw-r--r-- | src/ViewStyle.cxx | 15 | ||||
-rw-r--r-- | src/ViewStyle.h | 2 |
15 files changed, 60 insertions, 111 deletions
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; |