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 (); } }
void SvgWindow::renderSvg (SvgSource *source, SvgTexture &texture, CompSize size, float x1, float y1, float x2, float y2) { float w = x2 - x1; float h = y2 - y1; cairo_save (texture.cr); cairo_set_operator (texture.cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (texture.cr, 1.0, 1.0, 1.0, 0.0); cairo_paint (texture.cr); cairo_set_operator (texture.cr, CAIRO_OPERATOR_OVER); cairo_scale (texture.cr, 1.0 / w, 1.0 / h); cairo_scale (texture.cr, (double) size.width () / source->dimension.width, (double) size.height () / source->dimension.height); cairo_translate (texture.cr, -x1 * source->dimension.width, -y1 * source->dimension.height); rsvg_handle_render_cairo (source->svg, texture.cr); cairo_restore (texture.cr); }
void calculateWallOffset (const CompRect &output, const CompPoint &offsetInScreenCoords, const CompPoint &vpSize, const CompSize &screenSize, float &offsetInWorldX, float &offsetInWorldY, float &worldScaleFactorX, float &worldScaleFactorY, float animationProgress) { const float sx = screenSize.width () / static_cast <float> (output.width ()); const float sy = screenSize.height () / static_cast <float> (output.height ()); offsetInWorldX = 0.0; offsetInWorldY = 0.0; worldScaleFactorX = 1.0f; worldScaleFactorY = 1.0f; if (output.left () == 0) { offsetInWorldX = ((vpSize.x () * sx) / ((float) output.width ()) * (offsetInScreenCoords.x ()) * animationProgress); worldScaleFactorX = 1.0f - ((float) (offsetInScreenCoords.x ()) / (float) (output.width ())) * animationProgress; } if (output.top () == 0) { offsetInWorldY = ((vpSize.y () * sy) / ((float) output.height ()) * (offsetInScreenCoords.y ()) * animationProgress); worldScaleFactorY = 1.0f - ((float) (offsetInScreenCoords.y ()) / (float) output.height ()) * animationProgress; } }
bool SvgWindow::initTexture (SvgSource *source, SvgTexture &texture, CompSize size) { Display *dpy = screen->dpy (); texture.size = size; texture.pixmap = None; texture.cr = NULL; if (size.width () && size.height ()) { cairo_surface_t *surface; XWindowAttributes attr; XGetWindowAttributes (dpy, window->id (), &attr); texture.pixmap = XCreatePixmap (dpy, screen->root (), size.width (), size.height (), attr.depth); texture.textures = GLTexture::bindPixmapToTexture (texture.pixmap, size.width (), size.height (), attr.depth); if (texture.textures.empty ()) { compLogMessage ("svg", CompLogLevelInfo, "Couldn't bind pixmap 0x%x to texture", (int) texture.pixmap); XFreePixmap (dpy, texture.pixmap); return false; } surface = cairo_xlib_surface_create (dpy, texture.pixmap, attr.visual, size.width (), size.height ()); texture.cr = cairo_create (surface); cairo_surface_destroy (surface); } return true; }
bool WallScreen::checkDestination (unsigned int destX, unsigned int destY) { CompPoint point; CompSize size; point = screen->vp (); size = screen->vpSize (); if (point.x () - destX >= (unsigned int) size.width ()) return false; if (point.y () - destY >= (unsigned int) size.height ()) return false; return true; }
bool GLFramebufferObject::allocate (const CompSize &size, const char *image, GLenum format, GLenum type) { priv->status = -1; if (!priv->glTex || size.width () != priv->glTex->width () || size.height () != priv->glTex->height ()) { if (priv->glTex) GLTexture::decRef (priv->glTex); priv->glTex = NULL; GLTexture::List list = GLTexture::imageDataToTexture (image, size, format, type); if (list.size () != 1 || list[0] == NULL) return false; priv->glTex = list[0]; GLTexture::incRef (priv->glTex); if (GL::fboStencilSupported) { (*GL::bindRenderbuffer) (GL::RENDERBUFFER, priv->rbStencilId); (*GL::renderbufferStorage) (GL::RENDERBUFFER, GL::DEPTH24_STENCIL8, size.width (), size.height ()); } } priv->pushFBO (); (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, priv->glTex->target (), priv->glTex->name (), 0); priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER); priv->popFBO (); return true; }
bool PngScreen::writePng (unsigned char *buffer, std::ostream &file, CompSize &size, int stride) { png_struct *png; png_info *info; png_byte **rows; png_color_16 white; int i, height = size.height (); rows = new png_byte *[height]; if (!rows) return false; for (i = 0; i < height; i++) rows[height - i - 1] = buffer + i * stride; png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png) { delete [] rows; return false; } info = png_create_info_struct (png); if (!info) { png_destroy_write_struct (&png, NULL); delete [] rows; return false; } if (setjmp (png_jmpbuf (png))) { png_destroy_write_struct (&png, NULL); delete [] rows; return false; } png_set_write_fn (png, &file, stdioWriteFunc, NULL); png_set_IHDR (png, info, size.width (), size.height (), 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); white.red = 0xff; white.blue = 0xff; white.green = 0xff; png_set_bKGD (png, info, &white); png_write_info (png, info); png_write_image (png, rows); png_write_end (png, info); png_destroy_write_struct (&png, &info); delete [] rows; return true; }