int msPreloadSVGSymbol(symbolObj *symbol) { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) struct svg_symbol_cache *cache; if(!symbol->renderer_cache) { cache = msSmallCalloc(1,sizeof(struct svg_symbol_cache)); symbol->renderer_free_func = &freeSVGCache; } else { cache = symbol->renderer_cache; } if(cache->svgc) return MS_SUCCESS; #ifdef USE_SVG_CAIRO { unsigned int svg_width, svg_height; int status; status = svg_cairo_create(&cache->svgc); if (status) { msSetError(MS_RENDERERERR, "problem creating cairo svg", "msPreloadSVGSymbol()"); return MS_FAILURE; } status = svg_cairo_parse(cache->svgc, symbol->full_pixmap_path); if (status) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } svg_cairo_get_size (cache->svgc, &svg_width, &svg_height); if (svg_width == 0 || svg_height == 0) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } symbol->sizex = svg_width; symbol->sizey = svg_height; } #else { RsvgDimensionData dim; cache->svgc = rsvg_handle_new_from_file(symbol->full_pixmap_path,NULL); if(!cache->svgc) { msSetError(MS_RENDERERERR,"failed to load svg file %s", "msPreloadSVGSymbol()", symbol->full_pixmap_path); } rsvg_handle_get_dimensions_sub (cache->svgc, &dim, NULL); symbol->sizex = dim.width; symbol->sizey = dim.height; } #endif symbol->renderer_cache = cache; return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", "msPreloadSVGSymbol()"); return MS_FAILURE; #endif }
int renderSVGSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { #ifdef USE_SVG_CAIRO cairo_renderer *r = CAIRO_RENDERER(img); //double ox=symbol->sizex*0.5,oy=symbol->sizey*0.5; unsigned int svg_width, svg_height; svg_cairo_status_t status; svg_cairo_t *svgc; double scale; //use cache for svg surface if(!symbol->renderer_cache) { status = svg_cairo_create(&svgc); status = svg_cairo_parse_buffer(svgc, symbol->svg_text, strlen(symbol->svg_text)); if (status) { msSetError(MS_RENDERERERR, "problem creating cairo svg", "renderSVGSymbolCairo()"); return MS_FAILURE; } symbol->renderer_cache = svgc; } assert(symbol->renderer_cache); svgc=(svg_cairo_t *)symbol->renderer_cache; svg_cairo_get_size (svgc, &svg_width, &svg_height); //scale such that the SVG is rendered at the desired size in pixels scale = style->scale; /* if (style->scale != 1) { scale = MS_MIN(style->scale / (double) svg_width, style->scale / (double) svg_height); } else { scale = style->scale; } */ cairo_save(r->cr); cairo_translate(r->cr,x,y); cairo_scale(r->cr,scale,scale); if (style->rotation != 0) { cairo_rotate(r->cr, -style->rotation); cairo_translate (r->cr, -(int)svg_width/2, -(int)svg_height/2); } else cairo_translate (r->cr, -(int)svg_width/2, -(int)svg_height/2); status = svg_cairo_render(svgc, r->cr); cairo_restore(r->cr); return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", "renderSVGSymbolCairo()"); return MS_FAILURE; #endif }
int msPreloadSVGSymbol(symbolObj *symbol) { #ifdef USE_SVG_CAIRO svg_cairo_t *svgc; int status; unsigned int svg_width, svg_height; if(symbol->svg_cairo_surface) return MS_SUCCESS; if(!symbol->svg_text) return MS_FAILURE; status = svg_cairo_create(&svgc); if (status) { msSetError(MS_RENDERERERR, "problem creating cairo svg", "msPreloadSVGSymbol()"); return MS_FAILURE; } status = svg_cairo_parse_buffer(svgc, symbol->svg_text, strlen(symbol->svg_text)); if (status) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } svg_cairo_get_size (svgc, &svg_width, &svg_height); if (svg_width == 0 || svg_height == 0) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } symbol->sizex = svg_width; symbol->sizey = svg_height; symbol->svg_cairo_surface = (void *)svgc; return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", "msPreloadSVGSymbol()"); return MS_FAILURE; #endif }
static svg_cairo_status_t render_to_png (FILE *svg_file, FILE *png_file, double scale, int width, int height) { unsigned int svg_width, svg_height; svg_cairo_status_t status; cairo_t *cr; svg_cairo_t *svgc; cairo_surface_t *surface; double dx = 0, dy = 0; status = svg_cairo_create (&svgc); if (status) { fprintf (stderr, "Failed to create svg_cairo_t. Exiting.\n"); exit(1); } status = svg_cairo_parse_file (svgc, svg_file); if (status) return status; svg_cairo_get_size (svgc, &svg_width, &svg_height); if (width < 0 && height < 0) { width = (svg_width * scale + 0.5); height = (svg_height * scale + 0.5); } else if (width < 0) { scale = (double) height / (double) svg_height; width = (svg_width * scale + 0.5); } else if (height < 0) { scale = (double) width / (double) svg_width; height = (svg_height * scale + 0.5); } else { scale = MIN ((double) width / (double) svg_width, (double) height / (double) svg_height); /* Center the resulting image */ dx = (width - (int) (svg_width * scale + 0.5)) / 2; dy = (height - (int) (svg_height * scale + 0.5)) / 2; } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); cairo_translate (cr, dx, dy); cairo_scale (cr, scale, scale); /* XXX: This probably doesn't need to be here (eventually) */ cairo_set_source_rgb (cr, 1, 1, 1); status = svg_cairo_render (svgc, cr); status = write_surface_to_png_file (surface, png_file); cairo_surface_destroy (surface); cairo_destroy (cr); if (status) return status; svg_cairo_destroy (svgc); return status; }
int msRenderSVGToPixmap(symbolObj *symbol, symbolStyleObj *style) { #ifdef USE_SVG_CAIRO unsigned int svg_width, svg_height; svg_cairo_status_t status; cairo_t *cr; svg_cairo_t *svgc; cairo_surface_t *surface; unsigned char *pb; rasterBufferObj *rb; //rendering_buffer *rc; int width, height, surface_w, surface_h,row; double scale; //already rendered at the right size and scale? return if (symbol->pixmap_buffer) { if (style->scale == symbol->pixmap_buffer->scale && style->rotation == symbol->pixmap_buffer->rotation) { return MS_SUCCESS; } else { if(symbol->renderer!=NULL) symbol->renderer->freeSymbol(symbol); msFreeRasterBuffer(symbol->pixmap_buffer); } } if (!symbol->svg_cairo_surface ) msPreloadSVGSymbol(symbol); if (!symbol->svg_cairo_surface) return MS_FAILURE; //set up raster svgc =symbol->svg_cairo_surface; svg_cairo_get_size (svgc, &svg_width, &svg_height); width = surface_w = svg_width; height = surface_h = svg_height; //scale such that the SVG is rendered at the desired size in pixels scale = style->scale; /*MS_MIN(style->scale / (double) svg_width, style->scale / (double) svg_height);*/ //increase pixmap size to accomodate scaling/rotation if (scale != 1.0 && style->scale != 1.0) { width = surface_w = (svg_width * scale + 0.5); height = surface_h = (svg_height * scale + 0.5); } if (style->rotation != 0) { surface_w = MS_NINT(width * 1.415); surface_h = MS_NINT(height * 1.415); } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_w, surface_h); cr = cairo_create(surface); if (style->rotation != 0) { cairo_translate (cr, surface_w/2, surface_h/2); cairo_rotate(cr, -style->rotation); cairo_translate (cr, -width/2, -height/2); } if (style->scale != 1.0) { cairo_scale(cr,scale,scale); } status = svg_cairo_render(svgc, cr); pb = cairo_image_surface_get_data(surface); //set up raster symbol->pixmap_buffer = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj)); MS_CHECK_ALLOC(symbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); initializeRasterBufferCairo(symbol->pixmap_buffer, surface_w, surface_h, 0); rb = symbol->pixmap_buffer; memcpy(rb->data.rgba.pixels, pb, surface_w * surface_h * 4 * sizeof(unsigned char)); /* unpremultiply the data */ for(row=0; row<rb->height; row++) { int col; unsigned char *a,*r,*g,*b; r=rb->data.rgba.r+row*rb->data.rgba.row_step; g=rb->data.rgba.g+row*rb->data.rgba.row_step; b=rb->data.rgba.b+row*rb->data.rgba.row_step; a=rb->data.rgba.a+row*rb->data.rgba.row_step; for(col=0; col<rb->width; col++) { if(*a && *a < 255) { double da = *a/255.0; *r/=da; *g/=da; *b/=da; } a+=rb->data.rgba.pixel_step; r+=rb->data.rgba.pixel_step; g+=rb->data.rgba.pixel_step; b+=rb->data.rgba.pixel_step; } } rb->scale = style->scale; rb->rotation = style->rotation; cairo_destroy(cr); cairo_surface_destroy(surface); return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but MapServer is not built with libsvgcairo", "renderSVGSymbolCairo()"); return MS_FAILURE; #endif }
int msPreloadSVGSymbol(symbolObj *symbol) { #ifdef USE_SVG_CAIRO int status; unsigned int svg_width, svg_height; struct svg_symbol_cache *cache; if(!symbol->renderer_cache) { cache = msSmallCalloc(1,sizeof(struct svg_symbol_cache)); } else { cache = symbol->renderer_cache; } if(cache->svgc) return MS_SUCCESS; if (!symbol->svg_text) { FILE *stream; long int file_len; if ((stream = fopen(symbol->full_pixmap_path, "rb")) == NULL) { msSetError(MS_IOERR, "Could not open svg file %s", "msPreloadSVGSymbol()",symbol->full_pixmap_path); return (MS_FAILURE); } fseek(stream, 0, SEEK_END); file_len = ftell(stream); rewind(stream); symbol->svg_text = (char*) msSmallMalloc(sizeof (char) * file_len); if (1 != fread(symbol->svg_text, file_len, 1, stream)) { msSetError(MS_IOERR, "failed to read %d bytes from svg file %s", "loadSymbol()", file_len, symbol->full_pixmap_path); free(symbol->svg_text); return MS_FAILURE; } symbol->svg_text[file_len - 1] = '\0'; fclose(stream); } status = svg_cairo_create(&cache->svgc); if (status) { msSetError(MS_RENDERERERR, "problem creating cairo svg", "msPreloadSVGSymbol()"); return MS_FAILURE; } status = svg_cairo_parse_buffer(cache->svgc, symbol->svg_text, strlen(symbol->svg_text)); if (status) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } svg_cairo_get_size (cache->svgc, &svg_width, &svg_height); if (svg_width == 0 || svg_height == 0) { msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); return MS_FAILURE; } symbol->sizex = svg_width; symbol->sizey = svg_height; symbol->renderer_cache = cache; return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", "msPreloadSVGSymbol()"); return MS_FAILURE; #endif }
SDL_Surface *load_svg(frame_t *frame, const char *name, int alpha) { svg_cairo_t *svg; unsigned int svg_width; unsigned int svg_height; int bpp = 32; /* bits per pixel */ int btpp = 4; /* bytes per pixel */ int stride; int space; char *image; cairo_surface_t *cairo_surface; cairo_t *cr; Uint32 rmask = 0x00ff0000; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x000000ff; Uint32 amask = 0xff000000; SDL_Surface *sdl_surf_tmp; SDL_Surface *sdl_surf; svg_cairo_create(&svg); svg_cairo_parse(svg, name); svg_cairo_get_size(svg, &svg_width, &svg_height); stride = svg_width * btpp; /* scanline width */ space = svg_height * stride; image = malloc(space); if (!image) { fprintf(stderr, "ugh: malloc(%d)\n", space); exit(1); } cairo_surface = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_ARGB32, svg_width, svg_height, stride); cr = cairo_create(cairo_surface); /* cairo_scale(cr, 1, 1); */ svg_cairo_render(svg, cr); cairo_destroy(cr); cairo_surface_destroy(cairo_surface); svg_cairo_destroy(svg); sdl_surf_tmp = SDL_CreateRGBSurfaceFrom(image, svg_width, svg_height, bpp, stride, rmask, gmask, bmask, amask); sdl_surf = alpha ? SDL_DisplayFormatAlpha(sdl_surf_tmp) : SDL_DisplayFormat(sdl_surf_tmp); if (!sdl_surf) { fprintf(stderr, "ugh: unable to convert image: %s: %s\n", name, SDL_GetError()); exit(1); } SDL_FreeSurface(sdl_surf_tmp); frame->image_list[frame->image_list_size] = sdl_surf; show_image_info(frame, sdl_surf, name, alpha); ++frame->image_list_size; return sdl_surf; }