Also removed uiAttributeLangauge for compatibility reasons too. Let's settle all the TODOs now.
This commit is contained in:
parent
074350bf99
commit
0df8346bff
|
@ -0,0 +1 @@
|
||||||
|
Removed because proper support on OS X doesn't come until 10.9 unless we use a font with an ltag table; none of the fonts I have come with ltag tables (none of the fonts on OS X do, or at least don't come with a sr entry in their ltag table, and OpenType has replaced ltag with what appears to be custom sub-tables of the GPOS and GSUB tables.)
|
|
@ -0,0 +1,19 @@
|
||||||
|
struct fontParams {
|
||||||
|
uiDrawFontDescriptor desc;
|
||||||
|
uint16_t featureTypes[maxFeatures];
|
||||||
|
uint16_t featureSelectors[maxFeatures];
|
||||||
|
size_t nFeatures;
|
||||||
|
const char *language;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// locale identifiers are specified as BCP 47: https://developer.apple.com/reference/corefoundation/cflocale?language=objc
|
||||||
|
case uiAttributeLanguage:
|
||||||
|
// LONGTERM FUTURE when we move to 10.9, switch to using kCTLanguageAttributeName
|
||||||
|
ensureFontInRange(p, start, end);
|
||||||
|
adjustFontInRange(p, start, end, ^(struct fontParams *fp) {
|
||||||
|
fp->language = (const char *) (spec->Value);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
desc = fontdescAppendFeatures(desc, fp->featureTypes, fp->featureSelectors, fp->nFeatures, fp->language);
|
|
@ -0,0 +1,9 @@
|
||||||
|
PangoLanguage *lang;
|
||||||
|
|
||||||
|
// language strings are specified as BCP 47: https://developer.gnome.org/pango/1.30/pango-Scripts-and-Languages.html#pango-language-from-string https://www.ietf.org/rfc/rfc3066.txt
|
||||||
|
case uiAttributeLanguage:
|
||||||
|
lang = pango_language_from_string((const char *) (spec->Value));
|
||||||
|
addattr(p, start, end,
|
||||||
|
pango_attr_language_new(lang));
|
||||||
|
// lang *cannot* be freed
|
||||||
|
break;
|
|
@ -0,0 +1,10 @@
|
||||||
|
WCHAR *localeName;
|
||||||
|
|
||||||
|
// locale names are specified as BCP 47: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx https://www.ietf.org/rfc/rfc4646.txt
|
||||||
|
case uiAttributeLanguage:
|
||||||
|
localeName = toUTF16((char *) (spec->Value));
|
||||||
|
hr = p->layout->SetLocaleName(localeName, range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying locale name attribute", hr);
|
||||||
|
uiFree(localeName);
|
||||||
|
break;
|
|
@ -0,0 +1,2 @@
|
||||||
|
case uiAttributeLanguage:
|
||||||
|
return asciiStringsEqualCaseFold((char *) (attr->spec.Value), (char *) (spec->Value));
|
|
@ -0,0 +1,27 @@
|
||||||
|
before "or any combination of the above"
|
||||||
|
|
||||||
|
// thanks to https://twitter.com/codeman38/status/831924064012886017
|
||||||
|
next = "\xD0\xB1\xD0\xB3\xD0\xB4\xD0\xBF\xD1\x82";
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, "multiple languages (compare ");
|
||||||
|
start = uiAttributedStringLen(attrstr);
|
||||||
|
end = start + strlen(next);
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||||
|
spec.Type = uiAttributeItalic;
|
||||||
|
spec.Value = uiDrawTextItalicItalic;
|
||||||
|
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||||
|
spec.Type = uiAttributeLanguage;
|
||||||
|
spec.Value = (uintptr_t) "ru";
|
||||||
|
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, " to ");
|
||||||
|
start = uiAttributedStringLen(attrstr);
|
||||||
|
end = start + strlen(next);
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||||
|
spec.Type = uiAttributeItalic;
|
||||||
|
spec.Value = uiDrawTextItalicItalic;
|
||||||
|
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||||
|
spec.Type = uiAttributeLanguage;
|
||||||
|
spec.Value = (uintptr_t) "sr";
|
||||||
|
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, " \xE2\x80\x94 may require changing the font)");
|
||||||
|
|
||||||
|
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
|
@ -0,0 +1,112 @@
|
||||||
|
// note: this doesn't work for languages; we have to parse the ltag table
|
||||||
|
|
||||||
|
// fortunately features that aren't supported are simply ignored, so we can copy them all in
|
||||||
|
// LONGTERM FUTURE when we switch to 10.9, the language parameter won't be needed anymore
|
||||||
|
// LONGTERM FUTURE and on 10.10 we can use OpenType tags directly!
|
||||||
|
CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint16_t *types, const uint16_t *selectors, size_t n, const char *language)
|
||||||
|
{
|
||||||
|
CTFontDescriptorRef new;
|
||||||
|
CFMutableArrayRef outerArray;
|
||||||
|
CFDictionaryRef innerDict;
|
||||||
|
CFNumberRef numType, numSelector;
|
||||||
|
const void *keys[2], *values[2];
|
||||||
|
size_t i;
|
||||||
|
CFArrayRef languages;
|
||||||
|
CFIndex il, nl;
|
||||||
|
CFStringRef curlang;
|
||||||
|
char d[2];
|
||||||
|
|
||||||
|
outerArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||||
|
if (outerArray == NULL) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
keys[0] = kCTFontFeatureTypeIdentifierKey;
|
||||||
|
keys[1] = kCTFontFeatureSelectorIdentifierKey;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
numType = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
||||||
|
(const SInt16 *) (types + i));
|
||||||
|
numSelector = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
||||||
|
(const SInt16 *) (selectors + i));
|
||||||
|
values[0] = numType;
|
||||||
|
values[1] = numSelector;
|
||||||
|
innerDict = CFDictionaryCreate(NULL,
|
||||||
|
keys, values, 2,
|
||||||
|
// TODO are these correct?
|
||||||
|
&kCFCopyStringDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
if (innerDict == NULL) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
CFArrayAppendValue(outerArray, innerDict);
|
||||||
|
CFRelease(innerDict);
|
||||||
|
CFRelease(numSelector);
|
||||||
|
CFRelease(numType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we have to take care of the language
|
||||||
|
if (language != NULL) {
|
||||||
|
languages = CTFontDescriptorCopyAttribute(desc, kCTFontLanguagesAttribute);
|
||||||
|
if (languages != NULL) {
|
||||||
|
nl = CFArrayGetCount(languages);
|
||||||
|
d[0] = language[0];
|
||||||
|
if (d[0] >= 'A' && d[0] <= 'Z')
|
||||||
|
d[0] += 'a' - 'A';
|
||||||
|
d[1] = language[1];
|
||||||
|
if (d[1] >= 'A' && d[1] <= 'Z')
|
||||||
|
d[1] += 'a' - 'A';
|
||||||
|
for (il = 0; il < nl; il++) {
|
||||||
|
char c[2];
|
||||||
|
|
||||||
|
curlang = (CFStringRef) CFArrayGetValueAtIndex(languages, il);
|
||||||
|
// TODO check for failure
|
||||||
|
CFStringGetBytes(curlang, CFRangeMake(0, 2),
|
||||||
|
kCFStringEncodingUTF8, 0, false,
|
||||||
|
(UInt8 *) c, 2, NULL);
|
||||||
|
if (c[0] >= 'A' && c[0] <= 'Z')
|
||||||
|
c[0] += 'a' - 'A';
|
||||||
|
if (c[1] >= 'A' && c[1] <= 'Z')
|
||||||
|
c[1] += 'a' - 'A';
|
||||||
|
if (c[0] == d[0] && c[1] == d[1])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (il != nl) {
|
||||||
|
uint16_t typ;
|
||||||
|
|
||||||
|
typ = kLanguageTagType;
|
||||||
|
il++;
|
||||||
|
numType = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
||||||
|
(const SInt16 *) (&typ));
|
||||||
|
numSelector = CFNumberCreate(NULL, kCFNumberCFIndexType,
|
||||||
|
&il);
|
||||||
|
values[0] = numType;
|
||||||
|
values[1] = numSelector;
|
||||||
|
innerDict = CFDictionaryCreate(NULL,
|
||||||
|
keys, values, 2,
|
||||||
|
// TODO are these correct?
|
||||||
|
&kCFCopyStringDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
if (innerDict == NULL) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
CFArrayAppendValue(outerArray, innerDict);
|
||||||
|
CFRelease(innerDict);
|
||||||
|
CFRelease(numSelector);
|
||||||
|
CFRelease(numType);
|
||||||
|
}
|
||||||
|
CFRelease(languages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keys[0] = kCTFontFeatureSettingsAttribute;
|
||||||
|
values[0] = outerArray;
|
||||||
|
innerDict = CFDictionaryCreate(NULL,
|
||||||
|
keys, values, 1,
|
||||||
|
// TODO are these correct?
|
||||||
|
&kCFCopyStringDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
CFRelease(outerArray);
|
||||||
|
new = CTFontDescriptorCreateCopyWithAttributes(desc, innerDict);
|
||||||
|
CFRelease(desc);
|
||||||
|
CFRelease(innerDict);
|
||||||
|
return new;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
after UnderlineColor, before feature tags
|
||||||
|
|
||||||
|
// TODO document that this will also enable language-specific font features (TODO on DirectWrite too?)
|
||||||
|
// TODO document that this should be strict BCP 47 form (A-Z, a-z, 0-9, and -) for maximum compatibility
|
||||||
|
uiAttributeLanguage, // BCP 47 string
|
|
@ -12,3 +12,6 @@ If readded, this will need to be a layout-wide setting, not a per-character sett
|
||||||
More links:
|
More links:
|
||||||
https://www.w3.org/TR/2012/NOTE-jlreq-20120403/#line-composition
|
https://www.w3.org/TR/2012/NOTE-jlreq-20120403/#line-composition
|
||||||
https://www.w3.org/TR/REC-CSS2/notes.html
|
https://www.w3.org/TR/REC-CSS2/notes.html
|
||||||
|
|
||||||
|
TODO indicate where in the attributes.c file that block of code should go (or drop it entirely for the reasons listed above)
|
||||||
|
TODO same for ui.h
|
||||||
|
|
|
@ -342,9 +342,6 @@ static int specsIdentical(struct attr *attr, uiAttributeSpec *spec)
|
||||||
attr->spec.G == spec->G &&
|
attr->spec.G == spec->G &&
|
||||||
attr->spec.B == spec->B &&
|
attr->spec.B == spec->B &&
|
||||||
attr->spec.A == spec->A;
|
attr->spec.A == spec->A;
|
||||||
case uiAttributeLanguage:
|
|
||||||
return asciiStringsEqualCaseFold((char *) (attr->spec.Value), (char *) (spec->Value));
|
|
||||||
// TODO
|
|
||||||
// TODO use boolsEqual() on boolean features
|
// TODO use boolsEqual() on boolean features
|
||||||
}
|
}
|
||||||
// handles the rest
|
// handles the rest
|
||||||
|
|
|
@ -74,7 +74,6 @@ struct fontParams {
|
||||||
uint16_t featureTypes[maxFeatures];
|
uint16_t featureTypes[maxFeatures];
|
||||||
uint16_t featureSelectors[maxFeatures];
|
uint16_t featureSelectors[maxFeatures];
|
||||||
size_t nFeatures;
|
size_t nFeatures;
|
||||||
const char *language;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
|
static void ensureFontInRange(struct foreachParams *p, size_t start, size_t end)
|
||||||
|
@ -258,15 +257,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
if (spec->Value == uiDrawUnderlineColorCustom)
|
if (spec->Value == uiDrawUnderlineColorCustom)
|
||||||
CFRelease(color);
|
CFRelease(color);
|
||||||
break;
|
break;
|
||||||
// locale identifiers are specified as BCP 47: https://developer.apple.com/reference/corefoundation/cflocale?language=objc
|
|
||||||
case uiAttributeLanguage:
|
|
||||||
// LONGTERM FUTURE when we move to 10.9, switch to using kCTLanguageAttributeName
|
|
||||||
ensureFontInRange(p, start, end);
|
|
||||||
adjustFontInRange(p, start, end, ^(struct fontParams *fp) {
|
|
||||||
fp->language = (const char *) (spec->Value);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
// TODO
|
|
||||||
default:
|
default:
|
||||||
// handle typographic features
|
// handle typographic features
|
||||||
ap.p = p;
|
ap.p = p;
|
||||||
|
@ -285,7 +275,7 @@ static CTFontRef fontdescToCTFont(struct fontParams *fp)
|
||||||
CTFontRef font;
|
CTFontRef font;
|
||||||
|
|
||||||
desc = fontdescToCTFontDescriptor(&(fp->desc));
|
desc = fontdescToCTFontDescriptor(&(fp->desc));
|
||||||
desc = fontdescAppendFeatures(desc, fp->featureTypes, fp->featureSelectors, fp->nFeatures, fp->language);
|
desc = fontdescAppendFeatures(desc, fp->featureTypes, fp->featureSelectors, fp->nFeatures);
|
||||||
font = CTFontCreateWithFontDescriptor(desc, fp->desc.Size, NULL);
|
font = CTFontCreateWithFontDescriptor(desc, fp->desc.Size, NULL);
|
||||||
CFRelease(desc); // TODO correct?
|
CFRelease(desc); // TODO correct?
|
||||||
return font;
|
return font;
|
||||||
|
|
|
@ -257,7 +257,7 @@ CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd)
|
||||||
// fortunately features that aren't supported are simply ignored, so we can copy them all in
|
// fortunately features that aren't supported are simply ignored, so we can copy them all in
|
||||||
// LONGTERM FUTURE when we switch to 10.9, the language parameter won't be needed anymore
|
// LONGTERM FUTURE when we switch to 10.9, the language parameter won't be needed anymore
|
||||||
// LONGTERM FUTURE and on 10.10 we can use OpenType tags directly!
|
// LONGTERM FUTURE and on 10.10 we can use OpenType tags directly!
|
||||||
CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint16_t *types, const uint16_t *selectors, size_t n, const char *language)
|
CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint16_t *types, const uint16_t *selectors, size_t n)
|
||||||
{
|
{
|
||||||
CTFontDescriptorRef new;
|
CTFontDescriptorRef new;
|
||||||
CFMutableArrayRef outerArray;
|
CFMutableArrayRef outerArray;
|
||||||
|
@ -265,10 +265,6 @@ CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint1
|
||||||
CFNumberRef numType, numSelector;
|
CFNumberRef numType, numSelector;
|
||||||
const void *keys[2], *values[2];
|
const void *keys[2], *values[2];
|
||||||
size_t i;
|
size_t i;
|
||||||
CFArrayRef languages;
|
|
||||||
CFIndex il, nl;
|
|
||||||
CFStringRef curlang;
|
|
||||||
char d[2];
|
|
||||||
|
|
||||||
outerArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
outerArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||||
if (outerArray == NULL) {
|
if (outerArray == NULL) {
|
||||||
|
@ -297,60 +293,6 @@ CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint1
|
||||||
CFRelease(numType);
|
CFRelease(numType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we have to take care of the language
|
|
||||||
if (language != NULL) {
|
|
||||||
languages = CTFontDescriptorCopyAttribute(desc, kCTFontLanguagesAttribute);
|
|
||||||
if (languages != NULL) {
|
|
||||||
nl = CFArrayGetCount(languages);
|
|
||||||
d[0] = language[0];
|
|
||||||
if (d[0] >= 'A' && d[0] <= 'Z')
|
|
||||||
d[0] += 'a' - 'A';
|
|
||||||
d[1] = language[1];
|
|
||||||
if (d[1] >= 'A' && d[1] <= 'Z')
|
|
||||||
d[1] += 'a' - 'A';
|
|
||||||
for (il = 0; il < nl; il++) {
|
|
||||||
char c[2];
|
|
||||||
|
|
||||||
curlang = (CFStringRef) CFArrayGetValueAtIndex(languages, il);
|
|
||||||
// TODO check for failure
|
|
||||||
CFStringGetBytes(curlang, CFRangeMake(0, 2),
|
|
||||||
kCFStringEncodingUTF8, 0, false,
|
|
||||||
(UInt8 *) c, 2, NULL);
|
|
||||||
if (c[0] >= 'A' && c[0] <= 'Z')
|
|
||||||
c[0] += 'a' - 'A';
|
|
||||||
if (c[1] >= 'A' && c[1] <= 'Z')
|
|
||||||
c[1] += 'a' - 'A';
|
|
||||||
if (c[0] == d[0] && c[1] == d[1])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (il != nl) {
|
|
||||||
uint16_t typ;
|
|
||||||
|
|
||||||
typ = kLanguageTagType;
|
|
||||||
il++;
|
|
||||||
numType = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
|
||||||
(const SInt16 *) (&typ));
|
|
||||||
numSelector = CFNumberCreate(NULL, kCFNumberCFIndexType,
|
|
||||||
&il);
|
|
||||||
values[0] = numType;
|
|
||||||
values[1] = numSelector;
|
|
||||||
innerDict = CFDictionaryCreate(NULL,
|
|
||||||
keys, values, 2,
|
|
||||||
// TODO are these correct?
|
|
||||||
&kCFCopyStringDictionaryKeyCallBacks,
|
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
|
||||||
if (innerDict == NULL) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
CFArrayAppendValue(outerArray, innerDict);
|
|
||||||
CFRelease(innerDict);
|
|
||||||
CFRelease(numSelector);
|
|
||||||
CFRelease(numType);
|
|
||||||
}
|
|
||||||
CFRelease(languages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keys[0] = kCTFontFeatureSettingsAttribute;
|
keys[0] = kCTFontFeatureSettingsAttribute;
|
||||||
values[0] = outerArray;
|
values[0] = outerArray;
|
||||||
innerDict = CFDictionaryCreate(NULL,
|
innerDict = CFDictionaryCreate(NULL,
|
||||||
|
|
|
@ -142,7 +142,7 @@ extern void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdg
|
||||||
|
|
||||||
// fontmatch.m
|
// fontmatch.m
|
||||||
extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
|
extern CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd);
|
||||||
extern CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint16_t *types, const uint16_t *selectors, size_t n, const char *language);
|
extern CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uint16_t *types, const uint16_t *selectors, size_t n);
|
||||||
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
|
extern void fontdescFromCTFontDescriptor(CTFontDescriptorRef ctdesc, uiDrawFontDescriptor *uidesc);
|
||||||
|
|
||||||
// attrstr.m
|
// attrstr.m
|
||||||
|
|
|
@ -130,32 +130,6 @@ static void setupAttributedString(void)
|
||||||
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
||||||
|
|
||||||
// thanks to https://twitter.com/codeman38/status/831924064012886017
|
|
||||||
next = "\xD0\xB1\xD0\xB3\xD0\xB4\xD0\xBF\xD1\x82";
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, "multiple languages (compare ");
|
|
||||||
start = uiAttributedStringLen(attrstr);
|
|
||||||
end = start + strlen(next);
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
|
||||||
spec.Type = uiAttributeItalic;
|
|
||||||
spec.Value = uiDrawTextItalicItalic;
|
|
||||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
|
||||||
spec.Type = uiAttributeLanguage;
|
|
||||||
spec.Value = (uintptr_t) "ru";
|
|
||||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, " to ");
|
|
||||||
start = uiAttributedStringLen(attrstr);
|
|
||||||
end = start + strlen(next);
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
|
||||||
spec.Type = uiAttributeItalic;
|
|
||||||
spec.Value = uiDrawTextItalicItalic;
|
|
||||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
|
||||||
spec.Type = uiAttributeLanguage;
|
|
||||||
spec.Value = (uintptr_t) "sr";
|
|
||||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, " \xE2\x80\x94 may require changing the font)");
|
|
||||||
|
|
||||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
|
||||||
|
|
||||||
// TODO randomize these ranges better
|
// TODO randomize these ranges better
|
||||||
// TODO make some overlap to test that
|
// TODO make some overlap to test that
|
||||||
// TODO also change colors to light foreground dark background
|
// TODO also change colors to light foreground dark background
|
||||||
|
|
|
@ -15,10 +15,6 @@ _UI_ENUM(uiAttribute) {
|
||||||
// TODO ensure the color in the case we don't specify it is the text color?
|
// TODO ensure the color in the case we don't specify it is the text color?
|
||||||
uiAttributeUnderlineColor, // enum uiDrawUnderlineColor
|
uiAttributeUnderlineColor, // enum uiDrawUnderlineColor
|
||||||
|
|
||||||
// TODO document that this will also enable language-specific font features (TODO on DirectWrite too?)
|
|
||||||
// TODO document that this should be strict BCP 47 form (A-Z, a-z, 0-9, and -) for maximum compatibility
|
|
||||||
uiAttributeLanguage, // BCP 47 string
|
|
||||||
|
|
||||||
// These attributes represent typographic features. Each feature
|
// These attributes represent typographic features. Each feature
|
||||||
// is a separate attribute, to make composition easier. The
|
// is a separate attribute, to make composition easier. The
|
||||||
// availability of for each attribute are defined by the font; the
|
// availability of for each attribute are defined by the font; the
|
||||||
|
|
|
@ -142,7 +142,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
struct foreachParams *p = (struct foreachParams *) data;
|
struct foreachParams *p = (struct foreachParams *) data;
|
||||||
GClosure *closure;
|
GClosure *closure;
|
||||||
PangoUnderline underline;
|
PangoUnderline underline;
|
||||||
PangoLanguage *lang;
|
|
||||||
struct otParam op;
|
struct otParam op;
|
||||||
|
|
||||||
switch (spec->Type) {
|
switch (spec->Type) {
|
||||||
|
@ -226,14 +225,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// language strings are specified as BCP 47: https://developer.gnome.org/pango/1.30/pango-Scripts-and-Languages.html#pango-language-from-string https://www.ietf.org/rfc/rfc3066.txt
|
|
||||||
case uiAttributeLanguage:
|
|
||||||
lang = pango_language_from_string((const char *) (spec->Value));
|
|
||||||
addattr(p, start, end,
|
|
||||||
pango_attr_language_new(lang));
|
|
||||||
// lang *cannot* be freed
|
|
||||||
break;
|
|
||||||
// TODO
|
|
||||||
default:
|
default:
|
||||||
// handle typographic features
|
// handle typographic features
|
||||||
op.p = p;
|
op.p = p;
|
||||||
|
|
|
@ -112,7 +112,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
WCHAR *wfamily;
|
WCHAR *wfamily;
|
||||||
size_t ostart, oend;
|
size_t ostart, oend;
|
||||||
BOOL hasUnderline;
|
BOOL hasUnderline;
|
||||||
WCHAR *localeName;
|
|
||||||
struct otParam op;
|
struct otParam op;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -230,15 +229,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// locale names are specified as BCP 47: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx https://www.ietf.org/rfc/rfc4646.txt
|
|
||||||
case uiAttributeLanguage:
|
|
||||||
localeName = toUTF16((char *) (spec->Value));
|
|
||||||
hr = p->layout->SetLocaleName(localeName, range);
|
|
||||||
if (hr != S_OK)
|
|
||||||
logHRESULT(L"error applying locale name attribute", hr);
|
|
||||||
uiFree(localeName);
|
|
||||||
break;
|
|
||||||
// TODO
|
|
||||||
default:
|
default:
|
||||||
// handle typographic features
|
// handle typographic features
|
||||||
op.p = p;
|
op.p = p;
|
||||||
|
|
Loading…
Reference in New Issue