move some of the impl in fonthost into typeface virtuals
git-svn-id: http://skia.googlecode.com/svn/trunk@7944 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
b9ba1eadc8
commit
dc09f07671
@ -13,6 +13,10 @@
|
|||||||
#include "SkAdvancedTypefaceMetrics.h"
|
#include "SkAdvancedTypefaceMetrics.h"
|
||||||
#include "SkWeakRefCnt.h"
|
#include "SkWeakRefCnt.h"
|
||||||
|
|
||||||
|
class SkDescriptor;
|
||||||
|
class SkFontDescriptor;
|
||||||
|
class SkScalerContext;
|
||||||
|
struct SkScalerContextRec;
|
||||||
class SkStream;
|
class SkStream;
|
||||||
class SkAdvancedTypefaceMetrics;
|
class SkAdvancedTypefaceMetrics;
|
||||||
class SkWStream;
|
class SkWStream;
|
||||||
@ -184,7 +188,7 @@ public:
|
|||||||
int getUnitsPerEm() const;
|
int getUnitsPerEm() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** uniqueID must be unique (please!) and non-zero
|
/** uniqueID must be unique and non-zero
|
||||||
*/
|
*/
|
||||||
SkTypeface(Style style, SkFontID uniqueID, bool isFixedWidth = false);
|
SkTypeface(Style style, SkFontID uniqueID, bool isFixedWidth = false);
|
||||||
virtual ~SkTypeface();
|
virtual ~SkTypeface();
|
||||||
@ -192,11 +196,22 @@ protected:
|
|||||||
friend class SkScalerContext;
|
friend class SkScalerContext;
|
||||||
static SkTypeface* GetDefaultTypeface();
|
static SkTypeface* GetDefaultTypeface();
|
||||||
|
|
||||||
|
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 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const;
|
||||||
|
virtual void onFilterRec(SkScalerContextRec*) const;
|
||||||
|
virtual void onGetFontDescriptor(SkFontDescriptor*) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkFontID fUniqueID;
|
SkFontID fUniqueID;
|
||||||
Style fStyle;
|
Style fStyle;
|
||||||
bool fIsFixedWidth;
|
bool fIsFixedWidth;
|
||||||
|
|
||||||
|
// just so deprecated fonthost can call protected methods
|
||||||
|
friend class SkFontHost;
|
||||||
|
|
||||||
typedef SkWeakRefCnt INHERITED;
|
typedef SkWeakRefCnt INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,3 +134,21 @@ int SkTypeface::getUnitsPerEm() const {
|
|||||||
#endif
|
#endif
|
||||||
return upem;
|
return upem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "SkFontDescriptor.h"
|
||||||
|
|
||||||
|
int SkTypeface::onGetUPEM() const { return 0; }
|
||||||
|
int SkTypeface::onGetTableTags(SkFontTableTag tags[]) const { return 0; }
|
||||||
|
size_t SkTypeface::onGetTableData(SkFontTableTag, size_t offset,
|
||||||
|
size_t length, void* data) const { return 0; }
|
||||||
|
SkScalerContext* SkTypeface::onCreateScalerContext(const SkDescriptor*) const {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void SkTypeface::onFilterRec(SkScalerContextRec*) const {}
|
||||||
|
void SkTypeface::onGetFontDescriptor(SkFontDescriptor* desc) const {
|
||||||
|
desc->setStyle(this->style());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -407,12 +407,21 @@ public:
|
|||||||
|
|
||||||
SkString fName;
|
SkString fName;
|
||||||
AutoCFRelease<CTFontRef> fFontRef;
|
AutoCFRelease<CTFontRef> fFontRef;
|
||||||
};
|
|
||||||
|
|
||||||
static CTFontRef typeface_to_fontref(const SkTypeface* face) {
|
protected:
|
||||||
const SkTypeface_Mac* macface = reinterpret_cast<const SkTypeface_Mac*>(face);
|
friend class SkFontHost; // to access our protected members for deprecated methods
|
||||||
return macface->fFontRef;
|
|
||||||
}
|
virtual int onGetUPEM() const SK_OVERRIDE;
|
||||||
|
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 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
|
||||||
|
virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
|
||||||
|
virtual void onGetFontDescriptor(SkFontDescriptor*) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef SkTypeface INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[]) {
|
static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[]) {
|
||||||
SkASSERT(fontRef);
|
SkASSERT(fontRef);
|
||||||
@ -1683,21 +1692,9 @@ size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, int3
|
|||||||
|
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
|
|
||||||
// we take ownership of the ref
|
|
||||||
static const char* get_str(CFStringRef ref, SkString* str) {
|
|
||||||
CFStringToSkString(ref, str);
|
|
||||||
CFSafeRelease(ref);
|
|
||||||
return str->c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
|
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
|
||||||
CTFontRef ctFont = typeface_to_fontref(face);
|
SkFontDescriptor desc;
|
||||||
SkFontDescriptor desc(face->style());
|
face->onGetFontDescriptor(&desc);
|
||||||
SkString tmpStr;
|
|
||||||
|
|
||||||
desc.setFamilyName(get_str(CTFontCopyFamilyName(ctFont), &tmpStr));
|
|
||||||
desc.setFullName(get_str(CTFontCopyFullName(ctFont), &tmpStr));
|
|
||||||
desc.setPostscriptName(get_str(CTFontCopyPostScriptName(ctFont), &tmpStr));
|
|
||||||
|
|
||||||
desc.serialize(stream);
|
desc.serialize(stream);
|
||||||
|
|
||||||
@ -1719,10 +1716,12 @@ SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
|
SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
|
||||||
return new SkScalerContext_Mac(desc);
|
return new SkScalerContext_Mac(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
||||||
SkFontID nextFontID = 0;
|
SkFontID nextFontID = 0;
|
||||||
SkTypeface* face = GetDefaultFace();
|
SkTypeface* face = GetDefaultFace();
|
||||||
@ -1732,14 +1731,105 @@ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
|||||||
return nextFontID;
|
return nextFontID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
|
// DEPRECATED
|
||||||
|
void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface* face) {
|
||||||
|
face->onFilterRec(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
int SkFontHost::CountTables(SkFontID fontID) {
|
||||||
|
SkTypeface* face = SkTypefaceCache::FindByID(fontID);
|
||||||
|
return face ? face->onGetTableTags(NULL) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
|
||||||
|
SkTypeface* face = SkTypefaceCache::FindByID(fontID);
|
||||||
|
return face ? face->onGetTableTags(tags) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
|
||||||
|
SkTypeface* face = SkTypefaceCache::FindByID(fontID);
|
||||||
|
return face ? face->onGetTableData(tag, 0, 0, NULL) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
|
||||||
|
size_t offset, size_t length, void* dst) {
|
||||||
|
SkTypeface* face = SkTypefaceCache::FindByID(fontID);
|
||||||
|
return face ? face->onGetTableData(tag, offset, length, dst) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int SkTypeface_Mac::onGetUPEM() const {
|
||||||
|
AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
|
||||||
|
return CGFontGetUnitsPerEm(cgFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If, as is the case with web fonts, the CTFont data isn't available,
|
||||||
|
// the CGFont data may work. While the CGFont may always provide the
|
||||||
|
// right result, leave the CTFont code path to minimize disruption.
|
||||||
|
static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) {
|
||||||
|
CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag,
|
||||||
|
kCTFontTableOptionNoOptions);
|
||||||
|
if (NULL == data) {
|
||||||
|
AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, NULL));
|
||||||
|
data = CGFontCopyTableForTag(cgFont, tag);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
|
||||||
|
AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef,
|
||||||
|
kCTFontTableOptionNoOptions));
|
||||||
|
if (NULL == cfArray) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = CFArrayGetCount(cfArray);
|
||||||
|
if (tags) {
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(cfArray, i));
|
||||||
|
tags[i] = static_cast<SkFontTableTag>(fontTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset,
|
||||||
|
size_t length, void* dstData) const {
|
||||||
|
AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag));
|
||||||
|
if (NULL == srcData) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t srcSize = CFDataGetLength(srcData);
|
||||||
|
if (offset >= srcSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (length > srcSize - offset) {
|
||||||
|
length = srcSize - offset;
|
||||||
|
}
|
||||||
|
if (dstData) {
|
||||||
|
memcpy(dstData, CFDataGetBytePtr(srcData) + offset, length);
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkScalerContext* SkTypeface_Mac::onCreateScalerContext(const SkDescriptor* desc) const {
|
||||||
|
return new SkScalerContext_Mac(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
|
||||||
unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
|
unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
|
||||||
SkScalerContext::kAutohinting_Flag;
|
SkScalerContext::kAutohinting_Flag;
|
||||||
|
|
||||||
rec->fFlags &= ~flagsWeDontSupport;
|
rec->fFlags &= ~flagsWeDontSupport;
|
||||||
|
|
||||||
bool lcdSupport = supports_LCD();
|
bool lcdSupport = supports_LCD();
|
||||||
|
|
||||||
// Only two levels of hinting are supported.
|
// Only two levels of hinting are supported.
|
||||||
// kNo_Hinting means avoid CoreGraphics outline dilation.
|
// kNo_Hinting means avoid CoreGraphics outline dilation.
|
||||||
// kNormal_Hinting means CoreGraphics outline dilation is allowed.
|
// kNormal_Hinting means CoreGraphics outline dilation is allowed.
|
||||||
@ -1751,18 +1841,18 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
|
|||||||
hinting = SkPaint::kNormal_Hinting;
|
hinting = SkPaint::kNormal_Hinting;
|
||||||
}
|
}
|
||||||
rec->setHinting(hinting);
|
rec->setHinting(hinting);
|
||||||
|
|
||||||
// FIXME: lcd smoothed un-hinted rasterization unsupported.
|
// FIXME: lcd smoothed un-hinted rasterization unsupported.
|
||||||
// Tracked by http://code.google.com/p/skia/issues/detail?id=915 .
|
// Tracked by http://code.google.com/p/skia/issues/detail?id=915 .
|
||||||
// There is no current means to honor a request for unhinted lcd,
|
// There is no current means to honor a request for unhinted lcd,
|
||||||
// so arbitrarilly ignore the hinting request and honor lcd.
|
// so arbitrarilly ignore the hinting request and honor lcd.
|
||||||
|
|
||||||
// Hinting and smoothing should be orthogonal, but currently they are not.
|
// Hinting and smoothing should be orthogonal, but currently they are not.
|
||||||
// CoreGraphics has no API to influence hinting. However, its lcd smoothed
|
// CoreGraphics has no API to influence hinting. However, its lcd smoothed
|
||||||
// output is drawn from auto-dilated outlines (the amount of which is
|
// output is drawn from auto-dilated outlines (the amount of which is
|
||||||
// determined by AppleFontSmoothing). Its regular anti-aliased output is
|
// determined by AppleFontSmoothing). Its regular anti-aliased output is
|
||||||
// drawn from un-dilated outlines.
|
// drawn from un-dilated outlines.
|
||||||
|
|
||||||
// The behavior of Skia is as follows:
|
// The behavior of Skia is as follows:
|
||||||
// [AA][no-hint]: generate AA using CoreGraphic's AA output.
|
// [AA][no-hint]: generate AA using CoreGraphic's AA output.
|
||||||
// [AA][yes-hint]: use CoreGraphic's LCD output and reduce it to a single
|
// [AA][yes-hint]: use CoreGraphic's LCD output and reduce it to a single
|
||||||
@ -1770,7 +1860,7 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
|
|||||||
// [LCD][no-hint]: curently unable to honor, and must pick which to respect.
|
// [LCD][no-hint]: curently unable to honor, and must pick which to respect.
|
||||||
// Currenly side with LCD, effectively ignoring the hinting setting.
|
// Currenly side with LCD, effectively ignoring the hinting setting.
|
||||||
// [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output.
|
// [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output.
|
||||||
|
|
||||||
if (isLCDFormat(rec->fMaskFormat)) {
|
if (isLCDFormat(rec->fMaskFormat)) {
|
||||||
if (lcdSupport) {
|
if (lcdSupport) {
|
||||||
//CoreGraphics creates 555 masks for smoothed text anyway.
|
//CoreGraphics creates 555 masks for smoothed text anyway.
|
||||||
@ -1780,7 +1870,7 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
|
|||||||
rec->fMaskFormat = SkMask::kA8_Format;
|
rec->fMaskFormat = SkMask::kA8_Format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unhinted A8 masks (those not derived from LCD masks) must respect SK_GAMMA_APPLY_TO_A8.
|
// Unhinted A8 masks (those not derived from LCD masks) must respect SK_GAMMA_APPLY_TO_A8.
|
||||||
// All other masks can use regular gamma.
|
// All other masks can use regular gamma.
|
||||||
if (SkMask::kA8_Format == rec->fMaskFormat && SkPaint::kNo_Hinting == hinting) {
|
if (SkMask::kA8_Format == rec->fMaskFormat && SkPaint::kNo_Hinting == hinting) {
|
||||||
@ -1793,76 +1883,19 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
// we take ownership of the ref
|
||||||
|
static const char* get_str(CFStringRef ref, SkString* str) {
|
||||||
int SkFontHost::CountTables(SkFontID fontID) {
|
CFStringToSkString(ref, str);
|
||||||
CTFontRef ctFont = GetFontRefFromFontID(fontID);
|
CFSafeRelease(ref);
|
||||||
AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(ctFont,
|
return str->c_str();
|
||||||
kCTFontTableOptionNoOptions));
|
|
||||||
if (NULL == cfArray) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return CFArrayGetCount(cfArray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
|
void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc) const {
|
||||||
CTFontRef ctFont = GetFontRefFromFontID(fontID);
|
this->INHERITED::onGetFontDescriptor(desc);
|
||||||
AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(ctFont,
|
SkString tmpStr;
|
||||||
kCTFontTableOptionNoOptions));
|
|
||||||
if (NULL == cfArray) {
|
desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
|
||||||
return 0;
|
desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
|
||||||
}
|
desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
|
||||||
|
|
||||||
int count = CFArrayGetCount(cfArray);
|
|
||||||
if (tags) {
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(cfArray, i));
|
|
||||||
tags[i] = static_cast<SkFontTableTag>(fontTag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If, as is the case with web fonts, the CTFont data isn't available,
|
|
||||||
// the CGFont data may work. While the CGFont may always provide the
|
|
||||||
// right result, leave the CTFont code path to minimize disruption.
|
|
||||||
static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) {
|
|
||||||
CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag, kCTFontTableOptionNoOptions);
|
|
||||||
if (NULL == data) {
|
|
||||||
AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, NULL));
|
|
||||||
data = CGFontCopyTableForTag(cgFont, tag);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
|
|
||||||
CTFontRef ctFont = GetFontRefFromFontID(fontID);
|
|
||||||
AutoCFRelease<CFDataRef> srcData(copyTableFromFont(ctFont, tag));
|
|
||||||
if (NULL == srcData) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return CFDataGetLength(srcData);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
|
|
||||||
size_t offset, size_t length, void* dst) {
|
|
||||||
CTFontRef ctFont = GetFontRefFromFontID(fontID);
|
|
||||||
AutoCFRelease<CFDataRef> srcData(copyTableFromFont(ctFont, tag));
|
|
||||||
if (NULL == srcData) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t srcSize = CFDataGetLength(srcData);
|
|
||||||
if (offset >= srcSize) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((offset + length) > srcSize) {
|
|
||||||
length = srcSize - offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst) {
|
|
||||||
memcpy(dst, CFDataGetBytePtr(srcData) + offset, length);
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user