|  | 
| 3 | 3 | // found in the LICENSE file. | 
| 4 | 4 | 
 | 
| 5 | 5 | #include "impeller/tessellator/tessellator.h" | 
| 6 |  | -#include "flutter/fml/logging.h" | 
| 7 | 6 | 
 | 
| 8 | 7 | #include "third_party/libtess2/Include/tesselator.h" | 
| 9 | 8 | 
 | 
| @@ -79,74 +78,131 @@ Tessellator::Result Tessellator::Tessellate( | 
| 79 | 78 |   constexpr int kVertexSize = 2; | 
| 80 | 79 |   constexpr int kPolygonSize = 3; | 
| 81 | 80 | 
 | 
| 82 |  | -  //---------------------------------------------------------------------------- | 
| 83 |  | -  /// Feed contour information to the tessellator. | 
| 84 |  | -  /// | 
| 85 |  | -  static_assert(sizeof(Point) == 2 * sizeof(float)); | 
| 86 |  | -  for (size_t contour_i = 0; contour_i < polyline.contours.size(); | 
| 87 |  | -       contour_i++) { | 
| 88 |  | -    size_t start_point_index, end_point_index; | 
| 89 |  | -    std::tie(start_point_index, end_point_index) = | 
| 90 |  | -        polyline.GetContourPointBounds(contour_i); | 
| 91 |  | - | 
| 92 |  | -    ::tessAddContour(tessellator,  // the C tessellator | 
| 93 |  | -                     kVertexSize,  // | 
| 94 |  | -                     polyline.points.data() + start_point_index,  // | 
| 95 |  | -                     sizeof(Point),                               // | 
| 96 |  | -                     end_point_index - start_point_index          // | 
| 97 |  | -    ); | 
| 98 |  | -  } | 
| 99 |  | - | 
| 100 |  | -  //---------------------------------------------------------------------------- | 
| 101 |  | -  /// Let's tessellate. | 
| 102 |  | -  /// | 
| 103 |  | -  auto result = ::tessTesselate(tessellator,                   // tessellator | 
| 104 |  | -                                ToTessWindingRule(fill_type),  // winding | 
| 105 |  | -                                TESS_POLYGONS,                 // element type | 
| 106 |  | -                                kPolygonSize,                  // polygon size | 
| 107 |  | -                                kVertexSize,                   // vertex size | 
| 108 |  | -                                nullptr  // normal (null is automatic) | 
| 109 |  | -  ); | 
| 110 |  | - | 
| 111 |  | -  if (result != 1) { | 
| 112 |  | -    return Result::kTessellationError; | 
| 113 |  | -  } | 
| 114 |  | - | 
| 115 |  | -  int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize; | 
| 116 |  | -  auto vertices = tessGetVertices(tessellator); | 
| 117 |  | -  int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize; | 
| 118 |  | -  auto elements = tessGetElements(tessellator); | 
| 119 |  | - | 
| 120 |  | -  if (elementItemCount < 65535) { | 
| 121 |  | -    // libtess uses an int index internally due to usage of -1 as a sentinel | 
| 122 |  | -    // value. | 
| 123 |  | -    std::vector<uint16_t> indices(elementItemCount); | 
| 124 |  | -    for (int i = 0; i < elementItemCount; i++) { | 
| 125 |  | -      indices[i] = static_cast<uint16_t>(elements[i]); | 
|  | 81 | +  if (polyline.contours.size() > 30 && fill_type == FillType::kNonZero) { | 
|  | 82 | +    std::vector<Point> points; | 
|  | 83 | +    std::vector<float> data; | 
|  | 84 | + | 
|  | 85 | +    //---------------------------------------------------------------------------- | 
|  | 86 | +    /// Feed contour information to the tessellator. | 
|  | 87 | +    /// | 
|  | 88 | +    size_t total = 0u; | 
|  | 89 | +    static_assert(sizeof(Point) == 2 * sizeof(float)); | 
|  | 90 | +    for (size_t contour_i = 0; contour_i < polyline.contours.size(); | 
|  | 91 | +         contour_i++) { | 
|  | 92 | +      size_t start_point_index, end_point_index; | 
|  | 93 | +      std::tie(start_point_index, end_point_index) = | 
|  | 94 | +          polyline.GetContourPointBounds(contour_i); | 
|  | 95 | + | 
|  | 96 | +      ::tessAddContour(tessellator,  // the C tessellator | 
|  | 97 | +                       kVertexSize,  // | 
|  | 98 | +                       polyline.points.data() + start_point_index,  // | 
|  | 99 | +                       sizeof(Point),                               // | 
|  | 100 | +                       end_point_index - start_point_index          // | 
|  | 101 | +      ); | 
|  | 102 | + | 
|  | 103 | +      //---------------------------------------------------------------------------- | 
|  | 104 | +      /// Let's tessellate. | 
|  | 105 | +      /// | 
|  | 106 | +      auto result = ::tessTesselate(tessellator,  // tessellator | 
|  | 107 | +                                    ToTessWindingRule(fill_type),  // winding | 
|  | 108 | +                                    TESS_POLYGONS,  // element type | 
|  | 109 | +                                    kPolygonSize,   // polygon size | 
|  | 110 | +                                    kVertexSize,    // vertex size | 
|  | 111 | +                                    nullptr  // normal (null is automatic) | 
|  | 112 | +      ); | 
|  | 113 | + | 
|  | 114 | +      if (result != 1) { | 
|  | 115 | +        return Result::kTessellationError; | 
|  | 116 | +      } | 
|  | 117 | + | 
|  | 118 | +      int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize; | 
|  | 119 | +      auto vertices = tessGetVertices(tessellator); | 
|  | 120 | +      for (int i = 0; i < vertexItemCount; i += 2) { | 
|  | 121 | +        points.emplace_back(vertices[i], vertices[i + 1]); | 
|  | 122 | +      } | 
|  | 123 | + | 
|  | 124 | +      int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize; | 
|  | 125 | +      auto elements = tessGetElements(tessellator); | 
|  | 126 | +      total += elementItemCount; | 
|  | 127 | +      for (int i = 0; i < elementItemCount; i++) { | 
|  | 128 | +        data.emplace_back(points[elements[i]].x); | 
|  | 129 | +        data.emplace_back(points[elements[i]].y); | 
|  | 130 | +      } | 
|  | 131 | +      points.clear(); | 
| 126 | 132 |     } | 
| 127 |  | -    if (!callback(vertices, vertexItemCount, indices.data(), | 
| 128 |  | -                  elementItemCount)) { | 
|  | 133 | +    if (!callback(data.data(), data.size(), nullptr, total)) { | 
| 129 | 134 |       return Result::kInputError; | 
| 130 | 135 |     } | 
| 131 | 136 |   } else { | 
| 132 |  | -    std::vector<Point> points; | 
| 133 |  | -    std::vector<uint32_t> indices; | 
| 134 |  | - | 
| 135 |  | -    int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize; | 
| 136 |  | -    auto vertices = tessGetVertices(tessellator); | 
| 137 |  | -    for (int i = 0; i < vertexItemCount; i += 2) { | 
| 138 |  | -      points.emplace_back(vertices[i], vertices[i + 1]); | 
|  | 137 | +    //---------------------------------------------------------------------------- | 
|  | 138 | +    /// Feed contour information to the tessellator. | 
|  | 139 | +    /// | 
|  | 140 | +    static_assert(sizeof(Point) == 2 * sizeof(float)); | 
|  | 141 | +    for (size_t contour_i = 0; contour_i < polyline.contours.size(); | 
|  | 142 | +         contour_i++) { | 
|  | 143 | +      size_t start_point_index, end_point_index; | 
|  | 144 | +      std::tie(start_point_index, end_point_index) = | 
|  | 145 | +          polyline.GetContourPointBounds(contour_i); | 
|  | 146 | + | 
|  | 147 | +      ::tessAddContour(tessellator,  // the C tessellator | 
|  | 148 | +                       kVertexSize,  // | 
|  | 149 | +                       polyline.points.data() + start_point_index,  // | 
|  | 150 | +                       sizeof(Point),                               // | 
|  | 151 | +                       end_point_index - start_point_index          // | 
|  | 152 | +      ); | 
| 139 | 153 |     } | 
| 140 | 154 | 
 | 
| 141 |  | -    int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize; | 
| 142 |  | -    auto elements = tessGetElements(tessellator); | 
| 143 |  | -    for (int i = 0; i < elementItemCount; i++) { | 
| 144 |  | -      indices.emplace_back(elements[i]); | 
|  | 155 | +    //---------------------------------------------------------------------------- | 
|  | 156 | +    /// Let's tessellate. | 
|  | 157 | +    /// | 
|  | 158 | +    auto result = ::tessTesselate(tessellator,                   // tessellator | 
|  | 159 | +                                  ToTessWindingRule(fill_type),  // winding | 
|  | 160 | +                                  TESS_POLYGONS,                 // element type | 
|  | 161 | +                                  kPolygonSize,                  // polygon size | 
|  | 162 | +                                  kVertexSize,                   // vertex size | 
|  | 163 | +                                  nullptr  // normal (null is automatic) | 
|  | 164 | +    ); | 
|  | 165 | + | 
|  | 166 | +    if (result != 1) { | 
|  | 167 | +      return Result::kTessellationError; | 
| 145 | 168 |     } | 
| 146 | 169 | 
 | 
| 147 |  | -    if (!callback(reinterpret_cast<float*>(points.data()), points.size(), | 
| 148 |  | -                  nullptr, 0u)) { | 
| 149 |  | -      return Result::kInputError; | 
|  | 170 | +    int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize; | 
|  | 171 | +    if (elementItemCount < 65535) { | 
|  | 172 | +      int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize; | 
|  | 173 | +      auto vertices = tessGetVertices(tessellator); | 
|  | 174 | +      auto elements = tessGetElements(tessellator); | 
|  | 175 | + | 
|  | 176 | +      // libtess uses an int index internally due to usage of -1 as a sentinel | 
|  | 177 | +      // value. | 
|  | 178 | +      std::vector<uint16_t> indices(elementItemCount); | 
|  | 179 | +      for (int i = 0; i < elementItemCount; i++) { | 
|  | 180 | +        indices[i] = static_cast<uint16_t>(elements[i]); | 
|  | 181 | +      } | 
|  | 182 | +      if (!callback(vertices, vertexItemCount, indices.data(), | 
|  | 183 | +                    elementItemCount)) { | 
|  | 184 | +        return Result::kInputError; | 
|  | 185 | +      } | 
|  | 186 | +    } else { | 
|  | 187 | +      std::vector<Point> points; | 
|  | 188 | +      std::vector<uint16_t> indices; | 
|  | 189 | + | 
|  | 190 | +      int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize; | 
|  | 191 | +      auto vertices = tessGetVertices(tessellator); | 
|  | 192 | +      for (int i = 0; i < vertexItemCount; i += 2) { | 
|  | 193 | +        points.emplace_back(vertices[i], vertices[i + 1]); | 
|  | 194 | +      } | 
|  | 195 | + | 
|  | 196 | +      int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize; | 
|  | 197 | +      auto elements = tessGetElements(tessellator); | 
|  | 198 | +      for (int i = 0; i < elementItemCount; i++) { | 
|  | 199 | +        indices.emplace_back(elements[i]); | 
|  | 200 | +      } | 
|  | 201 | + | 
|  | 202 | +      if (!callback(reinterpret_cast<float*>(points.data()), points.size(), | 
|  | 203 | +                    nullptr, elementItemCount)) { | 
|  | 204 | +        return Result::kInputError; | 
|  | 205 | +      } | 
| 150 | 206 |     } | 
| 151 | 207 |   } | 
| 152 | 208 | 
 | 
|  | 
0 commit comments