Skip to content

Instantly share code, notes, and snippets.

@carloscm
Created February 5, 2020 10:51
Show Gist options
  • Save carloscm/fdd0ad5b6a2bce76ad87123bba5a9e14 to your computer and use it in GitHub Desktop.
Save carloscm/fdd0ad5b6a2bce76ad87123bba5a9e14 to your computer and use it in GitHub Desktop.
// https://github.com/memononen/nanosvg
#include <nanosvg.h>
struct CLSVG {
vg::CommandListHandle handle = { VG_INVALID_HANDLE };
float width = 0.0f;
float height = 0.0f;
};
static uint32_t modulate_color_alpha(uint32_t color, float alpha) {
alpha = float(vg::colorGetAlpha(color)) * alpha;
return (color & 0xffffff) | (uint32_t(alpha) << 24);
}
CLSVG svg_to_vg(const std::string& file_path, float scale) {
CLSVG r;
auto& h = r.handle;
NSVGimage* image = nsvgParseFromFile(file_path.c_str(), "px", 96);
if (!image) {
return r;
}
r.width = image->width * scale;
r.height = image->height * scale;
r.handle = vg::createCommandList(vg_context,
vg::CommandListFlags::Cacheable | vg::CommandListFlags::AllowCommandCulling);
for (NSVGshape* shape = image->shapes; shape; shape = shape->next) {
if (!(shape->flags & NSVGflags::NSVG_FLAGS_VISIBLE)) {
continue;
}
vg::FillRule::Enum fr = vg::FillRule::NonZero;
switch (shape->fillRule) {
case NSVGfillRule::NSVG_FILLRULE_NONZERO: fr = vg::FillRule::NonZero; break;
case NSVGfillRule::NSVG_FILLRULE_EVENODD: fr = vg::FillRule::EvenOdd; break;
}
vg::PathType::Enum pt = vg::PathType::Concave; //vg::PathType::Convex;
vg::LineCap::Enum cap = vg::LineCap::Square;
switch (shape->strokeLineCap) {
case NSVGlineCap::NSVG_CAP_BUTT: cap = vg::LineCap::Butt; break;
case NSVGlineCap::NSVG_CAP_ROUND: cap = vg::LineCap::Round; break;
case NSVGlineCap::NSVG_CAP_SQUARE: cap = vg::LineCap::Square; break;
}
vg::LineJoin::Enum join = vg::LineJoin::Bevel;
switch (shape->strokeLineJoin) {
case NSVGlineJoin::NSVG_JOIN_BEVEL: join = vg::LineJoin::Bevel; break;
case NSVGlineJoin::NSVG_JOIN_MITER: join = vg::LineJoin::Miter; break;
case NSVGlineJoin::NSVG_JOIN_ROUND: join = vg::LineJoin::Round; break;
}
uint32_t fill_color = modulate_color_alpha(shape->fill.color, shape->opacity);
uint32_t stroke_color = modulate_color_alpha(shape->stroke.color, shape->opacity);
vg::clBeginPath(vg_context, h);
for (NSVGpath* path = shape->paths; path; path = path->next) {
if (path->npts < 1) {
continue;
}
vg::clMoveTo(vg_context, h, path->pts[0] * scale, path->pts[1] * scale);
for (int i = 0; i < path->npts - 1; i += 3) {
float* p = &path->pts[i * 2];
vg::clCubicTo(vg_context, h,
p[2] * scale, p[3] * scale,
p[4] * scale, p[5] * scale,
p[6] * scale, p[7] * scale);
}
if (path->closed || shape->fill.type != NSVG_PAINT_NONE) {
vg::clClosePath(vg_context, h);
}
}
// MISING:
// NSVG_PAINT_LINEAR_GRADIENT
// NSVG_PAINT_RADIAL_GRADIENT
if (shape->fill.type == NSVG_PAINT_COLOR) {
vg::clFillPath(vg_context, h, fill_color, VG_FILL_FLAGS(pt, fr, 0));
}
if (shape->stroke.type == NSVG_PAINT_COLOR) {
vg::clStrokePath(vg_context, h, stroke_color, shape->strokeWidth * scale, VG_STROKE_FLAGS(cap, join, 0));
}
}
nsvgDelete(image);
return r;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment