aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Reed <reed@google.com>2010-01-04 15:22:59 -0500
committerMike Reed <reed@google.com>2010-01-04 15:22:59 -0500
commit091f227385b467090b5a7169a8e2faf19eca7105 (patch)
tree5c682bba51c39912b4bacf131cf0dc3f5be97e26
parent2c497e64d20a73267eb92ae88fdc51ba2a356b55 (diff)
downloadexternal_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.h13
-rw-r--r--include/core/SkMath.h2
-rw-r--r--include/core/SkPaint.h7
-rw-r--r--include/core/SkScalerContext.h7
-rw-r--r--src/core/SkDraw.cpp7
-rw-r--r--src/core/SkGlyphCache.cpp4
-rw-r--r--src/core/SkGlyphCache.h5
-rw-r--r--src/core/SkPaint.cpp17
-rw-r--r--src/core/SkScalerContext.cpp19
-rw-r--r--src/ports/SkFontHost_FreeType.cpp16
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: