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