sammycage / plutovg Goto Github PK
View Code? Open in Web Editor NEWTiny 2D vector graphics library in C
License: MIT License
Tiny 2D vector graphics library in C
License: MIT License
I was wondering using LunaSVG in Godot and have it create editable 2d shapes in Godot Editor via plutovg output.
Any thoughts?
I'd like to use plutovg on some systems without a FPU or with a very slow FPU -- e.g. ESP32 (S2/S3 with xtenesa instruction set or C3 with RISC-V). I'm thinking of making this a compile-time option, by changing direct usage of float
/double
to plutovg-specific typedefs, and then using a library such as https://github.com/johnmcfarlane/cnl or https://github.com/MikeLankamp/fpm to optionally provide the implementation. (Which would require the code to be compiled as C++ though.)
Is there any interest in such an option? I'll probably do the hack regardless, but if there's a chance to get it upstreamed I'll make an effort to make it cleaner :)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="myCanvas1" style="width:300px;height:300px;background-color:green;">
<canvas id="myCanvas" width="200" height="150" left="10" style="border:5px solid #d3d3d3; background-color:transparent;"></canvas>
</div>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(0,0,200,150);
ctx.clearRect(50,50,100,50);
</script>
</body>
</html>
@sammycage can you show me a demo?
Is there a way to create surface and apply its to another one?
Furthermore, can I transform surface when applying?
Sample code:
#include "plutovg.h"
int main(void)
{
unsigned char data[] = { /* omission */ };
plutovg_surface_t* surface1 = plutovg_surface_create(300, 200);
plutovg_t* pluto = plutovg_create(surface1);
plutovg_surface_t* surface2 = plutovg_surface_create(300, 200);
surface2 = plutovg_surface_create_for_data(data, 300, 200, 4);
/*
Until here I don't have any problems.
If I do `plutovg_surface_write_to_png(surface2, "surface2.png");`, image is OK.
Problem is how to apply surface2 to surface1.
There is `plutovg_set_texture_surface`, but I didn't understand can I use it to satisfy the above conditions.
*/
}
Goal is to draw surface2 to surface1:
Thanks in advance!
fr: 100, cr: 5
#include "plutovg.h"
int main(void)
{
const int width = 150;
const int height = 150;
plutovg_surface_t *surface = plutovg_surface_create(width, height);
plutovg_t *pluto = plutovg_create(surface);
plutovg_save(pluto);
plutovg_gradient_t *g = plutovg_gradient_create_radial(75, 50, 5, 75, 50, 100);
plutovg_gradient_add_stop_rgba(g, 0, 1, 0, 0, 1);
plutovg_gradient_add_stop_rgba(g, 1, 1, 1, 1, 1);
plutovg_set_source_gradient(pluto, g);
plutovg_rect(pluto, 10, 10, 150, 100);
plutovg_fill_preserve(pluto);
plutovg_restore(pluto);
plutovg_surface_write_to_png(surface, "smiley.png");
plutovg_surface_destroy(surface);
plutovg_destroy(pluto);
return 0;
}
I can get the result from html canvas with same input.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(90, 60, 100, 75, 50, 5);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 100);
</script>
</body>
</html>
I tried to fix it, although I am not an expert in it. Just for reference.
Note: I removed if(gradient->radial.fr + v->dr * w >= 0)
, but lack mathematical proof
diff --git a/source/plutovg-blend.c b/source/plutovg-blend.c
index 9dd7541..c43b4c4 100644
--- a/source/plutovg-blend.c
+++ b/source/plutovg-blend.c
@@ -239,22 +239,39 @@ static void fetch_radial_gradient(uint32_t* buffer, const radial_gradient_values
const uint32_t* end = buffer + length;
if(v->extended)
{
- while(buffer < end)
+ if(v->dr >= 0)
{
- uint32_t result = 0;
- if(det >= 0)
+ while(buffer < end)
{
- double w = sqrt(det) - b;
- if(gradient->radial.fr + v->dr * w >= 0)
- result = gradient_pixel(gradient, w);
+ uint32_t result = 0;
+ if(det >= 0)
+ {
+ result = gradient_pixel(gradient, sqrt(det) - b);
+ }
+ *buffer = result;
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ ++buffer;
}
-
- *buffer = result;
- det += delta_det;
- delta_det += delta_delta_det;
- b += delta_b;
- ++buffer;
}
+ else
+ {
+ while(buffer < end)
+ {
+ uint32_t result = 0;
+ if(det >= 0)
+ {
+ result = gradient_pixel(gradient, -sqrt(det) - b);
+ }
+ *buffer = result;
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ ++buffer;
+ }
+ }
+
}
else
{
static void test_arc(const char * filename)
{
plutovg_surface_t * surface = plutovg_surface_create(256, 256);
plutovg_t * ctx = plutovg_create(surface);
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI / 180.0);
double angle2 = 180.0 * (M_PI / 180.0);
plutovg_set_line_width(ctx, 10.0);
plutovg_arc(ctx, xc, yc, radius, angle1, angle2, 0);
plutovg_stroke(ctx);
plutovg_set_source_rgba(ctx, 1, 0.2, 0.2, 0.6);
plutovg_set_line_width(ctx, 6.0);
plutovg_arc(ctx, xc, yc, 10.0, 0, 2 * M_PI, 0);
plutovg_fill(ctx);
plutovg_arc(ctx, xc, yc, radius, angle1, angle1, 0);
plutovg_line_to(ctx, xc, yc);
plutovg_arc(ctx, xc, yc, radius, angle2, angle2, 0);
plutovg_line_to(ctx, xc, yc);
plutovg_stroke(ctx);
plutovg_surface_write_to_png(surface, filename);
plutovg_destroy(ctx);
plutovg_surface_destroy(surface);
}
static void test_arc_negative(const char * filename)
{
plutovg_surface_t * surface = plutovg_surface_create(256, 256);
plutovg_t * ctx = plutovg_create(surface);
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI / 180.0);
double angle2 = 180.0 * (M_PI / 180.0);
plutovg_set_line_width(ctx, 10.0);
plutovg_arc(ctx, xc, yc, radius, angle1, angle2, 1);
plutovg_stroke(ctx);
plutovg_set_source_rgba(ctx, 1, 0.2, 0.2, 0.6);
plutovg_set_line_width(ctx, 6.0);
plutovg_arc(ctx, xc, yc, 10.0, 0, 2 * M_PI, 0);
plutovg_fill(ctx);
plutovg_arc(ctx, xc, yc, radius, angle1, angle1, 0);
plutovg_line_to(ctx, xc, yc);
plutovg_arc(ctx, xc, yc, radius, angle2, angle2, 0);
plutovg_line_to(ctx, xc, yc);
plutovg_stroke(ctx);
plutovg_surface_write_to_png(surface, filename);
plutovg_destroy(ctx);
plutovg_surface_destroy(surface);
}
Hello, can you please provide a font/text example?
https://github.com/Samsung/rlottie
I had a thought it would be possible to connect rlottie to plutovg. Not sure if it's a good idea.
Benefits is that if I can get plutovg to output Godot 2D Editor scenes. I can also get lottie via plutovg to do the same.
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
float rx = 10 + x * 40, ry = 10 + y * 40;
plutovg_round_rect(pluto, rx, ry, 35, 35, 10, 10);
plutovg_arc(pluto, rx + 10, ry + 10, 6, 0, M_PI_2, 1);
plutovg_set_source_rgb(pluto, 1, 192 / 255, 0);
}
}
plutovg_fill(pluto);
I want to draw round-rect with circle hole in it, but the code aboved turned out be wrong.
But when I use API just includes plutovg_move_to
and plutovg_line_to
to draw rect with rect hole, it turned out to be right.
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
float rx = 10 + x * 40, ry = 10 + y * 40;
plutovg_rect(pluto, rx, ry, 35, 35);
plutovg_move_to(pluto, rx + 10, ry + 10);
plutovg_line_to(pluto, rx + 10, ry + 10 + 20);
plutovg_line_to(pluto, rx + 10 + 20, ry + 10 + 20);
plutovg_line_to(pluto, rx + 10 + 20, ry + 10);
plutovg_close_path(pluto);
plutovg_set_source_rgb(pluto, 1, 192 / 255, 0);
}
}
plutovg_fill(pluto);
static unsigned int __inline clz(unsigned int x) {
int c = 31;
x &= ~x + 1;
if (n & 0x0000FFFF) c -= 16;
if (n & 0x00FF00FF) c -= 8;
if (n & 0x0F0F0F0F) c -= 4;
if (n & 0x33333333) c -= 2;
if (n & 0x55555555) c -= 1;
return c;
}
"n" is invaild iden, change to "x"
but do not well in Borland C++Builder, and I add something as below, and done well.
#elif defined(__BORLAND_CLANG__)
__inline int builtin_clz(int v)
{
if (v == 0)
return 31;
__asm
{
bsr ecx, dword ptr[v];
mov eax, 1Fh;
sub eax, ecx;
}
}
#define SW_FT_MSB(x) (31 - __builtin_clz(x))
LINK : fatal error LNK1104: cannot open file 'm.lib' ...
** Build with VSCode using "Visual Studio Community 2019 Release - amd64".
I tried the following changes then no errors occur. (also in Linux)
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index d5150e4..26ea9c5 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -5,4 +5,4 @@ set(CMAKE_C_STANDARD 99)
project(smiley C)
add_executable(smiley smiley.c)
-target_link_libraries(smiley plutovg m)
+if(WIN32)
+ target_link_libraries(smiley plutovg)
+else()
+ target_link_libraries(smiley plutovg m)
+endif()
plutovg_font_book_t* book = plutovg_font_book_create();
plutovg_font_book_add_from_file(book, "fonts/Helvetica.ttf", "Helvetica", plutovg_font_style_normal);
plutovg_font_book_add_from_file(book, "fonts/Helvetica-Bold.ttf", "Helvetica", plutovg_font_style_bold);
plutovg_surface_t* surface = plutovg_surface_create(128, 128);
plutovg_t* pluto = plutovg_create(surface);
plutovg_font_t* font = plutovg_font_load_from_book(book, "Helvetica", plutovg_font_style_normal, 12);
plutovg_set_font(pluto, font);
plutovg_text(pluto, "Hello World", 0, 24);
plutovg_surface_t* surface = plutovg_surface_create(128, 128);
plutovg_t* pluto = plutovg_create_with_font_book(surface, book);
plutovg_save(pluto);
plutovg_select_font(pluto, "Helvetica", plutovg_font_style_normal);
plutovg_text(pluto, "Hello World", 0, 24);
plutovg_restore(pluto);
plutovg_save(pluto);
plutovg_select_font(pluto, "Arial", plutovg_font_style_bold);
plutovg_text(pluto, "Hello World", 0, 48);
plutovg_restore(pluto);
I noticed font support was removed. Are there any plans to re-add some kind of font support?
In the rasterizer, longjmp() and setjmp() are used.
plutovg/source/plutovg-ft-raster.c
Line 293 in fa8002f
I'm trying to port plutovg to a platform which doesn't support these. Is there a version of the rasterizer which doesn't need them?
I've tried bringing in an older version from freetype, but it seems to work differently - expecting a bitmap to render to rather than making callbacks.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0,0,150,75);
ctx.fillStyle = "#00FF00";
ctx.fillRect(50,50,150,75);
ctx.fillStyle = "#0000FF";
ctx.fillRect(100,100,150,75);
</script>
</body>
</html>
how to do this by plutvg api?thanks!!!
you can try the code above in this website:
https://www.quanzhanketang.com/canvas/trycanvas_draw.html?filename=trycanvas_draw
void plutovg_fillRect(plutovg_t* ctx, double x, double y, double w, double h){
plutovg_save(ctx);
plutovg_rect(ctx, x, y, w, h);
plutovg_fill(ctx);
plutovg_restore(ctx);
}
static void test_fillRect(const char * filename)
{
plutovg_surface_t * surface = plutovg_surface_create(256, 256);
plutovg_t * ctx = plutovg_create(surface);
plutovg_set_source_rgb(ctx, 1, 0, 0);
plutovg_fillRect(ctx, 0, 0, 250, 100);
plutovg_set_source_rgb(ctx, 0, 1, 0);
plutovg_fillRect(ctx, 50, 50, 250, 100);
plutovg_set_source_rgb(ctx, 0, 0, 1);
plutovg_fillRect(ctx, 100, 100, 250, 100);
plutovg_surface_write_to_png(surface, filename);
plutovg_destroy(ctx);
plutovg_surface_destroy(surface);
}
The fillRect above is right?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.