SkPath ValueTraits<ShapeValue>::As<SkPath>(const ShapeValue& shape) { SkPath path; if (!shape.fVertices.empty()) { // conservatively assume all cubics path.incReserve(1 + SkToU32(shape.fVertices.size() * 3)); path.moveTo(shape.fVertices.front().fVertex); } const auto& addCubic = [&](size_t from, size_t to) { const auto c0 = shape.fVertices[from].fVertex + shape.fVertices[from].fOutPoint, c1 = shape.fVertices[to].fVertex + shape.fVertices[to].fInPoint; if (c0 == shape.fVertices[from].fVertex && c1 == shape.fVertices[to].fVertex) { // If the control points are coincident, we can power-reduce to a straight line. // TODO: we could also do that when the controls are on the same line as the // vertices, but it's unclear how common that case is. path.lineTo(shape.fVertices[to].fVertex); } else { path.cubicTo(c0, c1, shape.fVertices[to].fVertex); } }; for (size_t i = 1; i < shape.fVertices.size(); ++i) { addCubic(i - 1, i); } if (!shape.fVertices.empty() && shape.fClosed) { addCubic(shape.fVertices.size() - 1, 0); path.close(); } path.setIsVolatile(shape.fVolatile); path.shrinkToFit(); return path; }
void init() { offsetX = gfx::width / 2.0f; offsetY = gfx::height / 2.0f; initVGExp(); //addDistanceTransformCubic(controlPts, rcubic); addCubic(controlPts, rcubic, rtri); glm::vec3 cpt[3] = { glm::vec3(-20, 0, 1), glm::vec3(0, 20, 1), glm::vec3(20, 5, 1) }; //addAATriangle(cpt, rcubic); //testRCubic(); tessellateCubic(); Array<glm::vec2> cp; cp.assign(controlPts2, controlPts2+4); addCubic(mRasterCubic, mTri, cp); glClearStencil(0x80); colorRB = createRenderbuffer(GL_RGBA8, 8, 800, 600); depthRB = createRenderbuffer(GL_DEPTH24_STENCIL8, 8, 800, 600); fbo = createFramebuffer(colorRB, depthRB); glm::vec2 cps[8] = { glm::vec2(-20.0f, 0.0f), glm::vec2( 30.0f, 40.0f), glm::vec2(-30.0f, 40.0f), glm::vec2( 20.0f, 0.0f), }; const size_t maxIndices = 100 * 9; const size_t maxVertices = 100 * 5; const size_t maxB3Vertices = 100 * 10; vg::geometry_t geomPath = { (uint16_t*)core::thread_stack_alloc(sizeof(uint16_t)*maxIndices), (vf::p2_vertex_t*)core::thread_stack_alloc(sizeof(vf::p2_vertex_t)*maxVertices), (vf::p2uv3_vertex_t*)core::thread_stack_alloc(sizeof(vf::p2uv3_vertex_t)*maxB3Vertices), 0, 0, 0 }; vg::geometry_t geomPathOff = { (uint16_t*)core::thread_stack_alloc(sizeof(uint16_t)*maxIndices), (vf::p2_vertex_t*)core::thread_stack_alloc(sizeof(vf::p2_vertex_t)*maxVertices), (vf::p2uv3_vertex_t*)core::thread_stack_alloc(sizeof(vf::p2uv3_vertex_t)*maxB3Vertices), 0, 0, 0 }; uint16_t prevIdx, curIdx; uint16_t prevIdx2, curIdx2; prevIdx = 0; curIdx = vg::geomAddVertex(&geomPath, *(ml::vec2*)&cps[0]); prevIdx2 = vg::geomAddVertex(&geomPathOff, *(ml::vec2*)&cps[0]); curIdx2 = vg::geomAddVertex(&geomPathOff, *(ml::vec2*)&cps[3]); meshAddBezier3 (&geomPath, prevIdx, curIdx, cps[0], cps[1], cps[2], cps[3]); meshStrokeBezier3(&geomPathOff, prevIdx2, curIdx2, cps[0], cps[1], cps[2], cps[3]); testPath = vg::geomToPath(&geomPath); testPathOff = vg::geomToPath(&geomPathOff); core::thread_stack_reset(geomPath.indices); }