summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2020-04-22 19:54:20 -0700
committerMinh Nguyễn <mxn@1ec5.org>2020-04-24 13:46:40 -0700
commitbcfdbd187d22c8c46451ad70a481b1859e5c7f1e (patch)
tree783533f06688630c13af6a825675018c3b838a6d
parentc4c35449cbd0ef8b41ce334a53325101b8f1164e (diff)
downloadqtlocation-mapboxgl-bcfdbd187d22c8c46451ad70a481b1859e5c7f1e.tar.gz
[ios, macos] Avoid redundant fallback in font cascade list
A font descriptor should not be a fallback for itself.
-rw-r--r--platform/darwin/src/local_glyph_rasterizer.mm53
1 files changed, 38 insertions, 15 deletions
diff --git a/platform/darwin/src/local_glyph_rasterizer.mm b/platform/darwin/src/local_glyph_rasterizer.mm
index a6a9d9cca8..d34dbc1167 100644
--- a/platform/darwin/src/local_glyph_rasterizer.mm
+++ b/platform/darwin/src/local_glyph_rasterizer.mm
@@ -62,47 +62,70 @@ public:
}
}
- ~Impl() {
- }
-
+ /**
+ Returns whether local glyph rasterization is enabled globally.
+
+ The developer can disable local glyph rasterization by specifying no
+ fallback font names.
+ */
bool isEnabled() { return fallbackFontNames; }
CTFontDescriptorRef createFontDescriptor(const FontStack& fontStack) {
NSMutableArray *fontNames = [NSMutableArray arrayWithCapacity:fontStack.size() + fallbackFontNames.count];
for (auto& fontName : fontStack) {
+ // Per the Mapbox Style Specification, the text-font property comes
+ // with these last resort fonts by default, but they shouldn’t take
+ // precedence over any application or system fallback font that may
+ // be more appropriate to the current device.
if (fontName != util::LAST_RESORT_ALPHABETIC_FONT && fontName != util::LAST_RESORT_PAN_UNICODE_FONT) {
[fontNames addObject:@(fontName.c_str())];
}
}
[fontNames addObjectsFromArray:fallbackFontNames];
- CFMutableArrayRefHandle fontDescriptors(CFArrayCreateMutable(kCFAllocatorDefault, fontNames.count, &kCFTypeArrayCallBacks));
- for (NSString *name in fontNames) {
+ if (!fontNames.count) {
+ NSDictionary *fontAttributes = @{
+ (NSString *)kCTFontSizeAttribute: @(util::ONE_EM),
+ };
+ return CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes);
+ }
+
+ // Apply the first font name to the returned font descriptor; apply the
+ // rest of the font names to the cascade list.
+ CFStringRef mainFontName = (__bridge CFStringRef)fontNames.firstObject;
+ CFMutableArrayRefHandle fallbackDescriptors(CFArrayCreateMutable(kCFAllocatorDefault, fontNames.count, &kCFTypeArrayCallBacks));
+ for (NSString *name in [fontNames subarrayWithRange:NSMakeRange(1, fontNames.count - 1)]) {
NSDictionary *fontAttributes = @{
(NSString *)kCTFontSizeAttribute: @(util::ONE_EM),
+ // The name could be any of these three attributes of the font.
+ // It’s OK if it doesn’t match all three; Core Text will pick
+ // the font that matches the most attributes.
(NSString *)kCTFontNameAttribute: name,
(NSString *)kCTFontDisplayNameAttribute: name,
(NSString *)kCTFontFamilyNameAttribute: name,
};
CTFontDescriptorRefHandle descriptor(CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes));
- CFArrayAppendValue(*fontDescriptors, *descriptor);
+ CFArrayAppendValue(*fallbackDescriptors, *descriptor);
}
-
- CFStringRef keys[] = { kCTFontSizeAttribute, kCTFontCascadeListAttribute };
- CFTypeRef values[] = { (__bridge CFNumberRef)@(util::ONE_EM), *fontDescriptors };
+
+ CFStringRef keys[] = {
+ kCTFontSizeAttribute,
+ kCTFontNameAttribute, kCTFontDisplayNameAttribute, kCTFontFamilyNameAttribute,
+ kCTFontCascadeListAttribute,
+ };
+ CFTypeRef values[] = {
+ (__bridge CFNumberRef)@(util::ONE_EM),
+ mainFontName, mainFontName, mainFontName,
+ *fallbackDescriptors,
+ };
CFDictionaryRefHandle attributes(
CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys,
(const void**)&values, sizeof(keys) / sizeof(keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
- if (CFArrayGetCount(*fontDescriptors)) {
- CTFontDescriptorRef firstDescriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(*fontDescriptors, 0);
- return CTFontDescriptorCreateCopyWithAttributes(firstDescriptor, *attributes);
- } else {
- return CTFontDescriptorCreateWithAttributes(*attributes);
- }
+ return CTFontDescriptorCreateWithAttributes(*attributes);
}
CTFontRef createFont(const FontStack& fontStack) {