Improve the SkAdvancedTypefaceMetrics interface w.r.t. vertical advances.

Add a template function to type safe-combine bits of a bit field.

Review URL: http://codereview.appspot.com/4313053

git-svn-id: http://skia.googlecode.com/svn/trunk@1020 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
vandebo@chromium.org 2011-03-30 18:36:29 +00:00
parent e733071abe
commit 325cb9aa17
13 changed files with 79 additions and 35 deletions

View File

@ -76,6 +76,14 @@ public:
SkIRect fBBox; // The bounding box of all glyphs (in font units). SkIRect fBBox; // The bounding box of all glyphs (in font units).
// The type of advance data wanted.
enum PerGlyphInfo {
kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info.
kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
};
template <typename Data> template <typename Data>
struct AdvanceMetric { struct AdvanceMetric {
enum MetricType { enum MetricType {

View File

@ -177,14 +177,14 @@ public:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/** Retrieve detailed typeface metrics. Used by the PDF backend. /** Retrieve detailed typeface metrics. Used by the PDF backend.
@param perGlyphInfo Indicate if the glyph specific information. @param perGlyphInfo Indicate what glyph specific information (advances,
@param perGlyphInfo Indicate if the glyph specific information (advances names, etc.) should be populated.
and names) should be populated.
@return The returned object has already been referenced. NULL is @return The returned object has already been referenced. NULL is
returned if the font is not found. returned if the font is not found.
*/ */
static SkAdvancedTypefaceMetrics* GetAdvancedTypefaceMetrics( static SkAdvancedTypefaceMetrics* GetAdvancedTypefaceMetrics(
SkFontID fontID, bool perGlyphInfo); SkFontID fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo);
/** Return the number of tables in the font /** Return the number of tables in the font
*/ */

View File

@ -17,6 +17,7 @@
#ifndef SkTypeface_DEFINED #ifndef SkTypeface_DEFINED
#define SkTypeface_DEFINED #define SkTypeface_DEFINED
#include "SkAdvancedTypefaceMetrics.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
class SkStream; class SkStream;
@ -136,10 +137,14 @@ public:
static SkTypeface* Deserialize(SkStream*); static SkTypeface* Deserialize(SkStream*);
/** Retrieve detailed typeface metrics. Used by the PDF backend. /** Retrieve detailed typeface metrics. Used by the PDF backend.
@param perGlyphInfo Indicate if the glyph specific information (advances @param perGlyphInfo Indicate what glyph specific information (advances,
and names) should be populated. names, etc.) should be populated.
@return The returned object has already been referenced. @return The returned object has already been referenced.
*/ */
SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) const;
// Temporary: for transition purposes.
SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics(
bool perGlyphInfo) const; bool perGlyphInfo) const;

View File

@ -318,6 +318,13 @@ static inline uint32_t SkSetClearMask(uint32_t bits, bool cond,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/** Use to combine multiple bits in a bitmask in a type safe way.
*/
template <typename T>
T SkTBitOr(T a, T b) {
return (T)(a | b);
}
/** /**
* Use to cast a pointer to a different type, and maintaining strict-aliasing * Use to cast a pointer to a different type, and maintaining strict-aliasing
*/ */

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypeface.h" #include "SkTypeface.h"
#include "SkFontHost.h" #include "SkFontHost.h"
@ -76,6 +77,15 @@ SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
} }
SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
bool perGlyphInfo) const { SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) const {
return SkFontHost::GetAdvancedTypefaceMetrics(fUniqueID, perGlyphInfo); return SkFontHost::GetAdvancedTypefaceMetrics(fUniqueID, perGlyphInfo);
} }
// Temporary: for transitions purposes only.
SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
bool perGlyphInfo) const {
SkASSERT(!perGlyphInfo);
return SkFontHost::GetAdvancedTypefaceMetrics(
fUniqueID,
SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
}

View File

@ -28,6 +28,7 @@
#include "SkScalar.h" #include "SkScalar.h"
#include "SkStream.h" #include "SkStream.h"
#include "SkTypeface.h" #include "SkTypeface.h"
#include "SkTypes.h"
#include "SkUtils.h" #include "SkUtils.h"
namespace { namespace {
@ -411,7 +412,9 @@ SkPDFFont* SkPDFFont::getFontResource(SkTypeface* typeface, uint16_t glyphID) {
fontInfo = relatedFont->fFontInfo; fontInfo = relatedFont->fFontInfo;
fontDescriptor = relatedFont->fDescriptor.get(); fontDescriptor = relatedFont->fDescriptor.get();
} else { } else {
fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, true); fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, SkTBitOr(
SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo,
SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo));
SkSafeUnref(fontInfo.get()); // SkRefPtr and Get both took a reference. SkSafeUnref(fontInfo.get()); // SkRefPtr and Get both took a reference.
} }

