123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- /*
- * 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 "gm/gm.h"
- #include "include/core/SkCanvas.h"
- #include "include/core/SkColor.h"
- #include "include/core/SkFont.h"
- #include "include/core/SkPaint.h"
- #include "include/core/SkPath.h"
- #include "include/core/SkPoint.h"
- #include "include/core/SkRect.h"
- #include "include/core/SkScalar.h"
- #include "include/core/SkSize.h"
- #include "include/core/SkString.h"
- #include "include/core/SkTypeface.h"
- #include "include/core/SkTypes.h"
- #include "include/utils/SkRandom.h"
- #include "tools/ToolUtils.h"
- namespace skiagm {
- class DegenerateSegmentsGM : public GM {
- struct PathAndName {
- SkPath fPath;
- const char* fName1;
- const char* fName2;
- };
- SkString onShortName() override { return SkString("degeneratesegments"); }
- SkISize onISize() override { return {896, 930}; }
- typedef SkPoint (*AddSegmentFunc)(SkPath&, SkPoint&);
- // We need to use explicit commands here, instead of addPath, because we
- // do not want the moveTo that is added at the beginning of a path to
- // appear in the appended path.
- static SkPoint AddMove(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- return moveToPt;
- }
- static SkPoint AddMoveClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.close();
- return moveToPt;
- }
- static SkPoint AddDegenLine(SkPath& path, SkPoint& startPt) {
- path.lineTo(startPt);
- return startPt;
- }
- static SkPoint AddMoveDegenLine(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.lineTo(moveToPt);
- return moveToPt;
- }
- static SkPoint AddMoveDegenLineClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.lineTo(moveToPt);
- path.close();
- return moveToPt;
- }
- static SkPoint AddDegenQuad(SkPath& path, SkPoint& startPt) {
- path.quadTo(startPt, startPt);
- return startPt;
- }
- static SkPoint AddMoveDegenQuad(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.quadTo(moveToPt, moveToPt);
- return moveToPt;
- }
- static SkPoint AddMoveDegenQuadClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.quadTo(moveToPt, moveToPt);
- path.close();
- return moveToPt;
- }
- static SkPoint AddDegenCubic(SkPath& path, SkPoint& startPt) {
- path.cubicTo(startPt, startPt, startPt);
- return startPt;
- }
- static SkPoint AddMoveDegenCubic(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.cubicTo(moveToPt, moveToPt, moveToPt);
- return moveToPt;
- }
- static SkPoint AddMoveDegenCubicClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- path.moveTo(moveToPt);
- path.cubicTo(moveToPt, moveToPt, moveToPt);
- path.close();
- return moveToPt;
- }
- static SkPoint AddClose(SkPath& path, SkPoint& startPt) {
- path.close();
- return startPt;
- }
- static SkPoint AddLine(SkPath& path, SkPoint& startPt) {
- SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.lineTo(endPt);
- return endPt;
- }
- static SkPoint AddMoveLine(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.lineTo(endPt);
- return endPt;
- }
- static SkPoint AddMoveLineClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.lineTo(endPt);
- path.close();
- return endPt;
- }
- static SkPoint AddQuad(SkPath& path, SkPoint& startPt) {
- SkPoint midPt = startPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.quadTo(midPt, endPt);
- return endPt;
- }
- static SkPoint AddMoveQuad(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.quadTo(midPt, endPt);
- return endPt;
- }
- static SkPoint AddMoveQuadClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.quadTo(midPt, endPt);
- path.close();
- return endPt;
- }
- static SkPoint AddCubic(SkPath& path, SkPoint& startPt) {
- SkPoint t1Pt = startPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
- SkPoint t2Pt = startPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.cubicTo(t1Pt, t2Pt, endPt);
- return endPt;
- }
- static SkPoint AddMoveCubic(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
- SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.cubicTo(t1Pt, t2Pt, endPt);
- return endPt;
- }
- static SkPoint AddMoveCubicClose(SkPath& path, SkPoint& startPt) {
- SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
- SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
- SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
- SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
- path.moveTo(moveToPt);
- path.cubicTo(t1Pt, t2Pt, endPt);
- path.close();
- return endPt;
- }
- void drawPath(SkPath& path, SkCanvas* canvas, SkColor color,
- const SkRect& clip, SkPaint::Cap cap, SkPaint::Join join,
- SkPaint::Style style, SkPath::FillType fill,
- SkScalar strokeWidth) {
- path.setFillType(fill);
- SkPaint paint;
- paint.setStrokeCap(cap);
- paint.setStrokeWidth(strokeWidth);
- paint.setStrokeJoin(join);
- paint.setColor(color);
- paint.setStyle(style);
- canvas->save();
- canvas->clipRect(clip);
- canvas->drawPath(path, paint);
- canvas->restore();
- }
- void onDraw(SkCanvas* canvas) override {
- constexpr AddSegmentFunc gSegmentFunctions[] = {
- AddMove,
- AddMoveClose,
- AddDegenLine,
- AddMoveDegenLine,
- AddMoveDegenLineClose,
- AddDegenQuad,
- AddMoveDegenQuad,
- AddMoveDegenQuadClose,
- AddDegenCubic,
- AddMoveDegenCubic,
- AddMoveDegenCubicClose,
- AddClose,
- AddLine,
- AddMoveLine,
- AddMoveLineClose,
- AddQuad,
- AddMoveQuad,
- AddMoveQuadClose,
- AddCubic,
- AddMoveCubic,
- AddMoveCubicClose
- };
- const char* gSegmentNames[] = {
- "Move",
- "MoveClose",
- "DegenLine",
- "MoveDegenLine",
- "MoveDegenLineClose",
- "DegenQuad",
- "MoveDegenQuad",
- "MoveDegenQuadClose",
- "DegenCubic",
- "MoveDegenCubic",
- "MoveDegenCubicClose",
- "Close",
- "Line",
- "MoveLine",
- "MoveLineClose",
- "Quad",
- "MoveQuad",
- "MoveQuadClose",
- "Cubic",
- "MoveCubic",
- "MoveCubicClose"
- };
- struct FillAndName {
- SkPath::FillType fFill;
- const char* fName;
- };
- constexpr FillAndName gFills[] = {
- {SkPath::kWinding_FillType, "Winding"},
- {SkPath::kEvenOdd_FillType, "Even / Odd"},
- {SkPath::kInverseWinding_FillType, "Inverse Winding"},
- {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}
- };
- struct StyleAndName {
- SkPaint::Style fStyle;
- const char* fName;
- };
- constexpr StyleAndName gStyles[] = {
- {SkPaint::kFill_Style, "Fill"},
- {SkPaint::kStroke_Style, "Stroke 10"},
- {SkPaint::kStrokeAndFill_Style, "Stroke 10 And Fill"}
- };
- struct CapAndName {
- SkPaint::Cap fCap;
- SkPaint::Join fJoin;
- const char* fName;
- };
- constexpr CapAndName gCaps[] = {
- {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
- {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
- {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
- };
- SkPaint titlePaint;
- titlePaint.setColor(SK_ColorBLACK);
- titlePaint.setAntiAlias(true);
- SkFont font(ToolUtils::create_portable_typeface(), 15);
- const char title[] = "Random Paths Drawn Into Rectangle Clips With "
- "Indicated Style, Fill and Linecaps, "
- "with Stroke width 6";
- canvas->drawString(title, 20, 20, font, titlePaint);
- SkRandom rand;
- SkRect rect = SkRect::MakeWH(220*SK_Scalar1, 50*SK_Scalar1);
- canvas->save();
- canvas->translate(2*SK_Scalar1, 30 * SK_Scalar1); // The title
- canvas->save();
- unsigned numSegments = SK_ARRAY_COUNT(gSegmentFunctions);
- unsigned numCaps = SK_ARRAY_COUNT(gCaps);
- unsigned numStyles = SK_ARRAY_COUNT(gStyles);
- unsigned numFills = SK_ARRAY_COUNT(gFills);
- for (size_t row = 0; row < 6; ++row) {
- if (0 < row) {
- canvas->translate(0, rect.height() + 100*SK_Scalar1);
- }
- canvas->save();
- for (size_t column = 0; column < 4; ++column) {
- if (0 < column) {
- canvas->translate(rect.width() + 4*SK_Scalar1, 0);
- }
- SkColor color = ToolUtils::color_to_565(0xff007000);
- StyleAndName style = gStyles[(rand.nextU() >> 16) % numStyles];
- CapAndName cap = gCaps[(rand.nextU() >> 16) % numCaps];
- FillAndName fill = gFills[(rand.nextU() >> 16) % numFills];
- SkPath path;
- unsigned s1 = (rand.nextU() >> 16) % numSegments;
- unsigned s2 = (rand.nextU() >> 16) % numSegments;
- unsigned s3 = (rand.nextU() >> 16) % numSegments;
- unsigned s4 = (rand.nextU() >> 16) % numSegments;
- unsigned s5 = (rand.nextU() >> 16) % numSegments;
- SkPoint pt = SkPoint::Make(10*SK_Scalar1, 0);
- pt = gSegmentFunctions[s1](path, pt);
- pt = gSegmentFunctions[s2](path, pt);
- pt = gSegmentFunctions[s3](path, pt);
- pt = gSegmentFunctions[s4](path, pt);
- pt = gSegmentFunctions[s5](path, pt);
- this->drawPath(path, canvas, color, rect,
- cap.fCap, cap.fJoin, style.fStyle,
- fill.fFill, SK_Scalar1*6);
- SkPaint rectPaint;
- rectPaint.setColor(SK_ColorBLACK);
- rectPaint.setStyle(SkPaint::kStroke_Style);
- rectPaint.setStrokeWidth(-1);
- rectPaint.setAntiAlias(true);
- canvas->drawRect(rect, rectPaint);
- SkPaint labelPaint;
- labelPaint.setColor(color);
- labelPaint.setAntiAlias(true);
- font.setSize(10);
- canvas->drawString(style.fName, 0, rect.height() + 12, font, labelPaint);
- canvas->drawString(fill.fName, 0, rect.height() + 24, font, labelPaint);
- canvas->drawString(cap.fName, 0, rect.height() + 36, font, labelPaint);
- canvas->drawString(gSegmentNames[s1], 0, rect.height() + 48, font, labelPaint);
- canvas->drawString(gSegmentNames[s2], 0, rect.height() + 60, font, labelPaint);
- canvas->drawString(gSegmentNames[s3], 0, rect.height() + 72, font, labelPaint);
- canvas->drawString(gSegmentNames[s4], 0, rect.height() + 84, font, labelPaint);
- canvas->drawString(gSegmentNames[s5], 0, rect.height() + 96, font, labelPaint);
- }
- canvas->restore();
- }
- canvas->restore();
- canvas->restore();
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- DEF_GM( return new DegenerateSegmentsGM; )
- }
|