diff --git a/common/attrlist.c b/common/attrlist.c index 5afb862f..5c75da58 100644 --- a/common/attrlist.c +++ b/common/attrlist.c @@ -295,6 +295,12 @@ static int specsIdentical(struct attr *attr, uiAttributeSpec *spec) case uiAttributeSize: // TODO use a closest match? return attr->spec.Double == spec->Double; + case uiAttributeColor: + // TODO use a closest match? + return attr->spec.R == spec->R && + attr->spec.G == spec->G && + attr->spec.B == spec->B && + attr->spec.A == spec->A; // TODO } // handles the rest diff --git a/darwin/attrstr.m b/darwin/attrstr.m index 16f7fb92..e5d3c84e 100644 --- a/darwin/attrstr.m +++ b/darwin/attrstr.m @@ -43,9 +43,15 @@ static void adjustFontInRange(struct foreachParams *p, size_t start, size_t end, static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) { struct foreachParams *p = (struct foreachParams *) data; + CFRange range; + CGColorSpaceRef colorspace; + CGColorRef color; + CGFloat components[4]; start = attrstrUTF8ToUTF16(s, start); end = attrstrUTF8ToUTF16(s, end); + range.location = start; + range.length = end - start; switch (spec->Type) { case uiAttributeFamily: ensureFontInRange(p, start, end); @@ -77,6 +83,20 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t desc->Stretch = (uiDrawTextStretch) (spec->Value); }); break; + case uiAttributeColor: + colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + if (colorspace == NULL) { + // TODO + } + components[0] = spec->R; + components[1] = spec->G; + components[2] = spec->B; + components[3] = spec->A; + color = CGColorCreate(colorspace, components); + CFRelease(colorspace); + CFAttributedStringSetAttribute(p->mas, range, kCTForegroundColorAttributeName, color); + CFRelease(color); + break; // TODO } return 0; diff --git a/darwin/draw.m b/darwin/draw.m index d9aadede..b4be6e7f 100644 --- a/darwin/draw.m +++ b/darwin/draw.m @@ -218,6 +218,10 @@ static void fillGradient(CGContextRef ctxt, uiDrawPath *p, uiDrawBrush *b) // gradients need a color space // for consistency with windows, use sRGB colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + if (colorspace == NULL) { + // TODO + } + // TODO add NULL check to other uses of CGColorSpace // make the gradient colors = uiAlloc(b->NumStops * 4 * sizeof (CGFloat), "CGFloat[]"); diff --git a/examples/drawtext/attributes.c b/examples/drawtext/attributes.c index c2a91889..d5c47058 100644 --- a/examples/drawtext/attributes.c +++ b/examples/drawtext/attributes.c @@ -62,6 +62,20 @@ static void setupAttributedString(void) uiAttributedStringAppendUnattributed(attrstr, ", "); + next = "multiple colors"; + start = uiAttributedStringLen(attrstr); + end = start + strlen(next); + uiAttributedStringAppendUnattributed(attrstr, next); + spec.Type = uiAttributeColor; + // Direct2D "Crimson" (#DC143C) + spec.R = 0.8627450980392156; + spec.G = 0.0784313725490196; + spec.B = 0.2352941176470588; + spec.A = 0.75; + uiAttributedStringSetAttribute(attrstr, &spec, start, end); + + uiAttributedStringAppendUnattributed(attrstr, ", "); + next = "multiple TODO"; } diff --git a/ui_attrstr.h b/ui_attrstr.h index 096bcc4e..62a82f77 100644 --- a/ui_attrstr.h +++ b/ui_attrstr.h @@ -2,13 +2,12 @@ typedef struct uiAttributedString uiAttributedString; typedef struct uiAttributeSpec uiAttributeSpec; _UI_ENUM(uiAttribute) { - // TODO once we allow loading fonts in memory we can't use just one pointer anymore uiAttributeFamily, - // TODO no guarantee this can fit in a uintptr_t; we need a better way to store these... - uiAttributeSize, + uiAttributeSize, // use Double uiAttributeWeight, uiAttributeItalic, uiAttributeStretch, + uiAttributeColor, // use R, G, B, A // TODO // TODO uiAttributeSystem, // TODO uiAttributeCustom, @@ -18,6 +17,10 @@ struct uiAttributeSpec { uiAttribute Type; uintptr_t Value; double Double; + double R; + double G; + double B; + double A; }; typedef int (*uiAttributedStringForEachAttributeFunc)(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data);