summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--platform/darwin/src/local_glyph_rasterizer.mm98
2 files changed, 52 insertions, 48 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36c8126851..8c54342ce7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,7 +28,7 @@
- [ios, macos] Allow specifying multiple fonts or font families for local font rendering ([#16253](https://github.com/mapbox/mapbox-gl-native/pull/16253))
- The `localFontFamily` parameter of `mbgl::Renderer::Renderer()` and `mbgl::MapSnapshotter::MapSnapshotter()` can now contain a list of font family names, font display names, and font PostScript names, each name separated by a newline.
+ By default, CJK characters are now set in the font specified by the `text-font` layout property. If the named font is not installed on the device or bundled with the application, the characters are set in one of the fallback fonts passed into the `localFontFamily` parameter of `mbgl::Renderer::Renderer()` and `mbgl::MapSnapshotter::MapSnapshotter()`. This parameter can now contain a list of font family names, font display names, and font PostScript names, each name separated by a newline.
### 🐞 Bug fixes
diff --git a/platform/darwin/src/local_glyph_rasterizer.mm b/platform/darwin/src/local_glyph_rasterizer.mm
index bbbb482969..a6a9d9cca8 100644
--- a/platform/darwin/src/local_glyph_rasterizer.mm
+++ b/platform/darwin/src/local_glyph_rasterizer.mm
@@ -1,6 +1,7 @@
#include <mbgl/text/local_glyph_rasterizer.hpp>
#include <mbgl/util/i18n.hpp>
#include <mbgl/util/platform.hpp>
+#include <mbgl/util/constants.hpp>
#include <unordered_map>
@@ -54,60 +55,63 @@ using CTLineRefHandle = CFHandle<CTLineRef, CFTypeRef, CFRelease>;
class LocalGlyphRasterizer::Impl {
public:
Impl(const optional<std::string> fontFamily_)
- : fontFamily(fontFamily_)
- , fontHandle(NULL)
- {}
+ {
+ fallbackFontNames = [[NSUserDefaults standardUserDefaults] stringArrayForKey:@"MGLIdeographicFontFamilyName"];
+ if (fontFamily_) {
+ fallbackFontNames = [fallbackFontNames ?: @[] arrayByAddingObjectsFromArray:[@(fontFamily_->c_str()) componentsSeparatedByString:@"\n"]];
+ }
+ }
~Impl() {
- if (fontHandle) {
- CFRelease(fontHandle);
- }
}
-
- CTFontRef getFont() {
- if (!fontHandle) {
- NSArray<NSString *> *fontFamilyNames = [[NSUserDefaults standardUserDefaults] stringArrayForKey:@"MGLIdeographicFontFamilyName"] ?: @[];
- if (fontFamily) {
- fontFamilyNames = [fontFamilyNames arrayByAddingObjectsFromArray:[@(fontFamily->c_str()) componentsSeparatedByString:@"\n"]];
- }
- if (!fontFamilyNames.count) {
- return NULL;
+
+ bool isEnabled() { return fallbackFontNames; }
+
+ CTFontDescriptorRef createFontDescriptor(const FontStack& fontStack) {
+ NSMutableArray *fontNames = [NSMutableArray arrayWithCapacity:fontStack.size() + fallbackFontNames.count];
+ for (auto& fontName : fontStack) {
+ 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) {
+ NSDictionary *fontAttributes = @{
+ (NSString *)kCTFontSizeAttribute: @(util::ONE_EM),
+ (NSString *)kCTFontNameAttribute: name,
+ (NSString *)kCTFontDisplayNameAttribute: name,
+ (NSString *)kCTFontFamilyNameAttribute: name,
+ };
- CFMutableArrayRefHandle fontDescriptors(CFArrayCreateMutable(kCFAllocatorDefault, fontFamilyNames.count, &kCFTypeArrayCallBacks));
- for (NSString *name in fontFamilyNames) {
- NSDictionary *fontAttributes = @{
- (NSString *)kCTFontSizeAttribute: @(24.0),
- (NSString *)kCTFontNameAttribute: name,
- (NSString *)kCTFontDisplayNameAttribute: name,
- (NSString *)kCTFontFamilyNameAttribute: name,
- };
-
- CTFontDescriptorRefHandle descriptor(CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes));
- CFArrayAppendValue(*fontDescriptors, *descriptor);
- }
-
- CFStringRef keys[] = { kCTFontSizeAttribute, kCTFontCascadeListAttribute };
- CFTypeRef values[] = { (__bridge CFNumberRef)@(24.0), *fontDescriptors };
+ CTFontDescriptorRefHandle descriptor(CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes));
+ CFArrayAppendValue(*fontDescriptors, *descriptor);
+ }
- CFDictionaryRefHandle attributes(
- CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys,
- (const void**)&values, sizeof(keys) / sizeof(keys[0]),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
-
- CTFontDescriptorRefHandle descriptor(CTFontDescriptorCreateWithAttributes(*attributes));
- fontHandle = CTFontCreateWithFontDescriptor(*descriptor, 0.0, NULL);
- if (!fontHandle) {
- throw std::runtime_error("CTFontCreateWithFontDescriptor failed");
- }
+ CFStringRef keys[] = { kCTFontSizeAttribute, kCTFontCascadeListAttribute };
+ CFTypeRef values[] = { (__bridge CFNumberRef)@(util::ONE_EM), *fontDescriptors };
+
+ 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 fontHandle;
+ }
+
+ CTFontRef createFont(const FontStack& fontStack) {
+ CTFontDescriptorRefHandle descriptor(createFontDescriptor(fontStack));
+ return CTFontCreateWithFontDescriptor(*descriptor, 0.0, NULL);
}
private:
- optional<std::string> fontFamily;
- CTFontRef fontHandle;
+ NSArray<NSString *> *fallbackFontNames;
};
LocalGlyphRasterizer::LocalGlyphRasterizer(const optional<std::string>& fontFamily)
@@ -118,7 +122,7 @@ LocalGlyphRasterizer::~LocalGlyphRasterizer()
{}
bool LocalGlyphRasterizer::canRasterizeGlyph(const FontStack&, GlyphID glyphID) {
- return util::i18n::allowsFixedWidthGlyphGeneration(glyphID) && impl->getFont();
+ return util::i18n::allowsFixedWidthGlyphGeneration(glyphID) && impl->isEnabled();
}
PremultipliedImage drawGlyphBitmap(GlyphID glyphID, CTFontRef font, Size size) {
@@ -166,9 +170,9 @@ PremultipliedImage drawGlyphBitmap(GlyphID glyphID, CTFontRef font, Size size) {
return rgbaBitmap;
}
-Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack&, GlyphID glyphID) {
+Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack& fontStack, GlyphID glyphID) {
Glyph fixedMetrics;
- CTFontRef font = impl->getFont();
+ CTFontRef font = impl->createFont(fontStack);
if (!font) {
return fixedMetrics;
}