Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2012-08

Replicating Microsoft's AlphaBlend function with Cairo

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Anthony Walter

How can I stretch draw an area of a gdk pixbuf to a cairo surface with a user defined opacity?

I am trying to write a cross platform interface for working with bitmaps and want to add alpha blending to my cairo stretch draw method. What I have right now works just fine, but I am unable to think up a way of to mold alpha blending into a series of cairo/gdk apis which work somewhat like Microsoft's [AlphaBlend][1] function.

What I have so far is this:

    procedure TGtkBitmap.Draw(const Source: TRect; Canvas: TCanvas;
      const Dest: TRect; Alpha: Byte = $FF);
    var
      D: PGdkDrawable;
      C: Pcairo_t;
      M: cairo_matrix_t;
    begin
      if FBuffer = nil then
        Exit;
      if (WidthOf(Source) < 1) or (WidthOf(Dest) < 1) then
        Exit;
      if (HeightOf(Source) < 1) or (HeightOf(Dest) < 1) then
        Exit;
      D := TGtk2DeviceContext(Canvas.Handle).Drawable;
      C := gdk_cairo_create(D);
      gdk_cairo_set_source_pixbuf(C, FBuffer, 0, 0);
      cairo_matrix_init_identity(@M);
      cairo_matrix_translate(@M, Source.Left, Source.Top);
      cairo_matrix_scale(@M, WidthOf(Source) / WidthOf(Dest),
        HeightOf(Source) / HeightOf(Dest));
      cairo_matrix_translate(@M, -Dest.Left, -Dest.Top);
      cairo_pattern_set_matrix(cairo_get_source(C), @M);
      cairo_rectangle(C, Dest.Left, Dest.Top, WidthOf(Dest),
HeightOf(Dest));
      // what cairo functions can I combine here to vary
      // the opacity of the pattern fill using Alpha argument?
      cairo_fill(C);
      cairo_destroy(C);
    end;

Everything works fine, but I am unsure how to get alpha blending with a pix buff pattern working. I can imagine one way which involves creating a second cairo surface, drawing the entire pixbuf to it with a user defined opacity, then creating pattern for the first surface using the new surface, which all gets a little messy and probably is much slower than something I'd be happy with.

Here is a [video recording][2] of what I have working so far. I'd like to know from someone familiar with cairo, what can I insert into my routine above to set the alpha level of the pixbuf source pattern?

[1]:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183351%28v=vs.85%29.aspx [2]: http://youtu.be/VJJIwA1hi7c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20120824/ce9a3f01/attachment.html>

Reply by email

Marc Weustink
to Anthony Walter: How can I stretch draw an area of a gdk pixbuf to a cairo surface with a user defined…
Anthony Walter wrote 8 lines
How can I stretch draw an area of a gdk pixbuf to a cairo surface with a user defined opacity? I am trying to write a cross platform interface for working with bitmaps and want to add alpha blending to my cairo stretch draw method. What I have right now works just fine, but I am unable to think up a way of to mold alpha blending into a series of cairo/gdk apis which work somewhat like Microsoft's [AlphaBlend][1] function.

IIRC When implementing Alphablend for the LCL, I've written an AlphaBlend replacement for win9x winNT and WinCE.
It's somewhere in the windows interface sources.

This routine simply blends buffers of rgba pixels

Marc

Reply by email