Created
February 5, 2020 10:51
-
-
Save carloscm/fdd0ad5b6a2bce76ad87123bba5a9e14 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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