179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2012 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/SkPaint.h"
 | |
| #include "include/core/SkPoint.h"
 | |
| #include "include/core/SkRRect.h"
 | |
| #include "include/core/SkRect.h"
 | |
| #include "include/core/SkScalar.h"
 | |
| #include "include/core/SkSize.h"
 | |
| #include "include/core/SkString.h"
 | |
| #include "include/core/SkTypes.h"
 | |
| #include "tools/ToolUtils.h"
 | |
| 
 | |
| typedef void (*InsetProc)(const SkRRect&, SkScalar dx, SkScalar dy, SkRRect*);
 | |
| 
 | |
| static void inset0(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
 | |
|     SkRect r = src.rect();
 | |
| 
 | |
|     r.inset(dx, dy);
 | |
|     if (r.isEmpty()) {
 | |
|         dst->setEmpty();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     SkVector radii[4];
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i] = src.radii((SkRRect::Corner)i);
 | |
|     }
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i].fX -= dx;
 | |
|         radii[i].fY -= dy;
 | |
|     }
 | |
|     dst->setRectRadii(r, radii);
 | |
| }
 | |
| 
 | |
| static void inset1(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
 | |
|     SkRect r = src.rect();
 | |
| 
 | |
|     r.inset(dx, dy);
 | |
|     if (r.isEmpty()) {
 | |
|         dst->setEmpty();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     SkVector radii[4];
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i] = src.radii((SkRRect::Corner)i);
 | |
|     }
 | |
|     dst->setRectRadii(r, radii);
 | |
| }
 | |
| 
 | |
| static void inset2(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
 | |
|     SkRect r = src.rect();
 | |
| 
 | |
|     r.inset(dx, dy);
 | |
|     if (r.isEmpty()) {
 | |
|         dst->setEmpty();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     SkVector radii[4];
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i] = src.radii((SkRRect::Corner)i);
 | |
|     }
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         if (radii[i].fX) {
 | |
|             radii[i].fX -= dx;
 | |
|         }
 | |
|         if (radii[i].fY) {
 | |
|             radii[i].fY -= dy;
 | |
|         }
 | |
|     }
 | |
|     dst->setRectRadii(r, radii);
 | |
| }
 | |
| 
 | |
| static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
 | |
|     return newSize * radius / oldSize;
 | |
| }
 | |
| 
 | |
| static void inset3(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
 | |
|     SkRect r = src.rect();
 | |
| 
 | |
|     r.inset(dx, dy);
 | |
|     if (r.isEmpty()) {
 | |
|         dst->setEmpty();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     SkVector radii[4];
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i] = src.radii((SkRRect::Corner)i);
 | |
|     }
 | |
|     for (int i = 0; i < 4; ++i) {
 | |
|         radii[i].fX = prop(radii[i].fX, r.width(), src.rect().width());
 | |
|         radii[i].fY = prop(radii[i].fY, r.height(), src.rect().height());
 | |
|     }
 | |
|     dst->setRectRadii(r, radii);
 | |
| }
 | |
| 
 | |
| static void draw_rrect_color(SkCanvas* canvas, const SkRRect& rrect) {
 | |
|     SkPaint paint;
 | |
|     paint.setAntiAlias(true);
 | |
|     paint.setStyle(SkPaint::kStroke_Style);
 | |
| 
 | |
|     if (rrect.isRect()) {
 | |
|         paint.setColor(SK_ColorRED);
 | |
|     } else if (rrect.isOval()) {
 | |
|         paint.setColor(ToolUtils::color_to_565(0xFF008800));
 | |
|     } else if (rrect.isSimple()) {
 | |
|         paint.setColor(SK_ColorBLUE);
 | |
|     } else {
 | |
|         paint.setColor(SK_ColorBLACK);
 | |
|     }
 | |
|     canvas->drawRRect(rrect, paint);
 | |
| }
 | |
| 
 | |
| static void drawrr(SkCanvas* canvas, const SkRRect& rrect, InsetProc proc) {
 | |
|     SkRRect rr;
 | |
|     for (SkScalar d = -30; d <= 30; d += 5) {
 | |
|         proc(rrect, d, d, &rr);
 | |
|         draw_rrect_color(canvas, rr);
 | |
|     }
 | |
| }
 | |
| 
 | |
| class RRectGM : public skiagm::GM {
 | |
| public:
 | |
|     RRectGM() {}
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     SkString onShortName() override {
 | |
|         return SkString("rrect");
 | |
|     }
 | |
| 
 | |
|     SkISize onISize() override {
 | |
|         return SkISize::Make(820, 710);
 | |
|     }
 | |
| 
 | |
|     void onDraw(SkCanvas* canvas) override {
 | |
|         constexpr InsetProc insetProcs[] = {
 | |
|             inset0, inset1, inset2, inset3
 | |
|         };
 | |
| 
 | |
|         SkRRect rrect[4];
 | |
|         SkRect r = { 0, 0, 120, 100 };
 | |
|         SkVector radii[4] = {
 | |
|             { 0, 0 }, { 30, 1 }, { 10, 40 }, { 40, 40 }
 | |
|         };
 | |
| 
 | |
|         rrect[0].setRect(r);
 | |
|         rrect[1].setOval(r);
 | |
|         rrect[2].setRectXY(r, 20, 20);
 | |
|         rrect[3].setRectRadii(r, radii);
 | |
| 
 | |
|         canvas->translate(50.5f, 50.5f);
 | |
|         for (size_t j = 0; j < SK_ARRAY_COUNT(insetProcs); ++j) {
 | |
|             canvas->save();
 | |
|             for (size_t i = 0; i < SK_ARRAY_COUNT(rrect); ++i) {
 | |
|                 drawrr(canvas, rrect[i], insetProcs[j]);
 | |
|                 canvas->translate(200, 0);
 | |
|             }
 | |
|             canvas->restore();
 | |
|             canvas->translate(0, 170);
 | |
|         }
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     using INHERITED = GM;
 | |
| };
 | |
| 
 | |
| DEF_GM( return new RRectGM; )
 |