1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 8d71fe99fe4d54230572223915166bea8efd67d85reed@google.com#include "SkFontConfigInterface.h" 96930b57221ea7010dcab516559fa6bc5a0fb3807djsollen@google.com#include "SkFontConfigTypeface.h" 10d71fe99fe4d54230572223915166bea8efd67d85reed@google.com#include "SkFontDescriptor.h" 11df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org#include "SkFontHost.h" 120da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com#include "SkFontHost_FreeType_common.h" 13822bde74b954df6ed91b01529477e7fd41716fffreed@google.com#include "SkFontStream.h" 14df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org#include "SkStream.h" 1580f5465083bdc5449223f5875b401648616e8e09reed@google.com#include "SkTypeface.h" 16f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com#include "SkTypefaceCache.h" 17b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com 186d2fef9834531ea0e400b6d57a9619f77ca1962bdjsollen@google.com/////////////////////////////////////////////////////////////////////////////// 196d2fef9834531ea0e400b6d57a9619f77ca1962bdjsollen@google.com/////////////////////////////////////////////////////////////////////////////// 206d2fef9834531ea0e400b6d57a9619f77ca1962bdjsollen@google.com 21d71fe99fe4d54230572223915166bea8efd67d85reed@google.comSK_DECLARE_STATIC_MUTEX(gFontConfigInterfaceMutex); 22d71fe99fe4d54230572223915166bea8efd67d85reed@google.comstatic SkFontConfigInterface* gFontConfigInterface; 23df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 24d71fe99fe4d54230572223915166bea8efd67d85reed@google.comSkFontConfigInterface* SkFontConfigInterface::RefGlobal() { 25d71fe99fe4d54230572223915166bea8efd67d85reed@google.com SkAutoMutexAcquire ac(gFontConfigInterfaceMutex); 265ca3bd0cbb34cb4e61c0ea3591a4967ee1d6140askia.committer@gmail.com 27d71fe99fe4d54230572223915166bea8efd67d85reed@google.com return SkSafeRef(gFontConfigInterface); 28d71fe99fe4d54230572223915166bea8efd67d85reed@google.com} 29b13d63c4c0878a3de7230f79a7044830c93d3849bungeman@google.com 30d71fe99fe4d54230572223915166bea8efd67d85reed@google.comSkFontConfigInterface* SkFontConfigInterface::SetGlobal(SkFontConfigInterface* fc) { 31d71fe99fe4d54230572223915166bea8efd67d85reed@google.com SkAutoMutexAcquire ac(gFontConfigInterfaceMutex); 32df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 33d71fe99fe4d54230572223915166bea8efd67d85reed@google.com SkRefCnt_SafeAssign(gFontConfigInterface, fc); 34d71fe99fe4d54230572223915166bea8efd67d85reed@google.com return fc; 35d71fe99fe4d54230572223915166bea8efd67d85reed@google.com} 36d71fe99fe4d54230572223915166bea8efd67d85reed@google.com 37d71fe99fe4d54230572223915166bea8efd67d85reed@google.com/////////////////////////////////////////////////////////////////////////////// 38f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com/////////////////////////////////////////////////////////////////////////////// 39f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com 40f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com// convenience function to create the direct interface if none is installed. 41f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.comextern SkFontConfigInterface* SkCreateDirectFontConfigInterface(); 42d71fe99fe4d54230572223915166bea8efd67d85reed@google.com 4380f5465083bdc5449223f5875b401648616e8e09reed@google.comstatic SkFontConfigInterface* RefFCI() { 44b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com for (;;) { 45b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com SkFontConfigInterface* fci = SkFontConfigInterface::RefGlobal(); 46b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com if (fci) { 47b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com return fci; 48b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com } 49e438ddbc7451ec80f953266409fea4695e78c8c2tomhudson fci = SkFontConfigInterface::GetSingletonDirectInterface(&gFontConfigInterfaceMutex); 50750a24bb3d39e59d32db3f166ad3f39c7560c0a9reed@google.com SkFontConfigInterface::SetGlobal(fci); 51b1c65b62bf276872ab4f9da7569ea7f0899a3569reed@google.com } 5280f5465083bdc5449223f5875b401648616e8e09reed@google.com} 5380f5465083bdc5449223f5875b401648616e8e09reed@google.com 54381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com// export this to SkFontMgr_fontconfig.cpp until this file just goes away. 55381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.comSkFontConfigInterface* SkFontHost_fontconfig_ref_global(); 56381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.comSkFontConfigInterface* SkFontHost_fontconfig_ref_global() { 57381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com return RefFCI(); 58381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com} 59381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com 60381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com/////////////////////////////////////////////////////////////////////////////// 61381bb43efb1697a67b1c02d1d9774fef9c643c4breed@google.com 62f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.comstruct FindRec { 63f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com FindRec(const char* name, SkTypeface::Style style) 64f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com : fFamilyName(name) // don't need to make a deep copy 65f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com , fStyle(style) {} 66d71fe99fe4d54230572223915166bea8efd67d85reed@google.com 67f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com const char* fFamilyName; 68f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkTypeface::Style fStyle; 69f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com}; 70df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 71f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.comstatic bool find_proc(SkTypeface* face, SkTypeface::Style style, void* ctx) { 72f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com FontConfigTypeface* fci = (FontConfigTypeface*)face; 73f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com const FindRec* rec = (const FindRec*)ctx; 74df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 75f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com return rec->fStyle == style && fci->isFamilyName(rec->fFamilyName); 76f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com} 77df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 78e027a6ed9b9e2a96be846ddefb2b06e350858eedreed@google.comSkTypeface* FontConfigTypeface::LegacyCreateTypeface( 79e027a6ed9b9e2a96be846ddefb2b06e350858eedreed@google.com const SkTypeface* familyFace, 80e027a6ed9b9e2a96be846ddefb2b06e350858eedreed@google.com const char familyName[], 81e027a6ed9b9e2a96be846ddefb2b06e350858eedreed@google.com SkTypeface::Style style) { 8280f5465083bdc5449223f5875b401648616e8e09reed@google.com SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); 8380f5465083bdc5449223f5875b401648616e8e09reed@google.com if (NULL == fci.get()) { 8480f5465083bdc5449223f5875b401648616e8e09reed@google.com return NULL; 8580f5465083bdc5449223f5875b401648616e8e09reed@google.com } 8680f5465083bdc5449223f5875b401648616e8e09reed@google.com 87df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org if (familyFace) { 88f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com FontConfigTypeface* fct = (FontConfigTypeface*)familyFace; 89f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com familyName = fct->getFamilyName(); 90b13d63c4c0878a3de7230f79a7044830c93d3849bungeman@google.com } 91b13d63c4c0878a3de7230f79a7044830c93d3849bungeman@google.com 92f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com FindRec rec(familyName, style); 93f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec); 94f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com if (face) { 950b8a2fe2cde14d15dec1b8252d0f328312f9e59creed@google.com// SkDebugf("found cached face <%s> <%s> %p [%d]\n", familyName, ((FontConfigTypeface*)face)->getFamilyName(), face, face->getRefCnt()); 96f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com return face; 97f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com } 98f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com 99f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkFontConfigInterface::FontIdentity indentity; 100f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkString outFamilyName; 101f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkTypeface::Style outStyle; 102f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com 103f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com if (!fci->matchFamilyName(familyName, style, 104f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com &indentity, &outFamilyName, &outStyle)) { 105d71fe99fe4d54230572223915166bea8efd67d85reed@google.com return NULL; 106df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org } 10780f5465083bdc5449223f5875b401648616e8e09reed@google.com 108d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com // check if we, in fact, already have this. perhaps fontconfig aliased the 109d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com // requested name to some other name we actually have... 110d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com rec.fFamilyName = outFamilyName.c_str(); 111d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com rec.fStyle = outStyle; 112d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec); 113d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com if (face) { 114d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com return face; 115d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com } 116d44d988127841cf9180bb7ba91b6eba8127af467reed@google.com 117c4df655b37aea7097d3007b299de582ba517ef16commit-bot@chromium.org face = FontConfigTypeface::Create(outStyle, indentity, outFamilyName); 118f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkTypefaceCache::Add(face, style); 1190b8a2fe2cde14d15dec1b8252d0f328312f9e59creed@google.com// SkDebugf("add face <%s> <%s> %p [%d]\n", familyName, outFamilyName.c_str(), face, face->getRefCnt()); 120f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com return face; 121d71fe99fe4d54230572223915166bea8efd67d85reed@google.com} 122df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 123822bde74b954df6ed91b01529477e7fd41716fffreed@google.com/////////////////////////////////////////////////////////////////////////////// 124822bde74b954df6ed91b01529477e7fd41716fffreed@google.com 1252cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.comSkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { 1262cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com SkStream* stream = this->getLocalStream(); 127f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com if (stream) { 1285bfc8396228b7a9e5be679aeb10f30860adf938freed@google.com // should have been provided by CreateFromStream() 1295bfc8396228b7a9e5be679aeb10f30860adf938freed@google.com *ttcIndex = 0; 1306cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com 1316cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com SkAutoTUnref<SkStream> dupStream(stream->duplicate()); 1326cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com if (dupStream) { 1336cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com return dupStream.detach(); 1346cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com } 1356cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com 1366cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com // TODO: update interface use, remove the following code in this block. 1376cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com size_t length = stream->getLength(); 1386cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com 1396cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com const void* memory = stream->getMemoryBase(); 14049f085dddff10473b6ebf832a974288300224e60bsalomon if (memory) { 1416cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com return new SkMemoryStream(memory, length, true); 1426cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com } 1436cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com 1446cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com SkAutoTMalloc<uint8_t> allocMemory(length); 1456cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com stream->rewind(); 1466cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com if (length == stream->read(allocMemory.get(), length)) { 14788605bb51d9f90e03c9cc448ed2ebcba2854ed14bungeman@google.com SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream()); 14888605bb51d9f90e03c9cc448ed2ebcba2854ed14bungeman@google.com copyStream->setMemoryOwned(allocMemory.detach(), length); 14988605bb51d9f90e03c9cc448ed2ebcba2854ed14bungeman@google.com return copyStream.detach(); 1506cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com } 1516cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com 1526cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com stream->rewind(); 1536cab1a4b6a68aa81237731308ff37a646d48f51cbungeman@google.com stream->ref(); 154f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com } else { 155f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); 156f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com if (NULL == fci.get()) { 157f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com return NULL; 158f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com } 1592cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com stream = fci->openStream(this->getIdentity()); 1602cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com *ttcIndex = this->getIdentity().fTTCIndex; 161f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com } 162f71a2335f9b64442c65b45d1f703cd4ffb84129dreed@google.com return stream; 163df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org} 164df8ecfbcffb297c361cb3e30ab4d7469a6b2e966agl@chromium.org 165b374d6a62c0259387d90cad74753d8bad9ee1beabungemanvoid FontConfigTypeface::onGetFamilyName(SkString* familyName) const { 166b374d6a62c0259387d90cad74753d8bad9ee1beabungeman *familyName = this->getFamilyName(); 167b374d6a62c0259387d90cad74753d8bad9ee1beabungeman} 168b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 1695526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.comvoid FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 1705526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com bool* isLocalStream) const { 171822bde74b954df6ed91b01529477e7fd41716fffreed@google.com desc->setFamilyName(this->getFamilyName()); 172d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman desc->setFontIndex(this->getIdentity().fTTCIndex); 1735526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com *isLocalStream = SkToBool(this->getLocalStream()); 174822bde74b954df6ed91b01529477e7fd41716fffreed@google.com} 175