don't use drawPosText

Skia can now build if we mark drawPosText as private,
Will hide/remove next (after Chrome CL)

Bug: skia:
Change-Id: I156560b025c119af302545bb5bd60678f7b8e8f7
Reviewed-on: https://skia-review.googlesource.com/c/179985
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2018-12-25 17:35:49 -05:00 committed by Skia Commit-Bot
parent 5d77c200a8
commit 212e9060ed
12 changed files with 46 additions and 822 deletions

View File

@ -1,181 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Benchmark.h"
#include "Resources.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTemplates.h"
#include "SkTypeface.h"
#ifdef SK_SUPPORT_LEGACY_PAINT_TEXTMEASURE
enum FontQuality {
kBW,
kAA,
kLCD,
};
static const char* fontQualityName(const SkPaint& paint) {
if (!paint.isAntiAlias()) {
return "BW";
}
if (paint.isLCDRenderText()) {
return "LCD";
}
return "AA";
}
/* Some considerations for performance:
short -vs- long strings (measuring overhead)
tiny -vs- large pointsize (measure blit -vs- overhead)
1 -vs- many point sizes (measure cache lookup)
normal -vs- subpixel -vs- lineartext (minor)
force purge after each draw to measure scaler
textencoding?
text -vs- postext - pathtext
*/
class TextBench : public Benchmark {
SkPaint fPaint;
SkString fText;
SkString fName;
FontQuality fFQ;
bool fDoPos;
bool fDoColorEmoji;
sk_sp<SkTypeface> fColorEmojiTypeface;
SkPoint* fPos;
public:
TextBench(const char text[], int ps,
SkColor color, FontQuality fq, bool doColorEmoji = false, bool doPos = false)
: fText(text)
, fFQ(fq)
, fDoPos(doPos)
, fDoColorEmoji(doColorEmoji)
, fPos(nullptr) {
fPaint.setAntiAlias(kBW != fq);
fPaint.setLCDRenderText(kLCD == fq);
fPaint.setTextSize(SkIntToScalar(ps));
fPaint.setColor(color);
}
~TextBench() override {
delete[] fPos;
}
protected:
void onDelayedSetup() override {
if (fDoColorEmoji) {
SkASSERT(kBW == fFQ);
fColorEmojiTypeface = MakeResourceAsTypeface("fonts/Funkster.ttf");
}
if (fDoPos) {
size_t len = fText.size();
SkScalar* adv = new SkScalar[len];
fPaint.getTextWidths(fText.c_str(), len, adv);
fPos = new SkPoint[len];
SkScalar x = 0;
for (size_t i = 0; i < len; ++i) {
fPos[i].set(x, SkIntToScalar(50));
x += adv[i];
}
delete[] adv;
}
}
const char* onGetName() override {
fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
if (fDoPos) {
fName.append("_pos");
}
fName.appendf("_%s", fontQualityName(fPaint));
if (SK_ColorBLACK == fPaint.getColor()) {
fName.append("_BK");
} else if (SK_ColorWHITE == fPaint.getColor()) {
fName.append("_WT");
} else {
fName.appendf("_%02X", fPaint.getAlpha());
}
if (fDoColorEmoji) {
fName.append("_ColorEmoji");
}
return fName.c_str();
}
void onDraw(int loops, SkCanvas* canvas) override {
const SkIPoint dim = this->getSize();
SkRandom rand;
SkPaint paint(fPaint);
this->setupPaint(&paint);
// explicitly need these
paint.setColor(fPaint.getColor());
paint.setAntiAlias(kBW != fFQ);
paint.setLCDRenderText(kLCD == fFQ);
if (fDoColorEmoji && fColorEmojiTypeface) {
paint.setTypeface(fColorEmojiTypeface);
}
const SkScalar x0 = SkIntToScalar(-10);
const SkScalar y0 = SkIntToScalar(-10);
if (fDoPos) {
// realistically, the matrix is often at least translated, so we
// do that since it exercises different code in drawPosText.
canvas->translate(SK_Scalar1, SK_Scalar1);
}
for (int i = 0; i < loops; i++) {
if (fDoPos) {
canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint);
} else {
SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
canvas->drawString(fText, x, y, paint);
}
}
}
private:
typedef Benchmark INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
#define STR "Hamburgefons"
DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA, false, true); )
#endif

