void SvgWindow::updateSvgContext () { if (context) { finiTexture (context->texture[0]); finiTexture (context->texture[1]); } else { context = new SvgContext; if (!context) return; } int x1, y1, x2, y2; CompSize wSize; initTexture (source, context->texture[1], context->size); context->source = source; wSize.setWidth (window->geometry ().width ()); wSize.setHeight (window->geometry ().height ()); decor_apply_gravity (source->p1.gravity, source->p1.x, source->p1.y, wSize.width (), wSize.height (), &x1, &y1); decor_apply_gravity (source->p2.gravity, source->p2.x, source->p2.y, wSize.width (), wSize.height (), &x2, &y2); x1 = MAX (x1, 0); y1 = MAX (y1, 0); x2 = MIN (x2, wSize.width ()); y2 = MIN (y2, wSize.height ()); if (!initTexture (source, context->texture[0], wSize)) { delete context; context = NULL; } else { renderSvg (source, context->texture[0], wSize, 0.0f, 0.0f, 1.0f, 1.0f); initTexture (source, context->texture[1], CompSize ()); context->box += CompRect (x1, y1, x2 - x1, y2 - y1); context->box.translate (window->geometry ().x (), window->geometry ().y ()); updateSvgMatrix (); } }
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; }
bool PngScreen::readPngData (png_struct *png, png_info *info, void *&data, CompSize &size) { png_uint_32 pngWidth, pngHeight; int depth, colorType, interlace; unsigned int pixelSize; png_byte **rowPointers; char *d; png_read_info (png, info); png_get_IHDR (png, info, &pngWidth, &pngHeight, &depth, &colorType, &interlace, NULL, NULL); size.setWidth (pngWidth); size.setHeight (pngHeight); /* convert palette/gray image to rgb */ if (colorType == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb (png); /* expand gray bit depth if needed */ if (colorType == PNG_COLOR_TYPE_GRAY && depth < 8) png_set_expand_gray_1_2_4_to_8 (png); /* transform transparency to alpha */ if (png_get_valid (png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha (png); if (depth == 16) png_set_strip_16 (png); if (depth < 8) png_set_packing (png); /* convert grayscale to RGB */ if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb (png); if (interlace != PNG_INTERLACE_NONE) png_set_interlace_handling (png); png_set_bgr (png); png_set_filler (png, 0xff, PNG_FILLER_AFTER); png_set_read_user_transform_fn (png, premultiplyData); png_read_update_info (png, info); pixelSize = 4; d = (char *) malloc (pngWidth * pngHeight * pixelSize); if (!d) return false; data = d; rowPointers = new png_byte *[pngHeight]; if (!rowPointers) { free (d); return false; } for (unsigned int i = 0; i < pngHeight; i++) rowPointers[i] = (png_byte *) (d + i * pngWidth * pixelSize); png_read_image (png, rowPointers); png_read_end (png, info); delete [] rowPointers; return true; }