And implemented uiAttributeBackground on OS X. Not sure what else to add besides the feature variants...

This commit is contained in:
Pietro Gagliardi 2017-02-13 02:10:39 -05:00
parent 9eba197fd1
commit 1c238bf85b
5 changed files with 43 additions and 5 deletions

View File

@ -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,

View File

@ -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;
} }

View File

@ -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?

View File

@ -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);

View File

@ -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;