92 }
else if (fDepth > 0.f) {
94 }
else if (fDepth < 0.f) {
130 paint->setStrokeWidth(0.f);
151 , fHairline(hairline) {}
159 bool forceRaster =
false) {
162 supersample, forceRaster));
167 if (fSupersampleFactor != 1) {
168 name.
prependf(
"%dx-", fSupersampleFactor * fSupersampleFactor);
174 return Make(fRenderer->toHairline(), fSupersampleFactor, fForceRasterBackend);
195 surface->getCanvas()->scale(fSupersampleFactor, fSupersampleFactor);
196 fRenderer->draw(
surface->getCanvas(),
paint, tx, ty, angle);
197 surface->getCanvas()->restore();
201 fLastRendered =
surface->makeImageSnapshot();
211 static constexpr float kFilter[] = {
212 0.f, 0.f, 0.f, 0.f, 16.f/255,
213 0.f, 0.f, 0.f, 0.f, 200.f/255,
214 0.f, 0.f, 0.f, 0.f, 16.f/255,
215 0.f, 0.f, 0.f, 255.f, 0.f
233 bool fForceRasterBackend;
236 int fSupersampleFactor;
239 : fForceRasterBackend(forceRaster)
240 , fLastRendered(nullptr)
241 , fRenderer(
std::move(renderer))
242 , fSupersampleFactor(supersample) { }
257 for (
int i = 0; i < fShapes.size(); ++i) {
273 fCurrentStage = AnimStage::kMoveLeft;
274 fLastFrameTime = -1.f;
277 fAnimTranslate =
false;
282 canvas->
clear(0xFFFFFFFF);
287 canvas->
drawString(
"Each row features a rendering command under different AA strategies. "
288 "Native refers to the current backend of the viewer, e.g. OpenGL.",
292 fStrokeWidth), 0, 24, font,
text);
294 " to 0, 'space' adds 15)", fAngle), 0, 36, font,
text);
296 fSubpixelX, fSubpixelY), 0, 48, font,
text);
301 this->drawShapes(canvas,
"Native", 0, fNative);
304 this->drawShapes(canvas,
"Raster", 1, fRaster);
307 this->drawShapes(canvas,
"Hairline", 2, fHairline);
310 this->drawShapes(canvas,
"SSx16", 3, fSS4);
313 this->drawShapes(canvas,
"SSx64", 4, fSS16);
318 SkScalar dt = fLastFrameTime < 0.f ? 0.f : t - fLastFrameTime;
321 if (!fAnimRotate && !fAnimTranslate) {
323 fLastFrameTime = -1.f;
327 switch(fCurrentStage) {
328 case AnimStage::kMoveLeft:
329 fSubpixelX += 2.f * dt;
330 if (fSubpixelX >= 1.f) {
332 fCurrentStage = AnimStage::kMoveDown;
335 case AnimStage::kMoveDown:
336 fSubpixelY += 2.f * dt;
337 if (fSubpixelY >= 1.f) {
339 fCurrentStage = AnimStage::kMoveRight;
342 case AnimStage::kMoveRight:
343 fSubpixelX -= 2.f * dt;
344 if (fSubpixelX <= -1.f) {
346 fCurrentStage = AnimStage::kMoveUp;
349 case AnimStage::kMoveUp:
350 fSubpixelY -= 2.f * dt;
351 if (fSubpixelY <= -1.f) {
353 fCurrentStage = fAnimRotate ? AnimStage::kRotate : AnimStage::kMoveLeft;
356 case AnimStage::kRotate: {
357 SkScalar newAngle = fAngle + dt * 15.f;
363 if (fAnimTranslate) {
364 fCurrentStage = this->getTranslationStage();
377 fAnimTranslate = !fAnimTranslate;
378 if (!fAnimTranslate && fAnimRotate && fCurrentStage != AnimStage::kRotate) {
380 fCurrentStage = AnimStage::kRotate;
381 }
else if (fAnimTranslate && !fAnimRotate &&
382 fCurrentStage == AnimStage::kRotate) {
384 fCurrentStage = this->getTranslationStage();
389 fAnimRotate = !fAnimRotate;
390 if (!fAnimRotate && fAnimTranslate && fCurrentStage == AnimStage::kRotate) {
392 fCurrentStage = this->getTranslationStage();
393 }
else if (fAnimRotate && !fAnimTranslate &&
394 fCurrentStage != AnimStage::kRotate) {
396 fCurrentStage = AnimStage::kRotate;
399 case 'u': fAngle = 0.f;
return true;
400 case 'y': fAngle = 90.f;
return true;
401 case ' ': fAngle =
SkScalarMod(fAngle + 15.f, 360.f);
return true;
402 case '-': fStrokeWidth = std::max(0.1f, fStrokeWidth - 0.05f);
return true;
403 case '=': fStrokeWidth = std::min(1.f, fStrokeWidth + 0.05f);
return true;
422 enum class AnimStage {
423 kMoveRight, kMoveDown, kMoveLeft, kMoveUp, kRotate
434 AnimStage getTranslationStage() {
438 if (fSubpixelX > -1.f) {
439 if (fSubpixelX >= 1.f) {
441 return AnimStage::kMoveDown;
442 }
else if (fSubpixelY > 0.f) {
444 return AnimStage::kMoveRight;
447 return AnimStage::kMoveLeft;
451 return fSubpixelY > -1.f ? AnimStage::kMoveUp : AnimStage::kMoveLeft;
455 void drawShapes(
SkCanvas* canvas,
const char*
name,
int gridX,
459 for (
int i = 0; i < shapes.size(); ++i) {
460 this->drawShape(canvas,
name, gridX, shapes[i].
get(), i == 0);
465 void drawShape(
SkCanvas* canvas,
const char*
name,
int gridX,
466 OffscreenShapeRenderer* shape,
bool drawNameLabels) {
479 SkScalar centering = shape->name().size() * 4.f;
487 if (drawNameLabels) {
499 paint.setAntiAlias(
true);
500 paint.setStrokeWidth(fStrokeWidth);
504 shape->prepareBuffer(canvas, &
paint, fSubpixelX, fSubpixelY, fAngle);
511 canvas->
drawRect(kZoomTile, outline);
512 shape->redraw(canvas, 8.0f);
520 shape->redraw(canvas, 1.f);
528 shape->redraw(canvas, 1.f,
true);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
constexpr SkColor SK_ColorTRANSPARENT
constexpr SkColor SK_ColorWHITE
#define SkScalarMod(x, y)
#define SkScalarRoundToScalar(x)
SK_API SkString static SkString SkStringPrintf()
void drawRect(const SkRect &rect, const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
@ kFast_SrcRectConstraint
sample outside bounds; faster
void clear(SkColor color)
void rotate(SkScalar degrees)
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
static sk_sp< SkColorFilter > Matrix(const SkColorMatrix &)
void setStyle(Style style)
void setColor(SkColor color)
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
@ kMiter_Join
extends to miter limit
void setColorFilter(sk_sp< SkColorFilter > colorFilter)
void append(const char text[])
void void void void void prependf(const char format[],...) SK_PRINTF_LIKE(2
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
void redraw(SkCanvas *canvas, SkScalar scale=1.f, bool debugMode=false)
sk_sp< ShapeRenderer > toHairline() override
static sk_sp< OffscreenShapeRenderer > Make(sk_sp< ShapeRenderer > renderer, int supersample, bool forceRaster=false)
~OffscreenShapeRenderer() override=default
void prepareBuffer(SkCanvas *canvas, SkPaint *paint, SkScalar tx, SkScalar ty, SkScalar angle)
void draw(SkCanvas *canvas, SkPaint *paint, SkScalar tx, SkScalar ty, SkScalar angle) override
static sk_sp< ShapeRenderer > MakeCurve(SkScalar depth, bool hairline=false)
sk_sp< ShapeRenderer > toHairline() override
static sk_sp< ShapeRenderer > MakeLine(bool hairline=false)
void draw(SkCanvas *canvas, SkPaint *paint, SkScalar tx, SkScalar ty, SkScalar angle) override
static sk_sp< ShapeRenderer > MakeLines(SkScalar depth, bool hairline=false)
void draw(SkCanvas *canvas, SkPaint *paint, SkScalar tx, SkScalar ty, SkScalar angle) override
static sk_sp< ShapeRenderer > Make()
sk_sp< ShapeRenderer > toHairline() override
virtual sk_sp< ShapeRenderer > toHairline()=0
static constexpr SkScalar kTileHeight
static constexpr SkScalar kTileWidth
virtual void draw(SkCanvas *canvas, SkPaint *paint, SkScalar tx, SkScalar ty, SkScalar angle)=0
void applyLocalTransform(SkCanvas *canvas, SkScalar tx, SkScalar ty, SkScalar angle)
virtual SkString name()=0
void load(SkScalar w, SkScalar h) override
bool animate(double nanos) override
bool onChar(SkUnichar key) override
void draw(SkCanvas *canvas) override
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
font
Font Metadata and Metrics.
const myers::Point & get(const myers::Segment &)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)