Fixed surrogate pair drawing on OS X.

This commit is contained in:
Pietro Gagliardi 2016-05-23 01:11:43 -04:00
parent e3bcf31764
commit 5d63fe4cec
2 changed files with 43 additions and 4 deletions

View File

@ -18,6 +18,9 @@ This README is being written.<br>
*Note that today's entry may be updated later today.* *Note that today's entry may be updated later today.*
* **23 May 2016**
* Fixed surrogate pair drawing on OS X.
* **22 May 2016** * **22 May 2016**
* Removed `uiControlVerifyDestroy()`; that is now part of `uiFreeControl()` itself. * Removed `uiControlVerifyDestroy()`; that is now part of `uiFreeControl()` itself.
* Added `uiPi`, a constant for π. This is provided for C and C++ programmers, where there is no standard named constant for π; bindings authors shouldn't need to worry about this. * Added `uiPi`, a constant for π. This is provided for C and C++ programmers, where there is no standard named constant for π; bindings authors shouldn't need to worry about this.

View File

@ -442,15 +442,17 @@ void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metri
struct uiDrawTextLayout { struct uiDrawTextLayout {
CFMutableAttributedStringRef mas; CFMutableAttributedStringRef mas;
CFRange *charsToRanges;
double width; double width;
}; };
uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFont, double width) uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFont, double width)
{ {
uiDrawTextLayout *layout; uiDrawTextLayout *layout;
//TODO CFStringRef cfstr;
CFAttributedStringRef immutable; CFAttributedStringRef immutable;
CFMutableDictionaryRef attr; CFMutableDictionaryRef attr;
CFStringRef backing;
CFIndex i, j, n;
layout = uiNew(uiDrawTextLayout); layout = uiNew(uiDrawTextLayout);
@ -458,11 +460,9 @@ uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFo
// this will retain defaultFont->f; no need to worry // this will retain defaultFont->f; no need to worry
CFDictionaryAddValue(attr, kCTFontAttributeName, defaultFont->f); CFDictionaryAddValue(attr, kCTFontAttributeName, defaultFont->f);
// TODO convert the NSString call to a CFString call
immutable = CFAttributedStringCreate(NULL, (CFStringRef) [NSString stringWithUTF8String:str], attr); immutable = CFAttributedStringCreate(NULL, (CFStringRef) [NSString stringWithUTF8String:str], attr);
if (immutable == NULL) if (immutable == NULL)
complain("error creating immutable attributed string in uiDrawNewTextLayout()"); complain("error creating immutable attributed string in uiDrawNewTextLayout()");
//TODO CFRelease(cfstr);
CFRelease(attr); CFRelease(attr);
layout->mas = CFAttributedStringCreateMutableCopy(NULL, 0, immutable); layout->mas = CFAttributedStringCreateMutableCopy(NULL, 0, immutable);
@ -472,11 +472,34 @@ uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFo
uiDrawTextLayoutSetWidth(layout, width); uiDrawTextLayoutSetWidth(layout, width);
// unfortunately the CFRanges for attributes expect UTF-16 codepoints
// we want full characters
// fortunately CFStringGetRangeOfComposedCharactersAtIndex() is here for us
backing = CFAttributedStringGetString(layout->mas);
n = CFStringGetLength(backing);
// allocate one extra, just to be safe
layout->charsToRanges = (CFRange *) uiAlloc((n + 1) * sizeof (CFRange), "CFRange[]");
i = 0;
j = 0;
while (i < n) {
CFRange range;
range = CFStringGetRangeOfComposedCharactersAtIndex(backing, i);
i = range.location + range.length;
layout->charsToRanges[j] = range;
j++;
}
// and set the last one
layout->charsToRanges[j].location = i;
layout->charsToRanges[j].length = 0;
// TODO how will this affect drawing things that aren't surrogate pairs?
return layout; return layout;
} }
void uiDrawFreeTextLayout(uiDrawTextLayout *layout) void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
{ {
uiFree(layout->charsToRanges);
CFRelease(layout->mas); CFRelease(layout->mas);
uiFree(layout); uiFree(layout);
} }
@ -604,7 +627,20 @@ void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextL
CGContextSetTextPosition(c, x, y); CGContextSetTextPosition(c, x, y);
#endif #endif
#define rangeToCFRange() CFRangeMake(startChar, endChar - startChar) static CFRange charsToRange(uiDrawTextLayout *layout, intmax_t startChar, intmax_t endChar)
{
CFRange start, end;
CFRange out;
start = layout->charsToRanges[startChar];
end = layout->charsToRanges[endChar];
out.location = start.location;
// - 1 to avoid including the first code point after end
out.length = (end.location + end.length - 1) - start.location;
return out;
}
#define rangeToCFRange() charsToRange(layout, startChar, endChar)
void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, intmax_t startChar, intmax_t endChar, double r, double g, double b, double a) void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, intmax_t startChar, intmax_t endChar, double r, double g, double b, double a)
{ {