git-svn-id: http://skia.googlecode.com/svn/trunk@8359 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2013-03-25 13:03:37 +00:00
parent 77279cbf9b
commit 5526ede94a
10 changed files with 91 additions and 288 deletions

View File

@ -152,23 +152,6 @@ private:
///////////////////////////////////////////////////////////////////////////
/** Write a unique identifier to the stream, so that the same typeface can
be retrieved with Deserialize(). The standard format is to serialize
a SkFontDescriptor followed by a uint32_t length value. If the length
is non-zero then the following bytes (of that length) represent a
serialized copy of the font which can be recreated from a stream.
*/
static void Serialize(const SkTypeface*, SkWStream*);
/** Given a stream created by Serialize(), return a new typeface (like
CreateTypeface) which is either an exact match to the one serialized
or the best available typeface based on the data in the deserialized
SkFontDescriptor.
*/
static SkTypeface* Deserialize(SkStream*);
///////////////////////////////////////////////////////////////////////////
friend class SkTypeface;
};

View File

@ -218,13 +218,13 @@ protected:
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const = 0;
virtual SkStream* onOpenStream(int* ttcIndex) const = 0;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const = 0;
virtual int onGetUPEM() const;
virtual int onGetTableTags(SkFontTableTag tags[]) const;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const;
virtual void onGetFontDescriptor(SkFontDescriptor*) const;
private:
SkFontID fUniqueID;

View File

@ -1,4 +1,3 @@
/*
* Copyright 2011 The Android Open Source Project
*
@ -6,10 +5,12 @@
* found in the LICENSE file.
*/
#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypeface.h"
#include "SkFontDescriptor.h"
#include "SkFontHost.h"
#include "SkFontStream.h"
#include "SkStream.h"
#include "SkTypeface.h"
SK_DEFINE_INST_COUNT(SkTypeface)
@ -88,19 +89,42 @@ SkTypeface* SkTypeface::CreateFromFile(const char path[]) {
///////////////////////////////////////////////////////////////////////////////
void SkTypeface::serialize(SkWStream* stream) const {
SkFontHost::Serialize(this, stream);
void SkTypeface::serialize(SkWStream* wstream) const {
bool isLocal = false;
SkFontDescriptor desc(this->style());
this->onGetFontDescriptor(&desc, &isLocal);
desc.serialize(wstream);
if (isLocal) {
int ttcIndex; // TODO: write this to the stream?
SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex));
if (rstream.get()) {
size_t length = rstream->getLength();
wstream->writePackedUInt(length);
wstream->writeStream(rstream, length);
} else {
wstream->writePackedUInt(0);
}
} else {
wstream->writePackedUInt(0);
}
}
SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
return SkFontHost::Deserialize(stream);
}
SkFontDescriptor desc(stream);
size_t length = stream->readPackedUInt();
if (length > 0) {
void* addr = sk_malloc_flags(length, 0);
if (addr) {
SkAutoTUnref<SkStream> localStream(SkNEW_ARGS(SkMemoryStream,
(addr, length, false)));
return SkTypeface::CreateFromStream(localStream.get());
}
// failed to allocate, so just skip and create-from-name
stream->skip(length);
}
SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo info,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const {
return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle());
}
///////////////////////////////////////////////////////////////////////////////
@ -136,10 +160,15 @@ int SkTypeface::getUnitsPerEm() const {
return this->onGetUPEM();
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo info,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const {
return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
}
#include "SkFontDescriptor.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int SkTypeface::onGetUPEM() const {
int upem = 0;
@ -155,13 +184,6 @@ int SkTypeface::onGetUPEM() const {
return upem;
}
void SkTypeface::onGetFontDescriptor(SkFontDescriptor* desc) const {
desc->setStyle(this->style());
}
#include "SkFontStream.h"
#include "SkStream.h"
int SkTypeface::onGetTableTags(SkFontTableTag tags[]) const {
int ttcIndex;
SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
@ -176,3 +198,4 @@ size_t SkTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
? SkFontStream::GetTableData(stream, ttcIndex, tag, offset, length, data)
: 0;
}

View File

@ -316,6 +316,9 @@ public:
virtual const char* getUniqueString() const = 0;
virtual const char* getFilePath() const = 0;
protected:
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
private:
bool fIsSysFont;
@ -737,57 +740,19 @@ static void load_system_fonts() {
///////////////////////////////////////////////////////////////////////////////
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
SkFontDescriptor descriptor;
void FamilyTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
{
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
descriptor.setFamilyName(find_family_name(face));
descriptor.setStyle(face->style());
descriptor.setFontFileName(((FamilyTypeface*)face)->getUniqueString());
}
descriptor.serialize(stream);
const bool isCustomFont = !((FamilyTypeface*)face)->isSysFont();
if (isCustomFont) {
// store the entire font in the fontData
SkStream* fontStream = face->openStream(NULL);
const uint32_t length = fontStream->getLength();
stream->writePackedUInt(length);
stream->writeStream(fontStream, length);
fontStream->unref();
} else {
stream->writePackedUInt(0);
desc->setFamilyName(find_family_name(this));
desc->setFontFileName(this->getUniqueString());
}
*isLocalStream = !this->isSysFont();
}
#if 0 // do we need this different name lookup for Deserialize?
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
{
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
load_system_fonts();
}
SkFontDescriptor descriptor(stream);
const char* familyName = descriptor.getFamilyName();
const char* fontFileName = descriptor.getFontFileName();
const SkTypeface::Style style = descriptor.getStyle();
const uint32_t customFontDataLength = stream->readPackedUInt();
if (customFontDataLength > 0) {
// generate a new stream to store the custom typeface
SkMemoryStream* fontStream = new SkMemoryStream(customFontDataLength - 1);
stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1);
SkTypeface* face = CreateTypefaceFromStream(fontStream);
fontStream->unref();
return face;
}
...
if (NULL != fontFileName && 0 != *fontFileName) {
const FontInitRec* rec = gSystemFonts;
for (size_t i = 0; i < gNumSystemFonts; i++) {
@ -802,9 +767,9 @@ SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
}
}
}
return SkFontHost::CreateTypeface(NULL, familyName, style);
...
}
#endif
///////////////////////////////////////////////////////////////////////////////

