OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkPaint.h" | 8 #include "SkPaint.h" |
9 #include "SkAutoKern.h" | 9 #include "SkAutoKern.h" |
10 #include "SkChecksum.h" | 10 #include "SkChecksum.h" |
11 #include "SkColorFilter.h" | 11 #include "SkColorFilter.h" |
12 #include "SkData.h" | 12 #include "SkData.h" |
13 #include "SkDraw.h" | 13 #include "SkDraw.h" |
14 #include "SkFontDescriptor.h" | 14 #include "SkFontDescriptor.h" |
15 #include "SkGlyphCache.h" | 15 #include "SkGlyphCache.h" |
16 #include "SkImageFilter.h" | 16 #include "SkImageFilter.h" |
17 #include "SkMaskFilter.h" | 17 #include "SkMaskFilter.h" |
18 #include "SkMaskGamma.h" | 18 #include "SkMaskGamma.h" |
19 #include "SkMutex.h" | 19 #include "SkMutex.h" |
20 #include "SkReadBuffer.h" | 20 #include "SkReadBuffer.h" |
21 #include "SkWriteBuffer.h" | 21 #include "SkWriteBuffer.h" |
22 #include "SkPaintDefaults.h" | 22 #include "SkPaintDefaults.h" |
23 #include "SkPathEffect.h" | 23 #include "SkPathEffect.h" |
24 #include "SkRasterizer.h" | 24 #include "SkRasterizer.h" |
25 #include "SkScalar.h" | 25 #include "SkScalar.h" |
26 #include "SkScalerContext.h" | 26 #include "SkScalerContext.h" |
27 #include "SkShader.h" | 27 #include "SkShader.h" |
28 #include "SkStringUtils.h" | 28 #include "SkStringUtils.h" |
29 #include "SkStroke.h" | 29 #include "SkStroke.h" |
| 30 #include "SkStrokeRec.h" |
| 31 #include "SkSurfacePriv.h" |
| 32 #include "SkTextBlob.h" |
| 33 #include "SkTextBlobRunIterator.h" |
30 #include "SkTextFormatParams.h" | 34 #include "SkTextFormatParams.h" |
31 #include "SkTextToPathIter.h" | 35 #include "SkTextToPathIter.h" |
32 #include "SkTLazy.h" | 36 #include "SkTLazy.h" |
33 #include "SkTypeface.h" | 37 #include "SkTypeface.h" |
34 #include "SkStrokeRec.h" | |
35 #include "SkSurfacePriv.h" | |
36 #include "SkXfermode.h" | 38 #include "SkXfermode.h" |
37 | 39 |
38 static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) { | 40 static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) { |
39 return cond ? bits | mask : bits & ~mask; | 41 return cond ? bits | mask : bits & ~mask; |
40 } | 42 } |
41 | 43 |
42 // define this to get a printf for out-of-range parameter in setters | 44 // define this to get a printf for out-of-range parameter in setters |
43 // e.g. setTextSize(-1) | 45 // e.g. setTextSize(-1) |
44 //#define SK_REPORT_API_RANGE_CHECK | 46 //#define SK_REPORT_API_RANGE_CHECK |
45 | 47 |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 const SkPath* iterPath; | 1122 const SkPath* iterPath; |
1121 while (iter.next(&iterPath, &xpos)) { | 1123 while (iter.next(&iterPath, &xpos)) { |
1122 matrix.postTranslate(xpos - prevXPos, 0); | 1124 matrix.postTranslate(xpos - prevXPos, 0); |
1123 if (iterPath) { | 1125 if (iterPath) { |
1124 path->addPath(*iterPath, matrix); | 1126 path->addPath(*iterPath, matrix); |
1125 } | 1127 } |
1126 prevXPos = xpos; | 1128 prevXPos = xpos; |
1127 } | 1129 } |
1128 } | 1130 } |
1129 | 1131 |
1130 int SkPaint::getTextIntercepts(const void* textData, size_t length, | |
1131 SkScalar x, SkScalar y, const SkScalar bounds[2], | |
1132 SkScalar* array) const { | |
1133 SkASSERT(length == 0 || textData != nullptr); | |
1134 if (!length) { | |
1135 return 0; | |
1136 } | |
1137 | |
1138 const char* text = (const char*) textData; | |
1139 SkTextInterceptsIter iter(text, length, *this, bounds, x, y, | |
1140 SkTextInterceptsIter::TextType::kText); | |
1141 int count = 0; | |
1142 while (iter.next(array, &count)) { | |
1143 } | |
1144 return count; | |
1145 } | |
1146 | |
1147 void SkPaint::getPosTextPath(const void* textData, size_t length, | 1132 void SkPaint::getPosTextPath(const void* textData, size_t length, |
1148 const SkPoint pos[], SkPath* path) const { | 1133 const SkPoint pos[], SkPath* path) const { |
1149 SkASSERT(length == 0 || textData != nullptr); | 1134 SkASSERT(length == 0 || textData != nullptr); |
1150 | 1135 |
1151 const char* text = (const char*)textData; | 1136 const char* text = (const char*)textData; |
1152 if (text == nullptr || length == 0 || path == nullptr) { | 1137 if (text == nullptr || length == 0 || path == nullptr) { |
1153 return; | 1138 return; |
1154 } | 1139 } |
1155 | 1140 |
1156 SkTextToPathIter iter(text, length, *this, false); | 1141 SkTextToPathIter iter(text, length, *this, false); |
1157 SkMatrix matrix; | 1142 SkMatrix matrix; |
1158 SkPoint prevPos; | 1143 SkPoint prevPos; |
1159 prevPos.set(0, 0); | 1144 prevPos.set(0, 0); |
1160 | 1145 |
1161 matrix.setScale(iter.getPathScale(), iter.getPathScale()); | 1146 matrix.setScale(iter.getPathScale(), iter.getPathScale()); |
1162 path->reset(); | 1147 path->reset(); |
1163 | 1148 |
1164 unsigned int i = 0; | 1149 unsigned int i = 0; |
1165 const SkPath* iterPath; | 1150 const SkPath* iterPath; |
1166 while (iter.next(&iterPath, nullptr)) { | 1151 while (iter.next(&iterPath, nullptr)) { |
1167 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); | 1152 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); |
1168 if (iterPath) { | 1153 if (iterPath) { |
1169 path->addPath(*iterPath, matrix); | 1154 path->addPath(*iterPath, matrix); |
1170 } | 1155 } |
1171 prevPos = pos[i]; | 1156 prevPos = pos[i]; |
1172 i++; | 1157 i++; |
1173 } | 1158 } |
1174 } | 1159 } |
1175 | 1160 |
| 1161 template <SkTextInterceptsIter::TextType TextType, typename Func> |
| 1162 int GetTextIntercepts(const SkPaint& paint, const void* text, size_t length, |
| 1163 const SkScalar bounds[2], SkScalar* array, Func posMaker)
{ |
| 1164 SkASSERT(length == 0 || text != nullptr); |
| 1165 if (!length) { |
| 1166 return 0; |
| 1167 } |
| 1168 |
| 1169 const SkPoint pos0 = posMaker(0); |
| 1170 SkTextInterceptsIter iter(static_cast<const char*>(text), length, paint, bou
nds, |
| 1171 pos0.x(), pos0.y(), TextType); |
| 1172 |
| 1173 int i = 0; |
| 1174 int count = 0; |
| 1175 while (iter.next(array, &count)) { |
| 1176 if (TextType == SkTextInterceptsIter::TextType::kPosText) { |
| 1177 const SkPoint pos = posMaker(++i); |
| 1178 iter.setPosition(pos.x(), pos.y()); |
| 1179 } |
| 1180 } |
| 1181 |
| 1182 return count; |
| 1183 } |
| 1184 |
| 1185 int SkPaint::getTextIntercepts(const void* textData, size_t length, |
| 1186 SkScalar x, SkScalar y, const SkScalar bounds[2], |
| 1187 SkScalar* array) const { |
| 1188 |
| 1189 return GetTextIntercepts<SkTextInterceptsIter::TextType::kText>( |
| 1190 *this, textData, length, bounds, array, [&x, &y] (int) -> SkPoint { |
| 1191 return SkPoint::Make(x, y); |
| 1192 }); |
| 1193 } |
| 1194 |
1176 int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkP
oint pos[], | 1195 int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkP
oint pos[], |
1177 const SkScalar bounds[2], SkScalar* array) con
st { | 1196 const SkScalar bounds[2], SkScalar* array) con
st { |
1178 SkASSERT(length == 0 || textData != nullptr); | 1197 |
1179 if (!length) { | 1198 return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>( |
1180 return 0; | 1199 *this, textData, length, bounds, array, [&pos] (int i) -> SkPoint { |
| 1200 return pos[i]; |
| 1201 }); |
| 1202 } |
| 1203 |
| 1204 int SkPaint::getPosTextHIntercepts(const void* textData, size_t length, const Sk
Scalar xpos[], |
| 1205 SkScalar constY, const SkScalar bounds[2], |
| 1206 SkScalar* array) const { |
| 1207 |
| 1208 return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>( |
| 1209 *this, textData, length, bounds, array, [&xpos, &constY] (int i) -> SkPo
int { |
| 1210 return SkPoint::Make(xpos[i], constY); |
| 1211 }); |
| 1212 } |
| 1213 |
| 1214 int SkPaint::getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds
[2], |
| 1215 SkScalar* intervals) const { |
| 1216 int count = 0; |
| 1217 SkPaint runPaint(*this); |
| 1218 |
| 1219 SkTextBlobRunIterator it(blob); |
| 1220 while (!it.done()) { |
| 1221 it.applyFontToPaint(&runPaint); |
| 1222 const size_t runByteCount = it.glyphCount() * sizeof(SkGlyphID); |
| 1223 SkScalar* runIntervals = intervals ? intervals + count : nullptr; |
| 1224 |
| 1225 switch (it.positioning()) { |
| 1226 case SkTextBlob::kDefault_Positioning: |
| 1227 count += runPaint.getTextIntercepts(it.glyphs(), runByteCount, it.of
fset().x(), |
| 1228 it.offset().y(), bounds, runInte
rvals); |
| 1229 break; |
| 1230 case SkTextBlob::kHorizontal_Positioning: |
| 1231 count += runPaint.getPosTextHIntercepts(it.glyphs(), runByteCount, i
t.pos(), |
| 1232 it.offset().y(), bounds, run
Intervals); |
| 1233 break; |
| 1234 case SkTextBlob::kFull_Positioning: |
| 1235 count += runPaint.getPosTextIntercepts(it.glyphs(), runByteCount, |
| 1236 reinterpret_cast<const SkPoin
t*>(it.pos()), |
| 1237 bounds, runIntervals); |
| 1238 break; |
| 1239 } |
| 1240 |
| 1241 it.next(); |
1181 } | 1242 } |
1182 | 1243 |
1183 const char* text = (const char*) textData; | |
1184 SkTextInterceptsIter iter(text, length, *this, bounds, pos[0].fX, pos[0].fY, | |
1185 SkTextInterceptsIter::TextType::kPosText); | |
1186 int i = 0; | |
1187 int count = 0; | |
1188 while (iter.next(array, &count)) { | |
1189 i++; | |
1190 iter.setPosition(pos[i].fX, pos[i].fY); | |
1191 } | |
1192 return count; | 1244 return count; |
1193 } | 1245 } |
1194 | 1246 |
1195 SkRect SkPaint::getFontBounds() const { | 1247 SkRect SkPaint::getFontBounds() const { |
1196 SkMatrix m; | 1248 SkMatrix m; |
1197 m.setScale(fTextSize * fTextScaleX, fTextSize); | 1249 m.setScale(fTextSize * fTextScaleX, fTextSize); |
1198 m.postSkew(fTextSkewX, 0); | 1250 m.postSkew(fTextSkewX, 0); |
1199 | 1251 |
1200 SkTypeface* typeface = this->getTypeface(); | 1252 SkTypeface* typeface = this->getTypeface(); |
1201 if (nullptr == typeface) { | 1253 if (nullptr == typeface) { |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2332 } | 2384 } |
2333 | 2385 |
2334 uint32_t SkPaint::getHash() const { | 2386 uint32_t SkPaint::getHash() const { |
2335 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2387 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
2336 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2388 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
2337 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo
f(uint32_t), | 2389 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo
f(uint32_t), |
2338 "SkPaint_notPackedTightly"); | 2390 "SkPaint_notPackedTightly"); |
2339 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2391 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
2340 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2392 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
2341 } | 2393 } |
OLD | NEW |