diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-31 17:28:16 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-31 17:28:16 +0000 |
commit | 7051f73afe986918635f4dd7d0c1610a42df2603 (patch) | |
tree | b3a1ebce3525f70f526b520f286cc544106763bf /skia | |
parent | b5a2bb6a4aea3f2564e1fd1b2746616f5d7161de (diff) | |
download | chromium_src-7051f73afe986918635f4dd7d0c1610a42df2603.zip chromium_src-7051f73afe986918635f4dd7d0c1610a42df2603.tar.gz chromium_src-7051f73afe986918635f4dd7d0c1610a42df2603.tar.bz2 |
Skia: bring us closer to upstream.
I want to bring us closer to upstream Skia. This patch consists of
hunks pulled from code.google.com/p/skia. I'll also be pushing changes
the other way.
Review URL: http://codereview.chromium.org/57018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12873 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/include/SkFontHost.h | 28 | ||||
-rw-r--r-- | skia/include/SkScalerContext.h | 12 | ||||
-rw-r--r-- | skia/ports/SkFontHost_FreeType.cpp | 53 | ||||
-rw-r--r-- | skia/sgl/SkScalerContext.cpp | 11 |
4 files changed, 76 insertions, 28 deletions
diff --git a/skia/include/SkFontHost.h b/skia/include/SkFontHost.h index 73010e7..c3b2e2d 100644 --- a/skia/include/SkFontHost.h +++ b/skia/include/SkFontHost.h @@ -26,8 +26,32 @@ class SkWStream; /** \class SkFontHost - This class is ported to each environment. It is responsible for bridging the gap - between SkTypeface and the resulting platform-specific instance of SkScalerContext. + This class is ported to each environment. It is responsible for bridging + the gap between the (sort of) abstract class SkTypeface and the + platform-specific implementation that provides access to font files. + + One basic task is for each create (subclass of) SkTypeface, the FontHost is + resonsible for assigning a uniqueID. The ID should be unique for the + underlying font file/data, not unique per typeface instance. Thus it is + possible/common to request a typeface for the same font more than once + (e.g. asking for the same font by name several times). The FontHost may + return seperate typeface instances in that case, or it may choose to use a + cache and return the same instance (but calling typeface->ref(), since the + caller is always responsible for calling unref() on each instance that is + returned). Either way, the fontID for those instance(s) will be the same. + In addition, the fontID should never be set to 0. That value is used as a + sentinel to indicate no-font-id. + + The major aspects are: + 1) Given either a name/style, return a subclass of SkTypeface that + references the closest matching font available on the host system. + 2) Given the data for a font (either in a stream or a file name), return + a typeface that allows access to that data. + 3) Each typeface instance carries a 32bit ID for its corresponding font. + SkFontHost turns that ID into a stream to access the font's data. + 4) Given a font ID, return a subclass of SkScalerContext, which connects a + font scaler (e.g. freetype or other) to the font's data. + 5) Utilites to manage the font cache (budgeting) and gamma correction */ class SkFontHost { public: diff --git a/skia/include/SkScalerContext.h b/skia/include/SkScalerContext.h index ec2cd0d..df846f2 100644 --- a/skia/include/SkScalerContext.h +++ b/skia/include/SkScalerContext.h @@ -85,6 +85,12 @@ struct SkGlyph { size_t computeImageSize() const; + /** Call this to set all of the metrics fields to 0 (e.g. if the scaler + encounters an error measuring a glyph). Note: this does not alter the + fImage, fPath, fID, fMaskFormat fields. + */ + void zeroMetrics(); + enum { kSubBits = 2, kSubMask = ((1 << kSubBits) - 1), @@ -163,10 +169,16 @@ public: SkScalerContext(const SkDescriptor* desc); virtual ~SkScalerContext(); + // remember our glyph offset/base void setBaseGlyphCount(unsigned baseGlyphCount) { fBaseGlyphCount = baseGlyphCount; } + /** Return the corresponding glyph for the specified unichar. Since contexts + may be chained (under the hood), the glyphID that is returned may in + fact correspond to a different font/context. In that case, we use the + base-glyph-count to know how to translate back into local glyph space. + */ uint16_t charToGlyphID(SkUnichar uni); unsigned getGlyphCount() const { return this->generateGlyphCount(); } diff --git a/skia/ports/SkFontHost_FreeType.cpp b/skia/ports/SkFontHost_FreeType.cpp index 94bbf2b..8aa8a38 100644 --- a/skia/ports/SkFontHost_FreeType.cpp +++ b/skia/ports/SkFontHost_FreeType.cpp @@ -73,6 +73,9 @@ class SkScalerContext_FreeType : public SkScalerContext { public: SkScalerContext_FreeType(const SkDescriptor* desc); virtual ~SkScalerContext_FreeType(); + bool success() const { + return fFaceRec != NULL && fFTSize != NULL; + } protected: virtual unsigned generateGlyphCount() const; @@ -110,7 +113,7 @@ struct SkFaceRec { SkFaceRec(SkStream* strm, uint32_t fontID); ~SkFaceRec() { - SkFontHost::CloseStream(fFontID, fSkStream); + fSkStream->unref(); } }; @@ -156,6 +159,7 @@ SkFaceRec::SkFaceRec(SkStream* strm, uint32_t fontID) fFTStream.close = sk_stream_close; } +// Will return 0 on failure static SkFaceRec* ref_ft_face(uint32_t fontID) { SkFaceRec* rec = gFaceRecHead; while (rec) { @@ -170,7 +174,6 @@ static SkFaceRec* ref_ft_face(uint32_t fontID) { SkStream* strm = SkFontHost::OpenStream(fontID); if (NULL == strm) { SkDEBUGF(("SkFontHost::OpenStream failed opening %x\n", fontID)); - sk_throw(); return 0; } @@ -197,7 +200,6 @@ static SkFaceRec* ref_ft_face(uint32_t fontID) { if (err) { // bad filename, try the default font fprintf(stderr, "ERROR: unable to open font '%x'\n", fontID); SkDELETE(rec); - sk_throw(); return 0; } else { SkASSERT(rec->fFace); @@ -235,7 +237,7 @@ static void unref_ft_face(FT_Face face) { /////////////////////////////////////////////////////////////////////////// SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) - : SkScalerContext(desc), fFTSize(NULL) { + : SkScalerContext(desc) { SkAutoMutexAcquire ac(gFTMutex); FT_Error err; @@ -248,8 +250,13 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) ++gFTCount; // load the font file + fFTSize = NULL; + fFace = NULL; fFaceRec = ref_ft_face(fRec.fFontID); - fFace = fFaceRec ? fFaceRec->fFace : NULL; + if (NULL == fFaceRec) { + return; + } + fFace = fFaceRec->fFace; // compute our factors from the record @@ -308,13 +315,13 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) render_flags = FT_LOAD_TARGET_LIGHT; break; case kNormal_Hints: - // Uncommenting the following line disables the font's hinting - // tables. For test_shell we want font hinting on so that we can - // generate baselines that look at little like Firefox. It's - // expected that Mike Reed will rework this code sometime soon so - // we don't wish to make more extensive changes. - //flags |= FT_LOAD_FORCE_AUTOHINT; #ifdef ANDROID + // The following line disables the font's hinting tables. For + // Chromium we want font hinting on so that we can generate + // baselines that look at little like Firefox. It's expected that + // Mike Reed will rework this code sometime soon so we don't wish + // to make more extensive changes. + flags |= FT_LOAD_FORCE_AUTOHINT; /* Switch to light hinting (vertical only) to address some chars that behaved poorly with NORMAL. In the future we could consider making this choice exposed at runtime to the caller. @@ -425,17 +432,6 @@ static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) { } } -static void set_glyph_metrics_on_error(SkGlyph* glyph) { - glyph->fRsbDelta = 0; - glyph->fLsbDelta = 0; - glyph->fWidth = 0; - glyph->fHeight = 0; - glyph->fTop = 0; - glyph->fLeft = 0; - glyph->fAdvanceX = 0; - glyph->fAdvanceY = 0; -} - void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) { #ifdef FT_ADVANCES_H /* unhinted and light hinted text have linearly scaled advances @@ -445,7 +441,7 @@ void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) { SkAutoMutexAcquire ac(gFTMutex); if (this->setupSize()) { - set_glyph_metrics_on_error(glyph); + glyph->zeroMetrics(); return; } @@ -486,7 +482,7 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n", fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, err)); ERROR: - set_glyph_metrics_on_error(glyph); + glyph->zeroMetrics(); return; } @@ -633,7 +629,7 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { #define ft2sk(x) SkFixedToScalar((x) << 10) -#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 3 +#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 2 #define CONST_PARAM const #else // older freetype doesn't use const here #define CONST_PARAM @@ -867,7 +863,12 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, //////////////////////////////////////////////////////////////////////// SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) { - return SkNEW_ARGS(SkScalerContext_FreeType, (desc)); + SkScalerContext_FreeType* c = SkNEW_ARGS(SkScalerContext_FreeType, (desc)); + if (!c->success()) { + SkDELETE(c); + c = NULL; + } + return c; } /////////////////////////////////////////////////////////////////////////////// diff --git a/skia/sgl/SkScalerContext.cpp b/skia/sgl/SkScalerContext.cpp index 854c4de..0129dea 100644 --- a/skia/sgl/SkScalerContext.cpp +++ b/skia/sgl/SkScalerContext.cpp @@ -52,6 +52,17 @@ size_t SkGlyph::computeImageSize() const { return size; } +void SkGlyph::zeroMetrics() { + fAdvanceX = 0; + fAdvanceY = 0; + fWidth = 0; + fHeight = 0; + fTop = 0; + fLeft = 0; + fRsbDelta = 0; + fLsbDelta = 0; +} + #ifdef SK_DEBUG #define DUMP_RECx #endif |