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 |