start to use font for measure, not paint
-- lots more where this came from
Bug: skia:2664
Change-Id: I8bb47f02c156b0b88fbb92fec73af0eb6641b1bf
Reviewed-on: https://skia-review.googlesource.com/c/173769
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/bench/FontCacheBench.cpp b/bench/FontCacheBench.cpp
index beae47a..2eb2b71 100644
--- a/bench/FontCacheBench.cpp
+++ b/bench/FontCacheBench.cpp
@@ -36,15 +36,14 @@
}
void onDraw(int loops, SkCanvas* canvas) override {
- SkPaint paint;
- this->setupPaint(&paint);
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAntiAlias);
const uint16_t* array = gUniqueGlyphIDs;
while (*array != gUniqueGlyphIDs_Sentinel) {
int count = count_glyphs(array);
for (int i = 0; i < loops; ++i) {
- paint.measureText(array, count * sizeof(uint16_t));
+ (void)font.measureText(array, count * sizeof(uint16_t), kGlyphID_SkTextEncoding);
}
array += count + 1; // skip the sentinel
}
diff --git a/bench/PicturePlaybackBench.cpp b/bench/PicturePlaybackBench.cpp
index 54ecd3c..40dde4b 100644
--- a/bench/PicturePlaybackBench.cpp
+++ b/bench/PicturePlaybackBench.cpp
@@ -17,130 +17,8 @@
// This is designed to emulate about 4 screens of textual content
-
-class PicturePlaybackBench : public Benchmark {
-public:
- PicturePlaybackBench(const char name[]) {
- fName.printf("picture_playback_%s", name);
- fPictureWidth = SkIntToScalar(PICTURE_WIDTH);
- fPictureHeight = SkIntToScalar(PICTURE_HEIGHT);
- fTextSize = SkIntToScalar(TEXT_SIZE);
- }
-
- enum {
- PICTURE_WIDTH = 1000,
- PICTURE_HEIGHT = 4000,
- TEXT_SIZE = 10
- };
-protected:
- virtual const char* onGetName() {
- return fName.c_str();
- }
-
- virtual void onDraw(int loops, SkCanvas* canvas) {
-
- SkPictureRecorder recorder;
- SkCanvas* pCanvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, nullptr, 0);
- this->recordCanvas(pCanvas);
- sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
-
- const SkPoint translateDelta = getTranslateDelta(loops);
-
- for (int i = 0; i < loops; i++) {
- picture->playback(canvas);
- canvas->translate(translateDelta.fX, translateDelta.fY);
- }
- }
-
- virtual void recordCanvas(SkCanvas* canvas) = 0;
- virtual SkPoint getTranslateDelta(int N) {
- SkIPoint canvasSize = onGetSize();
- return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/N),
- SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/N));
- }
-
- SkString fName;
- SkScalar fPictureWidth;
- SkScalar fPictureHeight;
- SkScalar fTextSize;
-private:
- typedef Benchmark INHERITED;
-};
-
-
-class TextPlaybackBench : public PicturePlaybackBench {
-public:
- TextPlaybackBench() : INHERITED("drawText") { }
-protected:
- void recordCanvas(SkCanvas* canvas) override {
- SkPaint paint;
- paint.setTextSize(fTextSize);
- paint.setColor(SK_ColorBLACK);
-
- const char* text = "Hamburgefons";
- size_t len = strlen(text);
- const SkScalar textWidth = paint.measureText(text, len);
-
- for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
- for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
- canvas->drawText(text, len, x, y, paint);
- }
- }
- }
-private:
- typedef PicturePlaybackBench INHERITED;
-};
-
-class PosTextPlaybackBench : public PicturePlaybackBench {
-public:
- PosTextPlaybackBench(bool drawPosH)
- : INHERITED(drawPosH ? "drawPosTextH" : "drawPosText")
- , fDrawPosH(drawPosH) { }
-protected:
- void recordCanvas(SkCanvas* canvas) override {
- SkPaint paint;
- paint.setTextSize(fTextSize);
- paint.setColor(SK_ColorBLACK);
-
- const char* text = "Hamburgefons";
- size_t len = strlen(text);
- const SkScalar textWidth = paint.measureText(text, len);
-
- SkScalar* adv = new SkScalar[len];
- paint.getTextWidths(text, len, adv);
-
- for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
- for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
-
- SkPoint* pos = new SkPoint[len];
- SkScalar advX = 0;
-
- for (size_t i = 0; i < len; i++) {
- if (fDrawPosH)
- pos[i].set(x + advX, y);
- else
- pos[i].set(x + advX, y + i);
- advX += adv[i];
- }
-
- canvas->drawPosText(text, len, pos, paint);
- delete[] pos;
- }
- }
- delete[] adv;
- }
-private:
- bool fDrawPosH;
- typedef PicturePlaybackBench INHERITED;
-};
-
-
///////////////////////////////////////////////////////////////////////////////
-DEF_BENCH( return new TextPlaybackBench(); )
-DEF_BENCH( return new PosTextPlaybackBench(true); )
-DEF_BENCH( return new PosTextPlaybackBench(false); )
-
// Chrome draws into small tiles with impl-side painting.
// This benchmark measures the relative performance of our bounding-box hierarchies,
// both when querying tiles perfectly and when not.
diff --git a/gm/all_bitmap_configs.cpp b/gm/all_bitmap_configs.cpp
index d403fba..33d39cb 100644
--- a/gm/all_bitmap_configs.cpp
+++ b/gm/all_bitmap_configs.cpp
@@ -10,8 +10,9 @@
#include "gm.h"
#include "sk_tool_utils.h"
-#include "SkMath.h"
#include "SkColorPriv.h"
+#include "SkFont.h"
+#include "SkMath.h"
static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
const SkBitmap* srcPtr = &src;
@@ -56,23 +57,21 @@
return bm;
}
-static void draw_center_letter(char c,
- SkPaint* p,
- SkColor color,
- SkScalar x,
- SkScalar y,
- SkCanvas* canvas) {
+static void draw_center_letter(char c, const SkFont& font, SkColor color,
+ SkScalar x, SkScalar y, SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setColor(color);
SkRect bounds;
- p->setColor(color);
- p->measureText(&c, 1, &bounds);
- canvas->drawText(&c, 1, x - bounds.centerX(), y - bounds.centerY(), *p);
+ font.measureText(&c, 1, kUTF8_SkTextEncoding, &bounds);
+ canvas->drawSimpleText(&c, 1, kUTF8_SkTextEncoding,
+ x - bounds.centerX(), y - bounds.centerY(),
+ font, paint);
}
static void color_wheel_native(SkCanvas* canvas) {
SkAutoCanvasRestore autoCanvasRestore(canvas, true);
canvas->translate(0.5f * SCALE, 0.5f * SCALE);
SkPaint p;
- p.setAntiAlias(false);
p.setColor(SK_ColorWHITE);
canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, p);
@@ -81,15 +80,18 @@
const SkScalar D = 0.3f * SkIntToScalar(SCALE);
const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
const SkScalar Y = D * SK_ScalarHalf;
- sk_tool_utils::set_portable_typeface(&p, nullptr, SkFontStyle::Bold());
- p.setTextSize(0.28125f * SCALE);
- draw_center_letter('K', &p, SK_ColorBLACK, Z, Z, canvas);
- draw_center_letter('R', &p, SK_ColorRED, Z, D, canvas);
- draw_center_letter('G', &p, SK_ColorGREEN, -X, -Y, canvas);
- draw_center_letter('B', &p, SK_ColorBLUE, X, -Y, canvas);
- draw_center_letter('C', &p, SK_ColorCYAN, Z, -D, canvas);
- draw_center_letter('M', &p, SK_ColorMAGENTA, X, Y, canvas);
- draw_center_letter('Y', &p, SK_ColorYELLOW, -X, Y, canvas);
+
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAlias);
+ font.setTypeface(sk_tool_utils::create_portable_typeface(nullptr, SkFontStyle::Bold()));
+ font.setSize(0.28125f * SCALE);
+ draw_center_letter('K', font, SK_ColorBLACK, Z, Z, canvas);
+ draw_center_letter('R', font, SK_ColorRED, Z, D, canvas);
+ draw_center_letter('G', font, SK_ColorGREEN, -X, -Y, canvas);
+ draw_center_letter('B', font, SK_ColorBLUE, X, -Y, canvas);
+ draw_center_letter('C', font, SK_ColorCYAN, Z, -D, canvas);
+ draw_center_letter('M', font, SK_ColorMAGENTA, X, Y, canvas);
+ draw_center_letter('Y', font, SK_ColorYELLOW, -X, Y, canvas);
}
template <typename T>
diff --git a/gm/atlastext.cpp b/gm/atlastext.cpp
index cdcd694..9fc7d6c 100644
--- a/gm/atlastext.cpp
+++ b/gm/atlastext.cpp
@@ -15,6 +15,7 @@
#include "SkAtlasTextTarget.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
+#include "SkFont.h"
#include "SkTypeface.h"
#include "SkUTF.h"
#include "gpu/TestContext.h"
@@ -29,18 +30,17 @@
if (!text.size()) {
return x;
}
- auto font = SkAtlasTextFont::Make(typeface, size);
+ auto atlas_font = SkAtlasTextFont::Make(typeface, size);
int cnt = SkUTF::CountUTF8(text.c_str(), text.size());
std::unique_ptr<SkGlyphID[]> glyphs(new SkGlyphID[cnt]);
typeface->charsToGlyphs(text.c_str(), SkTypeface::Encoding::kUTF8_Encoding, glyphs.get(), cnt);
// Using a paint to get the positions for each glyph.
- SkPaint paint;
- paint.setTextSize(size);
- paint.setTypeface(std::move(typeface));
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkFont font;
+ font.setSize(size);
+ font.setTypeface(std::move(typeface));
std::unique_ptr<SkScalar[]> widths(new SkScalar[cnt]);
- paint.getTextWidths(glyphs.get(), cnt * sizeof(SkGlyphID), widths.get(), nullptr);
+ font.getWidths(glyphs.get(), cnt, widths.get());
std::unique_ptr<SkPoint[]> positions(new SkPoint[cnt]);
positions[0] = {x, y};
@@ -48,7 +48,7 @@
positions[i] = {positions[i - 1].fX + widths[i - 1], y};
}
- target->drawText(glyphs.get(), positions.get(), cnt, color, *font);
+ target->drawText(glyphs.get(), positions.get(), cnt, color, *atlas_font);
// Return the width of the of draw.
return positions[cnt - 1].fX + widths[cnt - 1] - positions[0].fX;
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 4dd40cf..1079eeb 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -113,10 +113,12 @@
// Draw labels for the input to the processor and the processor to the right of
// the test rect. The input label appears above the processor label.
+ SkFont labelFont;
+ labelFont.setTypeface(sk_tool_utils::create_portable_typeface());
+ labelFont.setEdging(SkFont::Edging::kAntiAlias);
+ labelFont.setSize(10.f);
SkPaint labelPaint;
- sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setAntiAlias(true);
- labelPaint.setTextSize(10.f);
SkString inputLabel;
inputLabel.set("Input: ");
if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
@@ -129,21 +131,21 @@
SkRect inputLabelBounds;
// get the bounds of the text in order to position it
- labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
- &inputLabelBounds);
- canvas->drawString(inputLabel,
+ labelFont.measureText(inputLabel.c_str(), inputLabel.size(),
+ kUTF8_SkTextEncoding, &inputLabelBounds);
+ canvas->drawSimpleText(inputLabel.c_str(), inputLabel.size(), kUTF8_SkTextEncoding,
renderRect.fRight + kPad,
- -inputLabelBounds.fTop, labelPaint);
+ -inputLabelBounds.fTop, labelFont, labelPaint);
// update the bounds to reflect the offset we used to draw it.
inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
SkRect procLabelBounds;
- labelPaint.measureText(procLabel.c_str(), procLabel.size(),
- &procLabelBounds);
- canvas->drawString(procLabel,
+ labelFont.measureText(procLabel.c_str(), procLabel.size(),
+ kUTF8_SkTextEncoding, &procLabelBounds);
+ canvas->drawSimpleText(procLabel.c_str(), procLabel.size(), kUTF8_SkTextEncoding,
renderRect.fRight + kPad,
inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
- labelPaint);
+ labelFont, labelPaint);
procLabelBounds.offset(renderRect.fRight + kPad,
inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
diff --git a/gm/flippity.cpp b/gm/flippity.cpp
index 1cdc500..a040ba1 100644
--- a/gm/flippity.cpp
+++ b/gm/flippity.cpp
@@ -59,13 +59,16 @@
// Create a fixed size text label like "LL" or "LR".
static sk_sp<SkImage> make_text_image(GrContext* context, const char* text, SkColor color) {
SkPaint paint;
- sk_tool_utils::set_portable_typeface(&paint);
paint.setAntiAlias(true);
- paint.setTextSize(32);
paint.setColor(color);
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAntiAlias);
+ font.setTypeface(sk_tool_utils::create_portable_typeface());
+ font.setSize(32);
+
SkRect bounds;
- paint.measureText(text, strlen(text), &bounds);
+ font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
const SkMatrix mat = SkMatrix::MakeRectToRect(bounds, SkRect::MakeWH(kLabelSize, kLabelSize),
SkMatrix::kFill_ScaleToFit);
@@ -76,7 +79,7 @@
canvas->clear(SK_ColorWHITE);
canvas->concat(mat);
- canvas->drawText(text, strlen(text), 0, 0, paint);
+ canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 0, 0, font, paint);
sk_sp<SkImage> image = surf->makeImageSnapshot();
diff --git a/gm/fontcache.cpp b/gm/fontcache.cpp
index c9c8cf7..44732ab 100644
--- a/gm/fontcache.cpp
+++ b/gm/fontcache.cpp
@@ -21,9 +21,10 @@
#include "sk_tool_utils.h"
static SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x,
- SkScalar y, const SkPaint& paint) {
- canvas->drawString(text, x, y, paint);
- return x + paint.measureText(text.c_str(), text.size());
+ SkScalar y, const SkFont& font) {
+ SkPaint paint;
+ canvas->drawSimpleText(text.c_str(), text.size(), kUTF8_SkTextEncoding, x, y, font, paint);
+ return x + font.measureText(text.c_str(), text.size(), kUTF8_SkTextEncoding);
}
class FontCacheGM : public skiagm::GM {
@@ -87,10 +88,9 @@
SkString("abcdefghijklmnopqrstuvwxyz"),
SkString("0123456789"),
SkString("!@#$%^&*()<>[]{}")};
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setLCDRenderText(false);
- paint.setSubpixelText(true);
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAntiAlias);
+ font.setSubpixel(true);
static const SkScalar kSubPixelInc = 1 / 2.f;
SkScalar x = 0;
@@ -106,11 +106,11 @@
do {
for (auto s : kSizes) {
auto size = 2 * s;
- paint.setTextSize(size);
+ font.setSize(size);
for (const auto& typeface : fTypefaces) {
- paint.setTypeface(typeface);
+ font.setTypeface(typeface);
for (const auto& text : kTexts) {
- x = size + draw_string(canvas, text, x + subpixelX, y + subpixelY, paint);
+ x = size + draw_string(canvas, text, x + subpixelX, y + subpixelY, font);
x = SkScalarCeilToScalar(x);
if (x + 100 > kSize) {
x = 0;
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 20adb1d..74e706a 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -968,6 +968,18 @@
*/
SkScalar getFontSpacing() const { return this->getFontMetrics(nullptr); }
+ /** Returns the union of bounds of all glyphs.
+ Returned dimensions are computed by font manager from font data,
+ ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
+
+ If text size is large, text scale is one, and text skew is zero,
+ returns the bounds as:
+ { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
+
+ @return union of bounds of all glyphs
+ */
+ SkRect getFontBounds() const;
+
/** Converts text into glyph indices.
Returns the number of glyph indices represented by text.
SkPaint::TextEncoding specifies how text represents characters or glyphs.
@@ -1004,6 +1016,7 @@
@return true if all text corresponds to a non-zero glyph index
*/
bool containsText(const void* text, size_t byteLength) const;
+#endif
/** Converts glyphs into text if possible.
Glyph values without direct Unicode equivalents are mapped to zero.
@@ -1018,6 +1031,7 @@
*/
void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
+#ifdef SK_SUPPORT_LEGACY_PAINT_TEXTMEASURE
/** Returns the number of glyphs in text.
Uses SkPaint::TextEncoding to count the glyphs.
Returns the same result as textToGlyphs().
@@ -1124,6 +1138,7 @@
*/
void getPosTextPath(const void* text, size_t length,
const SkPoint pos[], SkPath* path) const;
+#endif
#ifdef SK_SUPPORT_LEGACY_TEXTINTERCEPTS
public:
@@ -1221,19 +1236,6 @@
int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
SkScalar* intervals) const;
- /** Returns the union of bounds of all glyphs.
- Returned dimensions are computed by font manager from font data,
- ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
-
- If text size is large, text scale is one, and text skew is zero,
- returns the bounds as:
- { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
-
- @return union of bounds of all glyphs
- */
- SkRect getFontBounds() const;
-#endif
-
/** Returns true if SkPaint prevents all drawing;
otherwise, the SkPaint may or may not allow drawing.
diff --git a/tools/fonts/create_test_font.cpp b/tools/fonts/create_test_font.cpp
index f782dc8..51a2881 100644
--- a/tools/fonts/create_test_font.cpp
+++ b/tools/fonts/create_test_font.cpp
@@ -9,10 +9,11 @@
// and ./tools/fonts/test_font_<generic name>.inc which are read by
// ./tools/fonts/SkTestFontMgr.cpp
+#include "SkFont.h"
+#include "SkFontMetrics.h"
#include "SkFontStyle.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
-#include "SkPaint.h"
#include "SkPath.h"
#include "SkSpan.h"
#include "SkStream.h"
@@ -120,15 +121,13 @@
return count;
}
-static void output_path_data(const SkPaint& paint,
+static void output_path_data(const SkFont& font,
int emSize, SkString* ptsOut, SkTDArray<SkPath::Verb>* verbs,
SkTDArray<unsigned>* charCodes, SkTDArray<SkScalar>* widths) {
for (SkUnichar index = 0x00; index < 0x7f; ++index) {
- uint16_t utf16[2];
- size_t utf16Bytes = sizeof(uint16_t) * SkUTF::ToUTF16(index, utf16);
+ uint16_t glyphID = font.unicharToGlyph(index);
SkPath path;
- SkASSERT(paint.getTextEncoding() == SkPaint::kUTF16_TextEncoding);
- paint.getTextPath(utf16, utf16Bytes, 0, 0, &path);
+ font.getPath(glyphID, &path);
SkPath::RawIter iter(path);
SkPath::Verb verb;
SkPoint pts[4];
@@ -157,8 +156,7 @@
*verbs->append() = SkPath::kDone_Verb;
*charCodes->append() = index;
SkScalar width;
- SkDEBUGCODE(int charCount =) paint.getTextWidths(utf16, utf16Bytes, &width);
- SkASSERT(charCount == 1);
+ font.getWidths(&glyphID, 1, &width);
// SkASSERT(floor(width) == width); // not true for Hiragino Maru Gothic Pro
*widths->append() = width;
if (0 == index) {
@@ -195,17 +193,17 @@
}
static void output_font(sk_sp<SkTypeface> face, const char* identifier, FILE* out) {
- int emSize = face->getUnitsPerEm() * 2;
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
- paint.setTextSize(emSize);
- paint.setTypeface(std::move(face));
+ const int emSize = face->getUnitsPerEm() * 2;
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAntiAlias);
+ font.setSize(emSize);
+ font.setTypeface(std::move(face));
+
SkTDArray<SkPath::Verb> verbs;
SkTDArray<unsigned> charCodes;
SkTDArray<SkScalar> widths;
SkString ptsOut;
- output_path_data(paint, emSize, &ptsOut, &verbs, &charCodes, &widths);
+ output_path_data(font, emSize, &ptsOut, &verbs, &charCodes, &widths);
fprintf(out, "const SkScalar %sPoints[] = {\n", identifier);
ptsOut = strip_final(ptsOut);
fprintf(out, "%s", ptsOut.c_str());
@@ -263,7 +261,7 @@
identifier, identifier);
SkFontMetrics metrics;
- paint.getFontMetrics(&metrics);
+ font.getMetrics(&metrics);
fprintf(out, "const SkFontMetrics %sMetrics = {\n", identifier);
SkString metricsStr;
metricsStr.printf("0x%08x, ", metrics.fFlags);