View File

@ -271,7 +271,8 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
sk_throw(); // not implemented sk_throw(); // not implemented
return NULL; return NULL;
} }

View File

@ -344,7 +344,8 @@ static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID) #if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
return NULL; return NULL;
#else #else
@ -386,12 +387,6 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
} }
} }
SkASSERT(!FT_HAS_VERTICAL(face));
#ifdef FT_IS_CID_KEYED
SkASSERT(FT_IS_CID_KEYED(face) ==
(info->fType == SkAdvancedTypefaceMetrics::kType1CID_Font));
#endif
info->fStyle = 0; info->fStyle = 0;
if (FT_IS_FIXED_WIDTH(face)) if (FT_IS_FIXED_WIDTH(face))
info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
@ -463,8 +458,12 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax, info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
face->bbox.xMax, face->bbox.yMin); face->bbox.xMax, face->bbox.yMin);
if (perGlyphInfo && canEmbed(face) && FT_IS_SCALABLE(face) && if (!canEmbed(face) || !FT_IS_SCALABLE(face) ||
info->fType != SkAdvancedTypefaceMetrics::kOther_Font) { info->fType == SkAdvancedTypefaceMetrics::kOther_Font) {
perGlyphInfo = SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo;
}
if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
if (FT_IS_FIXED_WIDTH(face)) { if (FT_IS_FIXED_WIDTH(face)) {
appendRange(&info->fGlyphWidths, 0); appendRange(&info->fGlyphWidths, 0);
int16_t advance = face->max_advance_width; int16_t advance = face->max_advance_width;
@ -492,18 +491,24 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fGlyphWidths.reset( info->fGlyphWidths.reset(
getAdvanceData(face, face->num_glyphs, &getWidthAdvance)); getAdvanceData(face, face->num_glyphs, &getWidthAdvance));
} }
}
if (info->fType == SkAdvancedTypefaceMetrics::kType1_Font) { if (perGlyphInfo & SkAdvancedTypefaceMetrics::kVAdvance_PerGlyphInfo &&
// Postscript fonts may contain more than 255 glyphs, so we end up FT_HAS_VERTICAL(face)) {
// using multiple font descriptions with a glyph ordering. Record SkASSERT(false); // Not implemented yet.
// the name of each glyph. }
info->fGlyphNames.reset(
new SkAutoTArray<SkString>(face->num_glyphs)); if (perGlyphInfo & SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo &&
for (int gID = 0; gID < face->num_glyphs; gID++) { info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {
char glyphName[128]; // PS limit for names is 127 bytes. // Postscript fonts may contain more than 255 glyphs, so we end up
FT_Get_Glyph_Name(face, gID, glyphName, 128); // using multiple font descriptions with a glyph ordering. Record
info->fGlyphNames->get()[gID].set(glyphName); // the name of each glyph.
} info->fGlyphNames.reset(
new SkAutoTArray<SkString>(face->num_glyphs));
for (int gID = 0; gID < face->num_glyphs; gID++) {
char glyphName[128]; // PS limit for names is 127 bytes.
FT_Get_Glyph_Name(face, gID, glyphName, 128);
info->fGlyphNames->get()[gID].set(glyphName);
} }
} }

View File

@ -481,7 +481,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented"); SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL; return NULL;
} }

View File

@ -676,7 +676,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented"); SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL; return NULL;
} }

View File

@ -35,7 +35,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented"); SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL; return NULL;
} }

View File

@ -592,7 +592,8 @@ SkStream* SkFontHost::OpenStream(uint32_t fontID) {
#if 0 #if 0
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented"); SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL; return NULL;
} }

View File

@ -613,7 +613,8 @@ static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
// static // static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) { uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkAutoMutexAcquire ac(gFTMutex); SkAutoMutexAcquire ac(gFTMutex);
LogFontTypeface* rec = LogFontTypeface::FindById(fontID); LogFontTypeface* rec = LogFontTypeface::FindById(fontID);
LOGFONT lf = rec->logFont(); LOGFONT lf = rec->logFont();
@ -721,7 +722,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
// If bit 2 is set, the embedding is read-only. // If bit 2 is set, the embedding is read-only.
if (otm.otmfsType & 0x1) { if (otm.otmfsType & 0x1) {
info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
} else if (perGlyphInfo) { } else if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
info->fGlyphWidths.reset( info->fGlyphWidths.reset(
getAdvanceData(hdc, glyphCount, &getWidthAdvance)); getAdvanceData(hdc, glyphCount, &getWidthAdvance));
} }