diff options
-rw-r--r-- | include/core/SkCanvas.h | 13 | ||||
-rw-r--r-- | include/core/SkDevice.h | 3 | ||||
-rw-r--r-- | include/core/SkDraw.h | 3 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 14 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 6 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 62 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libgif.cpp | 5 | ||||
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 15 | ||||
-rw-r--r-- | src/ports/SkFontHost_android.cpp | 16 |
9 files changed, 123 insertions, 14 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index f277a6b..bfa0d10 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -577,6 +577,19 @@ public: const SkPath& path, const SkMatrix* matrix, const SkPaint& paint); + /** Draw the text on path, with each character/glyph origin specified by the pos[] + array. The origin is interpreted by the Align setting in the paint. + @param text The text to be drawn + @param byteLength The number of bytes to read from the text parameter + @param pos Array of positions, used to position each character + @param paint The paint used for the text (e.g. color, size, style) + @param path The path to draw on + @param matrix The canvas matrix + */ + void drawPosTextOnPath(const void* text, size_t byteLength, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix); + /** Draw the picture into this canvas. This method effective brackets the playback of the picture's draw calls with save/restore, so the state of this canvas will be unchanged after this call. This contrasts with diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 4d678c6..0d724ba 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -120,6 +120,9 @@ public: virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint); + virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix); virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h index 8214859..a86ef67 100644 --- a/include/core/SkDraw.h +++ b/include/core/SkDraw.h @@ -54,6 +54,9 @@ public: int scalarsPerPosition, const SkPaint& paint) const; void drawTextOnPath(const char text[], size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) const; + void drawPosTextOnPath(const char text[], size_t byteLength, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix) const; void drawVertices(SkCanvas::VertexMode mode, int count, const SkPoint vertices[], const SkPoint textures[], const SkColor colors[], SkXfermode* xmode, diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 61998ec..26e39b5 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1238,6 +1238,20 @@ void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, ITER_END } +void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix) { + + ITER_BEGIN(paint, SkDrawFilter::kText_Type) + + while (iter.next()) { + iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos, + paint, path, matrix); + } + + ITER_END +} + void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint verts[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 139174d..8ce1bd8 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -92,6 +92,12 @@ void SkDevice::drawTextOnPath(const SkDraw& draw, const void* text, draw.drawTextOnPath((const char*)text, len, path, matrix, paint); } +void SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix) { + draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix); +} + void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, int vertexCount, const SkPoint verts[], const SkPoint textures[], diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index b3ce813..fb5e045 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1870,6 +1870,68 @@ void SkDraw::drawTextOnPath(const char text[], size_t byteLength, } } +void SkDraw::drawPosTextOnPath(const char text[], size_t byteLength, + const SkPoint pos[], const SkPaint& paint, + const SkPath& path, const SkMatrix* matrix) const { + // nothing to draw + if (text == NULL || byteLength == 0 || fClip->isEmpty() || + (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { + return; + } + + SkMatrix scaledMatrix; + SkPathMeasure meas(path, false); + + SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc( + SkPaint::kForward_TextBufferDirection, true); + + // Copied (modified) from SkTextToPathIter constructor to setup paint + SkPaint tempPaint(paint); + + tempPaint.setLinearText(true); + tempPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup + + if (tempPaint.getPathEffect() == NULL && !(tempPaint.getStrokeWidth() > 0 + && tempPaint.getStyle() != SkPaint::kFill_Style)) { + tempPaint.setStyle(SkPaint::kFill_Style); + tempPaint.setPathEffect(NULL); + } + // End copied from SkTextToPathIter constructor + + // detach cache + SkGlyphCache* cache = tempPaint.detachCache(NULL); + + // Must set scale, even if 1 + SkScalar scale = SK_Scalar1; + scaledMatrix.setScale(scale, scale); + + // Loop over all glyph ids + for (const char* stop = text + byteLength; text < stop; pos++) { + + const SkGlyph& glyph = glyphCacheProc(cache, &text); + SkPath tmp; + + const SkPath* glyphPath = cache->findPath(glyph); + if (glyphPath == NULL) { + continue; + } + + SkMatrix m(scaledMatrix); + m.postTranslate(pos->fX, 0); + + if (matrix) { + m.postConcat(*matrix); + } + + morphpath(&tmp, *glyphPath, meas, m); + this->drawPath(tmp, tempPaint); + + } + + // re-attach cache + SkGlyphCache::AttachCache(cache); +} + /////////////////////////////////////////////////////////////////////////////// struct VertState { diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp index d2470cc..75a9ee0 100644 --- a/src/images/SkImageDecoder_libgif.cpp +++ b/src/images/SkImageDecoder_libgif.cpp @@ -117,6 +117,11 @@ static const ColorMapObject* find_colormap(const GifFileType* gif) { if (NULL == cmap) { cmap = gif->SColorMap; } + + if (NULL == cmap) { + // no colormap found + return NULL; + } // some sanity checks if (cmap && ((unsigned)cmap->ColorCount > 256 || cmap->ColorCount != (1 << cmap->BitsPerPixel))) { diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index d734b8e..77c3797 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -976,11 +976,11 @@ SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) { /* Export this so that other parts of our FonttHost port can make use of our ability to extract the name+style from a stream, using FreeType's api. */ -SkTypeface::Style find_name_and_style(SkStream* stream, SkString* name) { +bool find_name_and_style(SkStream* stream, SkString* name, SkTypeface::Style* style) { FT_Library library; if (FT_Init_FreeType(&library)) { name->set(NULL); - return SkTypeface::kNormal; + return false; } FT_Open_Args args; @@ -1008,20 +1008,21 @@ SkTypeface::Style find_name_and_style(SkStream* stream, SkString* name) { if (FT_Open_Face(library, &args, 0, &face)) { FT_Done_FreeType(library); name->set(NULL); - return SkTypeface::kNormal; + return false; } name->set(face->family_name); - int style = SkTypeface::kNormal; + int tempStyle = SkTypeface::kNormal; if (face->style_flags & FT_STYLE_FLAG_BOLD) { - style |= SkTypeface::kBold; + tempStyle |= SkTypeface::kBold; } if (face->style_flags & FT_STYLE_FLAG_ITALIC) { - style |= SkTypeface::kItalic; + tempStyle |= SkTypeface::kItalic; } + *style = (SkTypeface::Style)tempStyle; FT_Done_Face(face); FT_Done_FreeType(library); - return (SkTypeface::Style)style; + return true; } diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp index f50e359..2550f9b 100644 --- a/src/ports/SkFontHost_android.cpp +++ b/src/ports/SkFontHost_android.cpp @@ -31,7 +31,7 @@ #define SK_FONT_FILE_PREFIX "/fonts/" #endif -SkTypeface::Style find_name_and_style(SkStream* stream, SkString* name); +bool find_name_and_style(SkStream* stream, SkString* name, SkTypeface::Style* style); static void GetFullPathForSysFonts(SkString* full, const char name[]) { full->set(getenv("ANDROID_ROOT")); @@ -363,14 +363,12 @@ static bool get_name_and_style(const char path[], SkString* name, SkMMAPStream stream(fullpath.c_str()); if (stream.getLength() > 0) { - *style = find_name_and_style(&stream, name); - return true; + return find_name_and_style(&stream, name, style); } else { SkFILEStream stream(fullpath.c_str()); if (stream.getLength() > 0) { - *style = find_name_and_style(&stream, name); - return true; + return find_name_and_style(&stream, name, style); } } @@ -646,9 +644,13 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { } SkString name; - SkTypeface::Style style = find_name_and_style(stream, &name); + SkTypeface::Style style; - return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream)); + if (find_name_and_style(stream, &name, &style)) { + return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream)); + } else { + return NULL; + } } SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { |