1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# HG changeset patch
# User Nicholas Cameron <ncameron@mozilla.com>
# Date 1337146927 -43200
# Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821
# Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8
Bug 746883; changes to the Skia library. r=gw280
diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h
--- a/gfx/skia/include/core/SkDraw.h
+++ b/gfx/skia/include/core/SkDraw.h
@@ -125,23 +125,24 @@ public:
#endif
};
class SkGlyphCache;
class SkTextToPathIter {
public:
SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
- bool applyStrokeAndPathEffects);
+ bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true);
~SkTextToPathIter();
const SkPaint& getPaint() const { return fPaint; }
SkScalar getPathScale() const { return fScale; }
const SkPath* next(SkScalar* xpos); //!< returns nil when there are no more paths
+ bool nextWithWhitespace(const SkPath** path, SkScalar* xpos); //!< returns false when there are no more paths
private:
SkGlyphCache* fCache;
SkPaint fPaint;
SkScalar fScale;
SkFixed fPrevAdvance;
const char* fText;
const char* fStop;
diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
--- a/gfx/skia/src/core/SkPaint.cpp
+++ b/gfx/skia/src/core/SkPaint.cpp
@@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void*
const SkPoint pos[], SkPath* path) const {
SkASSERT(length == 0 || textData != NULL);
const char* text = (const char*)textData;
if (text == NULL || length == 0 || path == NULL) {
return;
}
- SkTextToPathIter iter(text, length, *this, false);
+ SkTextToPathIter iter(text, length, *this, false, false);
SkMatrix matrix;
SkPoint prevPos;
prevPos.set(0, 0);
matrix.setScale(iter.getPathScale(), iter.getPathScale());
path->reset();
unsigned int i = 0;
const SkPath* iterPath;
- while ((iterPath = iter.next(NULL)) != NULL) {
- matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
- path->addPath(*iterPath, matrix);
- prevPos = pos[i];
+ while (iter.nextWithWhitespace(&iterPath, NULL)) {
+ if (iterPath) {
+ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
+ path->addPath(*iterPath, matrix);
+ prevPos = pos[i];
+ }
i++;
}
}
static void add_flattenable(SkDescriptor* desc, uint32_t tag,
SkFlattenableWriteBuffer* buffer) {
buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
}
@@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun
static bool has_thick_frame(const SkPaint& paint) {
return paint.getStrokeWidth() > 0 &&
paint.getStyle() != SkPaint::kFill_Style;
}
SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
const SkPaint& paint,
- bool applyStrokeAndPathEffects)
+ bool applyStrokeAndPathEffects,
+ bool useCanonicalTextSize)
: fPaint(paint) {
fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
true);
fPaint.setLinearText(true);
fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup
if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
applyStrokeAndPathEffects = false;
}
// can't use our canonical size if we need to apply patheffects
- if (fPaint.getPathEffect() == NULL) {
+ if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) {
fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
if (has_thick_frame(fPaint)) {
fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
}
} else {
fScale = SK_Scalar1;
}
@@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons
fXYIndex = paint.isVerticalText() ? 1 : 0;
}
SkTextToPathIter::~SkTextToPathIter() {
SkGlyphCache::AttachCache(fCache);
}
const SkPath* SkTextToPathIter::next(SkScalar* xpos) {
- while (fText < fStop) {
+ const SkPath* result;
+ while (nextWithWhitespace(&result, xpos)) {
+ if (result) {
+ if (xpos) {
+ *xpos = fXPos;
+ }
+ return result;
+ }
+ }
+ return NULL;
+}
+
+bool SkTextToPathIter::nextWithWhitespace(const SkPath** path, SkScalar* xpos) {
+ if (fText < fStop) {
const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking();
if (glyph.fWidth) {
if (xpos) {
*xpos = fXPos;
}
- return fCache->findPath(glyph);
+ *path = fCache->findPath(glyph);
+ return true;
+ } else {
+ *path = NULL;
+ return true;
}
}
- return NULL;
+ return false;
}
///////////////////////////////////////////////////////////////////////////////
bool SkPaint::nothingToDraw() const {
if (fLooper) {
return false;
}
|