예제 #1
0
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);
}
예제 #2
0
	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;
	    }
	}
예제 #3
0
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;
}
예제 #4
0
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 ();
    }
}
예제 #5
0
bool
CompText::renderWindowTitle (Window               window,
		             bool                 withViewportNumber,
		             const CompText::Attrib &attrib)
{
    CompString text;

    TEXT_SCREEN (screen);

    if (!ts)
	return false;

    if (withViewportNumber)
    {
	CompString title;
    	CompPoint  winViewport;
	CompSize   viewportSize;

	title = ts->getWindowName (window);
	if (!title.empty ())
	{
	    CompWindow *w;

	    w = screen->findWindow (window);
	    if (w)
	    {
		int viewport;

		winViewport  = w->defaultViewport ();
		viewportSize = screen->vpSize ();
		viewport = winViewport.y () * viewportSize.width () +
		           winViewport.x () + 1;
		text = compPrintf ("%s -[%d]-", title.c_str (), viewport);
	    }
	    else
	    {
		text = title;
	    }
	}
    }
    else
    {
	text = ts->getWindowName (window);
    }

    if (text.empty ())
	return false;

    return renderText (text, attrib);
}
예제 #6
0
bool
SvgScreen::fileToImage (CompString &path,
			CompSize   &size,
			int        &stride,
			void       *&data)
{
    CompString fileName = path;
    bool       status = false;
    int        len = fileName.length ();

    if (len < 4 || fileName.substr (len - 4, 4) != ".svg")
	fileName += ".svg";

    status = readSvgToImage (fileName.c_str (), size, data);

    if (status)
    {
	stride = size.width () * 4;
	return true;
    }

    status = screen->fileToImage (path, size, stride, data);

    return status;
}
예제 #7
0
bool
PngScreen::fileToImage (CompString &name,
			CompSize   &size,
			int        &stride,
			void       *&data)
{
    bool          status = false;
    std::ifstream file;
    CompString    fileName = fileNameWithExtension (name);

    file.open (fileName.c_str ());
    if (file.is_open ())
    {
	status = readPng (file, size, data);
	file.close ();
    }

    if (status)
    {
	stride = size.width () * 4;
	return true;
    }

    return screen->fileToImage (name, size, stride, data);
}
예제 #8
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}