32static constexpr SkRect kExampleBounds = {0.f, 0.f, 100.f, 100.f};
36enum class CropRelation {
43SkRect make_overlap(
const SkRect& r,
float amountX,
float amountY) {
47SkRect make_inset(
const SkRect& r,
float amountX,
float amountY) {
51SkRect make_outset(
const SkRect& r,
float amountX,
float amountY) {
55SkRect make_disjoint(
const SkRect& r,
float amountX,
float amountY) {
56 float xOffset = (amountX > 0.f ? (r.
width() + r.
width() * amountX) :
57 (amountX < 0.f ? (-r.
width() + r.
width() * amountX) : 0.f));
58 float yOffset = (amountY > 0.f ? (r.
height() + r.
height() * amountY) :
59 (amountY < 0.f ? (-r.
height() + r.
height() * amountY) : 0.f));
63void get_example_rects(CropRelation outputRelation, CropRelation inputRelation,
bool hintContent,
65 *outputBounds = kExampleBounds.
makeInset(20.f, 20.f);
66 switch(outputRelation) {
67 case CropRelation::kCropOverlapsRect:
68 *cropRect = make_overlap(*outputBounds, -0.15f, 0.15f);
70 !cropRect->
contains(*outputBounds) &&
73 case CropRelation::kCropContainsRect:
74 *cropRect = make_outset(*outputBounds, 0.15f, 0.15f);
77 case CropRelation::kRectContainsCrop:
78 *cropRect = make_inset(*outputBounds, 0.15f, 0.15f);
81 case CropRelation::kCropRectDisjoint:
82 *cropRect = make_disjoint(*outputBounds, 0.15f, 0.0f);
91 switch(inputRelation) {
92 case CropRelation::kCropOverlapsRect:
93 *contentBounds = make_overlap(*cropRect, 0.075f, -0.75f);
95 !contentBounds->
contains(*cropRect) &&
96 !cropRect->
contains(*contentBounds));
98 case CropRelation::kCropContainsRect:
99 *contentBounds = make_inset(*cropRect, 0.075f, 0.075f);
102 case CropRelation::kRectContainsCrop:
103 *contentBounds = make_outset(*cropRect, 0.1f, 0.1f);
106 case CropRelation::kCropRectDisjoint:
107 *contentBounds = make_disjoint(*cropRect, 0.0f, 0.075f);
114 *contentBounds = kExampleBounds;
121 const float w = kExampleBounds.
width();
122 const float h = kExampleBounds.
height();
130 paint.setAntiAlias(
true);
133 paint.setStrokeWidth(
h/16.f);
135 surf->getCanvas()->drawLine({0.f, 1.f*
h/4.f}, {
w, 1.f*
h/4.f},
paint);
136 paint.setColor( 0xFF71EEB8);
137 surf->getCanvas()->drawLine({0.f, 3.f*
h/8.f}, {
w, 3.f*
h/8.f},
paint);
139 surf->getCanvas()->drawLine({0.f, 5.f*
h/8.f}, {
w, 5.f*
h/8.f},
paint);
141 surf->getCanvas()->drawLine({0.f, 3.f*
h/4.f}, {
w, 3.f*
h/4.f},
paint);
144 paint.setStrokeWidth(
w/16.f);
145 paint.setColor( 0xFFFFA500);
146 surf->getCanvas()->drawLine({1.f*
w/4.f, 0.f}, {1.f*
h/4.f,
h},
paint);
148 surf->getCanvas()->drawLine({3.f*
w/8.f, 0.f}, {3.f*
h/8.f,
h},
paint);
150 surf->getCanvas()->drawLine({5.f*
w/8.f, 0.f}, {5.f*
h/8.f,
h},
paint);
152 surf->getCanvas()->drawLine({3.f*
w/4.f, 0.f}, {3.f*
h/4.f,
h},
paint);
161 return surf->makeImageSnapshot();
166 const SkRect& contentBounds,
174 : contentBounds.roundIn());
182 contentBounds.
top())));
183 surface->getCanvas()->translate(-cropRect.
left(), -cropRect.
top());
184 surface->getCanvas()->drawPaint(tiledContent);
185 return surface->makeImageSnapshot();
188void draw_example_tile(
191 CropRelation inputRelation,
194 CropRelation outputRelation) {
197 SkRect outputBounds, cropRect, contentBounds;
198 get_example_rects(outputRelation, inputRelation, hintContent,
199 &outputBounds, &cropRect, &contentBounds);
201 kExampleBounds.
contains(cropRect) &&
202 kExampleBounds.
contains(contentBounds));
204 auto image =
make_image(canvas, hintContent ? &contentBounds : nullptr);
211 canvas, make_cropped_image(
image, contentBounds, inputMode, cropRect));
214 tiledPaint.
setShader(cropImage->makeShader(outputMode, outputMode,
238 canvas->
saveLayer(hintContent ? &contentBounds : nullptr, &layerPaint);
253 border.
setColor(kOutputBoundsColor);
254 canvas->
drawRect(outputBounds, border);
260 border.
setColor(kContentBoundsColor);
261 canvas->
drawRect(contentBounds, border);
270void draw_example_column(
274 CropRelation outputRelation) {
275 const std::pair<CropRelation, bool> inputRelations[5] = {
276 { CropRelation::kCropOverlapsRect,
false },
277 { CropRelation::kCropOverlapsRect,
true },
278 { CropRelation::kCropContainsRect,
true },
279 { CropRelation::kRectContainsCrop,
true },
280 { CropRelation::kCropRectDisjoint,
true }
284 for (
auto [inputRelation, hintContent] : inputRelations) {
285 draw_example_tile(canvas, inputMode, inputRelation, hintContent,
286 outputMode, outputRelation);
296static constexpr float kGridWidth =
kNumCols * (kExampleBounds.
fRight+1.f) - 1.f;
297static constexpr float kGridHeight =
kNumRows * (kExampleBounds.
fBottom+1.f) - 1.f;
299void draw_example_grid(
304 for (
auto outputRelation : { CropRelation::kCropOverlapsRect,
305 CropRelation::kCropContainsRect,
306 CropRelation::kRectContainsCrop,
307 CropRelation::kCropRectDisjoint }) {
308 draw_example_column(canvas, inputMode, outputMode, outputRelation);
318 static const float kDashes[2] = {5.f, 15.f};
323 {kGridWidth - 0.5f,
y * (kExampleBounds.
fBottom+1.f) - 0.5f},
328 {
x * (kExampleBounds.
fRight+1.f) - 0.5f, kGridHeight - 0.5f},
340 : fInputMode(inputMode)
341 , fOutputMode(outputMode) {}
358 switch (fOutputMode) {
369 draw_example_grid(canvas, fInputMode, fOutputMode);
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkAssertResult(cond)
constexpr SkColor SK_ColorYELLOW
constexpr SkColor SK_ColorMAGENTA
constexpr SkColor SK_ColorCYAN
constexpr SkColor SK_ColorGRAY
constexpr SkColor SK_ColorBLUE
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorGREEN
constexpr SkColor SK_ColorDKGRAY
#define SkScalarRoundToInt(x)
#define SkScalarCeilToInt(x)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
void drawRect(const SkRect &rect, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void translate(SkScalar dx, SkScalar dy)
void drawPaint(const SkPaint &paint)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
const SkImageInfo & imageInfo() const
virtual sk_sp< SkImage > makeSubset(GrDirectContext *direct, const SkIRect &subset) const =0
static SkMatrix Translate(SkScalar dx, SkScalar dy)
void setStyle(Style style)
void setColor(SkColor color)
void setImageFilter(sk_sp< SkImageFilter > imageFilter)
void setStrokeCap(Cap cap)
@ kStroke_Style
set to stroke geometry
void setShader(sk_sp< SkShader > shader)
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
SkISize getISize() override
SkString getName() const override
void onDraw(SkCanvas *canvas) override
CropImageFilterGM(SkTileMode inputMode, SkTileMode outputMode)
static const uint8_t buffer[]
union flutter::testing::@2838::KeyboardChange::@76 content
static sk_sp< SkImage > make_image()
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
static constexpr SkISize Make(int32_t w, int32_t h)
SkImageInfo makeWH(int newWidth, int newHeight) const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkScalar fBottom
larger y-axis bounds
constexpr float left() const
constexpr SkRect makeOffset(float dx, float dy) const
constexpr float top() const
bool intersect(const SkRect &r)
SkRect makeOutset(float dx, float dy) const
bool intersects(const SkRect &r) const
SkRect makeInset(float dx, float dy) const
SkScalar fRight
larger x-axis bounds
bool contains(SkScalar x, SkScalar y) const
void roundOut(SkIRect *dst) const
constexpr float height() const
constexpr float width() const
static constexpr int kNumCols