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;
uiDrawPath *path;
uiDrawTextLayoutLineByteRange(layout, line, &lstart, &lend);
if (lend > end) // don't cross lines
lend = end;
startx = uiDrawTextLayoutByteLocationInLine(layout, line, start);
startx = uiDrawTextLayoutByteLocationInLine(layout, start, line);
// TODO explain this; note the use of start with lend
endx = layoutwid;
if (!isSelection || end <= lend)
endx = uiDrawTextLayoutByteLocationInLine(layout, line, lend);
endx = uiDrawTextLayoutByteLocationInLine(layout, lend, line);
uiDrawTextLayoutLineGetMetrics(layout, line, &m);
path = uiDrawNewPath(uiDrawFillModeWinding);
uiDrawPathAddRectangle(path,

View File

@ -9,6 +9,7 @@ struct foreachParams {
CFMutableAttributedStringRef mas;
NSMutableDictionary *converted;
uiDrawFontDescriptor *defaultFont;
NSMutableArray *backgroundBlocks;
};
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)
{
struct foreachParams *p = (struct foreachParams *) data;
@ -47,7 +62,11 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
CGColorSpaceRef colorspace;
CGColorRef color;
CGFloat components[4];
size_t ostart, oend;
backgroundBlock block;
ostart = start;
oend = end;
start = attrstrUTF8ToUTF16(s, start);
end = attrstrUTF8ToUTF16(s, end);
range.location = start;
@ -97,6 +116,12 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
CFAttributedStringSetAttribute(p->mas, range, kCTForegroundColorAttributeName, color);
CFRelease(color);
break;
case uiAttributeBackground:
block = mkBackgroundBlock(ostart, oend,
spec->R, spec->G, spec->B, spec->A);
[p->backgroundBlocks addObject:block];
Block_release(block);
break;
// TODO
}
return 0;
@ -154,7 +179,7 @@ static CTParagraphStyleRef mkParagraphStyle(uiDrawTextLayoutParams *p)
return ps;
}
CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p)
CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks)
{
CFStringRef cfstr;
CFMutableDictionaryRef defaultAttrs;
@ -194,10 +219,12 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p)
fep.mas = mas;
fep.converted = [NSMutableDictionary new];
fep.defaultFont = p->DefaultFont;
fep.backgroundBlocks = [NSMutableArray new];
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
applyAndFreeFontAttributes(&fep);
[fep.converted release];
CFAttributedStringEndEditing(mas);
*backgroundBlocks = fep.backgroundBlocks;
return mas;
}

View File

@ -28,6 +28,8 @@ struct uiDrawTextLayout {
// we compute this once when first creating the layout
uiDrawTextLayoutLineMetrics *lineMetrics;
NSArray *backgroundBlocks;
// for converting CFAttributedString indices from/to byte offsets
size_t *u8tou16;
size_t nUTF8;
@ -114,7 +116,7 @@ uiDrawTextLayout *uiDrawNewTextLayout(uiDrawTextLayoutParams *p)
CGRect rect;
tl = uiNew(uiDrawTextLayout);
tl->attrstr = attrstrToCoreFoundation(p);
tl->attrstr = attrstrToCoreFoundation(p, &(tl->backgroundBlocks));
range.location = 0;
range.length = CFAttributedStringGetLength(tl->attrstr);
tl->width = p->Width;
@ -165,6 +167,7 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
{
uiFree(tl->u16tou8);
uiFree(tl->u8tou16);
[tl->backgroundBlocks release];
uiFree(tl->lineMetrics);
// TODO release tl->lines?
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*
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
{
backgroundBlock b;
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
// 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?

View File

@ -145,4 +145,5 @@ extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
// 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);
spec.Type = uiAttributeBackground;
// Direct2D "Peach Puff" (#FFDAB9)
// TODO choose a darker color
spec.R = 1.0;
spec.G = 0.85490196078431372;
spec.B = 0.7254901960784313;