Add a basic CoreText-based fonts collector backend
This commit is contained in:
parent
f8c3504898
commit
973f0b09fc
3 changed files with 115 additions and 1 deletions
|
@ -59,7 +59,6 @@ src_OBJ := \
|
|||
$(d)export_framerate.o \
|
||||
$(d)fft.o \
|
||||
$(d)font_file_lister.o \
|
||||
$(d)font_file_lister_fontconfig.o \
|
||||
$(d)frame_main.o \
|
||||
$(d)gl_text.o \
|
||||
$(d)gl_wrap.o \
|
||||
|
@ -119,7 +118,10 @@ src_OBJ := \
|
|||
$(TOP)lib/libuniversalchardet.a \
|
||||
|
||||
ifeq (yes, $(BUILD_DARWIN))
|
||||
src_OBJ += $(d)font_file_lister_coretext.o
|
||||
src_OBJ += $(subst .mm,.o,$(wildcard $(d)osx/*.mm))
|
||||
else
|
||||
src_OBJ += $(d)font_file_lister_fontconfig.o
|
||||
endif
|
||||
|
||||
###############
|
||||
|
|
|
@ -63,7 +63,25 @@ public:
|
|||
};
|
||||
|
||||
using FontFileLister = GdiFontFileLister;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
struct CoreTextFontFileLister {
|
||||
CoreTextFontFileLister(FontCollectorStatusCallback &) {}
|
||||
|
||||
/// @brief Get the path to the font with the given styles
|
||||
/// @param facename Name of font face
|
||||
/// @param bold ASS font weight
|
||||
/// @param italic Italic?
|
||||
/// @param characters Characters in this style
|
||||
/// @return Path to the matching font file(s), or empty if not found
|
||||
CollectionResult GetFontPaths(std::string const& facename, int bold, bool italic, std::vector<int> const& characters);
|
||||
};
|
||||
|
||||
using FontFileLister = CoreTextFontFileLister;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct _FcConfig FcConfig;
|
||||
typedef struct _FcFontSet FcFontSet;
|
||||
|
||||
|
|
94
src/font_file_lister_coretext.mm
Normal file
94
src/font_file_lister_coretext.mm
Normal file
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) 2016, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#include "font_file_lister.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <CoreText/CoreText.h>
|
||||
|
||||
namespace {
|
||||
void process_font(CollectionResult& ret, NSFontDescriptor *font, int bold, bool italic,
|
||||
std::vector<int> const& characters) {
|
||||
// For whatever reason there is no NSFontURLAttribute
|
||||
NSURL *url = [font objectForKey:(__bridge NSString *)kCTFontURLAttribute];
|
||||
if (!url)
|
||||
return;
|
||||
|
||||
NSDictionary *attributes = [font objectForKey:NSFontTraitsAttribute];
|
||||
double weight = [attributes[NSFontWeightTrait] doubleValue];
|
||||
double slant = [attributes[NSFontSlantTrait] doubleValue];
|
||||
|
||||
if (italic != (slant > 0.03))
|
||||
return;
|
||||
if (bold == 0 && weight > 0)
|
||||
return;
|
||||
if (bold == 1 && weight < 0.4)
|
||||
return;
|
||||
|
||||
NSCharacterSet *codepoints = [font objectForKey:NSFontCharacterSetAttribute];
|
||||
for (int chr : characters) {
|
||||
if (![codepoints longCharacterIsMember:chr]) {
|
||||
ret.missing += chr;
|
||||
}
|
||||
}
|
||||
|
||||
ret.paths.push_back(url.absoluteString.UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
CollectionResult CoreTextFontFileLister::GetFontPaths(std::string const& facename,
|
||||
int bold, bool italic,
|
||||
std::vector<int> const& characters) {
|
||||
CollectionResult ret;
|
||||
|
||||
@autoreleasepool {
|
||||
NSString *name = @(facename.c_str() + (facename[0] == '@'));
|
||||
NSArray *attrs = @[
|
||||
[NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontFamilyAttribute: name}],
|
||||
[NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontFaceAttribute: name}],
|
||||
[NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontNameAttribute: name}]
|
||||
];
|
||||
|
||||
auto font_collection = [NSFontCollection fontCollectionWithDescriptors:attrs];
|
||||
for (NSFontDescriptor *desc in font_collection.matchingDescriptors) {
|
||||
process_font(ret, desc, bold, italic, characters);
|
||||
|
||||
// If we didn't get any results, check for non-bold/italic variants
|
||||
// and collect them with a warning
|
||||
if (ret.paths.empty() && bold) {
|
||||
process_font(ret, desc, 0, italic, characters);
|
||||
if (!ret.paths.empty())
|
||||
ret.fake_bold = true;
|
||||
}
|
||||
|
||||
if (ret.paths.empty() && italic) {
|
||||
process_font(ret, desc, bold, false, characters);
|
||||
if (!ret.paths.empty())
|
||||
ret.fake_italic = true;
|
||||
}
|
||||
|
||||
if (ret.paths.empty() && bold && italic) {
|
||||
process_font(ret, desc, 0, false, characters);
|
||||
if (!ret.paths.empty()) {
|
||||
ret.fake_bold = true;
|
||||
ret.fake_italic = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue