diff options
Diffstat (limited to 'cocoa/PlatCocoa.mm')
| -rw-r--r-- | cocoa/PlatCocoa.mm | 140 | 
1 files changed, 69 insertions, 71 deletions
| 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; | 
