Fixed surrogate pair drawing on OS X.
This commit is contained in:
parent
e3bcf31764
commit
5d63fe4cec
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue