diff options
author | Mike Reed <reed@google.com> | 2010-01-04 15:22:59 -0500 |
---|---|---|
committer | Mike Reed <reed@google.com> | 2010-01-04 15:22:59 -0500 |
commit | 091f227385b467090b5a7169a8e2faf19eca7105 (patch) | |
tree | 5c682bba51c39912b4bacf131cf0dc3f5be97e26 | |
parent | 2c497e64d20a73267eb92ae88fdc51ba2a356b55 (diff) | |
download | external_skia-091f227385b467090b5a7169a8e2faf19eca7105.zip external_skia-091f227385b467090b5a7169a8e2faf19eca7105.tar.gz external_skia-091f227385b467090b5a7169a8e2faf19eca7105.tar.bz2 |
add inverse of textToGlyphs(), so we can extract the original text from the browser
display for copy/paste, given that webkit renders it using glyph codes (and we need
unichars).
hange 36311 in external/webkit is dependent on this.
Fixes http://b/2166748
-rw-r--r-- | include/core/SkBounder.h | 13 | ||||
-rw-r--r-- | include/core/SkMath.h | 2 | ||||
-rw-r--r-- | include/core/SkPaint.h | 7 | ||||
-rw-r--r-- | include/core/SkScalerContext.h | 7 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 7 | ||||
-rw-r--r-- | src/core/SkGlyphCache.cpp | 4 | ||||
-rw-r--r-- | src/core/SkGlyphCache.h | 5 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 17 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 19 | ||||
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 16 |
10 files changed, 93 insertions, 4 deletions
diff --git a/include/core/SkBounder.h b/include/core/SkBounder.h index f20961d..00fbbc6 100644 --- a/include/core/SkBounder.h +++ b/include/core/SkBounder.h @@ -38,7 +38,7 @@ public: Returns the result from onIRect. */ bool doIRect(const SkIRect&); - + bool doIRect(const SkIRect& , uint16_t glyphID); protected: /** Override in your subclass. This is called with the device bounds of an object (text, geometry, image) just before it is drawn. If your method @@ -46,7 +46,16 @@ protected: returns true, drawing continues. The bounds your method receives have already been transformed in to device coordinates, and clipped to the current clip. */ - virtual bool onIRect(const SkIRect&) = 0; + virtual bool onIRect(const SkIRect&) { + return false; + } + + /** Optionally, override in your subclass to receive the glyph ID when + text drawing supplies the device bounds of the object. + */ + virtual bool onIRect(const SkIRect& r, uint16_t glyphID) { + return onIRect(r); + } /** Called after each shape has been drawn. The default implementation does nothing, but your override could use this notification to signal itself diff --git a/include/core/SkMath.h b/include/core/SkMath.h index cf79e53..3f3c660 100644 --- a/include/core/SkMath.h +++ b/include/core/SkMath.h @@ -164,7 +164,7 @@ static inline int SkNextLog2(uint32_t value) { */ #if defined(__arm__) \ && !defined(__thumb__) \ - && !defined(__ARM_ARCH_4__) \ + && !defined(__ARM_ARCH_4T__) \ && !defined(__ARM_ARCH_5T__) static inline int32_t SkMulS16(S16CPU x, S16CPU y) { SkASSERT((int16_t)x == x); diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 659d875..01b0811 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -696,6 +696,13 @@ public: int textToGlyphs(const void* text, size_t byteLength, uint16_t glyphs[]) const; + /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped + to zero. Note: this does not look at the text-encoding setting in the + paint, only at the typeface. + */ + void glyphsToUnichars(const uint16_t glyphs[], int count, + SkUnichar text[]) const; + /** Return the number of drawable units in the specified text buffer. This looks at the current TextEncoding field of the paint. If you also want to have the text converted into glyph IDs, call textToGlyphs diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index 29c28f7..83bd0e7 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -206,6 +206,11 @@ public: */ uint16_t charToGlyphID(SkUnichar uni); + /** Map the glyphID to its glyph index, and then to its char code. Unmapped + glyphs return zero. + */ + SkUnichar glyphIDToChar(uint16_t glyphID); + unsigned getGlyphCount() const { return this->generateGlyphCount(); } void getAdvance(SkGlyph*); void getMetrics(SkGlyph*); @@ -229,6 +234,8 @@ protected: virtual void generatePath(const SkGlyph&, SkPath*) = 0; virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY) = 0; + // default impl returns 0, indicating failure. + virtual SkUnichar generateGlyphToChar(uint16_t); private: SkPathEffect* fPathEffect; diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 4f28cfe..78c282e 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1366,7 +1366,7 @@ static void D1G_Bounder(const SkDraw1Glyph& state, } } - if (state.fBounder->doIRect(cr)) { + if (state.fBounder->doIRect(cr, glyph.getGlyphID())) { mask.fRowBytes = glyph.rowBytes(); mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); mask.fImage = (uint8_t*)aa; @@ -2244,6 +2244,11 @@ bool SkBounder::doIRect(const SkIRect& r) { return rr.intersect(fClip->getBounds(), r) && this->onIRect(rr); } +bool SkBounder::doIRect(const SkIRect& r, uint16_t glyphID) { + SkIRect rr; + return rr.intersect(fClip->getBounds(), r) && this->onIRect(rr, glyphID); +} + bool SkBounder::doHairline(const SkPoint& pt0, const SkPoint& pt1, const SkPaint& paint) { SkIRect r; diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index 6b214df..cfd355c 100644 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -128,6 +128,10 @@ uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { } } +SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { + return fScalerContext->glyphIDToChar(glyphID); +} + /////////////////////////////////////////////////////////////////////////////// const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 2462ea5..cc81ed6 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -72,6 +72,11 @@ public: */ uint16_t unicharToGlyph(SkUnichar); + /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to + a character code of zero. + */ + SkUnichar glyphToUnichar(uint16_t); + /** Return the image associated with the glyph. If it has not been generated this will trigger that. */ diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 2432ee3..69baba5 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -376,6 +376,23 @@ int SkPaint::textToGlyphs(const void* textData, size_t byteLength, return gptr - glyphs; } +void SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, + SkUnichar textData[]) const { + if (count <= 0) { + return; + } + + SkASSERT(glyphs != NULL); + SkASSERT(textData != NULL); + + SkAutoGlyphCache autoCache(*this, NULL); + SkGlyphCache* cache = autoCache.getCache(); + + for (int index = 0; index < count; index++) { + textData[index] = cache->glyphToUnichar(glyphs[index]); + } +} + /////////////////////////////////////////////////////////////////////////////// static const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, const char** text) diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index b9cd3ac..b149be9 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -264,6 +264,21 @@ uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) { return SkToU16(glyphID); } +SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) { + SkScalerContext* ctx = this; + unsigned rangeEnd = 0; + do { + unsigned rangeStart = rangeEnd; + + rangeEnd += ctx->getGlyphCount(); + if (rangeStart <= glyphID && glyphID < rangeEnd) { + return ctx->generateGlyphToChar(glyphID - rangeStart); + } + ctx = ctx->getNextContext(); + } while (NULL != ctx); + return 0; +} + void SkScalerContext::getAdvance(SkGlyph* glyph) { // mark us as just having a valid advance glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; @@ -508,6 +523,10 @@ void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetr this->generateFontMetrics(mx, my); } +SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) { + return 0; +} + /////////////////////////////////////////////////////////////////////// void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, SkPath* devPath, SkMatrix* fillToDevMatrix) diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index c7e310e..d209086 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -115,6 +115,7 @@ protected: virtual void generatePath(const SkGlyph& glyph, SkPath* path); virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my); + virtual SkUnichar generateGlyphToChar(uint16_t glyph); private: SkFaceRec* fFaceRec; @@ -474,6 +475,21 @@ uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { return SkToU16(FT_Get_Char_Index( fFace, uni )); } +SkUnichar SkScalerContext_FreeType::generateGlyphToChar(uint16_t glyph) { + // iterate through each cmap entry, looking for matching glyph indices + FT_UInt glyphIndex; + SkUnichar charCode = FT_Get_First_Char( fFace, &glyphIndex ); + + while (glyphIndex != 0) { + if (glyphIndex == glyph) { + return charCode; + } + charCode = FT_Get_Next_Char( fFace, charCode, &glyphIndex ); + } + + return 0; +} + static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) { switch (format) { case SkMask::kHorizontalLCD_Format: |