Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: src/core/SkPaint.cpp

Issue 1654883003: add helper to create fancy underlines (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: correct comment to multiply by two Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkGlyphCache.cpp ('k') | src/core/SkTextToPathIter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkGlyphCache.cpp ('k') | src/core/SkTextToPathIter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698