View File

@ -89,7 +89,7 @@ protected:
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
private:
@ -183,43 +183,6 @@ SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID curr, SkFontID orig) {
///////////////////////////////////////////////////////////////////////////////
// Serialize, Deserialize need to be compatible across platforms, hence the use
// of SkFontDescriptor.
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
FontConfigTypeface* fct = (FontConfigTypeface*)face;
SkFontDescriptor desc;
fct->onGetFontDescriptor(&desc);
desc.serialize(stream);
// by convention, we also write out the actual sfnt data, preceeded by
// a packed-length. For now we skip that, so we just write the zero.
stream->writePackedUInt(0);
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkFontDescriptor descriptor(stream);
const char* familyName = descriptor.getFamilyName();
const SkTypeface::Style style = descriptor.getStyle();
size_t length = stream->readPackedUInt();
if (length > 0) {
void* addr = sk_malloc_flags(length, 0);
if (addr) {
SkAutoTUnref<SkStream> localStream(SkNEW_ARGS(SkMemoryStream,
(addr, length, false)));
return SkFontHost::CreateTypefaceFromStream(localStream.get());
}
// failed to allocate, so just skip and create-from-name
stream->skip(length);
}
return SkFontHost::CreateTypeface(NULL, familyName, style);
}
///////////////////////////////////////////////////////////////////////////////
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const {
SkStream* stream = this->getLocalStream();
if (stream) {
@ -262,7 +225,9 @@ size_t FontConfigTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
: 0;
}
void FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc) const {
desc->setStyle(this->style());
void FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
desc->setFamilyName(this->getFamilyName());
*isLocalStream = SkToBool(this->getLocalStream());
}

View File

@ -261,6 +261,9 @@ public:
virtual const char* getUniqueString() const = 0;
protected:
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
private:
FamilyRec* fFamilyRec; // we don't own this, just point to it
bool fIsSysFont;
@ -457,51 +460,11 @@ static void load_system_fonts() {
///////////////////////////////////////////////////////////////////////////////
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
SkFontDescriptor descriptor;
descriptor.setFamilyName(find_family_name(face));
descriptor.setStyle(face->style());
descriptor.setFontFileName(((FamilyTypeface*)face)->getUniqueString());
descriptor.serialize(stream);
const bool isCustomFont = !((FamilyTypeface*)face)->isSysFont();
if (isCustomFont) {
// store the entire font in the fontData
SkStream* fontStream = face->openStream(NULL);
const uint32_t length = fontStream->getLength();
stream->writePackedUInt(length);
stream->writeStream(fontStream, length);
fontStream->unref();
} else {
stream->writePackedUInt(0);
}
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
load_system_fonts();
SkFontDescriptor descriptor(stream);
const char* familyName = descriptor.getFamilyName();
const SkTypeface::Style style = descriptor.getStyle();
const uint32_t customFontDataLength = stream->readPackedUInt();
if (customFontDataLength > 0) {
// generate a new stream to store the custom typeface
SkMemoryStream* fontStream = new SkMemoryStream(customFontDataLength - 1);
stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1);
SkTypeface* face = CreateTypefaceFromStream(fontStream);
fontStream->unref();
return face;
}
return SkFontHost::CreateTypeface(NULL, familyName, style);
void FamilyTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
desc->setFamilyName(find_family_name(this));
desc->setFontFileName(this->getUniqueString());
*isLocalStream = !this->isSysFont();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -418,7 +418,7 @@ protected:
size_t length, void* data) const SK_OVERRIDE;
virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo,
const uint32_t*, uint32_t) const SK_OVERRIDE;
@ -1683,32 +1683,6 @@ SkStream* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
///////////////////////////////////////////////////////////////////////////////
#include "SkStream.h"
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
SkFontDescriptor desc;
face->onGetFontDescriptor(&desc);
desc.serialize(stream);
// by convention, we also write out the actual sfnt data, preceeded by
// a packed-length. For now we skip that, so we just write the zero.
stream->writePackedUInt(0);
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkFontDescriptor desc(stream);
// by convention, Serialize will have also written the actual sfnt data.
// for now, we just want to skip it.
size_t size = stream->readPackedUInt();
stream->skip(size);
return SkFontHost::CreateTypeface(NULL, desc.getFamilyName(), desc.getStyle());
}
///////////////////////////////////////////////////////////////////////////////
// DEPRECATED
SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) {
SkTypeface* face = GetDefaultFace();
@ -1847,11 +1821,14 @@ static const char* get_str(CFStringRef ref, SkString* str) {
return str->c_str();
}
void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc) const {
this->INHERITED::onGetFontDescriptor(desc);
void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
SkString tmpStr;
desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
// TODO: need to add support for local-streams (here and openStream)
*isLocalStream = false;
}

View File

