aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil Hodgson <nyamatongwe@gmail.com>2018-05-21 15:41:57 +1000
committerNeil Hodgson <nyamatongwe@gmail.com>2018-05-21 15:41:57 +1000
commitcc5e63013d7aa447a74fafba0ee4dd560b6952c7 (patch)
treeebd6b08100d42c768f91890dda49308055581789
parente0e105ea1559874a5a9097461d0d7933cb5cbbb4 (diff)
downloadscintilla-mirror-cc5e63013d7aa447a74fafba0ee4dd560b6952c7.tar.gz
If decoding DBCS text fails, use the MacRoman encoding to ensure something is
visible.
-rw-r--r--cocoa/PlatCocoa.mm14
-rw-r--r--cocoa/QuartzTextLayout.h32
-rw-r--r--doc/ScintillaHistory.html4
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>