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

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: less dense again (me, not the code) 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
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 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
OLDNEW
« src/core/SkGlyph.h ('K') | « src/core/SkGlyphCache.cpp ('k') | src/core/SkTextToPathIter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698