Initial import of Cobalt 2.8885 2016-07-27
diff --git a/src/third_party/skia/gm/convexpolyclip.cpp b/src/third_party/skia/gm/convexpolyclip.cpp
new file mode 100644
index 0000000..328cdb5
--- /dev/null
+++ b/src/third_party/skia/gm/convexpolyclip.cpp
@@ -0,0 +1,303 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#include "SkBitmap.h"
+#include "SkGradientShader.h"
+#include "SkTLList.h"
+
+static SkBitmap make_bmp(int w, int h) {
+    SkBitmap bmp;
+    bmp.allocN32Pixels(w, h, true);
+
+    SkCanvas canvas(bmp);
+    SkScalar wScalar = SkIntToScalar(w);
+    SkScalar hScalar = SkIntToScalar(h);
+
+    SkPoint     pt = { wScalar / 2, hScalar / 2 };
+
+    SkScalar    radius = 3 * SkMaxScalar(wScalar, hScalar);
+
+    SkColor     colors[] = { SK_ColorDKGRAY, 0xFF222255,
+                             0xFF331133, 0xFF884422,
+                             0xFF000022, SK_ColorWHITE,
+                             0xFFAABBCC};
+
+    SkScalar    pos[] = {0,
+                         SK_Scalar1 / 6,
+                         2 * SK_Scalar1 / 6,
+                         3 * SK_Scalar1 / 6,
+                         4 * SK_Scalar1 / 6,
+                         5 * SK_Scalar1 / 6,
+                         SK_Scalar1};
+
+    SkPaint paint;
+    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
+    SkMatrix mat = SkMatrix::I();
+    for (int i = 0; i < 4; ++i) {
+        paint.setShader(SkGradientShader::CreateRadial(
+                        pt, radius,
+                        colors, pos,
+                        SK_ARRAY_COUNT(colors),
+                        SkShader::kRepeat_TileMode,
+                        0, &mat))->unref();
+        canvas.drawRect(rect, paint);
+        rect.inset(wScalar / 8, hScalar / 8);
+        mat.preTranslate(6 * wScalar, 6 * hScalar);
+        mat.postScale(SK_Scalar1 / 3, SK_Scalar1 / 3);
+    }
+
+    paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
+    paint.setTextSize(wScalar / 2.2f);
+    paint.setShader(0);
+    paint.setColor(SK_ColorLTGRAY);
+    static const char kTxt[] = "Skia";
+    SkPoint texPos = { wScalar / 17, hScalar / 2 + paint.getTextSize() / 2.5f };
+    canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
+    paint.setColor(SK_ColorBLACK);
+    paint.setStyle(SkPaint::kStroke_Style);
+    paint.setStrokeWidth(SK_Scalar1);
+    canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
+    return bmp;
+}
+
+namespace skiagm {
+/**
+ * This GM tests convex polygon clips.
+ */
+class ConvexPolyClip : public GM {
+public:
+    ConvexPolyClip() {
+        this->setBGColor(0xFFFFFFFF);
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("convex_poly_clip");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        // When benchmarking the saveLayer set of draws is skipped.
+        int w = 435;
+        if (kBench_Mode != this->getMode()) {
+            w *= 2;
+        }
+        return SkISize::Make(w, 540);
+    }
+
+    virtual void onOnceBeforeDraw() SK_OVERRIDE {
+        SkPath tri;
+        tri.moveTo(5.f, 5.f);
+        tri.lineTo(100.f, 20.f);
+        tri.lineTo(15.f, 100.f);
+
+        fClips.addToTail()->setPath(tri);
+
+        SkPath hexagon;
+        static const SkScalar kRadius = 45.f;
+        const SkPoint center = { kRadius, kRadius };
+        for (int i = 0; i < 6; ++i) {
+            SkScalar angle = 2 * SK_ScalarPI * i / 6;
+            SkPoint point;
+            point.fY = SkScalarSinCos(angle, &point.fX);
+            point.scale(kRadius);
+            point = center + point;
+            if (0 == i) {
+                hexagon.moveTo(point);
+            } else {
+                hexagon.lineTo(point);
+            }
+        }
+        fClips.addToTail()->setPath(hexagon);
+
+        SkMatrix scaleM;
+        scaleM.setScale(1.1f, 0.4f, kRadius, kRadius);
+        hexagon.transform(scaleM);
+        fClips.addToTail()->setPath(hexagon);
+
+        fClips.addToTail()->setRect(SkRect::MakeXYWH(8.3f, 11.6f, 78.2f, 72.6f));
+
+        SkPath rotRect;
+        SkRect rect = SkRect::MakeLTRB(10.f, 12.f, 80.f, 86.f);
+        rotRect.addRect(rect);
+        SkMatrix rotM;
+        rotM.setRotate(23.f, rect.centerX(), rect.centerY());
+        rotRect.transform(rotM);
+        fClips.addToTail()->setPath(rotRect);
+
+        fBmp = make_bmp(100, 100);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkScalar y = 0;
+        static const SkScalar kMargin = 10.f;
+
+        SkPaint bgPaint;
+        bgPaint.setAlpha(0x15);
+        SkISize size = canvas->getDeviceSize();
+        SkRect dstRect = SkRect::MakeWH(SkIntToScalar(size.fWidth),
+                                        SkIntToScalar(size.fHeight));
+        canvas->drawBitmapRectToRect(fBmp, NULL, dstRect, &bgPaint);
+
+        static const char kTxt[] = "Clip Me!";
+        SkPaint txtPaint;
+        txtPaint.setTextSize(23.f);
+        txtPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&txtPaint);
+        txtPaint.setColor(SK_ColorDKGRAY);
+        SkScalar textW = txtPaint.measureText(kTxt, SK_ARRAY_COUNT(kTxt)-1);
+
+        SkScalar startX = 0;
+        int testLayers = kBench_Mode != this->getMode();
+        for (int doLayer = 0; doLayer <= testLayers; ++doLayer) {
+            for (SkTLList<Clip>::Iter iter(fClips, SkTLList<Clip>::Iter::kHead_IterStart);
+                 iter.get();
+                 iter.next()) {
+                const Clip* clip = iter.get();
+                SkScalar x = startX;
+                for (int aa = 0; aa < 2; ++aa) {
+                    if (doLayer) {
+                        SkRect bounds;
+                        clip->getBounds(&bounds);
+                        bounds.outset(2, 2);
+                        bounds.offset(x, y);
+                        canvas->saveLayer(&bounds, NULL);
+                    } else {
+                        canvas->save();
+                    }
+                    canvas->translate(x, y);
+                    clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
+                    canvas->drawBitmap(fBmp, 0, 0);
+                    canvas->restore();
+                    x += fBmp.width() + kMargin;
+                }
+                for (int aa = 0; aa < 2; ++aa) {
+
+                    SkPaint clipOutlinePaint;
+                    clipOutlinePaint.setAntiAlias(true);
+                    clipOutlinePaint.setColor(0x50505050);
+                    clipOutlinePaint.setStyle(SkPaint::kStroke_Style);
+                    clipOutlinePaint.setStrokeWidth(0);
+
+                    if (doLayer) {
+                        SkRect bounds;
+                        clip->getBounds(&bounds);
+                        bounds.outset(2, 2);
+                        bounds.offset(x, y);
+                        canvas->saveLayer(&bounds, NULL);
+                    } else {
+                        canvas->save();
+                    }
+                    canvas->translate(x, y);
+                    SkPath closedClipPath;
+                    clip->asClosedPath(&closedClipPath);
+                    canvas->drawPath(closedClipPath, clipOutlinePaint);
+                    clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
+                    canvas->scale(1.f, 1.8f);
+                    canvas->drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1,
+                                     0, 1.5f * txtPaint.getTextSize(),
+                                     txtPaint);
+                    canvas->restore();
+                    x += textW + 2 * kMargin;
+                }
+                y += fBmp.height() + kMargin;
+            }
+            y = 0;
+            startX += 2 * fBmp.width() + SkScalarCeilToInt(2 * textW) + 6 * kMargin;
+        }
+    }
+
+    virtual uint32_t onGetFlags() const {
+        return kAsBench_Flag | kSkipTiled_Flag;
+    }
+
+private:
+    class Clip {
+    public:
+        enum ClipType {
+            kNone_ClipType,
+            kPath_ClipType,
+            kRect_ClipType
+        };
+
+        Clip () : fClipType(kNone_ClipType) {}
+
+        void setOnCanvas(SkCanvas* canvas, SkRegion::Op op, bool aa) const {
+            switch (fClipType) {
+                case kPath_ClipType:
+                    canvas->clipPath(fPath, op, aa);
+                    break;
+                case kRect_ClipType:
+                    canvas->clipRect(fRect, op, aa);
+                    break;
+                case kNone_ClipType:
+                    SkDEBUGFAIL("Uninitialized Clip.");
+                    break;
+            }
+        }
+
+        void asClosedPath(SkPath* path) const {
+            switch (fClipType) {
+                case kPath_ClipType:
+                    *path = fPath;
+                    path->close();
+                    break;
+                case kRect_ClipType:
+                    path->reset();
+                    path->addRect(fRect);
+                    break;
+                case kNone_ClipType:
+                    SkDEBUGFAIL("Uninitialized Clip.");
+                    break;
+            }
+        }
+
+        void setPath(const SkPath& path) {
+            fClipType = kPath_ClipType;
+            fPath = path;
+        }
+
+        void setRect(const SkRect& rect) {
+            fClipType = kRect_ClipType;
+            fRect = rect;
+            fPath.reset();
+        }
+
+        ClipType getType() const { return fClipType; }
+
+        void getBounds(SkRect* bounds) const {
+            switch (fClipType) {
+                case kPath_ClipType:
+                    *bounds = fPath.getBounds();
+                    break;
+                case kRect_ClipType:
+                    *bounds = fRect;
+                    break;
+                case kNone_ClipType:
+                    SkDEBUGFAIL("Uninitialized Clip.");
+                    break;
+            }
+        }
+
+    private:
+        ClipType fClipType;
+        SkPath fPath;
+        SkRect fRect;
+    };
+
+    SkTLList<Clip>   fClips;
+    SkBitmap         fBmp;
+
+    typedef GM INHERITED;
+};
+
+DEF_GM( return SkNEW(ConvexPolyClip); )
+
+}