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 "SkAnnotation.h" | 9 #include "SkAnnotation.h" |
10 #include "SkAutoKern.h" | 10 #include "SkAutoKern.h" |
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 const SkPath* iterPath; | 1192 const SkPath* iterPath; |
1193 while (iter.next(&iterPath, &xpos)) { | 1193 while (iter.next(&iterPath, &xpos)) { |
1194 matrix.postTranslate(xpos - prevXPos, 0); | 1194 matrix.postTranslate(xpos - prevXPos, 0); |
1195 if (iterPath) { | 1195 if (iterPath) { |
1196 path->addPath(*iterPath, matrix); | 1196 path->addPath(*iterPath, matrix); |
1197 } | 1197 } |
1198 prevXPos = xpos; | 1198 prevXPos = xpos; |
1199 } | 1199 } |
1200 } | 1200 } |
1201 | 1201 |
| 1202 int SkPaint::getTextIntercepts(const void* textData, size_t length, |
| 1203 SkScalar x, SkScalar y, const SkScalar bounds[2],
|
| 1204 SkScalar* array) const { |
| 1205 SkASSERT(length == 0 || textData != nullptr); |
| 1206 if (!length) { |
| 1207 return 0; |
| 1208 } |
| 1209 |
| 1210 const char* text = (const char*) textData; |
| 1211 SkTextInterceptsIter iter(text, length, *this, bounds, x, y, |
| 1212 SkTextInterceptsIter::TextType::kText); |
| 1213 int count = 0; |
| 1214 while (iter.next(array, &count)) { |
| 1215 } |
| 1216 return count; |
| 1217 } |
| 1218 |
1202 void SkPaint::getPosTextPath(const void* textData, size_t length, | 1219 void SkPaint::getPosTextPath(const void* textData, size_t length, |
1203 const SkPoint pos[], SkPath* path) const { | 1220 const SkPoint pos[], SkPath* path) const { |
1204 SkASSERT(length == 0 || textData != nullptr); | 1221 SkASSERT(length == 0 || textData != nullptr); |
1205 | 1222 |
1206 const char* text = (const char*)textData; | 1223 const char* text = (const char*)textData; |
1207 if (text == nullptr || length == 0 || path == nullptr) { | 1224 if (text == nullptr || length == 0 || path == nullptr) { |
1208 return; | 1225 return; |
1209 } | 1226 } |
1210 | 1227 |
1211 SkTextToPathIter iter(text, length, *this, false); | 1228 SkTextToPathIter iter(text, length, *this, false); |
1212 SkMatrix matrix; | 1229 SkMatrix matrix; |
1213 SkPoint prevPos; | 1230 SkPoint prevPos; |
1214 prevPos.set(0, 0); | 1231 prevPos.set(0, 0); |
1215 | 1232 |
1216 matrix.setScale(iter.getPathScale(), iter.getPathScale()); | 1233 matrix.setScale(iter.getPathScale(), iter.getPathScale()); |
1217 path->reset(); | 1234 path->reset(); |
1218 | 1235 |
1219 unsigned int i = 0; | 1236 unsigned int i = 0; |
1220 const SkPath* iterPath; | 1237 const SkPath* iterPath; |
1221 while (iter.next(&iterPath, nullptr)) { | 1238 while (iter.next(&iterPath, nullptr)) { |
1222 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); | 1239 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); |
1223 if (iterPath) { | 1240 if (iterPath) { |
1224 path->addPath(*iterPath, matrix); | 1241 path->addPath(*iterPath, matrix); |
1225 } | 1242 } |
1226 prevPos = pos[i]; | 1243 prevPos = pos[i]; |
1227 i++; | 1244 i++; |
1228 } | 1245 } |
1229 } | 1246 } |
1230 | 1247 |
| 1248 int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkP
oint pos[], |
| 1249 const SkScalar bounds[2], SkScalar* array) con
st { |
| 1250 SkASSERT(length == 0 || textData != nullptr); |
| 1251 if (!length) { |
| 1252 return 0; |
| 1253 } |
| 1254 |
| 1255 const char* text = (const char*) textData; |
| 1256 SkTextInterceptsIter iter(text, length, *this, bounds, pos[0].fX, pos[0].fY, |
| 1257 SkTextInterceptsIter::TextType::kPosText); |
| 1258 int i = 0; |
| 1259 int count = 0; |
| 1260 while (iter.next(array, &count)) { |
| 1261 i++; |
| 1262 iter.setPosition(pos[i].fX, pos[i].fY); |
| 1263 } |
| 1264 return count; |
| 1265 } |
| 1266 |
1231 SkRect SkPaint::getFontBounds() const { | 1267 SkRect SkPaint::getFontBounds() const { |
1232 SkMatrix m; | 1268 SkMatrix m; |
1233 m.setScale(fTextSize * fTextScaleX, fTextSize); | 1269 m.setScale(fTextSize * fTextScaleX, fTextSize); |
1234 m.postSkew(fTextSkewX, 0); | 1270 m.postSkew(fTextSkewX, 0); |
1235 | 1271 |
1236 SkTypeface* typeface = this->getTypeface(); | 1272 SkTypeface* typeface = this->getTypeface(); |
1237 if (nullptr == typeface) { | 1273 if (nullptr == typeface) { |
1238 typeface = SkTypeface::GetDefaultTypeface(); | 1274 typeface = SkTypeface::GetDefaultTypeface(); |
1239 } | 1275 } |
1240 | 1276 |
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 } | 2321 } |
2286 #endif | 2322 #endif |
2287 | 2323 |
2288 /////////////////////////////////////////////////////////////////////////////// | 2324 /////////////////////////////////////////////////////////////////////////////// |
2289 | 2325 |
2290 static bool has_thick_frame(const SkPaint& paint) { | 2326 static bool has_thick_frame(const SkPaint& paint) { |
2291 return paint.getStrokeWidth() > 0 && | 2327 return paint.getStrokeWidth() > 0 && |
2292 paint.getStyle() != SkPaint::kFill_Style; | 2328 paint.getStyle() != SkPaint::kFill_Style; |
2293 } | 2329 } |
2294 | 2330 |
2295 SkTextToPathIter::SkTextToPathIter(const char text[], size_t length, | 2331 SkTextBaseIter::SkTextBaseIter(const char text[], size_t length, |
2296 const SkPaint& paint, | 2332 const SkPaint& paint, |
2297 bool applyStrokeAndPathEffects) | 2333 bool applyStrokeAndPathEffects) |
2298 : fPaint(paint) { | 2334 : fPaint(paint) { |
2299 fGlyphCacheProc = paint.getMeasureCacheProc(true); | 2335 fGlyphCacheProc = paint.getMeasureCacheProc(true); |
2300 | 2336 |
2301 fPaint.setLinearText(true); | 2337 fPaint.setLinearText(true); |
2302 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup | 2338 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup |
2303 | 2339 |
2304 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { | 2340 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { |
2305 applyStrokeAndPathEffects = false; | 2341 applyStrokeAndPathEffects = false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 } | 2384 } |
2349 fXPos = xOffset; | 2385 fXPos = xOffset; |
2350 fPrevAdvance = 0; | 2386 fPrevAdvance = 0; |
2351 | 2387 |
2352 fText = text; | 2388 fText = text; |
2353 fStop = text + length; | 2389 fStop = text + length; |
2354 | 2390 |
2355 fXYIndex = paint.isVerticalText() ? 1 : 0; | 2391 fXYIndex = paint.isVerticalText() ? 1 : 0; |
2356 } | 2392 } |
2357 | 2393 |
2358 SkTextToPathIter::~SkTextToPathIter() { | 2394 SkTextBaseIter::~SkTextBaseIter() { |
2359 SkGlyphCache::AttachCache(fCache); | 2395 SkGlyphCache::AttachCache(fCache); |
2360 } | 2396 } |
2361 | 2397 |
2362 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { | 2398 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { |
2363 if (fText < fStop) { | 2399 if (fText < fStop) { |
2364 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); | 2400 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); |
2365 | 2401 |
2366 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(gly
ph)), fScale); | 2402 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(gly
ph)), fScale); |
2367 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking()
; | 2403 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking()
; |
2368 | 2404 |
2369 if (glyph.fWidth) { | 2405 if (glyph.fWidth) { |
2370 if (path) { | 2406 if (path) { |
2371 *path = fCache->findPath(glyph); | 2407 *path = fCache->findPath(glyph); |
2372 } | 2408 } |
2373 } else { | 2409 } else { |
2374 if (path) { | 2410 if (path) { |
2375 *path = nullptr; | 2411 *path = nullptr; |
2376 } | 2412 } |
2377 } | 2413 } |
2378 if (xpos) { | 2414 if (xpos) { |
2379 *xpos = fXPos; | 2415 *xpos = fXPos; |
2380 } | 2416 } |
2381 return true; | 2417 return true; |
2382 } | 2418 } |
2383 return false; | 2419 return false; |
2384 } | 2420 } |
2385 | 2421 |
| 2422 bool SkTextInterceptsIter::next(SkScalar* array, int* count) { |
| 2423 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); |
| 2424 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph))
, fScale); |
| 2425 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); |
| 2426 if (fCache->findPath(glyph)) { |
| 2427 fCache->findIntercepts(fBounds, fScale, fXPos, SkToBool(fXYIndex), |
| 2428 const_cast<SkGlyph*>(&glyph), array, count); |
| 2429 } |
| 2430 return fText < fStop; |
| 2431 } |
| 2432 |
2386 /////////////////////////////////////////////////////////////////////////////// | 2433 /////////////////////////////////////////////////////////////////////////////// |
2387 | 2434 |
2388 // return true if the filter exists, and may affect alpha | 2435 // return true if the filter exists, and may affect alpha |
2389 static bool affects_alpha(const SkColorFilter* cf) { | 2436 static bool affects_alpha(const SkColorFilter* cf) { |
2390 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); | 2437 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); |
2391 } | 2438 } |
2392 | 2439 |
2393 // return true if the filter exists, and may affect alpha | 2440 // return true if the filter exists, and may affect alpha |
2394 static bool affects_alpha(const SkImageFilter* imf) { | 2441 static bool affects_alpha(const SkImageFilter* imf) { |
2395 // TODO: check if we should allow imagefilters to broadcast that they don't
affect alpha | 2442 // TODO: check if we should allow imagefilters to broadcast that they don't
affect alpha |
(...skipping 27 matching lines...) Expand all Loading... |
2423 } | 2470 } |
2424 | 2471 |
2425 uint32_t SkPaint::getHash() const { | 2472 uint32_t SkPaint::getHash() const { |
2426 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2473 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
2427 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2474 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
2428 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), | 2475 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), |
2429 "SkPaint_notPackedTightly"); | 2476 "SkPaint_notPackedTightly"); |
2430 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2477 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
2431 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2478 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
2432 } | 2479 } |
OLD | NEW |