View File

@ -1478,59 +1478,14 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
font, paint);
break;
}
#ifdef SK_SUPPORT_LEGACY_FONTMETRICS_IN_PAINT
case 46: {
fuzz_paint(fuzz, &paint, depth - 1);
font = fuzz_font(fuzz);
SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
int glyphCount = font.countText(text.begin(), SkToSizeT(text.count()), encoding);
if (glyphCount < 1) {
break;
}
SkAutoTMalloc<SkPoint> pos(glyphCount);
SkAutoTMalloc<SkScalar> widths(glyphCount);
font.LEGACY_applyToPaint(&paint);
paint.setTextEncoding(encoding);
paint.getTextWidths(text.begin(), SkToSizeT(text.count()), widths.get());
pos[0] = {0, 0};
for (int i = 1; i < glyphCount; ++i) {
float y;
fuzz->nextRange(&y, -0.5f * paint.getTextSize(), 0.5f * paint.getTextSize());
pos[i] = {pos[i - 1].x() + widths[i - 1], y};
}
canvas->drawPosText(text.begin(), SkToSizeT(text.count()), pos.get(), paint);
// was drawPosText
break;
}
case 47: {
fuzz_paint(fuzz, &paint, depth - 1);
font = fuzz_font(fuzz);
SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
int glyphCount = font.countText(text.begin(), SkToSizeT(text.count()), encoding);
SkAutoTMalloc<SkScalar> widths(glyphCount);
if (glyphCount < 1) {
break;
}
font.LEGACY_applyToPaint(&paint);
paint.setTextEncoding(encoding);
paint.getTextWidths(text.begin(), SkToSizeT(text.count()), widths.get());
SkScalar x = widths[0];
for (int i = 0; i < glyphCount; ++i) {
using std::swap;
swap(x, widths[i]);
x += widths[i];
SkScalar offset;
fuzz->nextRange(&offset, -0.125f * paint.getTextSize(),
0.125f * paint.getTextSize());
widths[i] += offset;
}
SkScalar y;
fuzz->next(&y);
canvas->drawPosTextH(text.begin(), SkToSizeT(text.count()), widths.get(), y, paint);
// was drawPosTextH
break;
}
#endif
case 48: {
// was drawtextonpath
break;
@ -1539,29 +1494,10 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
// was drawtextonpath
break;
}
#ifdef SK_SUPPORT_LEGACY_FONTMETRICS_IN_PAINT
case 50: {
fuzz_paint(fuzz, &paint, depth - 1);
font = fuzz_font(fuzz);
SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
SkRSXform rSXform[kMaxGlyphCount];
int glyphCount = font.countText(text.begin(), SkToSizeT(text.count()), encoding);
SkASSERT(glyphCount <= kMaxGlyphCount);
fuzz->nextN(rSXform, glyphCount);
SkRect cullRect;
bool useCullRect;
fuzz->next(&useCullRect);
if (useCullRect) {
fuzz->next(&cullRect);
}
font.LEGACY_applyToPaint(&paint);
paint.setTextEncoding(encoding);
canvas->drawTextRSXform(text.begin(), SkToSizeT(text.count()), rSXform,
useCullRect ? &cullRect : nullptr, paint);
// was drawTextRSXform
break;
}
#endif
case 51: {
sk_sp<SkTextBlob> blob = make_fuzz_textblob(fuzz);
fuzz_paint(fuzz, &paint, depth - 1);

View File

@ -8,9 +8,11 @@
#include "Fuzz.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkFont.h"
#include "SkImage.h"
#include "SkPath.h"
#include "SkSurface.h"
#include "SkTextBlob.h"
#include "SkTypeface.h"
#include "SkClipOpPriv.h"
@ -47,9 +49,6 @@ static void init_paint(Fuzz* fuzz, SkPaint* p) {
fuzz->nextRange(&tmp_u8, 0, (int)kHigh_SkFilterQuality);
p->setFilterQuality(static_cast<SkFilterQuality>(tmp_u8));
fuzz->nextRange(&tmp_u8, 0, (int)SkFontHinting::kFull);
p->setHinting(static_cast<SkFontHinting>(tmp_u8));
fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kLast_Cap);
p->setStrokeCap(static_cast<SkPaint::Cap>(tmp_u8));
@ -111,7 +110,7 @@ static void init_surface(Fuzz* fuzz, sk_sp<SkSurface>* s) {
}
static void fuzz_drawText(Fuzz* fuzz, sk_sp<SkTypeface> font) {
static void fuzz_drawText(Fuzz* fuzz, sk_sp<SkTypeface> typeface) {
SkPaint p;
init_paint(fuzz, &p);
sk_sp<SkSurface> surface;
@ -129,34 +128,31 @@ static void fuzz_drawText(Fuzz* fuzz, sk_sp<SkTypeface> font) {
x += p.getTextSize();
}
p.setTypeface(font);
// set text related attributes
SkFont font(typeface);
bool b;
fuzz->next(&b);
p.setAutohinted(b);
font.setForceAutoHinting(b);
fuzz->next(&b);
p.setEmbeddedBitmapText(b);
font.setEmbeddedBitmaps(b);
fuzz->next(&b);
p.setFakeBoldText(b);
font.setEmbolden(b);
fuzz->next(&b);
p.setLCDRenderText(b);
font.setEdging(b ? SkFont::Edging::kAntiAlias : SkFont::Edging::kSubpixelAntiAlias);
fuzz->next(&b);
p.setLinearText(b);
font.setLinearMetrics(b);
fuzz->next(&b);
p.setSubpixelText(b);
font.setSubpixel(b);
fuzz->next(&x);
p.setTextScaleX(x);
font.setScaleX(x);
fuzz->next(&x);
p.setTextSkewX(x);
font.setSkewX(x);
fuzz->next(&x);
p.setTextSize(x);
font.setSize(x);
SkCanvas* cnv = surface->getCanvas();
cnv->drawPosText(text, (kTxtLen-1), pts, p);
fuzz->next(&x);
fuzz->next(&y);
cnv->drawText(text, (kTxtLen-1), x, y, p);
cnv->drawTextBlob(SkTextBlob::MakeFromPosText(text, kTxtLen-1, pts, font), x, y, p);
}
static void fuzz_drawCircle(Fuzz* fuzz) {

View File

@ -118,7 +118,6 @@ bench_sources = [
"$_bench/StrokeBench.cpp",
"$_bench/SwizzleBench.cpp",
"$_bench/TableBench.cpp",
"$_bench/TextBench.cpp",
"$_bench/TextBlobBench.cpp",
"$_bench/TileBench.cpp",
"$_bench/TileImageFilterBench.cpp",

View File

@ -15,7 +15,6 @@ samples_sources = [
"$_samplecode/SampleAAGeometry.cpp",
"$_samplecode/SampleAARectModes.cpp",
"$_samplecode/SampleAARects.cpp",
"$_samplecode/SampleAll.cpp",
"$_samplecode/SampleAndroidShadows.cpp",
"$_samplecode/SampleAnimatedImage.cpp",
"$_samplecode/SampleAnimatedText.cpp",
@ -91,7 +90,6 @@ samples_sources = [
"$_samplecode/SampleStrokeRect.cpp",
"$_samplecode/SampleSubpixelTranslate.cpp",
"$_samplecode/SampleSVGFile.cpp",
"$_samplecode/SampleText.cpp",
"$_samplecode/SampleTextAlpha.cpp",
"$_samplecode/SampleTextBox.cpp",
"$_samplecode/SampleTextEffects.cpp",

View File

@ -1,312 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Sample.h"
#include "DecodeFile.h"
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkColorMatrixFilter.h"
#include "SkColorPriv.h"
#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkDiscretePathEffect.h"
#include "SkEmbossMaskFilter.h"
#include "SkGradientShader.h"
#include "SkMath.h"
#include "SkPath.h"
#include "SkPathMeasure.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkRandom.h"
#include "SkReadBuffer.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkTypeface.h"
#include "SkUTF.h"
#include "SkWriteBuffer.h"
#include <math.h>
class Dot2DPathEffect : public Sk2DPathEffect {
public:
Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
: Sk2DPathEffect(matrix), fRadius(radius) {}
protected:
void next(const SkPoint& loc, int u, int v, SkPath* dst) const override {
dst->addCircle(loc.fX, loc.fY, fRadius);
}
void flatten(SkWriteBuffer& buffer) const override {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fRadius);
}
private:
SK_FLATTENABLE_HOOKS(Dot2DPathEffect)
SkScalar fRadius;
typedef Sk2DPathEffect INHERITED;
};
class DemoView : public Sample {
public:
DemoView() {}
protected:
virtual bool onQuery(Sample::Event* evt) {
if (Sample::TitleQ(*evt)) {
Sample::TitleR(evt, "Demo");
return true;
}
return this->INHERITED::onQuery(evt);
}
virtual bool onClick(Click* click) {
return this->INHERITED::onClick(click);
}
void makePath(SkPath& path) {
path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
SkPath::kCCW_Direction);
for (int index = 0; index < 10; index++) {
SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
x *= index & 1 ? 7 : 14;
y *= index & 1 ? 7 : 14;
x += SkIntToScalar(20);
y += SkIntToScalar(20);
if (index == 0)
path.moveTo(x, y);
else
path.lineTo(x, y);
}
path.close();
}
virtual void onDrawContent(SkCanvas* canvas) {
canvas->save();
this->drawPicture(canvas, 0);
canvas->restore();
{
SkPictureRecorder recorder;
{
SkCanvas* record = recorder.beginRecording(320, 480, nullptr, 0);
this->drawPicture(record, 120);
}
sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
canvas->translate(0, SkIntToScalar(120));
SkRect clip;
clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
do {
canvas->save();
canvas->clipRect(clip);
picture->playback(canvas);
canvas->restore();
if (clip.fRight < SkIntToScalar(320))
clip.offset(SkIntToScalar(160), 0);
else if (clip.fBottom < SkIntToScalar(480))
clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
else
break;
} while (true);
}
}
void drawPicture(SkCanvas* canvas, int spriteOffset) {
SkMatrix matrix; matrix.reset();
SkPaint paint;
SkPath path;
SkPoint start = {0, 0};
SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
SkScalar left = 0, top = 0, x = 0, y = 0;
int index;
char ascii[] = "ascii...";
int asciiLength = sizeof(ascii) - 1;
char utf8[] = "utf8" "\xe2\x80\xa6";
makePath(path);
SkTDArray<SkPoint> pos;
pos.setCount(asciiLength);
for (index = 0; index < asciiLength; index++)
pos[index].set(SkIntToScalar((unsigned int)index * 10),
SkIntToScalar((unsigned int)index * 2));
SkTDArray<SkPoint> pos2;
pos2.setCount(asciiLength);
for (index = 0; index < asciiLength; index++)
pos2[index].set(SkIntToScalar((unsigned int)index * 10),
SkIntToScalar(20));
// shaders
SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
SkScalar* linearPos = nullptr;
int linearCount = 2;
SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
auto linear = SkGradientShader::MakeLinear(linearPoints,
linearColors, linearPos, linearCount, linearMode);
SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
SkScalar radialRadius = SkIntToScalar(25);
SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
int radialCount = 3;
SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
auto radial = SkGradientShader::MakeRadial(radialCenter,
radialRadius, radialColors, radialPos, radialCount,
radialMode);
SkEmbossMaskFilter::Light light;
light.fDirection[0] = SK_Scalar1/2;
light.fDirection[1] = SK_Scalar1/2;
light.fDirection[2] = SK_Scalar1/3;
light.fAmbient = 0x48;
light.fSpecular = 0x80;
auto lightingFilter = SkColorMatrixFilter::MakeLightingFilter(
0xff89bc45, 0xff112233);
canvas->save();
canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
paint.setAntiAlias(true);
paint.setFilterQuality(kLow_SkFilterQuality);
// !!! draw through a clip
paint.setColor(SK_ColorLTGRAY);
paint.setStyle(SkPaint::kFill_Style);
SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
canvas->clipRect(clip);
paint.setShader(SkShader::MakeBitmapShader(fTx,
SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode));
canvas->drawPaint(paint);
canvas->save();
// line (exercises xfermode, colorShader, colorFilter, filterShader)
paint.setColor(SK_ColorGREEN);
paint.setStrokeWidth(SkIntToScalar(10));
paint.setStyle(SkPaint::kStroke_Style);
paint.setBlendMode(SkBlendMode::kXor);
paint.setColorFilter(lightingFilter);
canvas->drawLine(start, stop, paint); // should not be green
paint.setBlendMode(SkBlendMode::kSrcOver);
paint.setColorFilter(nullptr);
// rectangle
paint.setStyle(SkPaint::kFill_Style);
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorYELLOW);
paint.setShader(linear);
paint.setPathEffect(pathEffectTest());
canvas->drawRect(rect, paint);
paint.setPathEffect(nullptr);
// circle w/ emboss & transparent (exercises 3dshader)
canvas->translate(SkIntToScalar(50), 0);
paint.setMaskFilter(SkEmbossMaskFilter::Make(
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5), light));
canvas->drawOval(rect, paint);
canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
// paint.setShader(transparentShader)->unref();
canvas->drawOval(rect, paint);
canvas->translate(0, SkIntToScalar(-10));
// path
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorRED);
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SkIntToScalar(5));
paint.setShader(radial);
paint.setMaskFilter(nullptr);
canvas->drawPath(path, paint);
paint.setShader(nullptr);
// bitmap
canvas->translate(SkIntToScalar(50), 0);
paint.setStyle(SkPaint::kFill_Style);
canvas->drawBitmap(fBug, left, top, &paint);
canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
paint.setShader(shaderTest()); // test compose shader
canvas->drawRect(rect2, paint);
paint.setShader(nullptr);
canvas->restore();
// text
canvas->translate(0, SkIntToScalar(60));
canvas->save();
paint.setColor(SK_ColorGRAY);
canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
canvas->translate(SkIntToScalar(50), 0);
paint.setColor(SK_ColorCYAN);
canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
canvas->translate(0, SkIntToScalar(60));
paint.setTextEncoding(kUTF8_SkTextEncoding);
canvas->restore();
}
virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
fClickPt.set(x, y);
return this->INHERITED::onFindClickHandler(x, y, modi);
}
sk_sp<SkPathEffect> pathEffectTest() {
static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
SkScalar gPhase = 0;
SkPath path;
path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
path.close();
path.offset(SkIntToScalar(-6), 0);
auto outer = SkPath1DPathEffect::Make(path, SkIntToScalar(12),
gPhase, SkPath1DPathEffect::kRotate_Style);
auto inner = SkDiscretePathEffect::Make(SkIntToScalar(2),
SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
return SkPathEffect::MakeCompose(outer, inner);
}
sk_sp<SkShader> shaderTest() {
SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr,
2, SkShader::kClamp_TileMode);
pts[1].set(0, SkIntToScalar(100));
SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
auto shaderB = SkGradientShader::MakeLinear(pts, colors2, nullptr,
2, SkShader::kClamp_TileMode);
return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB),
SkBlendMode::kDstIn);
}
virtual void startTest() {
decode_file("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
decode_file("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
decode_file("/Users/caryclark/Desktop/05psp04.gif", &fTx);
}
private:
SkPoint fClickPt;
SkBitmap fBug, fTb, fTx;
typedef Sample INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_SAMPLE( return new DemoView(); )

View File

@ -1,164 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Sample.h"
#include "SkCanvas.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUTF.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"
#include "SkStream.h"
static const struct {
const char* fName;
uint32_t fFlags;
bool fFlushCache;
} gHints[] = {
{ "Linear", SkPaint::kLinearText_Flag, false },
{ "Normal", 0, true },
{ "Subpixel", SkPaint::kSubpixelText_Flag, true }
};
static void DrawTheText(SkCanvas* canvas, const char text[], size_t length, SkScalar x, SkScalar y,
const SkPaint& paint, SkScalar clickX) {
SkPaint p(paint);
#if 0
canvas->drawText(text, length, x, y, paint);
#else
{
SkPoint pts[1000];
SkScalar xpos = x;
SkASSERT(length <= SK_ARRAY_COUNT(pts));
for (size_t i = 0; i < length; i++) {
pts[i].set(xpos, y);
xpos += paint.getTextSize();
}
canvas->drawPosText(text, length, pts, paint);
}
#endif
p.setSubpixelText(true);
x += SkIntToScalar(180);
canvas->drawText(text, length, x, y, p);
#ifdef SK_DEBUG
if (true) {
p.setSubpixelText(false);
p.setLinearText(true);
x += SkIntToScalar(180);
canvas->drawText(text, length, x, y, p);
}
#endif
}
class TextSpeedView : public Sample {
public:
TextSpeedView() {
fHints = 0;
fClickX = 0;
}
protected:
bool onQuery(Sample::Event* evt) override {
if (Sample::TitleQ(*evt)) {
Sample::TitleR(evt, "Text");
return true;
}
return this->INHERITED::onQuery(evt);
}
static void make_textstrip(SkBitmap* bm) {
bm->allocPixels(SkImageInfo::Make(200, 18, kRGB_565_SkColorType,
kOpaque_SkAlphaType));
bm->eraseColor(SK_ColorWHITE);
SkCanvas canvas(*bm);
SkPaint paint;
const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit";
paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag);
paint.setTextSize(SkIntToScalar(14));
canvas.drawString(s, SkIntToScalar(8), SkIntToScalar(14), paint);
}
static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) {
for (size_t i = 0; i < n; i++)
pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480);
}
void onDrawContent(SkCanvas* canvas) override {
SkAutoCanvasRestore restore(canvas, false);
{
SkRect r;
r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20));
// canvas->saveLayer(&r, nullptr, SkCanvas::kHasAlphaLayer_SaveFlag);
}
SkPaint paint;
// const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
int index = fHints % SK_ARRAY_COUNT(gHints);
index = 1;
// const char* style = gHints[index].fName;
// canvas->translate(0, SkIntToScalar(50));
// canvas->drawString(style, SkIntToScalar(20), SkIntToScalar(20), paint);
paint.setTypeface(SkTypeface::MakeFromFile("/skimages/samplefont.ttf"));
paint.setAntiAlias(true);
paint.setFlags(paint.getFlags() | gHints[index].fFlags);
SkRect clip;
clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155));
const char* text = "Hamburgefons";
size_t length = strlen(text);
SkScalar y = SkIntToScalar(0);
for (int i = 9; i <= 24; i++) {
paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/);
for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4;
dx += SkIntToScalar(1) /* /4 */) {
y += paint.getFontSpacing();
DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX);
}
}
if (gHints[index].fFlushCache) {
// SkGraphics::SetFontCacheUsed(0);
}
}
virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
unsigned modi) override {
fClickX = x;
return this->INHERITED::onFindClickHandler(x, y, modi);
}
bool onClick(Click* click) override {
return this->INHERITED::onClick(click);
}
private:
int fHints;
SkScalar fClickX;
typedef Sample INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_SAMPLE( return new TextSpeedView(); )

