[Lazarus] Replicating Microsoft's AlphaBlend function with Cairo

Anthony Walter sysrpl at gmail.com
Fri Aug 24 07:58:50 CEST 2012


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-ide.org/pipermail/lazarus/attachments/20120824/ce9a3f01/attachment-0002.html>


More information about the Lazarus mailing list