And implemented uiAttributeBackground on OS X. Not sure what else to add besides the feature variants...
This commit is contained in:
parent
9eba197fd1
commit
1c238bf85b
|
@ -68,13 +68,14 @@ void drawTextBackground(uiDrawContext *c, double x, double y, uiDrawTextLayout *
|
||||||
double startx, endx;
|
double startx, endx;
|
||||||
uiDrawPath *path;
|
uiDrawPath *path;
|
||||||
|
|
||||||
|
uiDrawTextLayoutLineByteRange(layout, line, &lstart, &lend);
|
||||||
if (lend > end) // don't cross lines
|
if (lend > end) // don't cross lines
|
||||||
lend = end;
|
lend = end;
|
||||||
startx = uiDrawTextLayoutByteLocationInLine(layout, line, start);
|
startx = uiDrawTextLayoutByteLocationInLine(layout, start, line);
|
||||||
// TODO explain this; note the use of start with lend
|
// TODO explain this; note the use of start with lend
|
||||||
endx = layoutwid;
|
endx = layoutwid;
|
||||||
if (!isSelection || end <= lend)
|
if (!isSelection || end <= lend)
|
||||||
endx = uiDrawTextLayoutByteLocationInLine(layout, line, lend);
|
endx = uiDrawTextLayoutByteLocationInLine(layout, lend, line);
|
||||||
uiDrawTextLayoutLineGetMetrics(layout, line, &m);
|
uiDrawTextLayoutLineGetMetrics(layout, line, &m);
|
||||||
path = uiDrawNewPath(uiDrawFillModeWinding);
|
path = uiDrawNewPath(uiDrawFillModeWinding);
|
||||||
uiDrawPathAddRectangle(path,
|
uiDrawPathAddRectangle(path,
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct foreachParams {
|
||||||
CFMutableAttributedStringRef mas;
|
CFMutableAttributedStringRef mas;
|
||||||
NSMutableDictionary *converted;
|
NSMutableDictionary *converted;
|
||||||
uiDrawFontDescriptor *defaultFont;
|
uiDrawFontDescriptor *defaultFont;
|
||||||
|
NSMutableArray *backgroundBlocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
|
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
|
||||||
|
@ -40,6 +41,20 @@ static void adjustFontInRange(struct foreachParams *p, size_t start, size_t end,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static backgroundBlock mkBackgroundBlock(size_t start, size_t end, double r, double g, double b, double a)
|
||||||
|
{
|
||||||
|
return Block_copy(^(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y) {
|
||||||
|
uiDrawBrush brush;
|
||||||
|
|
||||||
|
brush.Type = uiDrawBrushTypeSolid;
|
||||||
|
brush.R = r;
|
||||||
|
brush.G = g;
|
||||||
|
brush.B = b;
|
||||||
|
brush.A = a;
|
||||||
|
drawTextBackground(c, x, y, layout, start, end, &brush, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
||||||
{
|
{
|
||||||
struct foreachParams *p = (struct foreachParams *) data;
|
struct foreachParams *p = (struct foreachParams *) data;
|
||||||
|
@ -47,7 +62,11 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
CGColorSpaceRef colorspace;
|
CGColorSpaceRef colorspace;
|
||||||
CGColorRef color;
|
CGColorRef color;
|
||||||
CGFloat components[4];
|
CGFloat components[4];
|
||||||
|
size_t ostart, oend;
|
||||||
|
backgroundBlock block;
|
||||||
|
|
||||||
|
ostart = start;
|
||||||
|
oend = end;
|
||||||
start = attrstrUTF8ToUTF16(s, start);
|
start = attrstrUTF8ToUTF16(s, start);
|
||||||
end = attrstrUTF8ToUTF16(s, end);
|
end = attrstrUTF8ToUTF16(s, end);
|
||||||
range.location = start;
|
range.location = start;
|
||||||
|
@ -97,6 +116,12 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
CFAttributedStringSetAttribute(p->mas, range, kCTForegroundColorAttributeName, color);
|
CFAttributedStringSetAttribute(p->mas, range, kCTForegroundColorAttributeName, color);
|
||||||
CFRelease(color);
|
CFRelease(color);
|
||||||
break;
|
break;
|
||||||
|
case uiAttributeBackground:
|
||||||
|
block = mkBackgroundBlock(ostart, oend,
|
||||||
|
spec->R, spec->G, spec->B, spec->A);
|
||||||
|
[p->backgroundBlocks addObject:block];
|
||||||
|
Block_release(block);
|
||||||
|
break;
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,7 +179,7 @@ static CTParagraphStyleRef mkParagraphStyle(uiDrawTextLayoutParams *p)
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p)
|
CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks)
|
||||||
{
|
{
|
||||||
CFStringRef cfstr;
|
CFStringRef cfstr;
|
||||||
CFMutableDictionaryRef defaultAttrs;
|
CFMutableDictionaryRef defaultAttrs;
|
||||||
|
@ -194,10 +219,12 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p)
|
||||||
fep.mas = mas;
|
fep.mas = mas;
|
||||||
fep.converted = [NSMutableDictionary new];
|
fep.converted = [NSMutableDictionary new];
|
||||||
fep.defaultFont = p->DefaultFont;
|
fep.defaultFont = p->DefaultFont;
|
||||||
|
fep.backgroundBlocks = [NSMutableArray new];
|
||||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||||
applyAndFreeFontAttributes(&fep);
|
applyAndFreeFontAttributes(&fep);
|
||||||
[fep.converted release];
|
[fep.converted release];
|
||||||
CFAttributedStringEndEditing(mas);
|
CFAttributedStringEndEditing(mas);
|
||||||
|
|
||||||
|
*backgroundBlocks = fep.backgroundBlocks;
|
||||||
return mas;
|
return mas;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ struct uiDrawTextLayout {
|
||||||
// we compute this once when first creating the layout
|
// we compute this once when first creating the layout
|
||||||
uiDrawTextLayoutLineMetrics *lineMetrics;
|
uiDrawTextLayoutLineMetrics *lineMetrics;
|
||||||
|
|
||||||
|
NSArray *backgroundBlocks;
|
||||||
|
|
||||||
// for converting CFAttributedString indices from/to byte offsets
|
// for converting CFAttributedString indices from/to byte offsets
|
||||||
size_t *u8tou16;
|
size_t *u8tou16;
|
||||||
size_t nUTF8;
|
size_t nUTF8;
|
||||||
|
@ -114,7 +116,7 @@ uiDrawTextLayout *uiDrawNewTextLayout(uiDrawTextLayoutParams *p)
|
||||||
CGRect rect;
|
CGRect rect;
|
||||||
|
|
||||||
tl = uiNew(uiDrawTextLayout);
|
tl = uiNew(uiDrawTextLayout);
|
||||||
tl->attrstr = attrstrToCoreFoundation(p);
|
tl->attrstr = attrstrToCoreFoundation(p, &(tl->backgroundBlocks));
|
||||||
range.location = 0;
|
range.location = 0;
|
||||||
range.length = CFAttributedStringGetLength(tl->attrstr);
|
range.length = CFAttributedStringGetLength(tl->attrstr);
|
||||||
tl->width = p->Width;
|
tl->width = p->Width;
|
||||||
|
@ -165,6 +167,7 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
||||||
{
|
{
|
||||||
uiFree(tl->u16tou8);
|
uiFree(tl->u16tou8);
|
||||||
uiFree(tl->u8tou16);
|
uiFree(tl->u8tou16);
|
||||||
|
[tl->backgroundBlocks release];
|
||||||
uiFree(tl->lineMetrics);
|
uiFree(tl->lineMetrics);
|
||||||
// TODO release tl->lines?
|
// TODO release tl->lines?
|
||||||
CFRelease(tl->frame);
|
CFRelease(tl->frame);
|
||||||
|
@ -177,8 +180,13 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
||||||
// TODO document that (x,y) is the top-left corner of the *entire frame*
|
// TODO document that (x,y) is the top-left corner of the *entire frame*
|
||||||
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
||||||
{
|
{
|
||||||
|
backgroundBlock b;
|
||||||
|
|
||||||
CGContextSaveGState(c->c);
|
CGContextSaveGState(c->c);
|
||||||
|
|
||||||
|
for (b in tl->backgroundBlocks)
|
||||||
|
b(c, tl, x, y);
|
||||||
|
|
||||||
// Core Text doesn't draw onto a flipped view correctly; we have to pretend it was unflipped
|
// Core Text doesn't draw onto a flipped view correctly; we have to pretend it was unflipped
|
||||||
// see the iOS bits of the first example at https://developer.apple.com/library/mac/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW1 (iOS is naturally flipped)
|
// see the iOS bits of the first example at https://developer.apple.com/library/mac/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW1 (iOS is naturally flipped)
|
||||||
// TODO how is this affected by a non-identity CTM?
|
// TODO how is this affected by a non-identity CTM?
|
||||||
|
|
|
@ -145,4 +145,5 @@ extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
|
||||||
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
|
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
|
||||||
|
|
||||||
// attrstr.m
|
// attrstr.m
|
||||||
extern CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p);
|
typedef void (^backgroundBlock)(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y);
|
||||||
|
extern CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks);
|
||||||
|
|
|
@ -82,6 +82,7 @@ static void setupAttributedString(void)
|
||||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||||
spec.Type = uiAttributeBackground;
|
spec.Type = uiAttributeBackground;
|
||||||
// Direct2D "Peach Puff" (#FFDAB9)
|
// Direct2D "Peach Puff" (#FFDAB9)
|
||||||
|
// TODO choose a darker color
|
||||||
spec.R = 1.0;
|
spec.R = 1.0;
|
||||||
spec.G = 0.85490196078431372;
|
spec.G = 0.85490196078431372;
|
||||||
spec.B = 0.7254901960784313;
|
spec.B = 0.7254901960784313;
|
||||||
|
|
Loading…
Reference in New Issue