aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/core/SkCanvas.h13
-rw-r--r--include/core/SkDevice.h3
-rw-r--r--include/core/SkDraw.h3
-rw-r--r--src/core/SkCanvas.cpp14
-rw-r--r--src/core/SkDevice.cpp6
-rw-r--r--src/core/SkDraw.cpp62
-rw-r--r--src/images/SkImageDecoder_libgif.cpp5
-rw-r--r--src/ports/SkFontHost_FreeType.cpp15
-rw-r--r--src/ports/SkFontHost_android.cpp16
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[]) {