@ -27,19 +27,6 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkDEBUGFAIL("SkFontHost::Deserialize unimplemented");
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
SkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID,
SkFontID origFontID) {
return NULL;

View File

@ -216,6 +216,7 @@ protected:
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo,
const uint32_t*, uint32_t) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
};
class FontMemResourceTypeface : public LogFontTypeface {
@ -1279,19 +1280,17 @@ static void tchar_to_skstring(const TCHAR* t, SkString* s) {
#endif
}
void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
const LogFontTypeface* face = static_cast<const LogFontTypeface*>(rawFace);
SkFontDescriptor descriptor(face->style());
void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
// Get the actual name of the typeface. The logfont may not know this.
HFONT font = CreateFontIndirect(&face->fLogFont);
HFONT font = CreateFontIndirect(&fLogFont);
HDC deviceContext = ::CreateCompatibleDC(NULL);
HFONT savefont = (HFONT)SelectObject(deviceContext, font);
int fontNameLen; //length of fontName in TCHARS.
if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
LogFontTypeface::EnsureAccessible(rawFace);
call_ensure_accessible(fLogFont);
if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
fontNameLen = 0;
}
@ -1299,7 +1298,7 @@ void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
LogFontTypeface::EnsureAccessible(rawFace);
call_ensure_accessible(fLogFont);
if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
fontName[0] = 0;
}
@ -1315,39 +1314,9 @@ void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
SkString familyName;
tchar_to_skstring(fontName.get(), &familyName);
descriptor.setFamilyName(familyName.c_str());
//TODO: FileName and PostScriptName currently unsupported.
descriptor.serialize(stream);
if (face->fSerializeAsStream) {
// store the entire font in the fontData
SkAutoTUnref<SkStream> fontStream(face->openStream(NULL));
if (fontStream.get()) {
const uint32_t length = fontStream->getLength();
stream->writePackedUInt(length);
stream->writeStream(fontStream, length);
} else {
stream->writePackedUInt(0);
}
} else {
stream->writePackedUInt(0);
}
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkFontDescriptor descriptor(stream);
const uint32_t customFontDataLength = stream->readPackedUInt();
if (customFontDataLength > 0) {
// generate a new stream to store the custom typeface
SkAutoTUnref<SkMemoryStream> fontStream(SkNEW_ARGS(SkMemoryStream, (customFontDataLength - 1)));
stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1);
return CreateTypefaceFromStream(fontStream.get());
}
return SkFontHost::CreateTypeface(NULL, descriptor.getFamilyName(), descriptor.getStyle());
desc->setFamilyName(familyName.c_str());
*isLocalStream = this->fSerializeAsStream;
}
static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {

View File

@ -485,6 +485,7 @@ protected:
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo,
const uint32_t*, uint32_t) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
};
class SkScalerContext_Windows : public SkScalerContext {
@ -1046,13 +1047,11 @@ void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
path->transform(mat);
}
void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(rawFace);
SkFontDescriptor descriptor(face->style());
void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
bool* isLocalStream) const {
// Get the family name.
SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
HRV(face->fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
UINT32 dwFamilyNamesLength;
HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
@ -1070,36 +1069,8 @@ void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
str_len = WideCharToMultiByte(CP_UTF8, 0, dwFamilyNameChar.begin(), -1,
utf8FamilyName.begin(), str_len, NULL, NULL);
descriptor.setFamilyName(utf8FamilyName.begin());
//TODO: FileName and PostScriptName currently unsupported.
descriptor.serialize(stream);
if (NULL != face->fDWriteFontFileLoader.get()) {
// store the entire font in the fontData
SkStream* fontStream = face->fDWriteFontFileLoader->fStream.get();
const uint32_t length = fontStream->getLength();
stream->writePackedUInt(length);
stream->writeStream(fontStream, length);
} else {
stream->writePackedUInt(0);
}
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkFontDescriptor descriptor(stream);
const uint32_t customFontDataLength = stream->readPackedUInt();
if (customFontDataLength > 0) {
// generate a new stream to store the custom typeface
SkAutoTUnref<SkMemoryStream> fontStream(SkNEW_ARGS(SkMemoryStream, (customFontDataLength - 1)));
stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1);
return CreateTypefaceFromStream(fontStream.get());
}
return SkFontHost::CreateTypeface(NULL, descriptor.getFamilyName(), descriptor.getStyle());
desc->setFamilyName(utf8FamilyName.begin());
*isLocalStream = SkToBool(fDWriteFontFileLoader.get());
}
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {