diff options
-rw-r--r-- | gm/patch.cpp | 4 | ||||
-rw-r--r-- | gm/patchgrid.cpp | 165 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | gyp/utils.gypi | 2 | ||||
-rw-r--r-- | src/utils/SkPatchGrid.cpp | 188 | ||||
-rw-r--r-- | src/utils/SkPatchGrid.h | 144 |
6 files changed, 502 insertions, 2 deletions
diff --git a/gm/patch.cpp b/gm/patch.cpp index d4fe4ff1f3..2579993b82 100644 --- a/gm/patch.cpp +++ b/gm/patch.cpp @@ -87,9 +87,9 @@ protected: virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipTiled_Flag; } - + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { - + SkPaint paint; // The order of the colors and points is clockwise starting at upper-left corner. diff --git a/gm/patchgrid.cpp b/gm/patchgrid.cpp new file mode 100644 index 0000000000..79baf94253 --- /dev/null +++ b/gm/patchgrid.cpp @@ -0,0 +1,165 @@ + +/* + * 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 "SkPatchGrid.h" + +static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) { + //draw control points + SkPaint paint; + SkPoint bottom[4]; + SkPatchUtils::getBottomCubic(cubics, bottom); + SkPoint top[4]; + SkPatchUtils::getTopCubic(cubics, top); + SkPoint left[4]; + SkPatchUtils::getLeftCubic(cubics, left); + SkPoint right[4]; + SkPatchUtils::getRightCubic(cubics, right); + + paint.setColor(SK_ColorBLACK); + paint.setStrokeWidth(0.5); + SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] }; + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint); + + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right+1, paint); + + paint.setStrokeWidth(2); + + paint.setColor(SK_ColorRED); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint); + + paint.setColor(SK_ColorBLUE); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom+1, paint); + + paint.setColor(SK_ColorCYAN); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top+1, paint); + + paint.setColor(SK_ColorYELLOW); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left+1, paint); + + paint.setColor(SK_ColorGREEN); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right+1, paint); +} + +namespace skiagm { +/** + * This GM draws a grid of patches, it only uses colors so it could be considered a mesh gradient. + */ +class SkPatchGridGM : public GM { + +public: + SkPatchGridGM() { + this->setBGColor(0xFFFFFFFF); + } + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("patch_grid"); + } + + virtual SkISize onISize() SK_OVERRIDE { + return SkISize::Make(800, 800); + } + + virtual uint32_t onGetFlags() const SK_OVERRIDE { + return kSkipTiled_Flag; + } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + + SkPaint paint; + + SkPoint vertices[4][5] = { + {{50,50}, {150,50}, {250,50},{350,50},{450,50}}, + {{50,150}, {120,120}, {250,150},{350,150},{450,150}}, + {{50,250}, {150,250}, {250,250},{350,250},{450,250}}, + {{100,300}, {150,350}, {250,350},{350,350},{450,350}} + }; + + SkColor cornerColors[4][5] = { + {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, + {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, + {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, + {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, + }; + + SkPoint hrzCtrl[4][8] = { + {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}}, + {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}}, + {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}}, + {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}} + }; + + SkPoint vrtCtrl[6][5] = { + {{50,75},{150,75},{250,75},{350,75},{450,75}}, + {{50,125},{150,125},{250,125},{350,125},{450,125}}, + {{50,175},{150,175},{220,225},{350,175},{470,225}}, + {{50,225},{150,225},{220,175},{350,225},{470,155}}, + {{50,275},{150,275},{250,275},{350,275},{400,305}}, + {{50,325},{150,325},{250,325},{350,325},{450,325}} + }; + + static const int kRows = 3; + static const int kCols = 4; + + canvas->scale(3, 3); + SkPatchGrid grid(kRows, kCols, SkPatchGrid::kColors_VertexType, NULL); + for (int i = 0; i < kRows; i++) { + for (int j = 0; j < kCols; j++) { + SkPoint points[12]; + + //set corners + points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j]; + points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1]; + points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j]; + points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1]; + + points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2]; + points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1]; + points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2]; + points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1]; + + points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j]; + points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j]; + points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1]; + points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1]; + + SkColor colors[4]; + colors[0] = cornerColors[i][j]; + colors[1] = cornerColors[i][j + 1]; + colors[3] = cornerColors[i + 1][j]; + colors[2] = cornerColors[i + 1][j + 1]; + + grid.setPatch(j, i, points, colors, NULL); + } + } + + grid.draw(canvas, paint); + SkISize dims = grid.getDimensions(); + for (int y = 0; y < dims.height(); y++) { + for (int x = 0; x < dims.width(); x++) { + SkPoint cubics[12]; + grid.getPatch(x, y, cubics, NULL, NULL); + draw_control_points(canvas, cubics); + } + } + } + +private: + typedef GM INHERITED; +}; + +DEF_GM(return SkNEW(SkPatchGridGM); ) + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index e1cb1a6fd8..c1f527f517 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -127,6 +127,7 @@ '../gm/optimizations.cpp', '../gm/ovals.cpp', '../gm/patch.cpp', + '../gm/patchgrid.cpp', '../gm/patheffects.cpp', '../gm/pathfill.cpp', '../gm/pathinterior.cpp', diff --git a/gyp/utils.gypi b/gyp/utils.gypi index b033573dd9..9156b847c8 100644 --- a/gyp/utils.gypi +++ b/gyp/utils.gypi @@ -78,6 +78,8 @@ '<(skia_src_path)/utils/SkParseColor.cpp', '<(skia_src_path)/utils/SkParsePath.cpp', '<(skia_src_path)/utils/SkPictureUtils.cpp', + '<(skia_src_path)/utils/SkPatchGrid.cpp', + '<(skia_src_path)/utils/SkPatchGrid.h', '<(skia_src_path)/utils/SkPatchUtils.cpp', '<(skia_src_path)/utils/SkPatchUtils.h', '<(skia_src_path)/utils/SkPathUtils.cpp', diff --git a/src/utils/SkPatchGrid.cpp b/src/utils/SkPatchGrid.cpp new file mode 100644 index 0000000000..b1fea57403 --- /dev/null +++ b/src/utils/SkPatchGrid.cpp @@ -0,0 +1,188 @@ +/* + * 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 "SkPatchGrid.h" +#include "SkPatchUtils.h" + +SkPatchGrid::SkPatchGrid(int rows, int cols, VertexType flags, SkXfermode* xfer) + : fRows(0) + , fCols(0) + , fModeFlags(kNone_VertexType) + , fCornerPts(NULL) + , fCornerColors(NULL) + , fTexCoords(NULL) + , fHrzCtrlPts(NULL) + , fVrtCtrlPts(NULL) + , fXferMode(NULL) { + this->reset(rows, cols, flags, xfer); +} + +SkPatchGrid::~SkPatchGrid() { + SkDELETE_ARRAY(fCornerPts); + SkDELETE_ARRAY(fCornerColors); + SkDELETE_ARRAY(fTexCoords); + SkDELETE_ARRAY(fHrzCtrlPts); + SkDELETE_ARRAY(fVrtCtrlPts); +} + +bool SkPatchGrid::setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4]) { + // Check for the passed paramaters to be within the range of the grid dimensions and a valid + // pointer for the cubics' control points. + if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || NULL == cubics) { + return false; + } + + // setup corners and colors + int cornerPos = y * (fCols + 1) + x; + fCornerPts[cornerPos] = cubics[SkPatchUtils::kTopP0_CubicCtrlPts]; + fCornerPts[cornerPos + 1] = cubics[SkPatchUtils::kTopP3_CubicCtrlPts]; + fCornerPts[cornerPos + (fCols + 1)] = cubics[SkPatchUtils::kBottomP0_CubicCtrlPts]; + fCornerPts[cornerPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kBottomP3_CubicCtrlPts]; + + // set horizontal control points + int hrzPos = y * (fCols * 2) + (x * 2); + fHrzCtrlPts[hrzPos] = cubics[SkPatchUtils::kTopP1_CubicCtrlPts]; + fHrzCtrlPts[hrzPos + 1] = cubics[SkPatchUtils::kTopP2_CubicCtrlPts]; + fHrzCtrlPts[hrzPos + (fCols * 2)] = cubics[SkPatchUtils::kBottomP1_CubicCtrlPts]; + fHrzCtrlPts[hrzPos + (fCols * 2) + 1] = cubics[SkPatchUtils::kBottomP2_CubicCtrlPts]; + + // set vertical control points + int vrtPos = (y*2) * (fCols + 1) + x; + fVrtCtrlPts[vrtPos] = cubics[SkPatchUtils::kLeftP1_CubicCtrlPts]; + fVrtCtrlPts[vrtPos + 1] = cubics[SkPatchUtils::kRightP1_CubicCtrlPts]; + fVrtCtrlPts[vrtPos + (fCols + 1)] = cubics[SkPatchUtils::kLeftP2_CubicCtrlPts]; + fVrtCtrlPts[vrtPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kRightP2_CubicCtrlPts]; + + // set optional values (colors and texture coordinates) + if ((fModeFlags & kColors_VertexType) && NULL != colors) { + fCornerColors[cornerPos] = colors[0]; + fCornerColors[cornerPos + 1] = colors[1]; + fCornerColors[cornerPos + (fCols + 1)] = colors[3]; + fCornerColors[cornerPos + (fCols + 1) + 1] = colors[2]; + } + + if ((fModeFlags & kTexs_VertexType) && NULL != texCoords) { + fTexCoords[cornerPos] = texCoords[0]; + fTexCoords[cornerPos + 1] = texCoords[1]; + fTexCoords[cornerPos + (fCols + 1)] = texCoords[3]; + fTexCoords[cornerPos + (fCols + 1) + 1] = texCoords[2]; + } + + return true; +} + +bool SkPatchGrid::getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4], + SkPoint texCoords[4]) const { + + if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || NULL == cubics) { + return false; + } + + // set the patch by building the array of points and colors with the corresponding values. + int cornerPos = y * (fCols + 1) + x; + cubics[SkPatchUtils::kTopP0_CubicCtrlPts] = fCornerPts[cornerPos]; + cubics[SkPatchUtils::kTopP3_CubicCtrlPts] = fCornerPts[cornerPos + 1]; + cubics[SkPatchUtils::kBottomP0_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1)]; + cubics[SkPatchUtils::kBottomP3_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1) + 1]; + + int hrzPos = y * (fCols * 2) + (x * 2); + cubics[SkPatchUtils::kTopP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos]; + cubics[SkPatchUtils::kTopP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + 1]; + cubics[SkPatchUtils::kBottomP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2)]; + cubics[SkPatchUtils::kBottomP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2) + 1]; + + int vrtPos = (y*2) * (fCols + 1) + x; + cubics[SkPatchUtils::kLeftP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos]; + cubics[SkPatchUtils::kRightP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos + 1]; + cubics[SkPatchUtils::kLeftP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1)]; + cubics[SkPatchUtils::kRightP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1) + 1]; + + if ((fModeFlags & kColors_VertexType) && NULL != colors) { + colors[0] = fCornerColors[cornerPos]; + colors[1] = fCornerColors[cornerPos + 1]; + colors[3] = fCornerColors[cornerPos + (fCols + 1)]; + colors[2] = fCornerColors[cornerPos + (fCols + 1) + 1]; + } + + if ((fModeFlags & kTexs_VertexType) && NULL != texCoords) { + texCoords[0] = fTexCoords[cornerPos]; + texCoords[1] = fTexCoords[cornerPos + 1]; + texCoords[3] = fTexCoords[cornerPos + (fCols + 1)]; + texCoords[2] = fTexCoords[cornerPos + (fCols + 1) + 1]; + } + + return true; +} + +void SkPatchGrid::reset(int rows, int cols, VertexType flags, SkXfermode* xMode) { + SkDELETE_ARRAY(fCornerPts); + SkDELETE_ARRAY(fCornerColors); + SkDELETE_ARRAY(fTexCoords); + SkDELETE_ARRAY(fHrzCtrlPts); + SkDELETE_ARRAY(fVrtCtrlPts); + + fCols = cols; + fRows = rows; + fModeFlags = flags; + fXferMode = xMode; + + fCornerPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1)); + fHrzCtrlPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * fCols * 2); + fVrtCtrlPts = SkNEW_ARRAY(SkPoint, fRows * 2 * (fCols + 1)); + memset(fCornerPts, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint)); + memset(fHrzCtrlPts, 0, (fRows + 1) * fCols * 2 * sizeof(SkPoint)); + memset(fVrtCtrlPts, 0, fRows * 2 * (fCols + 1) * sizeof(SkPoint)); + + if (fModeFlags & kColors_VertexType) { + fCornerColors = SkNEW_ARRAY(SkColor, (fRows + 1) * (fCols + 1)); + memset(fCornerColors, 0, (fRows + 1) * (fCols + 1) * sizeof(SkColor)); + } + + if (fModeFlags & kTexs_VertexType) { + fTexCoords = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1)); + memset(fTexCoords, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint)); + } +} + +void SkPatchGrid::draw(SkCanvas* canvas, SkPaint& paint) { + int* maxCols = SkNEW_ARRAY(int, fCols); + int* maxRows = SkNEW_ARRAY(int, fRows); + memset(maxCols, 0, fCols * sizeof(int)); + memset(maxRows, 0, fRows * sizeof(int)); + + // Get the maximum level of detail per axis for each row and column + for (int y = 0; y < fRows; y++) { + for (int x = 0; x < fCols; x++) { + SkPoint cubics[12]; + this->getPatch(x, y, cubics, NULL, NULL); + SkMatrix matrix = canvas->getTotalMatrix(); + SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix); + maxCols[x] = SkMax32(maxCols[x], lod.width()); + maxRows[y] = SkMax32(maxRows[y], lod.height()); + } + } + // Draw the patches by generating their geometry with the maximum level of detail per axis. + for (int x = 0; x < fCols; x++) { + for (int y = 0; y < fRows; y++) { + SkPoint cubics[12]; + SkPoint texCoords[4]; + SkColor colors[4]; + this->getPatch(x, y, cubics, colors, texCoords); + SkPatchUtils::VertexData data; + SkPatchUtils::getVertexData(&data, cubics, + fModeFlags & kColors_VertexType ? colors : NULL, + fModeFlags & kTexs_VertexType ? texCoords : NULL, + maxCols[x], maxRows[y]); + canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, + data.fPoints, data.fTexCoords, data.fColors, fXferMode, + data.fIndices, data.fIndexCount, paint); + } + } + SkDELETE_ARRAY(maxCols); + SkDELETE_ARRAY(maxRows); +} diff --git a/src/utils/SkPatchGrid.h b/src/utils/SkPatchGrid.h new file mode 100644 index 0000000000..cf90098c68 --- /dev/null +++ b/src/utils/SkPatchGrid.h @@ -0,0 +1,144 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPatchGrid_DEFINED +#define SkPatchGrid_DEFINED + +#include "SkCanvas.h" +#include "SkPatchUtils.h" +#include "SkXfermode.h" + +/** + * Class that represents a grid of patches. Adjacent patches share their corners and a color is + * specified at each one of them. The colors are bilinearly interpolated across the patch. + * + * This implementation defines a bidimensional array of patches. There are 3 arrays to store the + * control points of the patches to avoid storing repeated data since there are several points + * shared between adjacent patches. + * + * The array fCornerPts stores the corner control points of the patches. + * The array fHrzPts holds the intermidiate control points of the top and bottom curves of a patch. + * The array fVrtPts holds the intermidiate control points of the left and right curves of a patch. + * The array fCornerColors holds the corner colors in the same format as fCornerPts. + * The array fTexCoords holds the texture coordinates in the same format as fCornerpts. + * + * fCornerPts fHrzPts fVrtPts + * -------------- ------------------- -------------- + * | C0 | C1 | C2 | | H0 | H1 | H2 | H3 | | V0 | V1 | V2 | + * -------------- ------------------ --------------- + * | C3 | C4 | C5 | | H4 | H5 | H6 | H7 | | V4 | V5 | V6 | + * -------------- ------------------- -------------- + * | C6 | C7 | C8 | | H8 | H9 | H10| H11| | V6 | V7 | V8 | + * -------------- ------------------- -------------- + * | V9 | V10| V11| + * -------------- + * + * With the above configuration we would have a 2x2 grid of patches: + * H0 H1 H2 H3 + * / \/ \ + * C0-------C1-------C2 + * /| | |\ + * v0 | v1 | v2 + * v3 | V4 | v5 + * \| | |/ + * C3-H4-H5-C4-H6-H7-C5 + * /| | |\ + * v6 | v7 | v8 + * v9 | v10 | v11 + * \| | |/ + * C6-------C7-------C8 + * \ / \ / + * H8 H9 H10 H11 + * + * When trying to get a patch at a certain position it justs builds it with the corresponding + * points. + * When adding a patch it tries to add the points at their corresponding position trying to comply + * with the adjacent points or overwriting them. + * + * Based the idea on the SVG2 spec for mesh gradients in which a grid of patches is build as in the + * the following example: + * <meshGradient x="100" y="100"> + * <meshRow> + * <meshPatch> + * <stop .../> + * Up to four stops in first patch. See details below. + * </meshPatch> + * <meshPatch> + * Any number of meshPatches in row. + * </meshPatch> + * </meshRow> + * <meshRow> + * Any number of meshRows, each with the same number of meshPatches as in the first row. + * </meshRow> + * </meshGradient> + */ +class SkPatchGrid { + +public: + + enum VertexType { + kNone_VertexType = 0X00, + kColors_VertexType = 0x01, + kTexs_VertexType = 0x02, + kColorsAndTexs_VertexType = 0x03 + }; + + SkPatchGrid(int rows = 0, int cols = 0, VertexType flags = kNone_VertexType, + SkXfermode* xfer = NULL); + + ~SkPatchGrid(); + + /** + * Add a patch at location (x,y) overwriting the previous patch and shared points so they + * mantain C0 connectivity. + * The control points must be passed in a clockwise order starting at the top left corner. + * The colors and texCoords are the values at the corners of the patch which will be bilerp + * across it, they must also be in counterclockwise order starting at the top left corner. + */ + bool setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4]); + + /** + * Get patch at location (x,y). If cubics, colors or texCoords is not NULL it sets patch's + * array with its corresponding values. + * The function returns false if the cubics parameter is NULL or if the (x,y) coordinates are + * not within the range of the grid. + */ + bool getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4], SkPoint texCoords[4]) const; + + /** + * Resets the grid of patches to contain rows and cols of patches. + */ + void reset(int rows, int cols, VertexType flags, SkXfermode* xMode); + + /** + * Draws the grid of patches. The patches are drawn starting at patch (0,0) drawing columns, so + * for a 2x2 grid the order would be (0,0)->(0,1)->(1,0)->(1,1). The order follows the order + * of the parametric coordinates of the coons patch. + */ + void draw(SkCanvas* canvas, SkPaint& paint); + + /** + * Get the dimensions of the grid of patches. + */ + SkISize getDimensions() const { + return SkISize::Make(fCols, fRows); + } + +private: + int fRows, fCols; + VertexType fModeFlags; + SkPoint* fCornerPts; + SkColor* fCornerColors; + SkPoint* fTexCoords; + SkPoint* fHrzCtrlPts; + SkPoint* fVrtCtrlPts; + SkXfermode* fXferMode; +}; + + +#endif |