diff options
| author | Neil Hodgson <nyamatongwe@gmail.com> | 2018-05-21 15:41:57 +1000 | 
|---|---|---|
| committer | Neil Hodgson <nyamatongwe@gmail.com> | 2018-05-21 15:41:57 +1000 | 
| commit | cc5e63013d7aa447a74fafba0ee4dd560b6952c7 (patch) | |
| tree | ebd6b08100d42c768f91890dda49308055581789 | |
| parent | e0e105ea1559874a5a9097461d0d7933cb5cbbb4 (diff) | |
| download | scintilla-mirror-cc5e63013d7aa447a74fafba0ee4dd560b6952c7.tar.gz | |
If decoding DBCS text fails, use the MacRoman encoding to ensure something is
visible.
| -rw-r--r-- | cocoa/PlatCocoa.mm | 14 | ||||
| -rw-r--r-- | cocoa/QuartzTextLayout.h | 32 | ||||
| -rw-r--r-- | doc/ScintillaHistory.html | 4 | 
3 files changed, 39 insertions, 11 deletions
| diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index 1141cca44..0e1e1544c 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -867,10 +867,20 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION yba  void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {  	CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); -	textLayout->setText(text, encoding, *TextStyleFromFont(font_)); +	const CFStringEncoding encodingUsed = +		textLayout->setText(text, encoding, *TextStyleFromFont(font_));  	CTLineRef mLine = textLayout->getCTLine(); -	assert(mLine != NULL); +	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; +	}  	if (unicodeMode) {  		// Map the widths given for UTF-16 characters back onto the UTF-8 input string diff --git a/cocoa/QuartzTextLayout.h b/cocoa/QuartzTextLayout.h index a3ed910de..62e695525 100644 --- a/cocoa/QuartzTextLayout.h +++ b/cocoa/QuartzTextLayout.h @@ -23,35 +23,49 @@ public:  	}  	~QuartzTextLayout() { -		if (mString != NULL) { +		if (mString) {  			CFRelease(mString);  			mString = NULL;  		} -		if (mLine != NULL) { +		if (mLine) {  			CFRelease(mLine);  			mLine = NULL;  		}  	} -	void 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); +			mString = NULL; +		} +		if (mLine) { +			CFRelease(mLine); +			mLine = NULL; +		} +  		const UInt8 *puiBuffer = reinterpret_cast<const UInt8 *>(sv.data());  		CFStringRef str = CFStringCreateWithBytes(NULL, puiBuffer, sv.length(), encoding, false); -		if (!str) -			return; +		if (!str) { +			// Failed to decode bytes into string with given encoding so try +			// MacRoman which should accept any byte. +			encoding = kCFStringEncodingMacRoman; +			str = CFStringCreateWithBytes(NULL, puiBuffer, sv.length(), encoding, false); +		} +		if (!str) { +			return encoding; +		}  		stringLength = CFStringGetLength(str);  		CFMutableDictionaryRef stringAttribs = r.getCTStyle(); -		if (mString != NULL) -			CFRelease(mString);  		mString = ::CFAttributedStringCreate(NULL, str, stringAttribs); -		if (mLine != NULL) -			CFRelease(mLine);  		mLine = ::CTLineCreateWithAttributedString(mString);  		CFRelease(str); +		return encoding;  	}  	/** Draw the text layout into a CGContext at the specified position. diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index bba75339b..030a6de53 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -552,6 +552,10 @@  	and ensure something is shown.  	</li>  	<li> +	On Cocoa, invalid text in DBCS encodings will be interpreted through the +	single-byte MacRoman encoding as that will accept any byte. +	</li> +	<li>  	Crashes fixed on macOS for invalid DBCS characters when dragging text,  	changing case of text, case-insensitive searching, and retrieving text as UTF-8.  	</li> | 
