hide non-blob versions of getTextIntercepts
likely will move this to SkFont soon Bug: skia: Change-Id: I53a6d9114c9e8768a50951e96284d10bda83285b Reviewed-on: https://skia-review.googlesource.com/c/175434 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
d2a5908939
commit
158df43c2d
@ -3423,118 +3423,6 @@ Text_Intercepts describe the intersection of drawn text Glyphs with a pair
|
||||
of lines parallel to the text advance. Text_Intercepts permits creating a
|
||||
underline that skips Descenders.
|
||||
|
||||
#Method int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
|
||||
const SkScalar bounds[2], SkScalar* intervals) const
|
||||
#In Text_Intercepts
|
||||
#Line # returns where lines intersect text; underlines ##
|
||||
#Populate
|
||||
|
||||
#NoExample
|
||||
#Height 128
|
||||
#Description
|
||||
Underline uses intercepts to draw on either side of the glyph Descender.
|
||||
##
|
||||
void draw(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setTextSize(120);
|
||||
SkPoint textOrigin = { 20, 100 };
|
||||
SkScalar bounds[] = { 100, 108 };
|
||||
int count = paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds, nullptr);
|
||||
std::vector<SkScalar> intervals;
|
||||
intervals.resize(count);
|
||||
(void) paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds,
|
||||
&intervals.front());
|
||||
canvas->drawString("y", textOrigin.fX, textOrigin.fY, paint);
|
||||
paint.setColor(SK_ColorRED);
|
||||
SkScalar x = textOrigin.fX;
|
||||
for (int i = 0; i < count; i += 2) {
|
||||
canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
|
||||
x = intervals[i + 1];
|
||||
}
|
||||
canvas->drawRect({intervals[count - 1], bounds[0],
|
||||
textOrigin.fX + paint.measureText("y", 1), bounds[1]}, paint);
|
||||
}
|
||||
##
|
||||
|
||||
##
|
||||
|
||||
#Method int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
|
||||
const SkScalar bounds[2], SkScalar* intervals) const
|
||||
#In Text_Intercepts
|
||||
#Line # returns where lines intersect positioned text; underlines ##
|
||||
#Populate
|
||||
|
||||
#NoExample
|
||||
#Description
|
||||
Text intercepts draw on either side of, but not inside, Glyphs in a run.
|
||||
##
|
||||
void draw(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setTextSize(120);
|
||||
SkPoint textPos[] = {{ 60, 90 }, { 120, 90 }};
|
||||
SkScalar bounds[] = { 40, 70 };
|
||||
const char str[] = "A+";
|
||||
int len = sizeof(str) - 1;
|
||||
int count = paint.getPosTextIntercepts(str, len, textPos, bounds, nullptr);
|
||||
std::vector<SkScalar> intervals;
|
||||
intervals.resize(count);
|
||||
(void) paint.getPosTextIntercepts(str, len, textPos, bounds, &intervals.front());
|
||||
canvas->drawPosText(str, len, textPos, paint);
|
||||
paint.setColor(SK_ColorRED);
|
||||
SkScalar x = textPos[0].fX;
|
||||
for (int i = 0; i < count; i+= 2) {
|
||||
canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
|
||||
x = intervals[i + 1];
|
||||
}
|
||||
if (count) {
|
||||
canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
|
||||
}
|
||||
}
|
||||
##
|
||||
|
||||
##
|
||||
|
||||
#Method int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
|
||||
SkScalar constY, const SkScalar bounds[2],
|
||||
SkScalar* intervals) const
|
||||
#In Text_Intercepts
|
||||
#Line # returns where lines intersect horizontally positioned text; underlines ##
|
||||
#Populate
|
||||
|
||||
#NoExample
|
||||
#Height 128
|
||||
#Description
|
||||
Text intercepts do not take stroke thickness into consideration.
|
||||
##
|
||||
void draw(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setTextSize(120);
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setStrokeWidth(4);
|
||||
SkScalar textPosH[] = { 20, 80, 140 };
|
||||
SkScalar y = 100;
|
||||
SkScalar bounds[] = { 56, 78 };
|
||||
const char str[] = "\\-/";
|
||||
int len = sizeof(str) - 1;
|
||||
int count = paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, nullptr);
|
||||
std::vector<SkScalar> intervals;
|
||||
intervals.resize(count);
|
||||
(void) paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, &intervals.front());
|
||||
canvas->drawPosTextH(str, len, textPosH, y, paint);
|
||||
paint.setColor(0xFFFF7777);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
SkScalar x = textPosH[0];
|
||||
for (int i = 0; i < count; i+= 2) {
|
||||
canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
|
||||
x = intervals[i + 1];
|
||||
}
|
||||
canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
|
||||
}
|
||||
##
|
||||
|
||||
##
|
||||
|
||||
|
||||
#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
|
||||
SkScalar* intervals) const
|
||||
#In Text_Intercepts
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
#include "Sk2DPathEffect.h"
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_TEXTINTERCEPTS
|
||||
|
||||
static SkPath create_underline(const SkTDArray<SkScalar>& intersections,
|
||||
SkScalar last, SkScalar finalPos,
|
||||
SkScalar uPos, SkScalar uWidth, SkScalar textSize) {
|
||||
@ -40,15 +38,21 @@ static SkPath create_underline(const SkTDArray<SkScalar>& intersections,
|
||||
return underline;
|
||||
}
|
||||
|
||||
static void find_intercepts(const char* test, size_t len, SkScalar x, SkScalar y,
|
||||
static void find_intercepts(const char* text, size_t len, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkScalar uWidth, SkTDArray<SkScalar>* intersections) {
|
||||
SkScalar uPos = y + uWidth;
|
||||
const SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
|
||||
auto blob = SkTextBlob::MakeFromText(text, len, font);
|
||||
|
||||
SkScalar uPos = uWidth;
|
||||
SkScalar bounds[2] = { uPos - uWidth / 2, uPos + uWidth / 2 };
|
||||
int count = paint.getTextIntercepts(test, len, x, y, bounds, nullptr);
|
||||
int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
|
||||
SkASSERT(!(count % 2));
|
||||
if (count) {
|
||||
intersections->setCount(count);
|
||||
paint.getTextIntercepts(test, len, x, y, bounds, intersections->begin());
|
||||
paint.getTextBlobIntercepts(blob.get(), bounds, intersections->begin());
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*intersections)[i] += x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +88,18 @@ DEF_SIMPLE_GM(fancyunderline, canvas, 900, 1350) {
|
||||
}
|
||||
}
|
||||
|
||||
static void find_intercepts(const char* test, size_t len, const SkPoint* pos, const SkPaint& paint,
|
||||
static void find_intercepts(const char* text, size_t len, const SkPoint* pos, const SkPaint& paint,
|
||||
SkScalar uWidth, SkTDArray<SkScalar>* intersections) {
|
||||
const SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
|
||||
auto blob = SkTextBlob::MakeFromPosText(text, len, pos, font);
|
||||
|
||||
SkScalar uPos = pos[0].fY + uWidth;
|
||||
SkScalar bounds[2] = { uPos - uWidth / 2, uPos + uWidth / 2 };
|
||||
int count = paint.getPosTextIntercepts(test, len, pos, bounds, nullptr);
|
||||
int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
|
||||
SkASSERT(!(count % 2));
|
||||
if (count) {
|
||||
intersections->setCount(count);
|
||||
paint.getPosTextIntercepts(test, len, pos, bounds, intersections->begin());
|
||||
paint.getTextBlobIntercepts(blob.get(), bounds, intersections->begin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,20 +149,14 @@ DEF_SIMPLE_GM(fancyposunderline, canvas, 900, 1350) {
|
||||
namespace {
|
||||
|
||||
sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const char* text) {
|
||||
SkPaint blobPaint(paint);
|
||||
const SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
|
||||
|
||||
const size_t textLen = strlen(text);
|
||||
const int glyphCount = blobPaint.textToGlyphs(text, textLen, nullptr);
|
||||
const int glyphCount = font.countText(text, textLen, kUTF8_SkTextEncoding);
|
||||
SkAutoTArray<SkGlyphID> glyphs(glyphCount);
|
||||
blobPaint.textToGlyphs(text, textLen, glyphs.get());
|
||||
|
||||
blobPaint.setTextEncoding(kGlyphID_SkTextEncoding);
|
||||
const size_t glyphTextBytes = SkTo<uint32_t>(glyphCount) * sizeof(SkGlyphID);
|
||||
const int widthCount = blobPaint.getTextWidths(glyphs.get(), glyphTextBytes, nullptr);
|
||||
SkAssertResult(widthCount == glyphCount);
|
||||
|
||||
font.textToGlyphs(text, textLen, kUTF8_SkTextEncoding, glyphs.get(), glyphCount);
|
||||
SkAutoTArray<SkScalar> widths(glyphCount);
|
||||
blobPaint.getTextWidths(glyphs.get(), glyphTextBytes, widths.get());
|
||||
font.getWidths(glyphs.get(), glyphCount, widths.get());
|
||||
|
||||
SkTextBlobBuilder blobBuilder;
|
||||
int glyphIndex = 0;
|
||||
@ -164,7 +165,7 @@ sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const char* text) {
|
||||
// Default-positioned run.
|
||||
{
|
||||
const int defaultRunLen = glyphCount / 3;
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRun(blobPaint,
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRun(font,
|
||||
defaultRunLen,
|
||||
advance, 0);
|
||||
memcpy(buf.glyphs, glyphs.get(), SkTo<uint32_t>(defaultRunLen) * sizeof(SkGlyphID));
|
||||
@ -177,7 +178,7 @@ sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const char* text) {
|
||||
// Horizontal-positioned run.
|
||||
{
|
||||
const int horizontalRunLen = glyphCount / 3;
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRunPosH(blobPaint,
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRunPosH(font,
|
||||
horizontalRunLen,
|
||||
0);
|
||||
memcpy(buf.glyphs, glyphs.get() + glyphIndex,
|
||||
@ -191,7 +192,7 @@ sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const char* text) {
|
||||
// Full-positioned run.
|
||||
{
|
||||
const int fullRunLen = glyphCount - glyphIndex;
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRunPos(blobPaint, fullRunLen);
|
||||
const SkTextBlobBuilder::RunBuffer& buf = blobBuilder.allocRunPos(font, fullRunLen);
|
||||
memcpy(buf.glyphs, glyphs.get() + glyphIndex,
|
||||
SkTo<uint32_t>(fullRunLen) * sizeof(SkGlyphID));
|
||||
for (int i = 0; i < fullRunLen; ++i) {
|
||||
@ -286,5 +287,3 @@ DEF_SIMPLE_GM(fancyunderlinebars, canvas, 1500, 460) {
|
||||
canvas->translate(0, textSize * 1.3f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1095,80 +1095,6 @@ public:
|
||||
const SkPoint pos[], SkPath* path) const;
|
||||
#endif
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_TEXTINTERCEPTS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
/** Returns the number of intervals that intersect bounds.
|
||||
bounds describes a pair of lines parallel to the text advance.
|
||||
The return count is zero or a multiple of two, and is at most twice the number of glyphs in
|
||||
the string.
|
||||
Uses SkTextEncoding to decode text, SkTypeface to get the glyph paths,
|
||||
and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
|
||||
Uses x, y to position intervals.
|
||||
|
||||
Pass nullptr for intervals to determine the size of the interval array.
|
||||
|
||||
intervals are cached to improve performance for multiple calls.
|
||||
|
||||
@param text character codes or glyph indices
|
||||
@param length number of bytes of text
|
||||
@param x x-axis value of the origin of the text
|
||||
@param y y-axis value of the origin of the text
|
||||
@param bounds lower and upper line parallel to the advance
|
||||
@param intervals returned intersections; may be nullptr
|
||||
@return number of intersections; may be zero
|
||||
*/
|
||||
int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
|
||||
const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
|
||||
/** Returns the number of intervals that intersect bounds.
|
||||
bounds describes a pair of lines parallel to the text advance.
|
||||
The return count is zero or a multiple of two, and is at most twice the number of glyphs in
|
||||
the string.
|
||||
Uses SkTextEncoding to decode text, SkTypeface to get the glyph paths,
|
||||
and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
|
||||
Uses pos array to position intervals.
|
||||
|
||||
Pass nullptr for intervals to determine the size of the interval array.
|
||||
|
||||
intervals are cached to improve performance for multiple calls.
|
||||
|
||||
@param text character codes or glyph indices
|
||||
@param length number of bytes of text
|
||||
@param pos positions of each glyph
|
||||
@param bounds lower and upper line parallel to the advance
|
||||
@param intervals returned intersections; may be nullptr
|
||||
@return number of intersections; may be zero
|
||||
*/
|
||||
int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
|
||||
const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
|
||||
/** Returns the number of intervals that intersect bounds.
|
||||
bounds describes a pair of lines parallel to the text advance.
|
||||
The return count is zero or a multiple of two, and is at most twice the number of glyphs in
|
||||
the string.
|
||||
Uses SkTextEncoding to decode text, SkTypeface to get the glyph paths,
|
||||
and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
|
||||
Uses xpos array, constY to position intervals.
|
||||
|
||||
Pass nullptr for intervals to determine the size of the interval array.
|
||||
|
||||
intervals are cached to improve performance for multiple calls.
|
||||
|
||||
@param text character codes or glyph indices
|
||||
@param length number of bytes of text
|
||||
@param xpos positions of each glyph on x-axis
|
||||
@param constY position of each glyph on y-axis
|
||||
@param bounds lower and upper line parallel to the advance
|
||||
@param intervals returned intersections; may be nullptr
|
||||
@return number of intersections; may be zero
|
||||
*/
|
||||
int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
|
||||
SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
public:
|
||||
|
||||
/** Returns the number of intervals that intersect bounds.
|
||||
bounds describes a pair of lines parallel to the text advance.
|
||||
The return count is zero or a multiple of two, and is at most twice the number of glyphs in
|
||||
@ -1314,6 +1240,13 @@ private:
|
||||
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
|
||||
int* count, SkRect* bounds) const;
|
||||
|
||||
int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
|
||||
const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
|
||||
const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
|
||||
SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
|
||||
/*
|
||||
* The luminance color is used to determine which Gamma Canonical color to map to. This is
|
||||
* really only used by backends which want to cache glyph masks, and need some way to know if
|
||||
|
Loading…
Reference in New Issue
Block a user