2011-07-28 14:26:00 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2006 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2008-12-17 15:59:43 +00:00
|
|
|
*/
|
|
|
|
|
2017-02-24 16:15:26 +00:00
|
|
|
#include "SkFontArguments.h"
|
2012-05-31 19:55:08 +00:00
|
|
|
#include "SkFontDescriptor.h"
|
2015-07-29 18:49:40 +00:00
|
|
|
#include "SkFontHost_FreeType_common.h"
|
2013-11-11 15:53:29 +00:00
|
|
|
#include "SkFontMgr.h"
|
2015-06-15 22:17:21 +00:00
|
|
|
#include "SkFontMgr_custom.h"
|
2015-07-29 18:49:40 +00:00
|
|
|
#include "SkFontStyle.h"
|
2016-09-16 13:24:20 +00:00
|
|
|
#include "SkMakeUnique.h"
|
2015-07-29 18:49:40 +00:00
|
|
|
#include "SkRefCnt.h"
|
2008-12-17 15:59:43 +00:00
|
|
|
#include "SkStream.h"
|
2015-07-29 18:49:40 +00:00
|
|
|
#include "SkString.h"
|
2013-11-11 15:53:29 +00:00
|
|
|
#include "SkTArray.h"
|
2015-07-29 18:49:40 +00:00
|
|
|
#include "SkTemplates.h"
|
|
|
|
#include "SkTypeface.h"
|
|
|
|
#include "SkTypes.h"
|
2013-11-11 15:53:29 +00:00
|
|
|
|
|
|
|
#include <limits>
|
2016-06-10 11:14:51 +00:00
|
|
|
#include <memory>
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2015-07-29 18:49:40 +00:00
|
|
|
class SkData;
|
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
|
|
|
|
bool sysFont, const SkString familyName, int index)
|
|
|
|
: INHERITED(style, isFixedPitch)
|
|
|
|
, fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
|
|
|
|
{ }
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
|
2013-03-22 17:21:59 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
|
|
|
|
*familyName = fFamilyName;
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
|
|
|
|
desc->setFamilyName(fFamilyName.c_str());
|
|
|
|
desc->setStyle(this->fontStyle());
|
|
|
|
*isLocal = !this->isSysFont();
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
int SkTypeface_Custom::getIndex() const { return fIndex; }
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2010-04-15 14:04:52 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
|
2013-11-11 15:53:29 +00:00
|
|
|
|
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
|
|
|
|
const SkFontStyle& style, bool isFixedPitch, bool sysFont,
|
|
|
|
const SkString familyName)
|
|
|
|
: INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
|
|
|
|
, fData(std::move(fontData))
|
|
|
|
{ }
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
|
|
|
|
*ttcIndex = fData->getIndex();
|
2017-09-16 01:39:47 +00:00
|
|
|
return fData->getStream()->duplicate().release();
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
|
|
|
|
return skstd::make_unique<SkFontData>(*fData);
|
|
|
|
}
|
2012-09-26 19:16:54 +00:00
|
|
|
|
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
|
|
|
|
const SkString familyName, const char path[], int index)
|
|
|
|
: INHERITED(style, isFixedPitch, sysFont, familyName, index)
|
|
|
|
, fPath(path)
|
|
|
|
{ }
|
2012-09-26 19:16:54 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
|
|
|
|
*ttcIndex = this->getIndex();
|
|
|
|
return SkStream::MakeFromFile(fPath.c_str()).release();
|
|
|
|
}
|
2009-09-28 16:12:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2013-11-11 15:53:29 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
|
2013-11-11 15:53:29 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
|
|
|
|
fStyles.emplace_back(std::move(typeface));
|
|
|
|
}
|
2014-11-14 18:52:53 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
int SkFontStyleSet_Custom::count() {
|
|
|
|
return fStyles.count();
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
|
|
|
|
SkASSERT(index < fStyles.count());
|
|
|
|
if (style) {
|
|
|
|
*style = fStyles[index]->fontStyle();
|
2013-11-11 15:53:29 +00:00
|
|
|
}
|
2017-02-08 22:29:33 +00:00
|
|
|
if (name) {
|
|
|
|
name->reset();
|
2016-06-10 11:14:51 +00:00
|
|
|
}
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
|
|
|
|
SkASSERT(index < fStyles.count());
|
|
|
|
return SkRef(fStyles[index].get());
|
|
|
|
}
|
2016-06-10 11:14:51 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
|
|
|
|
return this->matchStyleCSS3(pattern);
|
|
|
|
}
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
|
2016-06-10 19:43:17 +00:00
|
|
|
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
|
|
|
|
loader.loadSystemFonts(fScanner, &fFamilies);
|
2013-11-11 15:53:29 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
// Try to pick a default font.
|
|
|
|
static const char* defaultNames[] = {
|
|
|
|
"Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
|
|
|
|
};
|
|
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
|
|
|
|
sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
|
|
|
|
if (nullptr == set) {
|
|
|
|
continue;
|
2013-11-11 15:53:29 +00:00
|
|
|
}
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
|
|
|
|
SkFontStyle::kNormal_Width,
|
|
|
|
SkFontStyle::kUpright_Slant)));
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == tf) {
|
2017-02-08 22:29:33 +00:00
|
|
|
continue;
|
2013-11-11 15:53:29 +00:00
|
|
|
}
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
fDefaultFamily = set.get();
|
|
|
|
break;
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
2017-02-08 22:29:33 +00:00
|
|
|
if (nullptr == fDefaultFamily) {
|
|
|
|
fDefaultFamily = fFamilies[0].get();
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 12:59:12 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
int SkFontMgr_Custom::onCountFamilies() const {
|
|
|
|
return fFamilies.count();
|
|
|
|
}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
|
|
|
|
SkASSERT(index < fFamilies.count());
|
|
|
|
familyName->set(fFamilies[index]->getFamilyName());
|
|
|
|
}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
|
|
|
|
SkASSERT(index < fFamilies.count());
|
|
|
|
return SkRef(fFamilies[index].get());
|
|
|
|
}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
|
|
|
|
for (int i = 0; i < fFamilies.count(); ++i) {
|
|
|
|
if (fFamilies[i]->getFamilyName().equals(familyName)) {
|
|
|
|
return SkRef(fFamilies[i].get());
|
2015-03-30 19:53:48 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-08 22:29:33 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2013-11-11 15:53:29 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
|
|
|
|
const SkFontStyle& fontStyle) const
|
|
|
|
{
|
|
|
|
sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
|
|
|
|
return sset->matchStyle(fontStyle);
|
|
|
|
}
|
2014-10-28 22:07:23 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
|
|
|
|
const SkFontStyle&,
|
|
|
|
const char* bcp47[], int bcp47Count,
|
|
|
|
SkUnichar character) const
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
2013-08-02 00:20:34 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
|
|
|
|
const SkFontStyle& fontStyle) const
|
|
|
|
{
|
|
|
|
for (int i = 0; i < fFamilies.count(); ++i) {
|
|
|
|
for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
|
|
|
|
if (fFamilies[i]->fStyles[j].get() == familyMember) {
|
|
|
|
return fFamilies[i]->matchStyle(fontStyle);
|
2013-11-11 15:53:29 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
2017-02-08 22:29:33 +00:00
|
|
|
return nullptr;
|
2017-01-03 18:32:36 +00:00
|
|
|
}
|
2015-06-15 22:17:21 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
|
|
|
|
return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
|
|
|
|
int ttcIndex) const {
|
|
|
|
return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2013-03-27 20:01:49 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
|
|
|
|
const SkFontArguments& args) const {
|
2017-02-08 22:29:33 +00:00
|
|
|
using Scanner = SkTypeface_FreeType::Scanner;
|
|
|
|
bool isFixedPitch;
|
|
|
|
SkFontStyle style;
|
|
|
|
SkString name;
|
|
|
|
Scanner::AxisDefinitions axisDefinitions;
|
2017-02-24 16:15:26 +00:00
|
|
|
if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
|
2017-02-08 22:29:33 +00:00
|
|
|
&name, &style, &isFixedPitch, &axisDefinitions))
|
2015-03-30 19:53:48 +00:00
|
|
|
{
|
2015-08-27 14:41:13 +00:00
|
|
|
return nullptr;
|
2015-03-30 19:53:48 +00:00
|
|
|
}
|
2013-08-01 15:53:39 +00:00
|
|
|
|
2017-02-24 16:15:26 +00:00
|
|
|
const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
|
2017-02-08 22:29:33 +00:00
|
|
|
SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
|
2017-02-24 16:15:26 +00:00
|
|
|
Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-02-24 16:15:26 +00:00
|
|
|
auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
|
|
|
|
axisValues.get(), axisDefinitions.count());
|
2017-09-26 13:46:08 +00:00
|
|
|
return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2015-03-30 19:53:48 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const {
|
2017-02-08 22:29:33 +00:00
|
|
|
bool isFixedPitch;
|
|
|
|
SkFontStyle style;
|
|
|
|
SkString name;
|
|
|
|
if (!fScanner.scanFont(data->getStream(), data->getIndex(),
|
2017-09-26 13:46:08 +00:00
|
|
|
&name, &style, &isFixedPitch, nullptr)) {
|
2017-02-08 22:29:33 +00:00
|
|
|
return nullptr;
|
2013-11-11 15:53:29 +00:00
|
|
|
}
|
2017-09-26 13:46:08 +00:00
|
|
|
return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
|
2017-01-03 18:32:36 +00:00
|
|
|
}
|
2016-03-21 13:55:52 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
|
2017-02-08 22:29:33 +00:00
|
|
|
std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
|
2017-09-26 13:46:08 +00:00
|
|
|
return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2016-03-21 13:55:52 +00:00
|
|
|
|
2017-09-26 13:46:08 +00:00
|
|
|
sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
|
|
|
|
SkFontStyle style) const {
|
|
|
|
sk_sp<SkTypeface> tf;
|
2016-03-21 13:55:52 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
if (familyName) {
|
2017-09-26 13:46:08 +00:00
|
|
|
tf.reset(this->onMatchFamilyStyle(familyName, style));
|
2016-03-21 13:55:52 +00:00
|
|
|
}
|
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
if (nullptr == tf) {
|
2017-09-26 13:46:08 +00:00
|
|
|
tf.reset(fDefaultFamily->matchStyle(style));
|
2017-02-08 22:29:33 +00:00
|
|
|
}
|
2016-03-21 13:55:52 +00:00
|
|
|
|
2017-02-08 22:29:33 +00:00
|
|
|
return tf;
|
2017-01-03 18:32:36 +00:00
|
|
|
}
|