LIBAROMA_CANVASP libaroma_svg_ex( LIBAROMA_STREAMP stream, byte freeStream, byte use_px) { LIBAROMA_CANVASP cv = NULL; if (!stream) { return NULL; } char * data = libaroma_stream_to_string(stream,0); if (data){ NSVGimage *image = NULL; if (!use_px){ image=nsvgParse(data, "dp", ((float) libaroma_fb()->dpi)); } else{ image=nsvgParse(data, "px", ((float) libaroma_fb()->dpi)); } free(data); if (image == NULL) { ALOGW("libaroma_svg: Could not open SVG image."); goto exit; } NSVGrasterizer *rast =nsvgCreateRasterizer(); if (rast == NULL) { printf("libaroma_svg: Could not init rasterizer."); nsvgDelete(image); goto exit; } if (!use_px){ cv = libaroma_canvas_ex(libaroma_dp(image->width),libaroma_dp(image->height),1); } else{ cv = libaroma_canvas_ex(image->width,image->height,1); } libaroma_canvas_setcolor(cv,0,0); nsvgRasterize(rast,image,0,0,1,cv); nsvgDelete(image); nsvgDeleteRasterizer(rast); } exit: if (freeStream) { libaroma_stream_close(stream); } return cv; }
Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors) { NSVGimage *svg_image; PoolVector<uint8_t>::Read src_r = p_data->read(); svg_image = nsvgParse((char *)src_r.ptr(), "px", 96); if (svg_image == NULL) { ERR_PRINT("SVG Corrupted"); return ERR_FILE_CORRUPT; } if (convert_colors) _convert_colors(svg_image); float upscale = upsample ? 2.0 : 1.0; int w = (int)(svg_image->width * p_scale * upscale); int h = (int)(svg_image->height * p_scale * upscale); PoolVector<uint8_t> dst_image; dst_image.resize(w * h * 4); PoolVector<uint8_t>::Write dw = dst_image.write(); rasterizer.rasterize(svg_image, 0, 0, p_scale * upscale, (unsigned char *)dw.ptr(), w, h, w * 4); dw = PoolVector<uint8_t>::Write(); p_image->create(w, h, false, Image::FORMAT_RGBA8, dst_image); if (upsample) p_image->shrink_x2(); nsvgDelete(svg_image); return OK; }
VectorTexture::VectorTexture(std::string const * pGraphic, Filtering filtering, Wrap wrap) { // Parse graphics char* str = static_cast<char*>(malloc(sizeof(char) * pGraphic->size() + 1)); strcpy(str, pGraphic->data()); NSVGimage* svg = nsvgParse(str, "px", SVG_DPI); free(str); // Rasterize it and create OpenGL texture rasterizeGraphics(svg, filtering, wrap, ""); // Delete graphics nsvgDelete(svg); }
/* Load a SVG type image from an SDL datasource */ SDL_Surface *IMG_LoadSVG_RW(SDL_RWops *src) { char *data; struct NSVGimage *image; struct NSVGrasterizer *rasterizer; SDL_Surface *surface = NULL; float scale = 1.0f; data = (char *)SDL_LoadFile_RW(src, NULL, SDL_FALSE); if ( !data ) { return NULL; } /* For now just use default units of pixels at 96 DPI */ image = nsvgParse(data, "px", 96.0f); SDL_free(data); if ( !image ) { IMG_SetError("Couldn't parse SVG image"); return NULL; } rasterizer = nsvgCreateRasterizer(); if ( !rasterizer ) { IMG_SetError("Couldn't create SVG rasterizer"); nsvgDelete( image ); return NULL; } surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int)(image->width * scale), (int)(image->height * scale), 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); if ( !surface ) { nsvgDeleteRasterizer( rasterizer ); nsvgDelete( image ); return NULL; } nsvgRasterize(rasterizer, image, 0.0f, 0.0f, scale, (unsigned char *)surface->pixels, surface->w, surface->h, surface->pitch); nsvgDeleteRasterizer( rasterizer ); nsvgDelete( image ); return surface; }
static NSVGimage * ParseSVGWithOptions( Tcl_Interp *interp, const char *input, int length, Tcl_Obj *formatObj, RastOpts *ropts) { Tcl_Obj **objv = NULL; int objc = 0; double dpi = 96.0; char unit[3], *p; char *inputCopy = NULL; NSVGimage *nsvgImage; static const char *const fmtOptions[] = { "-dpi", "-scale", "-unit", NULL }; enum fmtOptions { OPT_DPI, OPT_SCALE, OPT_UNIT }; /* * The parser destroys the original input string, * therefore first duplicate. */ inputCopy = attemptckalloc(length+1); if (inputCopy == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL); goto error; } memcpy(inputCopy, input, length); inputCopy[length] = '\0'; /* * Process elements of format specification as a list. */ strcpy(unit, "px"); ropts->x = ropts->y = 0.0; ropts->scale = 1.0; if ((formatObj != NULL) && Tcl_ListObjGetElements(interp, formatObj, &objc, &objv) != TCL_OK) { goto error; } for (; objc > 0 ; objc--, objv++) { int optIndex; /* * Ignore the "svg" part of the format specification. */ if (!strcasecmp(Tcl_GetString(objv[0]), "svg")) { continue; } if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions, sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) { goto error; } if (objc < 2) { ckfree(inputCopy); inputCopy = NULL; Tcl_WrongNumArgs(interp, 1, objv, "value"); goto error; } objc--; objv++; switch ((enum fmtOptions) optIndex) { case OPT_DPI: if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) { goto error; } if (dpi < 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-dpi value must be positive", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI", NULL); goto error; } break; case OPT_SCALE: if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) == TCL_ERROR) { goto error; } if (ropts->scale <= 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-scale value must be positive", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE", NULL); goto error; } break; case OPT_UNIT: p = Tcl_GetString(objv[0]); if ((p != NULL) && (p[0])) { strncpy(unit, p, 3); unit[2] = '\0'; } break; } } nsvgImage = nsvgParse(inputCopy, unit, (float) dpi); if (nsvgImage == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL); goto error; } ckfree(inputCopy); return nsvgImage; error: if (inputCopy != NULL) { ckfree(inputCopy); } return NULL; }
int svg_to_ps(lua_State *L) { const char* input = luaL_checkstring(L, 1); int em = 72; if (lua_gettop(L) == 2) { em = luaL_checkinteger(L, 2); } struct NSVGimage* image; image = nsvgParse((char*)input, "pt", em); int max_output = 256; int output_l = 0; char *output = malloc(max_output); output[0] = '\0'; for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { double lastx = -1; double lasty = -1; for (int i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; char thisPath[256]; // Some kind of precision here? if (lastx != p[0] || lasty != p[1]) { // Move needed snprintf(thisPath, 256, "%f %f m ", p[0], p[1]); output = safe_append(output, &output_l, &max_output, thisPath); } snprintf(thisPath, 256, "%f %f %f %f %f %f c ", p[2],p[3], p[4],p[5], p[6],p[7]); lastx = p[6]; lasty = p[7]; output = safe_append(output, &output_l, &max_output, thisPath); } char strokeFillOper = 's'; // Just stroke if (!path->closed) strokeFillOper = 'S'; if (shape->stroke.type == NSVG_PAINT_COLOR) { int r = shape->stroke.color & 0xff; int g = (shape->stroke.color >> 8) & 0xff; int b = (shape->stroke.color >> 16)& 0xff; char color[256]; snprintf(color, 256, "%f w %f %f %f RG ", shape->strokeWidth, r/256.0, g/256.0, b/256.0); output = safe_append(output, &output_l, &max_output, color); } if (shape->fill.type == NSVG_PAINT_COLOR) { int r = shape->fill.color & 0xff; int g = (shape->fill.color >> 8) & 0xff; int b = (shape->fill.color >> 16)& 0xff; char color[256]; snprintf(color, 256, "%f %f %f rg ", r/256.0, g/256.0, b/256.0); output = safe_append(output, &output_l, &max_output, color); strokeFillOper = 'f'; if (shape->stroke.type == NSVG_PAINT_COLOR) { strokeFillOper = 'B'; } else { if (output_l + 2 > max_output) { output = realloc(output, max_output + 2); } output[output_l++] = 'h'; output[output_l++] = ' '; } } if (output_l + 3 > max_output) { output = realloc(output, max_output + 3); } output[output_l++] = strokeFillOper; output[output_l++] = ' '; output[output_l] = '\0'; }