diff options
Diffstat (limited to 'cocoa')
-rw-r--r-- | cocoa/PlatCocoa.h | 20 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 140 | ||||
-rw-r--r-- | cocoa/QuartzTextLayout.h | 4 | ||||
-rw-r--r-- | cocoa/QuartzTextStyle.h | 10 |
4 files changed, 86 insertions, 88 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; } |