SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } if (familyFace) { FontConfigTypeface* fct = (FontConfigTypeface*)familyFace; familyName = fct->getFamilyName(); } FindRec rec(familyName, style); SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec); if (face) { // SkDebugf("found cached face <%s> <%s> %p [%d]\n", familyName, ((FontConfigTypeface*)face)->getFamilyName(), face, face->getRefCnt()); return face; } SkFontConfigInterface::FontIdentity indentity; SkString outFamilyName; SkTypeface::Style outStyle; if (!fci->matchFamilyName(familyName, style, &indentity, &outFamilyName, &outStyle)) { return NULL; } face = SkNEW_ARGS(FontConfigTypeface, (outStyle, indentity, outFamilyName)); SkTypefaceCache::Add(face, style); // SkDebugf("add face <%s> <%s> %p [%d]\n", familyName, outFamilyName.c_str(), face, face->getRefCnt()); return face; }
SkStreamAsset* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStreamAsset* stream = this->getLocalStream(); if (stream) { // TODO: should have been provided by CreateFromStream() *ttcIndex = 0; return stream->duplicate(); } SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (nullptr == fci.get()) { return nullptr; } *ttcIndex = this->getIdentity().fTTCIndex; return fci->openStream(this->getIdentity()); }
SkTypeface* FontConfigTypeface::LegacyCreateTypeface( const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } if (familyFace) { FontConfigTypeface* fct = (FontConfigTypeface*)familyFace; familyName = fct->getFamilyName(); } FindRec rec(familyName, style); SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec); if (face) { // SkDebugf("found cached face <%s> <%s> %p [%d]\n", familyName, ((FontConfigTypeface*)face)->getFamilyName(), face, face->getRefCnt()); return face; } SkFontConfigInterface::FontIdentity indentity; SkString outFamilyName; SkTypeface::Style outStyle; if (!fci->matchFamilyName(familyName, style, &indentity, &outFamilyName, &outStyle)) { return NULL; } // check if we, in fact, already have this. perhaps fontconfig aliased the // requested name to some other name we actually have... rec.fFamilyName = outFamilyName.c_str(); rec.fStyle = outStyle; face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec); if (face) { return face; } face = FontConfigTypeface::Create(outStyle, indentity, outFamilyName); SkTypefaceCache::Add(face, style); // SkDebugf("add face <%s> <%s> %p [%d]\n", familyName, outFamilyName.c_str(), face, face->getRefCnt()); return face; }
SkTypeface* FontConfigTypeface::LegacyCreateTypeface(const char familyName[], SkTypeface::Style style) { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (nullptr == fci.get()) { return nullptr; } // Check if requested NameStyle is in the NameStyle cache. SkFontStyle requestedStyle(style); NameStyle nameStyle(familyName, requestedStyle); SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &nameStyle); if (face) { //SkDebugf("found cached face <%s> <%s> %p [%d]\n", // familyName, ((FontConfigTypeface*)face)->getFamilyName(), // face, face->getRefCnt()); return face; } SkFontConfigInterface::FontIdentity indentity; SkString outFamilyName; SkTypeface::Style outStyle; if (!fci->matchFamilyName(familyName, style, &indentity, &outFamilyName, &outStyle)) { return nullptr; } // Check if a typeface with this FontIdentity is already in the FontIdentity cache. face = SkTypefaceCache::FindByProcAndRef(find_by_FontIdentity, &indentity); if (!face) { face = FontConfigTypeface::Create(SkFontStyle(outStyle), indentity, outFamilyName); // Add this FontIdentity to the FontIdentity cache. SkTypefaceCache::Add(face, requestedStyle); } // TODO: Ensure requested NameStyle and resolved NameStyle are both in the NameStyle cache. //SkDebugf("add face <%s> <%s> %p [%d]\n", // familyName, outFamilyName.c_str(), // face, face->getRefCnt()); return face; }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // should have been provided by CreateFromStream() *ttcIndex = 0; SkAutoTUnref<SkStream> dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } // TODO: update interface use, remove the following code in this block. size_t length = stream->getLength(); const void* memory = stream->getMemoryBase(); if (NULL != memory) { return new SkMemoryStream(memory, length, true); } SkAutoTMalloc<uint8_t> allocMemory(length); stream->rewind(); if (length == stream->read(allocMemory.get(), length)) { SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream()); copyStream->setMemoryOwned(allocMemory.detach(), length); return copyStream.detach(); } stream->rewind(); stream->ref(); } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // TODO: fix issue 1176. // As of now open_stream will return a stream and unwind it, but the // SkStream is not thread safe, and if two threads use the stream they // may collide and print preview for example could still fail, // or there could be some failures in rendering if this stream is used // there. stream->rewind(); stream->ref(); // should have been provided by CreateFromStream() *ttcIndex = 0; } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }
SkFontConfigInterface* SkFontHost_fontconfig_ref_global() { return RefFCI(); }