View File

@ -459,7 +459,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
BREAK_ON_READ_ERROR(reader);
if (paint && text.text()) {
canvas->drawPosText(text.text(), text.length(), pos, *paint);
SkFont font = SkFont::LEGACY_ExtractFromPaint(*paint);
auto blob = SkTextBlob::MakeFromPosText(text.text(), text.length(), pos, font,
paint->getTextEncoding());
canvas->drawTextBlob(blob, 0, 0, *paint);
}
} break;
case DRAW_POS_TEXT_TOP_BOTTOM: {
@ -474,7 +477,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
SkRect clip = canvas->getLocalClipBounds();
if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
canvas->drawPosText(text.text(), text.length(), pos, *paint);
SkFont font = SkFont::LEGACY_ExtractFromPaint(*paint);
auto blob = SkTextBlob::MakeFromPosText(text.text(), text.length(), pos, font,
paint->getTextEncoding());
canvas->drawTextBlob(blob, 0, 0, *paint);
}
} break;
case DRAW_POS_TEXT_H: {
@ -487,7 +493,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
BREAK_ON_READ_ERROR(reader);
if (paint && text.text()) {
canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
SkFont font = SkFont::LEGACY_ExtractFromPaint(*paint);
auto blob = SkTextBlob::MakeFromPosTextH(text.text(), text.length(), xpos, constY,
font, paint->getTextEncoding());
canvas->drawTextBlob(blob, 0, 0, *paint);
}
} break;
case DRAW_POS_TEXT_H_TOP_BOTTOM: {
@ -504,7 +513,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
const SkScalar constY = *xpos++;
SkRect clip = canvas->getLocalClipBounds();
if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
SkFont font = SkFont::LEGACY_ExtractFromPaint(*paint);
auto blob = SkTextBlob::MakeFromPosTextH(text.text(), text.length(), xpos, constY,
font, paint->getTextEncoding());
canvas->drawTextBlob(blob, 0, 0, *paint);
}
} break;
case DRAW_RECT: {

View File

@ -64,55 +64,6 @@ static bool compare(const SkBitmap& ref, const SkIRect& iref,
return true;
}
DEF_TEST(DrawText, reporter) {
SkPaint paint;
paint.setColor(SK_ColorGRAY);
paint.setTextSize(SkIntToScalar(20));
SkIRect drawTextRect = SkIRect::MakeWH(64, 64);
SkBitmap drawTextBitmap;
create(&drawTextBitmap, drawTextRect);
SkCanvas drawTextCanvas(drawTextBitmap);
SkIRect drawPosTextRect = SkIRect::MakeWH(64, 64);
SkBitmap drawPosTextBitmap;
create(&drawPosTextBitmap, drawPosTextRect);
SkCanvas drawPosTextCanvas(drawPosTextBitmap);
// Two test cases "A" for the normal path through the code, and " " to check the
// early return path.
const char* cases[] = {"A", " "};
for (auto c : cases) {
for (float offsetY = 0.0f; offsetY < 1.0f; offsetY += (1.0f / 16.0f)) {
for (float offsetX = 0.0f; offsetX < 1.0f; offsetX += (1.0f / 16.0f)) {
SkPoint point = SkPoint::Make(25.0f + offsetX,
25.0f + offsetY);
for (unsigned int flags = 0; flags < (1 << 3); ++flags) {
static const unsigned int antiAliasFlag = 1;
static const unsigned int subpixelFlag = 1 << 1;
static const unsigned int lcdFlag = 1 << 2;
paint.setAntiAlias(SkToBool(flags & antiAliasFlag));
paint.setSubpixelText(SkToBool(flags & subpixelFlag));
paint.setLCDRenderText(SkToBool(flags & lcdFlag));
// Test: drawText and drawPosText draw the same.
drawBG(&drawTextCanvas);
drawTextCanvas.drawText(c, 1, point.fX, point.fY, paint);
drawBG(&drawPosTextCanvas);
drawPosTextCanvas.drawPosText(c, 1, &point, paint);
REPORTER_ASSERT(reporter,
compare(drawTextBitmap, drawTextRect,
drawPosTextBitmap, drawPosTextRect));
}
}
}
}
}
/** Test that drawing glyphs with empty paths is different from drawing glyphs without paths. */
DEF_TEST(DrawText_dashout, reporter) {
SkIRect size = SkIRect::MakeWH(64, 64);

View File

@ -8,6 +8,7 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkFont.h"
#include "SkFontDescriptor.h"
#include "SkGraphics.h"
#include "SkPaint.h"
@ -65,9 +66,8 @@ DEF_TEST(FontHostStream, reporter) {
{
SkPaint paint;
paint.setColor(SK_ColorGRAY);
paint.setTextSize(SkIntToScalar(30));
paint.setTypeface(SkTypeface::MakeFromName("Georgia", SkFontStyle()));
SkFont font(SkTypeface::MakeFromName("Georgia", SkFontStyle()), 30);
SkIRect origRect = SkIRect::MakeWH(64, 64);
SkBitmap origBitmap;
@ -83,7 +83,7 @@ DEF_TEST(FontHostStream, reporter) {
// Test: origTypeface and streamTypeface from orig data draw the same
drawBG(&origCanvas);
origCanvas.drawString("A", point.fX, point.fY, paint);
origCanvas.drawSimpleText("A", 1, kUTF8_SkTextEncoding, point.fX, point.fY, font, paint);
sk_sp<SkTypeface> typeface = SkPaintPriv::RefTypefaceOrDefault(paint);
int ttcIndex;
@ -103,7 +103,7 @@ DEF_TEST(FontHostStream, reporter) {
paint.setTypeface(streamTypeface);
drawBG(&streamCanvas);
streamCanvas.drawPosText("A", 1, &point, paint);
streamCanvas.drawSimpleText("A", 1, kUTF8_SkTextEncoding, point.fX, point.fY, font, paint);
REPORTER_ASSERT(reporter,
compare(origBitmap, origRect, streamBitmap, streamRect));

View File

@ -114,12 +114,14 @@ void test_whitespace_pos(skiatest::Reporter* reporter,
SkDOM dom;
SkPaint paint;
SkFont font;
SkPoint offset = SkPoint::Make(10, 20);
{
SkXMLParserWriter writer(dom.beginParsing());
std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
svgCanvas->drawText(txt, len, offset.x(), offset.y(), paint);
svgCanvas->drawSimpleText(txt, len, kUTF8_SkTextEncoding, offset.x(), offset.y(),
font, paint);
}
check_text_node(reporter, dom, dom.finishParsing(), offset, 2, expected);
@ -131,7 +133,8 @@ void test_whitespace_pos(skiatest::Reporter* reporter,
SkXMLParserWriter writer(dom.beginParsing());
std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
svgCanvas->drawPosTextH(txt, len, xpos, offset.y(), paint);
auto blob = SkTextBlob::MakeFromPosTextH(txt, len, &xpos[0], offset.y(), font);
svgCanvas->drawTextBlob(blob, 0, 0, paint);
}
check_text_node(reporter, dom, dom.finishParsing(), offset, 2, expected);
@ -142,8 +145,8 @@ void test_whitespace_pos(skiatest::Reporter* reporter,
}
SkXMLParserWriter writer(dom.beginParsing());
std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
svgCanvas->drawPosText(txt, len, pos, paint);
auto blob = SkTextBlob::MakeFromPosTextH(txt, len, &pos[0], font);
svgCanvas->drawTextBlob(blob, 0, 0, paint);
}
check_text_node(reporter, dom, dom.finishParsing(), offset, 2, expected);
}

View File

@ -409,19 +409,6 @@ static void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface)
testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1);
SkString testText("Hello World");
const SkPoint testPoints2[] = {
{ SkIntToScalar(0), SkIntToScalar(1) },
{ SkIntToScalar(1), SkIntToScalar(1) },
{ SkIntToScalar(2), SkIntToScalar(1) },
{ SkIntToScalar(3), SkIntToScalar(1) },
{ SkIntToScalar(4), SkIntToScalar(1) },
{ SkIntToScalar(5), SkIntToScalar(1) },
{ SkIntToScalar(6), SkIntToScalar(1) },
{ SkIntToScalar(7), SkIntToScalar(1) },
{ SkIntToScalar(8), SkIntToScalar(1) },
{ SkIntToScalar(9), SkIntToScalar(1) },
{ SkIntToScalar(10), SkIntToScalar(1) },
};
#define EXPECT_COPY_ON_WRITE(command) \
{ \
@ -444,9 +431,8 @@ static void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface)
EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0))
EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, testRect, nullptr))
EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, nullptr))
EXPECT_COPY_ON_WRITE(drawString(testText, 0, 1, testPaint))
EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \
testPaint))
EXPECT_COPY_ON_WRITE(drawSimpleText(testText.c_str(), testText.size(), kUTF8_SkTextEncoding, \
0, 1, SkFont(), testPaint))
}
DEF_TEST(SurfaceCopyOnWrite, reporter) {
test_copy_on_write(reporter, create_surface().get());