diff options
Diffstat (limited to 'cocoa')
-rw-r--r-- | cocoa/PlatCocoa.h | 10 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 98 |
2 files changed, 108 insertions, 0 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h index 1ddb203c7..b918e5ed0 100644 --- a/cocoa/PlatCocoa.h +++ b/cocoa/PlatCocoa.h @@ -104,6 +104,7 @@ 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, 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, @@ -111,6 +112,15 @@ public: 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; + + void DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, + ColourDesired back) override; + void DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, + ColourDesired back) override; + void DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override; + void MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) override; + XYPOSITION WidthTextUTF8(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; diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index 2e3ab2d57..f84a335aa 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -1227,6 +1227,104 @@ XYPOSITION SurfaceImpl::WidthText(const Font *font_, std::string_view text) { return static_cast<XYPOSITION>(textLayout->MeasureStringWidth()); } +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourDesired fore, ColourDesired back) { + FillRectangle(rc, back); + DrawTextTransparent(rc, font_, ybase, text, fore); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourDesired fore, ColourDesired back) { + CGContextSaveGState(gc); + CGContextClipToRect(gc, PRectangleToCGRect(rc)); + DrawTextNoClip(rc, font_, ybase, text, fore, back); + CGContextRestoreGState(gc); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourDesired fore) { + QuartzTextStyle *style = TextStyleFromFont(font_); + if (!style) { + return; + } + const CFStringEncoding encoding = kCFStringEncodingUTF8; + ColourDesired colour(fore.AsInteger()); + CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0, colour.GetGreen()/255.0, colour.GetBlue()/255.0, 1.0); + + style->setCTStyleColour(color); + + CGColorRelease(color); + + textLayout->setText(text, encoding, style); + textLayout->draw(gc, rc.left, ybase); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) { + const QuartzTextStyle *style = TextStyleFromFont(font_); + if (!style) { + return; + } + const CFStringEncoding encoding = kCFStringEncodingUTF8; + const CFStringEncoding encodingUsed = + textLayout->setText(text, encoding, style); + + CTLineRef mLine = textLayout->getCTLine(); + assert(mLine); + + if (encodingUsed != encoding) { + // Switched to MacRoman to make work so treat as single byte encoding. + for (int i=0; i<text.length(); i++) { + CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, i+1, nullptr); + positions[i] = static_cast<XYPOSITION>(xPosition); + } + return; + } + + // Map the widths given for UTF-16 characters back onto the UTF-8 input string + CFIndex fit = textLayout->getStringLength(); + int ui=0; + int i=0; + std::vector<CGFloat> linePositions(fit); + GetPositions(mLine, linePositions); + while (ui<fit) { + const unsigned char uch = text[i]; + const unsigned int byteCount = UTF8BytesOfLead[uch]; + const int codeUnits = UTF16LengthFromUTF8ByteCount(byteCount); + const CGFloat xPosition = linePositions[ui]; + for (unsigned int bytePos=0; (bytePos<byteCount) && (i<text.length()); bytePos++) { + positions[i++] = static_cast<XYPOSITION>(xPosition); + } + ui += codeUnits; + } + XYPOSITION lastPos = 0.0f; + if (i > 0) + lastPos = positions[i-1]; + while (i<text.length()) { + positions[i++] = lastPos; + } +} + +XYPOSITION SurfaceImpl::WidthTextUTF8(const Font *font_, std::string_view text) { + const QuartzTextStyle *style = TextStyleFromFont(font_); + if (!style) { + return 1; + } + textLayout->setText(text, kCFStringEncodingUTF8, style); + + return static_cast<XYPOSITION>(textLayout->MeasureStringWidth()); +} + +//-------------------------------------------------------------------------------------------------- + + // This string contains a good range of characters to test for size. const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |