static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { ViewerCbInfo *info = (ViewerCbInfo *) user_data; cairo_t *cr; gdouble page_width, page_height; cr = gtk_print_context_get_cairo_context (context); page_width = gtk_print_context_get_width (context); page_height = gtk_print_context_get_height (context); { RsvgHandle *handle; RsvgDimensionData svg_dimensions; struct RsvgSizeCallbackData size_data; /* should not fail */ handle = rsvg_handle_new_from_data(info->svg_bytes->data, info->svg_bytes->len, NULL); rsvg_handle_set_base_uri (handle, info->base_uri); rsvg_handle_set_dpi_x_y (handle, gtk_print_context_get_dpi_x(context), gtk_print_context_get_dpi_y(context)); rsvg_handle_get_dimensions(handle, &svg_dimensions); if (svg_dimensions.width > page_width || svg_dimensions.height > page_height) { /* scale down the image to the page's size, while preserving the aspect ratio */ if ((double) svg_dimensions.height * (double) page_width > (double) svg_dimensions.width * (double) page_height) { svg_dimensions.width = 0.5 + (double) svg_dimensions.width *(double) page_height / (double) svg_dimensions.height; svg_dimensions.height = page_height; } else { svg_dimensions.height = 0.5 + (double) svg_dimensions.height *(double) page_width / (double) svg_dimensions.width; svg_dimensions.width = page_width; } } size_data.type = RSVG_SIZE_WH; size_data.width = svg_dimensions.width; size_data.height = svg_dimensions.height; size_data.keep_aspect_ratio = FALSE; rsvg_handle_set_size_callback (handle, _rsvg_size_callback, &size_data, NULL); rsvg_handle_render_cairo(handle, cr); g_object_unref (handle); } }
static Boat* load_boat_images(Boat *boat) { boat->images = malloc(sizeof(SVGImages)); #if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init(); #endif boat->images->hull = load_svg(SAIL_IMAGE_HULL); boat->images->hull_dimensions = malloc(sizeof(RsvgDimensionData)); rsvg_handle_get_dimensions(boat->images->hull, boat->images->hull_dimensions); boat->images->sail = load_svg(SAIL_IMAGE_SAIL); boat->images->sail_tight = load_svg(SAIL_IMAGE_SAIL_TIGHT); boat->images->sail_dimensions = malloc(sizeof(RsvgDimensionData)); rsvg_handle_get_dimensions(boat->images->sail, boat->images->sail_dimensions); boat->images->sail = load_svg(SAIL_IMAGE_SAIL); boat->images->sail_dimensions = malloc(sizeof(RsvgDimensionData)); rsvg_handle_get_dimensions(boat->images->sail, boat->images->sail_dimensions); boat->images->rudder = load_svg(SAIL_IMAGE_RUDDER); boat->images->rudder_dimensions = malloc(sizeof(RsvgDimensionData)); rsvg_handle_get_dimensions(boat->images->rudder, boat->images->rudder_dimensions); return boat; }
static void vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out ) { RsvgDimensionData dimensions; int width; int height; double scale; double res; /* Calculate dimensions at default dpi/scale. */ rsvg_handle_set_dpi( svg->page, 72.0 ); rsvg_handle_get_dimensions( svg->page, &dimensions ); width = dimensions.width; height = dimensions.height; /* Calculate dimensions at required dpi/scale. */ scale = svg->scale * svg->dpi / 72.0; if( scale != 1.0 ) { rsvg_handle_set_dpi( svg->page, svg->dpi * svg->scale ); rsvg_handle_get_dimensions( svg->page, &dimensions ); if( width == dimensions.width && height == dimensions.height ) { /* SVG without width and height always reports the same * dimensions regardless of dpi. Apply dpi/scale using * cairo instead. */ svg->cairo_scale = scale; width = width * scale; height = height * scale; } else { /* SVG with width and height reports correctly scaled * dimensions. */ width = dimensions.width; height = dimensions.height; } } /* We need pixels/mm for vips. */ res = svg->dpi / 25.4; vips_image_init_fields( out, width, height, 4, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, res, res ); /* We render to a linecache, so fat strips work well. */ vips_image_pipelinev( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL ); }
JNIEXPORT void JNICALL Java_org_gnome_rsvg_RsvgHandle_rsvg_1handle_1get_1dimensions ( JNIEnv* env, jclass cls, jlong _self, jlong _data ) { RsvgHandle* self; RsvgDimensionData* data; // convert parameter self self = (RsvgHandle*) _self; // convert parameter data data = (RsvgDimensionData*) _data; // call function rsvg_handle_get_dimensions(self, data); // cleanup parameter self // cleanup parameter data }
int svg2pdf(const char *svg_filename, const char *pdf_filename) { RsvgHandle *svg_handle; RsvgDimensionData dimension_data; cairo_surface_t *surface; cairo_t *cr; rsvg_set_default_dpi(72.0); svg_handle = rsvg_handle_new_from_file(svg_filename, NULL); if(svg_handle == NULL) { return 0; } rsvg_handle_set_dpi(svg_handle, 72.0); rsvg_handle_get_dimensions(svg_handle, &dimension_data); surface = cairo_pdf_surface_create(pdf_filename, dimension_data.width, dimension_data.height); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { return 0; } cr = cairo_create(surface); if(cairo_status(cr) != CAIRO_STATUS_SUCCESS) { return 0; } if(!rsvg_handle_render_cairo(svg_handle, cr)) { return 0; } cairo_show_page(cr); cairo_surface_destroy(surface); cairo_destroy(cr); g_object_unref(svg_handle); return 1; }
static void test_render_crash (gconstpointer data) { GFile *file = G_FILE (data); RsvgHandle *handle; GError *error = NULL; RsvgDimensionData dimensions; cairo_surface_t *surface; cairo_t *cr; handle = rsvg_handle_new_from_gfile_sync (file, RSVG_HANDLE_FLAGS_NONE, NULL, &error); g_assert_no_error (error); g_assert (handle != NULL); rsvg_handle_get_dimensions (handle, &dimensions); g_assert (dimensions.width > 0); g_assert (dimensions.height > 0); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height); cr = cairo_create (surface); g_assert (rsvg_handle_render_cairo (handle, cr)); cairo_surface_destroy (surface); cairo_destroy (cr); g_object_unref (handle); }
JobFileSvg::JobFileSvg(const char* filename, double scale): JobFile(filename,scale), m_pCairo(NULL), m_cairoMutex(), m_pSurface(NULL), m_pRsvgHandle(NULL) { m_cairoMutex.lock(); float dpi=254.0; GError *error = NULL; RsvgDimensionData dimensions; g_type_init(); rsvg_set_default_dpi_x_y (dpi,dpi);//no reaction? m_pRsvgHandle = rsvg_handle_new_from_file (filename, &error); if( m_pRsvgHandle != NULL ){ rsvg_handle_get_dimensions (m_pRsvgHandle, &dimensions); //m_position.x = (1024-dimensions.width)/2; //m_position.y = (768-dimensions.height)/2; m_pSurface = (cairo_surface_t *)cairo_image_surface_create( CAIRO_FORMAT_ARGB32, m_scale*dimensions.width, m_scale*dimensions.height //1024, 768 ); m_pCairo = cairo_create(m_pSurface); cairo_scale( m_pCairo, m_scale, m_scale); m_size.width = m_scale*dimensions.width; m_size.height = m_scale*dimensions.height; m_position.x = (1024- m_size.width)/2; m_position.y = (768- m_size.height)/2; /* Check existens of layers "#layer0","#layer1",... * to get number of layers and the guarantee that * no inner layer is missed. * */ m_nmbrOfLayers = 0; while( true ){ std::ostringstream layerid; layerid << "#layer" << m_nmbrOfLayers; if( !rsvg_handle_has_sub( m_pRsvgHandle, layerid.str().c_str() )){ break; } m_nmbrOfLayers++; //std::cout << "Found layer " << layerid.str() << std::endl; } std::cout << "Found layers: " << m_nmbrOfLayers << std::endl; m_maxLayer = m_nmbrOfLayers-1; m_cairoMutex.unlock(); }else{ std::cout << "Error while loading file '" << filename << "'." << std::endl; m_cairoMutex.unlock(); throw JOB_LOAD_EXCEPTION; } }
static const char * _rsvg_render_page (const char *filename, cairo_surface_t **surface_out) { RsvgHandle *handle; RsvgDimensionData dimensions; GError *error = NULL; cairo_surface_t *surface; cairo_t *cr; cairo_status_t status; handle = rsvg_handle_new_from_file (filename, &error); if (handle == NULL) return error->message; /* XXX g_error_free */ rsvg_handle_get_dimensions (handle, &dimensions); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height); cr = cairo_create (surface); rsvg_handle_render_cairo (handle, cr); g_object_unref (handle); status = cairo_status (cr); cairo_destroy (cr); if (status) { cairo_surface_destroy (surface); return cairo_status_to_string (status); } *surface_out = surface; return NULL; }
static void draw(GtkWidget *widget, cairo_t *cr) { if (rsvg == NULL) return; double window_width, window_height; window_width = widget->allocation.width; window_height = widget->allocation.height; RsvgDimensionData dimensions; rsvg_handle_get_dimensions(rsvg, &dimensions); unsigned int w, h; w = dimensions.width; h = dimensions.height; double aspect_ratio; aspect_ratio = 1.0 * w / h; double page_width, page_height; page_height = window_height - 8; page_width = page_height * aspect_ratio; if (page_width > window_width - 8) { page_width = window_width - 8; page_height = page_width / aspect_ratio; } double x = (window_width - page_width + 4.) / 2.; double y = (window_height - page_height + 4.) / 2.; cairo_rectangle(cr, x, y, page_width, page_height); cairo_set_source_rgb(cr, 1, 1, 1); cairo_fill(cr); cairo_translate(cr, x, y); cairo_scale(cr, page_width/w, page_height/h); rsvg_handle_render_cairo(rsvg, cr); }
void JobFileSvg::setScale(double scale){ if( scale == m_scale ) return; m_scale = scale; //Flush cache of images m_cache.clear(); //save current midpoint cv::Point mid( m_position.x + m_size.width/2, m_position.y + m_size.height/2 ); RsvgDimensionData dimensions; rsvg_handle_get_dimensions (m_pRsvgHandle, &dimensions); //destroy and recreate cairo objects cairo_destroy (m_pCairo); cairo_surface_destroy (m_pSurface); m_pSurface = (cairo_surface_t *)cairo_image_surface_create( CAIRO_FORMAT_ARGB32, m_scale*dimensions.width, m_scale*dimensions.height ); m_pCairo = cairo_create(m_pSurface); cairo_scale( m_pCairo, m_scale, m_scale); m_size.width = m_scale*dimensions.width; m_size.height = m_scale*dimensions.height; m_position.x = mid.x - m_size.width/2; m_position.y = mid.y - m_size.height/2; }
static gboolean get_image_size (const char *filename, int *width, int *height) { RsvgHandle *handle; RsvgDimensionData dimensions; GError* error = NULL; if (filename == NULL) return FALSE; handle = rsvg_handle_new_from_file (filename, &error); if (error != NULL) { g_printerr ("%s\n", error->message); g_error_free (error); } if (handle == NULL) return FALSE; /* Compute image size */ rsvg_handle_get_dimensions (handle, &dimensions); g_object_unref (handle); if (dimensions.width == 0 || dimensions.height == 0) return FALSE; if (width) *width = dimensions.width; if (height) *height = dimensions.height; return TRUE; }
static Bool readSvgFileToImage(char *file, int *width, int *height, void **data) { cairo_surface_t *surface; FILE *fp; GError *error = NULL; RsvgHandle *svgHandle; RsvgDimensionData svgDimension; fp = fopen(file, "r"); if (!fp) return FALSE; fclose(fp); svgHandle = rsvg_handle_new_from_file(file, &error); if (!svgHandle) return FALSE; rsvg_handle_get_dimensions(svgHandle, &svgDimension); *width = svgDimension.width; *height = svgDimension.height; *data = malloc(svgDimension.width * svgDimension.height * 4); if (!*data) { rsvg_handle_free(svgHandle); return FALSE; } surface = cairo_image_surface_create_for_data(*data, CAIRO_FORMAT_ARGB32, svgDimension.width, svgDimension.height, svgDimension.width * 4); if (surface) { cairo_t *cr; cr = cairo_create(surface); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); rsvg_handle_render_cairo(svgHandle, cr); cairo_destroy(cr); cairo_surface_destroy(surface); } rsvg_handle_free(svgHandle); return TRUE; }
static void size_allocate_callback(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; if(g->image) cairo_surface_destroy(g->image); free(g->image_buffer); /* load the dt logo as a brackground */ char filename[PATH_MAX] = { 0 }; char datadir[PATH_MAX] = { 0 }; char *logo; dt_logo_season_t season = get_logo_season(); if(season != DT_LOGO_SEASON_NONE) logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.svg", (int)season); else logo = g_strdup("%s/pixmaps/idbutton.svg"); dt_loc_get_datadir(datadir, sizeof(datadir)); snprintf(filename, sizeof(filename), logo, datadir); g_free(logo); RsvgHandle *svg = rsvg_handle_new_from_file(filename, NULL); if(svg) { cairo_surface_t *surface; cairo_t *cr; RsvgDimensionData dimension; rsvg_handle_get_dimensions(svg, &dimension); float svg_size = MAX(dimension.width, dimension.height); float final_size = MIN(allocation->width, allocation->height) * 0.75; float factor = final_size / svg_size; float final_width = dimension.width * factor * darktable.gui->ppd, final_height = dimension.height * factor * darktable.gui->ppd; int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, final_width); g->image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8)); surface = dt_cairo_image_surface_create_for_data(g->image_buffer, CAIRO_FORMAT_ARGB32, final_width, final_height, stride); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { free(g->image_buffer); g->image_buffer = NULL; } else { cr = cairo_create(surface); cairo_scale(cr, factor, factor); rsvg_handle_render_cairo(svg, cr); cairo_destroy(cr); cairo_surface_flush(surface); g->image = surface; g->image_width = final_width / darktable.gui->ppd; g->image_height = final_height / darktable.gui->ppd; } g_object_unref(svg); } }
int main (int argc, char **argv) { RsvgDimensionData dimensions; RsvgHandle *logo_handle; cairo_surface_t *surface; GError *error = NULL; cairo_t *cr; cairo_status_t status; char *input, *size, *output; GString *layer; char *layer_name; int h, w; g_type_init (); input = argv[1]; size = argv[2]; layer = g_string_new (argv[3]); g_string_ascii_down (layer); g_string_prepend_c (layer, '#'); output = argv[4]; if (sscanf (size, "%dx%d", &w, &h) != 2) { g_warning ("Couldn't parse size '%s'", size); return 1; } logo_handle = rsvg_handle_new_from_file (input, &error); if (!logo_handle) { g_warning ("Couldn't open '%s': %s", input, error->message); g_error_free (error); return 1; } surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h); cr = cairo_create (surface); rsvg_handle_get_dimensions (logo_handle, &dimensions); cairo_scale (cr, (double) w / dimensions.width, (double) h / dimensions.height); layer_name = g_string_free (layer, FALSE); rsvg_handle_render_cairo_sub (logo_handle, cr, "#background"); // rsvg_handle_render_cairo_sub (logo_handle, cr, "#base"); rsvg_handle_render_cairo_sub (logo_handle, cr, layer_name); status = cairo_surface_write_to_png (surface, output); if (status != CAIRO_STATUS_SUCCESS) { g_warning ("Couldn't write output '%s': %s", output, cairo_status_to_string (status)); return 1; } g_free (layer_name); cairo_destroy (cr); return 0; }
void SvgWindow::setSvg (CompString &data, decor_point_t p[2]) { RsvgHandle *svg = NULL; GError *error = NULL; if (!gWindow) return; svg = rsvg_handle_new_from_data ((guint8 *) data.c_str (), data.length (), &error); if (source) { rsvg_handle_free (source->svg); source->svg = svg; } else { source = new SvgSource; if (source) source->svg = svg; } if (source && source->svg) { source->p1 = p[0]; source->p2 = p[1]; source->svg = svg; gWindow->glDrawSetEnabled (this, true); rsvg_handle_get_dimensions (svg, &source->dimension); updateSvgContext (); } else { if (svg) rsvg_handle_free (svg); if (source) { delete source; source = NULL; } if (context) { finiTexture (context->texture[0]); delete context; context = NULL; } gWindow->glDrawSetEnabled (this, false); } }
static void get_property (GObject * instance, guint prop_id, GValue * value, GParamSpec * pspec) { RsvgHandle *self = RSVG_HANDLE (instance); RsvgDimensionData dim; switch (prop_id) { case PROP_DPI_X: g_value_set_double (value, self->priv->dpi_x); break; case PROP_DPI_Y: g_value_set_double (value, self->priv->dpi_y); break; case PROP_BASE_URI: g_value_set_string (value, rsvg_handle_get_base_uri (self)); break; case PROP_WIDTH: rsvg_handle_get_dimensions (self, &dim); g_value_set_int (value, dim.width); break; case PROP_HEIGHT: rsvg_handle_get_dimensions (self, &dim); g_value_set_int (value, dim.height); break; case PROP_EM: rsvg_handle_get_dimensions (self, &dim); g_value_set_double (value, dim.em); break; case PROP_EX: rsvg_handle_get_dimensions (self, &dim); g_value_set_double (value, dim.ex); break; case PROP_TITLE: g_value_set_string (value, rsvg_handle_get_title (self)); break; case PROP_DESC: g_value_set_string (value, rsvg_handle_get_desc (self)); break; case PROP_METADATA: g_value_set_string (value, rsvg_handle_get_metadata (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (instance, prop_id, pspec); } }
bool SvgScreen::readSvgToImage (const char *file, CompSize &size, void *&data) { cairo_surface_t *surface; std::ifstream svgFile; GError *error = NULL; RsvgHandle *svgHandle; RsvgDimensionData svgDimension; svgFile.open (file); if (!svgFile.is_open ()) return false; svgFile.close (); svgHandle = rsvg_handle_new_from_file (file, &error); if (!svgHandle) return false; rsvg_handle_get_dimensions (svgHandle, &svgDimension); size.setWidth (svgDimension.width); size.setHeight (svgDimension.height); data = malloc (svgDimension.width * svgDimension.height * 4); if (!data) { rsvg_handle_free (svgHandle); return false; } surface = cairo_image_surface_create_for_data ((unsigned char *) data, CAIRO_FORMAT_ARGB32, svgDimension.width, svgDimension.height, svgDimension.width * 4); if (surface) { cairo_t *cr; cr = cairo_create (surface); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); rsvg_handle_render_cairo (svgHandle, cr); cairo_destroy (cr); cairo_surface_destroy (surface); } rsvg_handle_free (svgHandle); return true; }
/* * ui_insert_svg() is not currently used as it's quite slow * I've kept the code here am I might use it later */ void ui_insert_svg(RsvgHandle *svg, double x, double y, double size) { RsvgDimensionData dimensions; rsvg_handle_get_dimensions(svg, &dimensions); cairo_save(ui->w[ui->cur].c); cairo_translate(ui->w[ui->cur].c, x, y); cairo_scale(ui->w[ui->cur].c, size / dimensions.width, size / dimensions.width); rsvg_handle_render_cairo(svg, ui->w[ui->cur].c); cairo_restore(ui->w[ui->cur].c); }
/** * rsvg_handle_get_pixbuf_sub: * @handle: An #RsvgHandle * @id: The id of an element inside the SVG, or %NULL to render the whole SVG. For * example, if you have a layer called "layer1" that you wish to render, pass * "##layer1" as the id. * * Returns the pixbuf loaded by #handle. The pixbuf returned will be reffed, so * the caller of this function must assume that ref. If insufficient data has * been read to create the pixbuf, or an error occurred in loading, then %NULL * will be returned. Note that the pixbuf may not be complete until * @rsvg_handle_close has been called. * * Returns: the pixbuf loaded by #handle, or %NULL. * * Since: 2.14 **/ GdkPixbuf * rsvg_handle_get_pixbuf_sub (RsvgHandle * handle, const char *id) { RsvgDimensionData dimensions; GdkPixbuf *output = NULL; guint8 *pixels; cairo_surface_t *surface; cairo_t *cr; int rowstride; g_return_val_if_fail (handle != NULL, NULL); if (!handle->priv->finished) return NULL; rsvg_handle_get_dimensions (handle, &dimensions); if (!(dimensions.width && dimensions.height)) return NULL; rowstride = dimensions.width * 4; pixels = g_try_malloc0 (dimensions.width * dimensions.height * 4UL); if (!pixels) return NULL; surface = cairo_image_surface_create_for_data (pixels, CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height, rowstride); cr = cairo_create (surface); cairo_surface_destroy (surface); if (rsvg_handle_render_cairo_sub (handle, cr, id)) { rsvg_cairo_to_pixbuf (pixels, rowstride, dimensions.height); output = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8, dimensions.width, dimensions.height, rowstride, (GdkPixbufDestroyNotify) rsvg_pixmap_destroy, NULL); } else { g_free (pixels); output = NULL; } cairo_destroy (cr); return output; }
int main(int argc, char *argv[]) { FILE *fp; RsvgHandle *rsvg; cairo_device_t *dev = NULL; cairo_surface_t *surface = NULL; cairo_t *cr = NULL; RsvgDimensionData dimensions; if (argc < 3) { usage(); return 0; } fp = fopen(argv[1], "r"); if (fp == NULL) { printf("could not open '%s' for read\n", argv[1]); return 1; } fclose(fp); fp = fopen(argv[2], "w"); if (fp == NULL) { printf("could not open '%s' for write\n", argv[2]); return 1; } dev = cairo_xml_create_for_stream((cairo_write_func_t)write_func, fp); rsvg_set_default_dpi_x_y(-1, -1); rsvg = rsvg_handle_new_from_file(argv[1], NULL); rsvg_handle_get_dimensions(rsvg, &dimensions); fprintf(fp, "<image width='%d' height='%d'>\n", dimensions.width, dimensions.height); surface = cairo_xml_surface_create(dev, CAIRO_CONTENT_COLOR_ALPHA, dimensions.width, dimensions.height); cr = cairo_create(surface); rsvg_handle_render_cairo(rsvg, cr); rsvg_handle_close(rsvg, NULL); cairo_destroy(cr); cairo_surface_destroy(surface); fprintf(fp, "</image>\n"); fclose(fp); return 0; }
static VALUE rb_rsvg_handle_get_dim(VALUE self) { RsvgDimensionData dim; VALUE args[4]; rsvg_handle_get_dimensions(_SELF(self), &dim); args[0] = INT2NUM(dim.width); args[1] = INT2NUM(dim.height); args[2] = rb_float_new(dim.em); args[3] = rb_float_new(dim.ex); return rb_class_new_instance(sizeof(args) / sizeof(VALUE), args, cDim); }
static void gth_image_svg_set_handle (GthImageSvg *self, RsvgHandle *rsvg) { RsvgDimensionData dimension_data; if (self->rsvg == rsvg) return; self->rsvg = g_object_ref (rsvg); rsvg_handle_get_dimensions (self->rsvg, &dimension_data); self->original_width = dimension_data.width; self->original_height = dimension_data.height; gth_image_svg_set_zoom (GTH_IMAGE (self), 1.0, NULL, NULL); }
void ImagesStorage::loadFrenchDeck(RsvgHandle* rsvgCards) { RsvgDimensionData dim; rsvg_handle_get_dimensions(rsvgCards, &dim); Cairo::RefPtr<Cairo::ImageSurface> allImages = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, dim.width, dim.height); Cairo::RefPtr<Cairo::Context> cardsImagesDrawer = Cairo::Context::create( allImages ); cardsImagesDrawer->set_source_rgb(1, 1, 1); rsvg_handle_render_cairo(rsvgCards, cardsImagesDrawer->cobj()); for( Preference::SuitForwardIterator itSuit; itSuit.HasNext(); itSuit.Next() ) { for( Preference::RankForwardIterator itRank; itRank.HasNext(); itRank.Next() ) { cardsImages[FrenchDeckName][Preference::CreateCard(itSuit.GetObject(), itRank.GetObject())] = loadFrenchCard( allImages, Preference::CreateCard(itSuit.GetObject(), itRank.GetObject()) ); } } cardsImages[FrenchDeckName][Preference::UnknownCard] = loadFrenchCard(allImages, Preference::UnknownCard); }
static void gst_rsvg_overlay_set_svg_data (GstRsvgOverlay * overlay, const gchar * data, gboolean consider_as_filename) { GstBaseTransform *btrans = GST_BASE_TRANSFORM (overlay); gsize size; GError *error = NULL; if (overlay->handle) { g_object_unref (overlay->handle); overlay->handle = NULL; gst_base_transform_set_passthrough (btrans, TRUE); } /* data may be NULL */ if (data) { size = strlen (data); if (size) { /* Read data either from string or from file */ if (consider_as_filename) overlay->handle = rsvg_handle_new_from_file (data, &error); else overlay->handle = rsvg_handle_new_from_data ((guint8 *) data, size, &error); if (error || overlay->handle == NULL) { if (error) { GST_ERROR_OBJECT (overlay, "Cannot read SVG data: %s\n%s", error->message, data); g_error_free (error); } else { GST_ERROR_OBJECT (overlay, "Cannot read SVG data: %s", data); } } else { /* Get SVG dimension. */ RsvgDimensionData svg_dimension; rsvg_handle_get_dimensions (overlay->handle, &svg_dimension); overlay->svg_width = svg_dimension.width; overlay->svg_height = svg_dimension.height; gst_base_transform_set_passthrough (btrans, FALSE); GST_INFO_OBJECT (overlay, "updated SVG, %d x %d", overlay->svg_width, overlay->svg_height); } } } }
int main (int argc, char *argv[]) { GError *error = NULL; RsvgHandle *handle; RsvgDimensionData dim; double width, height; const char *filename = argv[1]; const char *output_filename = argv[2]; cairo_surface_t *surface; cairo_t *cr; cairo_status_t status; if (argc != 3) FAIL ("usage: svg2pdf input_file.svg output_file.pdf"); g_type_init (); rsvg_set_default_dpi (72.0); handle = rsvg_handle_new_from_file (filename, &error); if (error != NULL) FAIL (error->message); rsvg_handle_get_dimensions (handle, &dim); width = dim.width; height = dim.height; surface = cairo_pdf_surface_create (output_filename, width, height); cr = cairo_create (surface); /* Clear background */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); rsvg_handle_render_cairo (handle, cr); status = cairo_status (cr); if (status) FAIL (cairo_status_to_string (status)); cairo_destroy (cr); cairo_surface_destroy (surface); return 0; }
/* Rasterise given SVG image into the PNG format. When dimensions (width and * height) are set to -1, than SVG view-box is used. If only height is set to * -1, then original aspect ratio is preserved and image is resized according * to the width parameter. Upon failure this function returns NULL. */ struct raster_png *raster_svg_to_png(const char *svg, unsigned int width, unsigned int height) { RsvgHandle *rsvg; RsvgDimensionData dimension; cairo_t *cr; cairo_surface_t *surface; cairo_matrix_t matrix; struct raster_png *png; if ((png = calloc(1, sizeof(*png))) == NULL) return NULL; if ((rsvg = rsvg_handle_new_from_data(svg, strlen(svg), NULL)) == NULL) { raster_png_free(png); return NULL; } /* initialize default dimensions based on the SVG view-box */ rsvg_handle_get_dimensions(rsvg, &dimension); if (width == -1) width = dimension.width; if (height == -1) height = round((double)(width * dimension.height) / dimension.width); /* scale SVG image according to the given dimensions */ cairo_matrix_init_scale(&matrix, (double)width / dimension.width, (double)height / dimension.height); surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height); cr = cairo_create(surface); cairo_set_matrix(cr, &matrix); /* draw our SVG data to the Cairo surface */ if (rsvg_handle_render_cairo(rsvg, cr)) cairo_surface_write_to_png_stream(surface, _png_write_callback, png); cairo_destroy(cr); cairo_surface_destroy(surface); g_object_unref(G_OBJECT(rsvg)); return png; }
int main (int argc, char** argv) { cairo_t* cr3; cairo_surface_t* image; RsvgHandle* r_svg; RsvgError rs_err; RsvgDimensionData svgdim; cairo_matrix_t matrix; rsvg_init(); r_svg = rsvg_handle_new_from_file(argv[1], NULL); rsvg_handle_get_dimensions(r_svg, &svgdim); int width = svgdim.width; int height = svgdim.height; unsigned char* buf = (unsigned char*)malloc(width * height * 4); image = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, width, height, width * 4); cr3 = cairo_create(image); cairo_set_source_rgb(cr3, 1.0, 0.0, 0.0); cairo_paint(cr3); rsvg_handle_render_cairo(r_svg, cr3); cairo_surface_write_to_png(image, "output.png"); rsvg_handle_free(r_svg); rsvg_term(); cairo_destroy(cr3); cairo_surface_destroy(image); free(buf); return 0; }
/** * rsvg_handle_get_pixbuf_sub: * @handle: An #RsvgHandle * @id: The id of an element inside the SVG, or %NULL to render the whole SVG. For * example, if you have a layer called "layer1" that you wish to render, pass * "##layer1" as the id. * * Returns the pixbuf loaded by #handle. The pixbuf returned will be reffed, so * the caller of this function must assume that ref. If insufficient data has * been read to create the pixbuf, or an error occurred in loading, then %NULL * will be returned. Note that the pixbuf may not be complete until * @rsvg_handle_close has been called. * * Returns: the pixbuf loaded by #handle, or %NULL. * * Since: 2.14 **/ GdkPixbuf * rsvg_handle_get_pixbuf_sub (RsvgHandle * handle, const char *id) { RsvgDimensionData dimensions; GdkPixbuf *output = NULL; cairo_surface_t *surface; cairo_t *cr; g_return_val_if_fail (handle != NULL, NULL); if (!handle->priv->finished) return NULL; rsvg_handle_get_dimensions (handle, &dimensions); if (!(dimensions.width && dimensions.height)) return NULL; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } cr = cairo_create (surface); if (!rsvg_handle_render_cairo_sub (handle, cr, id)) { cairo_destroy (cr); cairo_surface_destroy (surface); return NULL; } cairo_destroy (cr); output = rsvg_cairo_surface_to_pixbuf (surface); cairo_surface_destroy (surface); return output; }
static void vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out ) { RsvgDimensionData dimensions; double res; rsvg_handle_get_dimensions( svg->page, &dimensions ); /* We need pixels/mm for vips. */ res = svg->dpi / 25.4; vips_image_init_fields( out, dimensions.width * svg->scale, dimensions.height * svg->scale, 4, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, res, res ); /* We render to a linecache, so fat strips work well. */ vips_image_pipelinev( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL ); }
void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) { dt_iop_watermark_data_t *data = (dt_iop_watermark_data_t *)piece->data; float *in = (float *)ivoid; float *out = (float *)ovoid; const int ch = piece->colors; double angle = (M_PI / 180) * -data->rotate; /* Load svg if not loaded */ gchar *svgdoc = _watermark_get_svgdoc(self, data, &piece->pipe->image); if(!svgdoc) { memcpy(ovoid, ivoid, (size_t)sizeof(float) * ch * roi_out->width * roi_out->height); return; } /* create the rsvghandle from parsed svg data */ GError *error = NULL; RsvgHandle *svg = rsvg_handle_new_from_data((const guint8 *)svgdoc, strlen(svgdoc), &error); g_free(svgdoc); if(!svg || error) { memcpy(ovoid, ivoid, (size_t)sizeof(float) * ch * roi_out->width * roi_out->height); return; } /* setup stride for performance */ int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, roi_out->width); /* create cairo memory surface */ guint8 *image = (guint8 *)g_malloc0_n(roi_out->height, stride); cairo_surface_t *surface = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_ARGB32, roi_out->width, roi_out->height, stride); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { // fprintf(stderr,"Cairo surface error: %s\n",cairo_status_to_string(cairo_surface_status(surface))); g_free(image); memcpy(ovoid, ivoid, (size_t)sizeof(float) * ch * roi_out->width * roi_out->height); return; } /* create cairo context and setup transformation/scale */ cairo_t *cr = cairo_create(surface); /* get the dimension of svg */ RsvgDimensionData dimension; rsvg_handle_get_dimensions(svg, &dimension); // width/height of current (possibly cropped) image const float iw = piece->buf_in.width; const float ih = piece->buf_in.height; const float uscale = data->scale / 100.0; // user scale, from GUI in percent // wbase, hbase are the base width and height, this is the multiplicator used for the offset computing // scale is the scale of the watermark itself and is used only to render it. float wbase, hbase, scale; if(data->sizeto == DT_SCALE_IMAGE) { // in image mode, the wbase and hbase are just the image width and height wbase = iw; hbase = ih; if(dimension.width > dimension.height) scale = (iw * roi_out->scale) / dimension.width; else scale = (ih * roi_out->scale) / dimension.height; } else { // in larger/smaller side mode, set wbase and hbase to the largest or smallest side of the image float larger; if(dimension.width > dimension.height) larger = (float)dimension.width; else larger = (float)dimension.height; if(iw > ih) { wbase = hbase = (data->sizeto == DT_SCALE_LARGER_BORDER) ? iw : ih; scale = (data->sizeto == DT_SCALE_LARGER_BORDER) ? (iw / larger) : (ih / larger); } else { wbase = hbase = (data->sizeto == DT_SCALE_SMALLER_BORDER) ? iw : ih; scale = (data->sizeto == DT_SCALE_SMALLER_BORDER) ? (iw / larger) : (ih / larger); } scale *= roi_out->scale; } scale *= uscale; // compute the width and height of the SVG object in image dimension. This is only used to properly // layout the watermark based on the alignment. float svg_width, svg_height; if(dimension.width > dimension.height) { if(data->sizeto == DT_SCALE_IMAGE || (iw > ih && data->sizeto == DT_SCALE_LARGER_BORDER) || (iw < ih && data->sizeto == DT_SCALE_SMALLER_BORDER)) { svg_width = iw * uscale; svg_height = dimension.height * (svg_width / dimension.width); } else { svg_width = ih * uscale; svg_height = dimension.height * (svg_width / dimension.width); } } else { if(data->sizeto == DT_SCALE_IMAGE || (ih > iw && data->sizeto == DT_SCALE_LARGER_BORDER) || (ih < iw && data->sizeto == DT_SCALE_SMALLER_BORDER)) { svg_height = ih * uscale; svg_width = dimension.width * (svg_height / dimension.height); } else { svg_height = iw * uscale; svg_width = dimension.width * (svg_height / dimension.height); } } // compute bounding box of rotated watermark float bb_width, bb_height; bb_width = fabs(svg_width * cos(angle)) + fabs(svg_height * sin(angle)); bb_height = fabs(svg_width * sin(angle)) + fabs(svg_height * cos(angle)); float bX = bb_width / 2.0 - svg_width / 2.0; float bY = bb_height / 2.0 - svg_height / 2.0; // compute translation for the given alignment in image dimension float ty = 0, tx = 0; if(data->alignment >= 0 && data->alignment < 3) // Align to verttop ty = bY; else if(data->alignment >= 3 && data->alignment < 6) // Align to vertcenter ty = (ih / 2.0) - (svg_height / 2.0); else if(data->alignment >= 6 && data->alignment < 9) // Align to vertbottom ty = ih - svg_height - bY; if(data->alignment == 0 || data->alignment == 3 || data->alignment == 6) tx = bX; else if(data->alignment == 1 || data->alignment == 4 || data->alignment == 7) tx = (iw / 2.0) - (svg_width / 2.0); else if(data->alignment == 2 || data->alignment == 5 || data->alignment == 8) tx = iw - svg_width - bX; // translate to position cairo_translate(cr, -roi_in->x, -roi_in->y); // add translation for the given value in GUI (xoffset,yoffset) tx += data->xoffset * wbase; ty += data->yoffset * hbase; cairo_translate(cr, tx * roi_out->scale, ty * roi_out->scale); // compute the center of the svg to rotate from the center float cX = svg_width / 2.0 * roi_out->scale; float cY = svg_height / 2.0 * roi_out->scale; cairo_translate(cr, cX, cY); cairo_rotate(cr, angle); cairo_translate(cr, -cX, -cY); // now set proper scale for the watermark itself cairo_scale(cr, scale, scale); /* render svg into surface*/ dt_pthread_mutex_lock(&darktable.plugin_threadsafe); rsvg_handle_render_cairo(svg, cr); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); cairo_destroy(cr); /* ensure that all operations on surface finishing up */ cairo_surface_flush(surface); /* render surface on output */ guint8 *sd = image; float opacity = data->opacity / 100.0; /* #ifdef _OPENMP #pragma omp parallel for default(none) shared(in, out,sd,opacity) schedule(static) #endif */ for(int j = 0; j < roi_out->height; j++) for(int i = 0; i < roi_out->width; i++) { float alpha = (sd[3] / 255.0) * opacity; /* svg uses a premultiplied alpha, so only use opacity for the blending */ out[0] = ((1.0 - alpha) * in[0]) + (opacity * (sd[2] / 255.0)); out[1] = ((1.0 - alpha) * in[1]) + (opacity * (sd[1] / 255.0)); out[2] = ((1.0 - alpha) * in[2]) + (opacity * (sd[0] / 255.0)); out[3] = in[3]; out += ch; in += ch; sd += 4; } /* clean up */ cairo_surface_destroy(surface); g_object_unref(svg); g_free(image); }