| /* |
| * 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 SkPatch_DEFINED |
| #define SkPatch_DEFINED |
| |
| #include "SkColor.h" |
| #include "SkPreConfig.h" |
| #include "SkPoint.h" |
| |
| /** |
| * Class that represents a coons patch. |
| */ |
| class SK_API SkPatch { |
| |
| public: |
| /** |
| * Structure that holds the vertex data related to the tessellation of a SkPatch. It is passed |
| * as a parameter to the function getVertexData which sets the points, colors and texture |
| * coordinates of the vertices and the indices for them to be drawn as triangles. |
| */ |
| struct VertexData { |
| int fVertexCount, fIndexCount; |
| SkPoint* fPoints; |
| SkPoint* fTexCoords; |
| uint32_t* fColors; |
| uint16_t* fIndices; |
| |
| VertexData() |
| : fVertexCount(0) |
| , fIndexCount(0) |
| , fPoints(NULL) |
| , fTexCoords(NULL) |
| , fColors(NULL) |
| , fIndices(NULL) { } |
| |
| ~VertexData() { |
| SkDELETE_ARRAY(fPoints); |
| SkDELETE_ARRAY(fTexCoords); |
| SkDELETE_ARRAY(fColors); |
| SkDELETE_ARRAY(fIndices); |
| } |
| }; |
| |
| // Enums for control points based on the order specified in the constructor (clockwise). |
| enum CubicCtrlPts { |
| kTopP0_CubicCtrlPts = 0, |
| kTopP1_CubicCtrlPts = 1, |
| kTopP2_CubicCtrlPts = 2, |
| kTopP3_CubicCtrlPts = 3, |
| |
| kRightP0_CubicCtrlPts = 3, |
| kRightP1_CubicCtrlPts = 4, |
| kRightP2_CubicCtrlPts = 5, |
| kRightP3_CubicCtrlPts = 6, |
| |
| kBottomP0_CubicCtrlPts = 9, |
| kBottomP1_CubicCtrlPts = 8, |
| kBottomP2_CubicCtrlPts = 7, |
| kBottomP3_CubicCtrlPts = 6, |
| |
| kLeftP0_CubicCtrlPts = 0, |
| kLeftP1_CubicCtrlPts = 11, |
| kLeftP2_CubicCtrlPts = 10, |
| kLeftP3_CubicCtrlPts = 9, |
| }; |
| |
| // Enum for corner colors also clockwise. |
| enum CornerColors { |
| kTopLeft_CornerColors = 0, |
| kTopRight_CornerColors, |
| kBottomRight_CornerColors, |
| kBottomLeft_CornerColors |
| }; |
| |
| enum { |
| kNumCtrlPts = 12, |
| kNumColors = 4, |
| kNumPtsCubic = 4 |
| }; |
| |
| /** |
| * Points are in the following order: |
| * (top curve) |
| * 0 1 2 3 |
| * (left curve) 11 4 (right curve) |
| * 10 5 |
| * 9 8 7 6 |
| * (bottom curve) |
| */ |
| SkPatch() { } |
| SkPatch(const SkPoint points[12], const SkColor colors[4]); |
| |
| /** |
| * Function that evaluates the coons patch interpolation. |
| * data refers to the pointer of the PatchData struct in which the tessellation data is set. |
| * lod refers the level of detail for each axis. |
| */ |
| bool getVertexData(SkPatch::VertexData* data, int lodX, int lodY) const; |
| |
| void getTopPoints(SkPoint points[4]) const { |
| points[0] = fCtrlPoints[kTopP0_CubicCtrlPts]; |
| points[1] = fCtrlPoints[kTopP1_CubicCtrlPts]; |
| points[2] = fCtrlPoints[kTopP2_CubicCtrlPts]; |
| points[3] = fCtrlPoints[kTopP3_CubicCtrlPts]; |
| } |
| |
| void getBottomPoints(SkPoint points[4]) const { |
| points[0] = fCtrlPoints[kBottomP0_CubicCtrlPts]; |
| points[1] = fCtrlPoints[kBottomP1_CubicCtrlPts]; |
| points[2] = fCtrlPoints[kBottomP2_CubicCtrlPts]; |
| points[3] = fCtrlPoints[kBottomP3_CubicCtrlPts]; |
| } |
| |
| void getLeftPoints(SkPoint points[4]) const { |
| points[0] = fCtrlPoints[kLeftP0_CubicCtrlPts]; |
| points[1] = fCtrlPoints[kLeftP1_CubicCtrlPts]; |
| points[2] = fCtrlPoints[kLeftP2_CubicCtrlPts]; |
| points[3] = fCtrlPoints[kLeftP3_CubicCtrlPts]; |
| } |
| |
| void getRightPoints(SkPoint points[4]) const { |
| points[0] = fCtrlPoints[kRightP0_CubicCtrlPts]; |
| points[1] = fCtrlPoints[kRightP1_CubicCtrlPts]; |
| points[2] = fCtrlPoints[kRightP2_CubicCtrlPts]; |
| points[3] = fCtrlPoints[kRightP3_CubicCtrlPts]; |
| } |
| |
| void getCornerPoints(SkPoint points[4]) const { |
| points[0] = fCtrlPoints[kTopP0_CubicCtrlPts]; |
| points[1] = fCtrlPoints[kTopP3_CubicCtrlPts]; |
| points[2] = fCtrlPoints[kBottomP3_CubicCtrlPts]; |
| points[3] = fCtrlPoints[kBottomP0_CubicCtrlPts]; |
| } |
| |
| const SkPoint* getControlPoints() const { |
| return fCtrlPoints; |
| } |
| |
| const SkColor* getColors() const { |
| return fCornerColors; |
| } |
| |
| void setPoints(const SkPoint points[12]) { |
| memcpy(fCtrlPoints, points, kNumCtrlPts * sizeof(SkPoint)); |
| } |
| |
| void setColors(const SkColor colors[4]) { |
| memcpy(fCornerColors, colors, kNumColors * sizeof(SkColor)); |
| } |
| |
| void reset(const SkPoint points[12], const SkColor colors[4]) { |
| this->setPoints(points); |
| this->setColors(colors); |
| } |
| |
| /** |
| * Write the patch to the buffer, and return the number of bytes written. |
| * If buffer is NULL, it still returns the number of bytes. |
| */ |
| size_t writeToMemory(void* buffer) const; |
| |
| /** |
| * Initializes the patch from the buffer |
| * |
| * buffer Memory to read from |
| * length Amount of memory available in the buffer |
| * returns the number of bytes read (must be a multiple of 4) or |
| * 0 if there was not enough memory available |
| */ |
| size_t readFromMemory(const void* buffer, size_t length); |
| |
| private: |
| SkPoint fCtrlPoints[kNumCtrlPts]; |
| SkColor fCornerColors[kNumColors]; |
| }; |
| |
| #endif |