blob: 5c9e89661790be334309527212e2478aef5d92c9 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2008 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
reed@google.comd71fe992013-02-25 20:38:07 +00008#include "SkFontConfigInterface.h"
djsollen@google.com6930b572013-05-15 20:11:20 +00009#include "SkFontConfigTypeface.h"
reed@google.comd71fe992013-02-25 20:38:07 +000010#include "SkFontDescriptor.h"
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +000011#include "SkStream.h"
reed@google.com80f54652013-02-25 22:19:20 +000012#include "SkTypeface.h"
reed@google.comf71a2332013-02-27 19:06:30 +000013#include "SkTypefaceCache.h"
reed@google.comb1c65b62013-02-26 15:50:51 +000014
djsollen@google.com6d2fef92013-09-06 18:00:04 +000015///////////////////////////////////////////////////////////////////////////////
16///////////////////////////////////////////////////////////////////////////////
17
reed@google.comd71fe992013-02-25 20:38:07 +000018SK_DECLARE_STATIC_MUTEX(gFontConfigInterfaceMutex);
19static SkFontConfigInterface* gFontConfigInterface;
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +000020
reed@google.comd71fe992013-02-25 20:38:07 +000021SkFontConfigInterface* SkFontConfigInterface::RefGlobal() {
22 SkAutoMutexAcquire ac(gFontConfigInterfaceMutex);
skia.committer@gmail.com5ca3bd02013-02-26 07:01:22 +000023
reed@google.comd71fe992013-02-25 20:38:07 +000024 return SkSafeRef(gFontConfigInterface);
25}
bungeman@google.comb13d63c2012-11-06 16:55:24 +000026
reed@google.comd71fe992013-02-25 20:38:07 +000027SkFontConfigInterface* SkFontConfigInterface::SetGlobal(SkFontConfigInterface* fc) {
28 SkAutoMutexAcquire ac(gFontConfigInterfaceMutex);
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +000029
reed@google.comd71fe992013-02-25 20:38:07 +000030 SkRefCnt_SafeAssign(gFontConfigInterface, fc);
31 return fc;
32}
bungeman@google.comb13d63c2012-11-06 16:55:24 +000033
reed@google.comd71fe992013-02-25 20:38:07 +000034///////////////////////////////////////////////////////////////////////////////
reed@google.comf71a2332013-02-27 19:06:30 +000035///////////////////////////////////////////////////////////////////////////////
36
37// convenience function to create the direct interface if none is installed.
38extern SkFontConfigInterface* SkCreateDirectFontConfigInterface();
reed@google.comd71fe992013-02-25 20:38:07 +000039
reed@google.com80f54652013-02-25 22:19:20 +000040static SkFontConfigInterface* RefFCI() {
reed@google.comb1c65b62013-02-26 15:50:51 +000041 for (;;) {
42 SkFontConfigInterface* fci = SkFontConfigInterface::RefGlobal();
43 if (fci) {
44 return fci;
45 }
tomhudsone438ddb2014-07-01 18:54:41 -070046 fci = SkFontConfigInterface::GetSingletonDirectInterface(&gFontConfigInterfaceMutex);
reed@google.com750a24b2013-04-22 18:45:12 +000047 SkFontConfigInterface::SetGlobal(fci);
reed@google.comb1c65b62013-02-26 15:50:51 +000048 }
reed@google.com80f54652013-02-25 22:19:20 +000049}
50
reed@google.com381bb432013-05-13 19:43:59 +000051// export this to SkFontMgr_fontconfig.cpp until this file just goes away.
52SkFontConfigInterface* SkFontHost_fontconfig_ref_global();
53SkFontConfigInterface* SkFontHost_fontconfig_ref_global() {
54 return RefFCI();
55}
56
57///////////////////////////////////////////////////////////////////////////////
58
bungemane8926162015-02-19 07:29:28 -080059struct NameStyle {
60 NameStyle(const char* name, const SkFontStyle& style)
reed@google.comf71a2332013-02-27 19:06:30 +000061 : fFamilyName(name) // don't need to make a deep copy
62 , fStyle(style) {}
63
64 const char* fFamilyName;
bungemana4c4a2d2014-10-20 13:33:19 -070065 SkFontStyle fStyle;
reed@google.comf71a2332013-02-27 19:06:30 +000066};
67
bungemane8926162015-02-19 07:29:28 -080068static bool find_by_NameStyle(SkTypeface* cachedTypeface,
69 const SkFontStyle& cachedStyle,
70 void* ctx)
71{
72 FontConfigTypeface* cachedFCTypeface = static_cast<FontConfigTypeface*>(cachedTypeface);
73 const NameStyle* nameStyle = static_cast<const NameStyle*>(ctx);
reed@google.comf71a2332013-02-27 19:06:30 +000074
bungemane8926162015-02-19 07:29:28 -080075 return nameStyle->fStyle == cachedStyle &&
76 cachedFCTypeface->isFamilyName(nameStyle->fFamilyName);
reed@google.comf71a2332013-02-27 19:06:30 +000077}
78
bungemane8926162015-02-19 07:29:28 -080079static bool find_by_FontIdentity(SkTypeface* cachedTypeface, const SkFontStyle&, void* ctx) {
80 typedef SkFontConfigInterface::FontIdentity FontIdentity;
81 FontConfigTypeface* cachedFCTypeface = static_cast<FontConfigTypeface*>(cachedTypeface);
82 FontIdentity* indentity = static_cast<FontIdentity*>(ctx);
83
84 return cachedFCTypeface->getIdentity() == *indentity;
85}
86
87SkTypeface* FontConfigTypeface::LegacyCreateTypeface(const char familyName[],
88 SkTypeface::Style style)
89{
reed@google.com80f54652013-02-25 22:19:20 +000090 SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
halcanary96fcdcc2015-08-27 07:41:13 -070091 if (nullptr == fci.get()) {
92 return nullptr;
reed@google.com80f54652013-02-25 22:19:20 +000093 }
94
bungemane8926162015-02-19 07:29:28 -080095 // Check if requested NameStyle is in the NameStyle cache.
bungemana4c4a2d2014-10-20 13:33:19 -070096 SkFontStyle requestedStyle(style);
bungemane8926162015-02-19 07:29:28 -080097 NameStyle nameStyle(familyName, requestedStyle);
98 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &nameStyle);
reed@google.comf71a2332013-02-27 19:06:30 +000099 if (face) {
bungemana4c4a2d2014-10-20 13:33:19 -0700100 //SkDebugf("found cached face <%s> <%s> %p [%d]\n",
101 // familyName, ((FontConfigTypeface*)face)->getFamilyName(),
102 // face, face->getRefCnt());
reed@google.comf71a2332013-02-27 19:06:30 +0000103 return face;
104 }
105
106 SkFontConfigInterface::FontIdentity indentity;
bungemana4c4a2d2014-10-20 13:33:19 -0700107 SkString outFamilyName;
108 SkTypeface::Style outStyle;
109 if (!fci->matchFamilyName(familyName, style, &indentity, &outFamilyName, &outStyle)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700110 return nullptr;
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +0000111 }
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +0000112
bungemane8926162015-02-19 07:29:28 -0800113 // Check if a typeface with this FontIdentity is already in the FontIdentity cache.
114 face = SkTypefaceCache::FindByProcAndRef(find_by_FontIdentity, &indentity);
115 if (!face) {
116 face = FontConfigTypeface::Create(SkFontStyle(outStyle), indentity, outFamilyName);
117 // Add this FontIdentity to the FontIdentity cache.
118 SkTypefaceCache::Add(face, requestedStyle);
reed@google.comd44d9882013-09-18 20:32:25 +0000119 }
bungemane8926162015-02-19 07:29:28 -0800120 // TODO: Ensure requested NameStyle and resolved NameStyle are both in the NameStyle cache.
reed@google.comd44d9882013-09-18 20:32:25 +0000121
bungemana4c4a2d2014-10-20 13:33:19 -0700122 //SkDebugf("add face <%s> <%s> %p [%d]\n",
123 // familyName, outFamilyName.c_str(),
124 // face, face->getRefCnt());
reed@google.comf71a2332013-02-27 19:06:30 +0000125 return face;
agl@chromium.orgdf8ecfb2009-04-28 17:30:01 +0000126}
127
reed@google.com822bde72013-03-04 16:28:33 +0000128///////////////////////////////////////////////////////////////////////////////
129
bungeman5f213d92015-01-27 05:39:10 -0800130SkStreamAsset* FontConfigTypeface::onOpenStream(int* ttcIndex) const {
131 SkStreamAsset* stream = this->getLocalStream();
reed@google.comf71a2332013-02-27 19:06:30 +0000132 if (stream) {
bungeman5f213d92015-01-27 05:39:10 -0800133 // TODO: should have been provided by CreateFromStream()
reed@google.com5bfc8392013-03-05 22:12:11 +0000134 *ttcIndex = 0;
bungeman5f213d92015-01-27 05:39:10 -0800135 return stream->duplicate();
reed@google.comf71a2332013-02-27 19:06:30 +0000136 }
bungeman5f213d92015-01-27 05:39:10 -0800137
138 SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
halcanary96fcdcc2015-08-27 07:41:13 -0700139 if (nullptr == fci.get()) {
140 return nullptr;
bungeman5f213d92015-01-27 05:39:10 -0800141 }
142
143 *ttcIndex = this->getIdentity().fTTCIndex;
144 return fci->openStream(this->getIdentity());
reed@google.comd71fe992013-02-25 20:38:07 +0000145}
146
bungemanb374d6a2014-09-17 07:48:59 -0700147void FontConfigTypeface::onGetFamilyName(SkString* familyName) const {
bungemancd87c512015-02-18 13:22:26 -0800148 *familyName = fFamilyName;
bungemanb374d6a2014-09-17 07:48:59 -0700149}
150
reed@google.com5526ede2013-03-25 13:03:37 +0000151void FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
152 bool* isLocalStream) const {
bungemancd87c512015-02-18 13:22:26 -0800153 SkString name;
154 this->getFamilyName(&name);
155 desc->setFamilyName(name.c_str());
reed@google.com5526ede2013-03-25 13:03:37 +0000156 *isLocalStream = SkToBool(this->getLocalStream());
reed@google.com822bde72013-03-04 16:28:33 +0000157}