Finalized and implemented underlines on OS X.
This commit is contained in:
parent
eb7dfa5cc4
commit
4195bc3b4b
|
@ -302,6 +302,12 @@ static int specsIdentical(struct attr *attr, uiAttributeSpec *spec)
|
|||
case uiAttributeSize:
|
||||
// TODO use a closest match?
|
||||
return attr->spec.Double == spec->Double;
|
||||
case uiAttributeUnderlineColor:
|
||||
if (attr->spec.Value != spec->Value)
|
||||
return 0;
|
||||
if (attr->spec.Value != uiDrawUnderlineColorCustom)
|
||||
return 1;
|
||||
// otherwise fall through
|
||||
case uiAttributeColor:
|
||||
case uiAttributeBackground:
|
||||
// TODO use a closest match?
|
||||
|
|
126
darwin/attrstr.m
126
darwin/attrstr.m
|
@ -1,6 +1,59 @@
|
|||
// 12 february 2017
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
// this is what AppKit does internally
|
||||
// WebKit does this too; see https://github.com/adobe/webkit/blob/master/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm
|
||||
static NSColor *spellingColor = nil;
|
||||
static NSColor *grammarColor = nil;
|
||||
static NSColor *auxiliaryColor = nil;
|
||||
|
||||
static NSColor *tryColorNamed(NSString *name)
|
||||
{
|
||||
NSImage *img;
|
||||
|
||||
img = [NSImage imageNamed:name];
|
||||
if (img == nil)
|
||||
return nil;
|
||||
return [NSColor colorWithPatternImage:img];
|
||||
}
|
||||
|
||||
void initUnderlineColors(void)
|
||||
{
|
||||
spellingColor = tryColorNamed(@"NSSpellingDot");
|
||||
if (spellingColor == nil) {
|
||||
// WebKit says this is needed for "older systems"; not sure how old, but 10.11 AppKit doesn't look for this
|
||||
spellingColor = tryColorNamed(@"SpellingDot");
|
||||
if (spellingColor == nil)
|
||||
spellingColor = [NSColor redColor];
|
||||
}
|
||||
[spellingColor retain]; // override autoreleasing
|
||||
|
||||
grammarColor = tryColorNamed(@"NSGrammarDot");
|
||||
if (grammarColor == nil) {
|
||||
// WebKit says this is needed for "older systems"; not sure how old, but 10.11 AppKit doesn't look for this
|
||||
grammarColor = tryColorNamed(@"GrammarDot");
|
||||
if (grammarColor == nil)
|
||||
grammarColor = [NSColor greenColor];
|
||||
}
|
||||
[grammarColor retain]; // override autoreleasing
|
||||
|
||||
auxiliaryColor = tryColorNamed(@"NSCorrectionDot");
|
||||
if (auxiliaryColor == nil) {
|
||||
// WebKit says this is needed for "older systems"; not sure how old, but 10.11 AppKit doesn't look for this
|
||||
auxiliaryColor = tryColorNamed(@"CorrectionDot");
|
||||
if (auxiliaryColor == nil)
|
||||
auxiliaryColor = [NSColor blueColor];
|
||||
}
|
||||
[auxiliaryColor retain]; // override autoreleasing
|
||||
}
|
||||
|
||||
void uninitUnderlineColors(void)
|
||||
{
|
||||
[auxiliaryColor release];
|
||||
[grammarColor release];
|
||||
[spellingColor release];
|
||||
}
|
||||
|
||||
// unlike the other systems, Core Text rolls family, size, weight, italic, width, AND opentype features into the "font" attribute
|
||||
// TODO opentype features and AAT fvar table info is lost, so a handful of fonts in the font panel ("Titling" variants of some fonts and Skia and possibly others but those are the examples I know about) cannot be represented by uiDrawFontDescriptor; what *can* we do about this since this info is NOT part of the font on other platforms?
|
||||
// TODO see if we could use NSAttributedString?
|
||||
|
@ -64,15 +117,34 @@ static backgroundBlock mkBackgroundBlock(size_t start, size_t end, double r, dou
|
|||
});
|
||||
}
|
||||
|
||||
static CGColorRef mkcolor(uiAttributeSpec *spec)
|
||||
{
|
||||
CGColorSpaceRef colorspace;
|
||||
CGColorRef color;
|
||||
CGFloat components[4];
|
||||
|
||||
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);
|
||||
return color;
|
||||
}
|
||||
|
||||
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];
|
||||
size_t ostart, oend;
|
||||
backgroundBlock block;
|
||||
int32_t us;
|
||||
CFNumberRef num;
|
||||
|
||||
ostart = start;
|
||||
oend = end;
|
||||
|
@ -112,16 +184,7 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
});
|
||||
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);
|
||||
color = mkcolor(spec);
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTForegroundColorAttributeName, color);
|
||||
CFRelease(color);
|
||||
break;
|
||||
|
@ -137,6 +200,45 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
else
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTVerticalFormsAttributeName, kCFBooleanFalse);
|
||||
break;
|
||||
case uiAttributeUnderline:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineStyleNone:
|
||||
us = kCTUnderlineStyleNone;
|
||||
break;
|
||||
case uiDrawUnderlineStyleSingle:
|
||||
us = kCTUnderlineStyleSingle;
|
||||
break;
|
||||
case uiDrawUnderlineStyleDouble:
|
||||
us = kCTUnderlineStyleDouble;
|
||||
break;
|
||||
case uiDrawUnderlineStyleSuggestion:
|
||||
// TODO incorrect if a solid color
|
||||
us = kCTUnderlineStyleThick;
|
||||
break;
|
||||
}
|
||||
num = CFNumberCreate(NULL, kCFNumberSInt32Type, &us);
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTUnderlineStyleAttributeName, num);
|
||||
CFRelease(num);
|
||||
break;
|
||||
case uiAttributeUnderlineColor:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineColorCustom:
|
||||
color = mkcolor(spec);
|
||||
break;
|
||||
case uiDrawUnderlineColorSpelling:
|
||||
color = [spellingColor CGColor];
|
||||
break;
|
||||
case uiDrawUnderlineColorGrammar:
|
||||
color = [grammarColor CGColor];
|
||||
break;
|
||||
case uiDrawUnderlineColorAuxiliary:
|
||||
color = [auxiliaryColor CGColor];
|
||||
break;
|
||||
}
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTUnderlineColorAttributeName, color);
|
||||
if (spec->Value == uiDrawUnderlineColorCustom)
|
||||
CFRelease(color);
|
||||
break;
|
||||
// TODO
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -125,6 +125,8 @@ const char *uiInit(uiInitOptions *o)
|
|||
[realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]];
|
||||
|
||||
setupFontPanel();
|
||||
|
||||
initUnderlineColors();
|
||||
}
|
||||
|
||||
globalPool = [[NSAutoreleasePool alloc] init];
|
||||
|
@ -140,6 +142,7 @@ void uiUninit(void)
|
|||
[globalPool release];
|
||||
|
||||
@autoreleasepool {
|
||||
uninitUnderlineColors();
|
||||
[delegate release];
|
||||
[realNSApp() setDelegate:nil];
|
||||
[app release];
|
||||
|
|
|
@ -145,5 +145,7 @@ extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
|
|||
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
|
||||
|
||||
// attrstr.m
|
||||
extern void initUnderlineColors(void);
|
||||
extern void uninitUnderlineColors(void);
|
||||
typedef void (^backgroundBlock)(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y);
|
||||
extern CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks);
|
||||
|
|
|
@ -98,8 +98,45 @@ static void setupAttributedString(void)
|
|||
spec.Type = uiAttributeVerticalForms;
|
||||
spec.Value = 1;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
|
||||
uiAttributedStringAppendUnattributed(attrstr, " (which you can draw rotated for proper vertical text)");
|
||||
|
||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
||||
|
||||
next = "multiple";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeUnderline;
|
||||
spec.Value = uiDrawUnderlineStyleSingle;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, " ");
|
||||
next = "underlines";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeUnderline;
|
||||
spec.Value = uiDrawUnderlineStyleDouble;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
spec.Type = uiAttributeUnderlineColor;
|
||||
spec.Value = uiDrawUnderlineColorCustom;
|
||||
spec.R = 0.5;
|
||||
spec.G = 0.0;
|
||||
spec.B = 1.0;
|
||||
spec.A = 1.0;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, " (");
|
||||
next = "including underlines for spelling correction and the like";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeUnderline;
|
||||
spec.Value = uiDrawUnderlineStyleSuggestion;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
spec.Type = uiAttributeUnderlineColor;
|
||||
spec.Value = uiDrawUnderlineColorSpelling;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, ")");
|
||||
|
||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
||||
|
||||
next = "multiple TODO";
|
||||
|
|
|
@ -29,6 +29,7 @@ _UI_ENUM(uiAttribute) {
|
|||
// TODO kCTStrokeWidthAttributeName/kCTStrokeColorAttributeName? doesn't seem to be present anywhere else?
|
||||
|
||||
uiAttributeUnderline, // enum uiDrawUnderlineStyle
|
||||
// TODO what is the color in the case we don't specify it, black or the text color?
|
||||
uiAttributeUnderlineColor, // enum uiDrawUnderlineColor
|
||||
|
||||
// TODO kCTSuperscriptAttributeName vs below
|
||||
|
|
Loading…
Reference in New Issue