| 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 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 const SkPath* iterPath; | 1252 const SkPath* iterPath; |
| 1253 while (iter.next(&iterPath, &xpos)) { | 1253 while (iter.next(&iterPath, &xpos)) { |
| 1254 matrix.postTranslate(xpos - prevXPos, 0); | 1254 matrix.postTranslate(xpos - prevXPos, 0); |
| 1255 if (iterPath) { | 1255 if (iterPath) { |
| 1256 path->addPath(*iterPath, matrix); | 1256 path->addPath(*iterPath, matrix); |
| 1257 } | 1257 } |
| 1258 prevXPos = xpos; | 1258 prevXPos = xpos; |
| 1259 } | 1259 } |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 int SkPaint::getTextIntercepts(const void* textData, size_t length, |
| 1263 SkScalar x, SkScalar y, const SkScalar bounds[2],
|
| 1264 SkScalar* array) const { |
| 1265 SkASSERT(length == 0 || textData != nullptr); |
| 1266 if (!length) { |
| 1267 return 0; |
| 1268 } |
| 1269 |
| 1270 const char* text = (const char*) textData; |
| 1271 SkTextInterceptsIter iter(text, length, *this, bounds, x, y, |
| 1272 SkTextInterceptsIter::TextType::kText); |
| 1273 int count = 0; |
| 1274 while (iter.next(array, &count)) { |
| 1275 } |
| 1276 return count; |
| 1277 } |
| 1278 |
| 1262 void SkPaint::getPosTextPath(const void* textData, size_t length, | 1279 void SkPaint::getPosTextPath(const void* textData, size_t length, |
| 1263 const SkPoint pos[], SkPath* path) const { | 1280 const SkPoint pos[], SkPath* path) const { |
| 1264 SkASSERT(length == 0 || textData != nullptr); | 1281 SkASSERT(length == 0 || textData != nullptr); |
| 1265 | 1282 |
| 1266 const char* text = (const char*)textData; | 1283 const char* text = (const char*)textData; |
| 1267 if (text == nullptr || length == 0 || path == nullptr) { | 1284 if (text == nullptr || length == 0 || path == nullptr) { |
| 1268 return; | 1285 return; |
| 1269 } | 1286 } |
| 1270 | 1287 |
| 1271 SkTextToPathIter iter(text, length, *this, false); | 1288 SkTextToPathIter iter(text, length, *this, false); |
| 1272 SkMatrix matrix; | 1289 SkMatrix matrix; |
| 1273 SkPoint prevPos; | 1290 SkPoint prevPos; |
| 1274 prevPos.set(0, 0); | 1291 prevPos.set(0, 0); |
| 1275 | 1292 |
| 1276 matrix.setScale(iter.getPathScale(), iter.getPathScale()); | 1293 matrix.setScale(iter.getPathScale(), iter.getPathScale()); |
| 1277 path->reset(); | 1294 path->reset(); |
| 1278 | 1295 |
| 1279 unsigned int i = 0; | 1296 unsigned int i = 0; |
| 1280 const SkPath* iterPath; | 1297 const SkPath* iterPath; |
| 1281 while (iter.next(&iterPath, nullptr)) { | 1298 while (iter.next(&iterPath, nullptr)) { |
| 1282 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); | 1299 matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); |
| 1283 if (iterPath) { | 1300 if (iterPath) { |
| 1284 path->addPath(*iterPath, matrix); | 1301 path->addPath(*iterPath, matrix); |
| 1285 } | 1302 } |
| 1286 prevPos = pos[i]; | 1303 prevPos = pos[i]; |
| 1287 i++; | 1304 i++; |
| 1288 } | 1305 } |
| 1289 } | 1306 } |
| 1290 | 1307 |
| 1308 int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkP
oint pos[], |
| 1309 const SkScalar bounds[2], SkScalar* array) con
st { |
| 1310 SkASSERT(length == 0 || textData != nullptr); |
| 1311 if (!length) { |
| 1312 return 0; |
| 1313 } |
| 1314 |
| 1315 const char* text = (const char*) textData; |
| 1316 SkTextInterceptsIter iter(text, length, *this, bounds, pos[0].fX, pos[0].fY, |
| 1317 SkTextInterceptsIter::TextType::kPosText); |
| 1318 int i = 0; |
| 1319 int count = 0; |
| 1320 while (iter.next(array, &count)) { |
| 1321 i++; |
| 1322 iter.setPosition(pos[i].fX, pos[i].fY); |
| 1323 } |
| 1324 return count; |
| 1325 } |
| 1326 |
| 1291 SkRect SkPaint::getFontBounds() const { | 1327 SkRect SkPaint::getFontBounds() const { |
| 1292 SkMatrix m; | 1328 SkMatrix m; |
| 1293 m.setScale(fTextSize * fTextScaleX, fTextSize); | 1329 m.setScale(fTextSize * fTextScaleX, fTextSize); |
| 1294 m.postSkew(fTextSkewX, 0); | 1330 m.postSkew(fTextSkewX, 0); |
| 1295 | 1331 |
| 1296 SkTypeface* typeface = this->getTypeface(); | 1332 SkTypeface* typeface = this->getTypeface(); |
| 1297 if (nullptr == typeface) { | 1333 if (nullptr == typeface) { |
| 1298 typeface = SkTypeface::GetDefaultTypeface(); | 1334 typeface = SkTypeface::GetDefaultTypeface(); |
| 1299 } | 1335 } |
| 1300 | 1336 |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 } | 2381 } |
| 2346 #endif | 2382 #endif |
| 2347 | 2383 |
| 2348 /////////////////////////////////////////////////////////////////////////////// | 2384 /////////////////////////////////////////////////////////////////////////////// |
| 2349 | 2385 |
| 2350 static bool has_thick_frame(const SkPaint& paint) { | 2386 static bool has_thick_frame(const SkPaint& paint) { |
| 2351 return paint.getStrokeWidth() > 0 && | 2387 return paint.getStrokeWidth() > 0 && |
| 2352 paint.getStyle() != SkPaint::kFill_Style; | 2388 paint.getStyle() != SkPaint::kFill_Style; |
| 2353 } | 2389 } |
| 2354 | 2390 |
| 2355 SkTextToPathIter::SkTextToPathIter(const char text[], size_t length, | 2391 SkTextBaseIter::SkTextBaseIter(const char text[], size_t length, |
| 2356 const SkPaint& paint, | 2392 const SkPaint& paint, |
| 2357 bool applyStrokeAndPathEffects) | 2393 bool applyStrokeAndPathEffects) |
| 2358 : fPaint(paint) { | 2394 : fPaint(paint) { |
| 2359 fGlyphCacheProc = paint.getMeasureCacheProc(true); | 2395 fGlyphCacheProc = paint.getMeasureCacheProc(true); |
| 2360 | 2396 |
| 2361 fPaint.setLinearText(true); | 2397 fPaint.setLinearText(true); |
| 2362 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup | 2398 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup |
| 2363 | 2399 |
| 2364 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { | 2400 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { |
| 2365 applyStrokeAndPathEffects = false; | 2401 applyStrokeAndPathEffects = false; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 } | 2444 } |
| 2409 fXPos = xOffset; | 2445 fXPos = xOffset; |
| 2410 fPrevAdvance = 0; | 2446 fPrevAdvance = 0; |
| 2411 | 2447 |
| 2412 fText = text; | 2448 fText = text; |
| 2413 fStop = text + length; | 2449 fStop = text + length; |
| 2414 | 2450 |
| 2415 fXYIndex = paint.isVerticalText() ? 1 : 0; | 2451 fXYIndex = paint.isVerticalText() ? 1 : 0; |
| 2416 } | 2452 } |
| 2417 | 2453 |
| 2418 SkTextToPathIter::~SkTextToPathIter() { | 2454 SkTextBaseIter::~SkTextBaseIter() { |
| 2419 SkGlyphCache::AttachCache(fCache); | 2455 SkGlyphCache::AttachCache(fCache); |
| 2420 } | 2456 } |
| 2421 | 2457 |
| 2422 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { | 2458 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { |
| 2423 if (fText < fStop) { | 2459 if (fText < fStop) { |
| 2424 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); | 2460 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); |
| 2425 | 2461 |
| 2426 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(gly
ph)), fScale); | 2462 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(gly
ph)), fScale); |
| 2427 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking()
; | 2463 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking()
; |
| 2428 | 2464 |
| 2429 if (glyph.fWidth) { | 2465 if (glyph.fWidth) { |
| 2430 if (path) { | 2466 if (path) { |
| 2431 *path = fCache->findPath(glyph); | 2467 *path = fCache->findPath(glyph); |
| 2432 } | 2468 } |
| 2433 } else { | 2469 } else { |
| 2434 if (path) { | 2470 if (path) { |
| 2435 *path = nullptr; | 2471 *path = nullptr; |
| 2436 } | 2472 } |
| 2437 } | 2473 } |
| 2438 if (xpos) { | 2474 if (xpos) { |
| 2439 *xpos = fXPos; | 2475 *xpos = fXPos; |
| 2440 } | 2476 } |
| 2441 return true; | 2477 return true; |
| 2442 } | 2478 } |
| 2443 return false; | 2479 return false; |
| 2444 } | 2480 } |
| 2445 | 2481 |
| 2482 bool SkTextInterceptsIter::next(SkScalar* array, int* count) { |
| 2483 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); |
| 2484 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph))
, fScale); |
| 2485 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); |
| 2486 if (fCache->findPath(glyph)) { |
| 2487 fCache->findIntercepts(fBounds, fScale, fXPos, SkToBool(fXYIndex), |
| 2488 const_cast<SkGlyph*>(&glyph), array, count); |
| 2489 } |
| 2490 return fText < fStop; |
| 2491 } |
| 2492 |
| 2446 /////////////////////////////////////////////////////////////////////////////// | 2493 /////////////////////////////////////////////////////////////////////////////// |
| 2447 | 2494 |
| 2448 // return true if the filter exists, and may affect alpha | 2495 // return true if the filter exists, and may affect alpha |
| 2449 static bool affects_alpha(const SkColorFilter* cf) { | 2496 static bool affects_alpha(const SkColorFilter* cf) { |
| 2450 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); | 2497 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); |
| 2451 } | 2498 } |
| 2452 | 2499 |
| 2453 // return true if the filter exists, and may affect alpha | 2500 // return true if the filter exists, and may affect alpha |
| 2454 static bool affects_alpha(const SkImageFilter* imf) { | 2501 static bool affects_alpha(const SkImageFilter* imf) { |
| 2455 // TODO: check if we should allow imagefilters to broadcast that they don't
affect alpha | 2502 // TODO: check if we should allow imagefilters to broadcast that they don't
affect alpha |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2483 } | 2530 } |
| 2484 | 2531 |
| 2485 uint32_t SkPaint::getHash() const { | 2532 uint32_t SkPaint::getHash() const { |
| 2486 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2533 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
| 2487 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2534 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
| 2488 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), | 2535 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), |
| 2489 "SkPaint_notPackedTightly"); | 2536 "SkPaint_notPackedTightly"); |
| 2490 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2537 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
| 2491 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2538 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
| 2492 } | 2539 } |
| OLD | NEW |