Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit dfa432c

Browse files
reed-at-googleSkia Commit-Bot
authored andcommitted
impl intercepts with fonts
Bug: skia: Change-Id: Ib3958c61822716846e12647afdfef4ecd979b474 Reviewed-on: https://skia-review.googlesource.com/c/176581 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
1 parent 72ab346 commit dfa432c

File tree

3 files changed

+54
-110
lines changed

3 files changed

+54
-110
lines changed

include/core/SkPaint.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,11 +1238,11 @@ class SK_API SkPaint {
12381238
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
12391239
int* count, SkRect* bounds) const;
12401240

1241-
int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
1241+
int getTextIntercepts(const SkFont&, const SkGlyphID[], int count, SkScalar x, SkScalar y,
12421242
const SkScalar bounds[2], SkScalar* intervals) const;
1243-
int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
1243+
int getPosTextIntercepts(const SkFont&, const SkGlyphID[], int count, const SkPoint pos[],
12441244
const SkScalar bounds[2], SkScalar* intervals) const;
1245-
int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
1245+
int getPosTextHIntercepts(const SkFont&, const SkGlyphID[], int count, const SkScalar xpos[],
12461246
SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
12471247

12481248
/*

src/core/SkPaint_text.cpp

Lines changed: 38 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -392,16 +392,12 @@ void SkPaint::getPosTextPath(const void* text, size_t length,
392392
}
393393

394394
template <SkTextInterceptsIter::TextType TextType, typename Func>
395-
int GetTextIntercepts(const SkPaint& paint, const void* text, size_t length,
396-
const SkScalar bounds[2], SkScalar* array, Func posMaker) {
397-
SkASSERT(length == 0 || text != nullptr);
398-
if (!length) {
399-
return 0;
400-
}
395+
int GetTextIntercepts(const SkFont& font, const SkPaint& paint, const SkGlyphID glyphs[],
396+
int glyphCount, const SkScalar bounds[2], SkScalar* array, Func posMaker) {
397+
SkASSERT(glyphCount == 0 || glyphs != nullptr);
401398

402399
const SkPoint pos0 = posMaker(0);
403-
SkTextInterceptsIter iter(static_cast<const char*>(text), length, paint, bounds,
404-
pos0.x(), pos0.y(), TextType);
400+
SkTextInterceptsIter iter(glyphs, glyphCount, font, paint, bounds, pos0.x(), pos0.y(), TextType);
405401

406402
int i = 0;
407403
int count = 0;
@@ -415,59 +411,56 @@ int GetTextIntercepts(const SkPaint& paint, const void* text, size_t length,
415411
return count;
416412
}
417413

418-
int SkPaint::getTextIntercepts(const void* textData, size_t length,
414+
int SkPaint::getTextIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
419415
SkScalar x, SkScalar y, const SkScalar bounds[2],
420416
SkScalar* array) const {
421417

422418
return GetTextIntercepts<SkTextInterceptsIter::TextType::kText>(
423-
*this, textData, length, bounds, array, [&x, &y] (int) -> SkPoint {
419+
font, *this, glyphs, count, bounds, array, [&x, &y] (int) -> SkPoint {
424420
return SkPoint::Make(x, y);
425421
});
426422
}
427423

428-
int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkPoint pos[],
429-
const SkScalar bounds[2], SkScalar* array) const {
424+
int SkPaint::getPosTextIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
425+
const SkPoint pos[], const SkScalar bounds[2],
426+
SkScalar* array) const {
430427

431428
return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
432-
*this, textData, length, bounds, array, [&pos] (int i) -> SkPoint {
429+
font, *this, glyphs, count, bounds, array, [&pos] (int i) -> SkPoint {
433430
return pos[i];
434431
});
435432
}
436433

437-
int SkPaint::getPosTextHIntercepts(const void* textData, size_t length, const SkScalar xpos[],
438-
SkScalar constY, const SkScalar bounds[2],
434+
int SkPaint::getPosTextHIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
435+
const SkScalar xpos[], SkScalar constY, const SkScalar bounds[2],
439436
SkScalar* array) const {
440437

441438
return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
442-
*this, textData, length, bounds, array, [&xpos, &constY] (int i) -> SkPoint {
439+
font, *this, glyphs, count, bounds, array, [&xpos, &constY] (int i) -> SkPoint {
443440
return SkPoint::Make(xpos[i], constY);
444441
});
445442
}
446443

447444
int SkPaint::getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
448445
SkScalar* intervals) const {
449446
int count = 0;
450-
SkPaint runPaint(*this);
451-
452447
SkTextBlobRunIterator it(blob);
448+
453449
while (!it.done()) {
454-
it.applyFontToPaint(&runPaint);
455-
const size_t runByteCount = it.glyphCount() * sizeof(SkGlyphID);
456450
SkScalar* runIntervals = intervals ? intervals + count : nullptr;
457451

458452
switch (it.positioning()) {
459453
case SkTextBlobRunIterator::kDefault_Positioning:
460-
count += runPaint.getTextIntercepts(it.glyphs(), runByteCount, it.offset().x(),
461-
it.offset().y(), bounds, runIntervals);
454+
count += this->getTextIntercepts(it.font(), it.glyphs(), it.glyphCount(), it.offset().x(),
455+
it.offset().y(), bounds, runIntervals);
462456
break;
463457
case SkTextBlobRunIterator::kHorizontal_Positioning:
464-
count += runPaint.getPosTextHIntercepts(it.glyphs(), runByteCount, it.pos(),
465-
it.offset().y(), bounds, runIntervals);
458+
count += this->getPosTextHIntercepts(it.font(), it.glyphs(), it.glyphCount(), it.pos(),
459+
it.offset().y(), bounds, runIntervals);
466460
break;
467461
case SkTextBlobRunIterator::kFull_Positioning:
468-
count += runPaint.getPosTextIntercepts(it.glyphs(), runByteCount,
469-
reinterpret_cast<const SkPoint*>(it.pos()),
470-
bounds, runIntervals);
462+
count += this->getPosTextIntercepts(it.font(), it.glyphs(), it.glyphCount(),
463+
reinterpret_cast<const SkPoint*>(it.pos()), bounds, runIntervals);
471464
break;
472465
}
473466

@@ -510,23 +503,19 @@ static bool has_thick_frame(const SkPaint& paint) {
510503
paint.getStyle() != SkPaint::kFill_Style;
511504
}
512505

513-
SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
514-
const SkPaint& paint,
515-
bool applyStrokeAndPathEffects)
516-
: fPaint(paint) {
517-
fGlyphCacheProc = SkFontPriv::GetGlyphCacheProc(paint.getTextEncoding(), true);
506+
SkTextBaseIter::SkTextBaseIter(const SkGlyphID glyphs[], int count, const SkFont& font,
507+
const SkPaint& paint)
508+
: fFont(font), fPaint(paint)
509+
{
510+
SkAssertResult(count >= 0);
518511

519-
fPaint.setLinearText(true);
512+
fFont.setLinearMetrics(true);
520513
fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache lookup
521514

522-
if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) {
523-
applyStrokeAndPathEffects = false;
524-
}
525-
526515
// can't use our canonical size if we need to apply patheffects
527516
if (fPaint.getPathEffect() == nullptr) {
528-
fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
529-
fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
517+
fScale = fFont.getSize() / SkPaint::kCanonicalTextSizeForPaths;
518+
fFont.setSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
530519
// Note: fScale can be zero here (even if it wasn't before the divide). It can also
531520
// be very very small. We call sk_ieee_float_divide below to ensure IEEE divide behavior,
532521
// since downstream we will check for the resulting coordinates being non-finite anyway.
@@ -538,24 +527,13 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
538527
fScale = SK_Scalar1;
539528
}
540529

541-
if (!applyStrokeAndPathEffects) {
542-
fPaint.setStyle(SkPaint::kFill_Style);
543-
fPaint.setPathEffect(nullptr);
544-
}
545-
546-
// SRGBTODO: Is this correct?
547-
const SkFont font = SkFont::LEGACY_ExtractFromPaint(fPaint);
548-
fCache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, fPaint);
530+
fPaint.setStyle(SkPaint::kFill_Style);
531+
fPaint.setPathEffect(nullptr);
549532

550-
SkPaint::Style style = SkPaint::kFill_Style;
551-
sk_sp<SkPathEffect> pe;
533+
fCache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(fFont, fPaint);
552534

553-
if (!applyStrokeAndPathEffects) {
554-
style = paint.getStyle(); // restore
555-
pe = paint.refPathEffect(); // restore
556-
}
557-
fPaint.setStyle(style);
558-
fPaint.setPathEffect(pe);
535+
fPaint.setStyle(paint.getStyle());
536+
fPaint.setPathEffect(paint.refPathEffect());
559537
fPaint.setMaskFilter(paint.refMaskFilter()); // restore
560538

561539
// now compute fXOffset if needed
@@ -564,41 +542,18 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
564542
fXPos = xOffset;
565543
fPrevAdvance = 0;
566544

567-
fText = text;
568-
fStop = text + length;
569-
}
570-
571-
bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
572-
if (fText < fStop) {
573-
const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText, fStop);
574-
575-
fXPos += fPrevAdvance * fScale;
576-
fPrevAdvance = advance(glyph); // + fPaint.getTextTracking();
577-
578-
if (glyph.fWidth) {
579-
if (path) {
580-
*path = fCache->findPath(glyph);
581-
}
582-
} else {
583-
if (path) {
584-
*path = nullptr;
585-
}
586-
}
587-
if (xpos) {
588-
*xpos = fXPos;
589-
}
590-
return true;
591-
}
592-
return false;
545+
fGlyphs = glyphs;
546+
fStop = glyphs + count;
593547
}
594548

595549
bool SkTextInterceptsIter::next(SkScalar* array, int* count) {
596-
const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText, fStop);
550+
SkASSERT(fGlyphs < fStop);
551+
const SkGlyph& glyph = fCache->getGlyphIDMetrics(*fGlyphs++);
597552
fXPos += fPrevAdvance * fScale;
598553
fPrevAdvance = advance(glyph); // + fPaint.getTextTracking();
599554
if (fCache->findPath(glyph)) {
600555
fCache->findIntercepts(fBounds, fScale, fXPos, false,
601556
const_cast<SkGlyph*>(&glyph), array, count);
602557
}
603-
return fText < fStop;
558+
return fGlyphs < fStop;
604559
}

src/core/SkTextToPathIter.h

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,36 @@
1313
#include "SkStrikeCache.h"
1414

1515
class SkTextBaseIter {
16+
public:
17+
const SkFont& getFont() const { return fFont; }
18+
const SkPaint& getPaint() const { return fPaint; }
19+
SkScalar getPathScale() const { return fScale; }
20+
1621
protected:
17-
SkTextBaseIter(const char text[], size_t length, const SkPaint& paint,
18-
bool applyStrokeAndPathEffects);
22+
SkTextBaseIter(const SkGlyphID glyphs[], int count, const SkFont&, const SkPaint& paint);
1923

2024
SkExclusiveStrikePtr fCache;
25+
SkFont fFont;
2126
SkPaint fPaint;
2227
SkScalar fScale;
2328
SkScalar fPrevAdvance;
24-
const char* fText;
25-
const char* fStop;
26-
SkFontPriv::GlyphCacheProc fGlyphCacheProc;
29+
const SkGlyphID* fGlyphs;
30+
const SkGlyphID* fStop;
2731

2832
SkScalar fXPos; // accumulated xpos, returned in next
2933
};
3034

31-
class SkTextToPathIter : SkTextBaseIter {
32-
public:
33-
SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
34-
bool applyStrokeAndPathEffects)
35-
: SkTextBaseIter(text, length, paint, applyStrokeAndPathEffects) {
36-
}
37-
38-
const SkPaint& getPaint() const { return fPaint; }
39-
SkScalar getPathScale() const { return fScale; }
40-
41-
/**
42-
* Returns false when all of the text has been consumed
43-
*/
44-
bool next(const SkPath** path, SkScalar* xpos);
45-
};
46-
4735
class SkTextInterceptsIter : SkTextBaseIter {
4836
public:
4937
enum class TextType {
5038
kText,
5139
kPosText
5240
};
5341

54-
SkTextInterceptsIter(const char text[], size_t length, const SkPaint& paint,
55-
const SkScalar bounds[2], SkScalar x, SkScalar y, TextType textType)
56-
: SkTextBaseIter(text, length, paint, false)
42+
SkTextInterceptsIter(const SkGlyphID glyphs[], int count, const SkFont& font,
43+
const SkPaint& paint, const SkScalar bounds[2], SkScalar x, SkScalar y,
44+
TextType textType)
45+
: SkTextBaseIter(glyphs, count, font, paint)
5746
{
5847
fBoundsBase[0] = bounds[0];
5948
fBoundsBase[1] = bounds[1];

0 commit comments

Comments
 (0)