mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
Added ability to draw solid strokes with dashes
[issues 1479: Shape](https://github.com/thorvg/thorvg/issues/1479) In order to build you need third party libraries. Before you start please read this: [LearnWebGPU](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html) Usage example: // init glfw glfwInit(); // create a windowed mode window and its opengl context glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(800, 800, "WebGPU base app", nullptr, nullptr); // get window size int width{}, height{}; glfwGetWindowSize(window, &width, &height); // init engine webgpu tvg::Initializer::init(tvg::CanvasEngine::Wg, 0); // create wg canvas auto canvasWg = tvg::WgCanvas::gen(); canvas_wg->target(glfwGetWin32Window(window), width, height); //Test for Stroke Dash for Arc, Circle, Rect auto shape = tvg::Shape::gen(); shape->appendArc(70, 600, 160, 10, 30, true); shape->appendCircle(70, 700, 20, 60); shape->appendRect(130, 710, 100, 40); shape->strokeFill(255, 0, 0); shape->strokeWidth(5); shape->strokeJoin(tvg::StrokeJoin::Round); shape->strokeCap(tvg::StrokeCap::Round); float dashPattern[2] = {20, 10}; shape->strokeDash(dashPattern, 2); if (canvas_wg->push(std::move(shape)) != tvg::Result::Success) return; while (!glfwWindowShouldClose(window)) { // webgpu canvas_wg->draw(); canvas_wg->sync(); // pull events glfwPollEvents(); } // terminate engine and window tvg::Initializer::term(tvg::CanvasEngine::Wg); glfwDestroyWindow(window); glfwTerminate();
This commit is contained in:
parent
a3adbef2c2
commit
52eca9630c
2 changed files with 46 additions and 1 deletions
|
@ -184,6 +184,13 @@ void WgRenderDataShape::stroke(WGPUDevice device, WGPUQueue queue, const RenderS
|
|||
decodePath(rshape, outlines);
|
||||
|
||||
WgVertexList strokes;
|
||||
if (rshape.stroke->dashPattern) {
|
||||
Array<WgVertexList*> segments;
|
||||
strokeSegments(rshape, outlines, segments);
|
||||
strokeSublines(rshape, segments, strokes);
|
||||
for (uint32_t i = 0; i < segments.count; i++)
|
||||
delete segments[i];
|
||||
} else
|
||||
strokeSublines(rshape, outlines, strokes);
|
||||
|
||||
// append shape if it can create at least one triangle
|
||||
|
@ -230,6 +237,43 @@ void WgRenderDataShape::decodePath(const RenderShape& rshape, Array<WgVertexList
|
|||
}
|
||||
}
|
||||
|
||||
void WgRenderDataShape::strokeSegments(const RenderShape& rshape, Array<WgVertexList*>& outlines, Array<WgVertexList*>& segments) {
|
||||
for (uint32_t i = 0; i < outlines.count; i++) {
|
||||
auto& vlist = outlines[i]->mVertexList;
|
||||
|
||||
// append single point segment
|
||||
if (vlist.count == 1) {
|
||||
auto segment = new WgVertexList();
|
||||
segment->mVertexList.push(vlist.last());
|
||||
segments.push(segment);
|
||||
}
|
||||
|
||||
if (vlist.count >= 2) {
|
||||
uint32_t icurr = 1;
|
||||
uint32_t ipatt = 0;
|
||||
WgPoint vcurr = vlist[0];
|
||||
while (icurr < vlist.count) {
|
||||
if (ipatt % 2 == 0) {
|
||||
segments.push(new WgVertexList());
|
||||
segments.last()->mVertexList.push(vcurr);
|
||||
}
|
||||
float lcurr = rshape.stroke->dashPattern[ipatt];
|
||||
while ((icurr < vlist.count) && (vlist[icurr].dist(vcurr) < lcurr)) {
|
||||
lcurr -= vlist[icurr].dist(vcurr);
|
||||
vcurr = vlist[icurr];
|
||||
icurr++;
|
||||
if (ipatt % 2 == 0) segments.last()->mVertexList.push(vcurr);
|
||||
}
|
||||
if (icurr < vlist.count) {
|
||||
vcurr = vcurr + (vlist[icurr] - vlist[icurr-1]).normal() * lcurr;
|
||||
if (ipatt % 2 == 0) segments.last()->mVertexList.push(vcurr);
|
||||
}
|
||||
ipatt = (ipatt + 1) % rshape.stroke->dashCnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WgRenderDataShape::strokeSublines(const RenderShape& rshape, Array<WgVertexList*>& outlines, WgVertexList& strokes) {
|
||||
float wdt = rshape.stroke->width / 2;
|
||||
for (uint32_t i = 0; i < outlines.count; i++) {
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
void stroke(WGPUDevice device, WGPUQueue queue, const RenderShape& rshape);
|
||||
private:
|
||||
void decodePath(const RenderShape& rshape, Array<WgVertexList*>& outlines);
|
||||
void strokeSegments(const RenderShape& rshape, Array<WgVertexList*>& outlines, Array<WgVertexList*>& segments);
|
||||
void strokeSublines(const RenderShape& rshape, Array<WgVertexList*>& outlines, WgVertexList& strokes);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue