mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-28 09:05:52 +00:00
svg2png: revise code to fix memory violation.
previous code didn't take care of multi-threading. This revise code to avoid changing canvas buffer during multi-tasking.
This commit is contained in:
parent
59f189bcb4
commit
a459a53bc7
1 changed files with 39 additions and 68 deletions
|
@ -52,48 +52,9 @@ struct PngBuilder {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct App {
|
struct App
|
||||||
|
{
|
||||||
void tvgDrawCmds(tvg::Canvas* canvas, bool useSvgSize)
|
void tvgRender(int w, int h)
|
||||||
{
|
|
||||||
if (!canvas) return;
|
|
||||||
|
|
||||||
auto picture = tvg::Picture::gen();
|
|
||||||
float fw, fh;
|
|
||||||
if (picture->load(fileName) != tvg::Result::Success) return;
|
|
||||||
|
|
||||||
picture->viewbox(nullptr, nullptr, &fw, &fh);
|
|
||||||
|
|
||||||
if (useSvgSize) {
|
|
||||||
width = fw;
|
|
||||||
height = fh;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tvg::Matrix m = {width / fw, 0, 0, 0, height / fh, 0, 0, 0, 1};
|
|
||||||
picture->transform(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bgColor != 0xffffffff) {
|
|
||||||
uint8_t bgColorR = (uint8_t) ((bgColor & 0xff0000) >> 16);
|
|
||||||
uint8_t bgColorG = (uint8_t) ((bgColor & 0x00ff00) >> 8);
|
|
||||||
uint8_t bgColorB = (uint8_t) ((bgColor & 0x0000ff));
|
|
||||||
|
|
||||||
//Background
|
|
||||||
auto shape = tvg::Shape::gen();
|
|
||||||
shape->appendRect(0, 0, width, height, 0, 0); //x, y, w, h, rx, ry
|
|
||||||
shape->fill(bgColorR, bgColorG, bgColorB, 255); //r, g, b, a
|
|
||||||
|
|
||||||
if (canvas->push(move(shape)) != tvg::Result::Success) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This showcase shows you asynchrounous loading of svg.
|
|
||||||
For this, pushing pictures at a certian sync time.
|
|
||||||
This means it earns the time to finish loading svg resources,
|
|
||||||
otherwise you can push pictures immediately. */
|
|
||||||
canvas->push(move(picture));
|
|
||||||
}
|
|
||||||
|
|
||||||
int tvgRender(int w, int h)
|
|
||||||
{
|
{
|
||||||
tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
|
tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
|
||||||
|
|
||||||
|
@ -104,36 +65,49 @@ struct App {
|
||||||
if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
|
if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
|
||||||
|
|
||||||
//Create a Canvas
|
//Create a Canvas
|
||||||
auto swCanvas = tvg::SwCanvas::gen();
|
auto canvas = tvg::SwCanvas::gen();
|
||||||
bool useSvgSize = false;
|
|
||||||
if (w == 0 && h == 0) {
|
//Create a Picture
|
||||||
w = h = 200; // Set temporary size
|
auto picture = tvg::Picture::gen();
|
||||||
useSvgSize = true;
|
if (picture->load(fileName) != tvg::Result::Success) return;
|
||||||
}
|
|
||||||
else {
|
float fw, fh;
|
||||||
|
picture->size(&fw, &fh);
|
||||||
|
|
||||||
|
//Proper size is not specified, Get default size.
|
||||||
|
if (w == 0 || h == 0) {
|
||||||
|
width = static_cast<uint32_t>(fw);
|
||||||
|
height = static_cast<uint32_t>(fh);
|
||||||
|
//Otherwise, transform size to keep aspect ratio
|
||||||
|
} else {
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
|
picture->size(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buffer = (uint32_t*)malloc(sizeof(uint32_t) * w * h);
|
//Setup the canvas
|
||||||
swCanvas->target(buffer, w, w, h, tvg::SwCanvas::ARGB8888);
|
auto buffer = (uint32_t*)malloc(sizeof(uint32_t) * width * height);
|
||||||
/* Push the shape into the Canvas drawing list
|
canvas->target(buffer, width, width, height, tvg::SwCanvas::ARGB8888);
|
||||||
When this shape is into the canvas list, the shape could update & prepare
|
|
||||||
internal data asynchronously for coming rendering.
|
|
||||||
Canvas keeps this shape node unless user call canvas->clear() */
|
|
||||||
tvgDrawCmds(swCanvas.get(), useSvgSize);
|
|
||||||
|
|
||||||
if (useSvgSize) {
|
//Background color?
|
||||||
//Resize target buffer
|
if (bgColor != 0xffffffff) {
|
||||||
buffer = (uint32_t*)realloc(buffer, sizeof(uint32_t) * width * height);
|
uint8_t bgColorR = (uint8_t) ((bgColor & 0xff0000) >> 16);
|
||||||
swCanvas->target(buffer, width, width, height, tvg::SwCanvas::ARGB8888);
|
uint8_t bgColorG = (uint8_t) ((bgColor & 0x00ff00) >> 8);
|
||||||
|
uint8_t bgColorB = (uint8_t) ((bgColor & 0x0000ff));
|
||||||
|
|
||||||
|
auto shape = tvg::Shape::gen();
|
||||||
|
shape->appendRect(0, 0, width, height, 0, 0);
|
||||||
|
shape->fill(bgColorR, bgColorG, bgColorB, 255);
|
||||||
|
|
||||||
|
if (canvas->push(move(shape)) != tvg::Result::Success) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Drawing
|
||||||
|
canvas->push(move(picture));
|
||||||
|
canvas->draw();
|
||||||
|
canvas->sync();
|
||||||
|
|
||||||
if (swCanvas->draw() == tvg::Result::Success) {
|
//Build Png
|
||||||
swCanvas->sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
PngBuilder builder;
|
PngBuilder builder;
|
||||||
builder.build(pngName.data(), width, height, buffer);
|
builder.build(pngName.data(), width, height, buffer);
|
||||||
|
|
||||||
|
@ -145,8 +119,6 @@ struct App {
|
||||||
} else {
|
} else {
|
||||||
cout << "engine is not supported" << endl;
|
cout << "engine is not supported" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int setup(int argc, char **argv, size_t *w, size_t *h)
|
int setup(int argc, char **argv, size_t *w, size_t *h)
|
||||||
|
@ -220,8 +192,7 @@ private:
|
||||||
std::string pngName;
|
std::string pngName;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int main(int argc, char **argv)
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
App app;
|
App app;
|
||||||
size_t w, h;
|
size_t w, h;
|
||||||
|
|
Loading…
Add table
Reference in a new issue