Bug 3926 - True dynamic linking of AlphaBlend
Summary: True dynamic linking of AlphaBlend
Status: RESOLVED FIXED
Alias: None
Product: cairo
Classification: Unclassified
Component: win32 backend (show other bugs)
Version: 0.9.3
Hardware: x86 (IA32) Windows (All)
: high normal
Assignee: Owen Taylor
QA Contact: cairo-bugs mailing list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-31 05:31 UTC by Hans Breuer
Modified: 2005-08-22 21:31 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
mozilla patch (2.75 KB, patch)
2005-08-18 16:29 UTC, Christian Biesinger
Details | Splinter Review
My version (derived from the Mozilla patch) (3.40 KB, patch)
2005-08-23 06:37 UTC, Owen Taylor
Details | Splinter Review

Description Hans Breuer 2005-07-31 05:31:16 UTC
AlphaBlend() is not available with all windows versions and it 
is not available with the SDK from msvc 6.0. Thus it appears 
appropriate to resolve it at runtime. Patch following:

diff --exclude-from=c:\util\tool\diff.ign -u --recursive
from-cvs/cairo/cairo/src/cairo-win32-surface.c
my-gtk/cairo/cairo/src/cairo-win32-surface.c
--- from-cvs/cairo/cairo/src/cairo-win32-surface.c	Thu Jul 28 22:24:57 2005
+++ my-gtk/cairo/cairo/src/cairo-win32-surface.c	Thu Jul 28 22:33:43 2005
@@ -39,6 +39,34 @@
 
 static const cairo_surface_backend_t cairo_win32_surface_backend;
 
+/*
+ * True dynamic linking of AlphaBlend not only simplifies the build process
+ * cause the SDK version can be lower. It also does allow the rest of cairo
+ * to run successful one a platform not providing msimg32.dll.
+ */
+static int
+_cairo_win32_alpha_blend(HDC dst, int xd, int yd, int wd, int hd,
+                         HDC src, int xs, int ys, int ws, int hs,
+                         BLENDFUNCTION bf)
+{
+    typedef BOOL (WINAPI *PFN_AlphaBlend)
(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
+
+    static HINSTANCE msimg32 = NULL; 
+    static PFN_AlphaBlend alpha_blend = NULL;
+    static int once = 0;
+
+    if (!once) {
+        msimg32 = LoadLibrary ("msimg32.dll");
+        alpha_blend = (PFN_AlphaBlend)GetProcAddress (msimg32, "AlphaBlend");
+        once = TRUE;
+    }
+
+    if (alpha_blend)
+        return alpha_blend(dst,xd,yd,wd,hd,src,xs,ys,ws,hs,bf);
+
+    return FALSE;
+}
+
 /**
  * _cairo_win32_print_gdi_error:
  * @context: context string to display along with the error
@@ -597,7 +625,7 @@
 	blend_function.SourceConstantAlpha = alpha;
 	blend_function.AlphaFormat = src->format == CAIRO_FORMAT_ARGB32 ? AC_SRC_ALPHA
: 0;
 
-	if (!AlphaBlend (dst->dc,
+	if (!_cairo_win32_alpha_blend  (dst->dc,
 			 dst_x, dst_y,
 			 width, height,
 			 src->dc,
Comment 1 Hans Breuer 2005-07-31 06:23:02 UTC
The other half of the patch - getting rid of WINVER define

diff --exclude-from=c:\util\tool\diff.ign -u --recursive
from-cvs/cairo/cairo/src/cairo-win32-private.h
my-gtk/cairo/cairo/src/cairo-win32-private.h
--- from-cvs/cairo/cairo/src/cairo-win32-private.h	Thu Feb 24 23:45:19 2005
+++ my-gtk/cairo/cairo/src/cairo-win32-private.h	Tue Apr 12 23:51:47 2005
@@ -36,13 +36,15 @@
 #ifndef CAIRO_WIN32_PRIVATE_H
 #define CAIRO_WIN32_PRIVATE_H
 
-/* We depend on various features introduced with Win2k and Win98,
- * like AlphaBlend. If it turns out to be a problem, we could
- * use GetProcAddress() to look them up.
+#include <cairo-win32.h>
+/* The only feature needed from WINVER 0x0500 but not available
+ * with standard msvc headers is this constant. Just defineing it
+ * is much better than forcing WINVER
  */
-#define WINVER 0x0500
+#ifndef AC_SRC_ALPHA
+#define AC_SRC_ALPHA 0x01
+#endif
 
-#include <cairo-win32.h>
 #include <cairoint.h>
 
 typedef struct _cairo_win32_surface {
Comment 2 Christian Biesinger 2005-08-06 22:39:17 UTC
Created attachment 3279 [details] [review]
Merge fixed point arithmetic support

this would be the patch used in mozilla for this purpose; it's a bit
different...
Comment 3 Christian Biesinger 2005-08-06 22:40:47 UTC
if my reading of cairo-surface.c is right, then the mozilla patch has the
advantage that it makes cairo-surface fallback to some other way of compositing
and thus it works even on win9x.
Comment 4 Christian Biesinger 2005-08-18 16:29:00 UTC
Created attachment 2920 [details] [review]
mozilla patch

reattaching the mozilla patch, looks like it disappeared
Comment 5 Carl Worth 2005-08-22 17:14:32 UTC
Move bugs against "cvs" version to "0.9.3" so we can remove the "cvs" version.
Comment 6 Owen Taylor 2005-08-23 06:37:36 UTC
Created attachment 3006 [details] [review]
My version (derived from the Mozilla patch)

I took the mozilla patch and fixed it up a lot stylistically. The result
looks OK to me and tests to work.

Remaining questions are:

 - Where is this "mozilla code" from? Who wrote it? Is it is in fact
   MPL/LGPL licensed (I assume so, since it's from the Mozilla tree,
   but worth checking)

 - Is the VC5 stuff really necessary? Are we even close to being able
   to compile Cairo on VC5?
Comment 7 Christian Biesinger 2005-08-23 08:26:53 UTC
it's from https://bugzilla.mozilla.org/show_bug.cgi?id=291818 which seems to
have copied the code that was checked in as part of
https://bugzilla.mozilla.org/show_bug.cgi?id=36694, written by
VYV03354@nifty.ne.jp  

being mozilla code, it is mpl/gpl/lgpl tri-licensed.

as for the vc5 question, no idea...
Comment 8 Hans Breuer 2005-08-23 13:47:38 UTC
Hi Owen,
one thing which appears to be missing in your patch seems to be
'the other half' - i.e. we should get rid of the #define WINVER 0x0500
Comment 9 Owen Taylor 2005-08-23 14:31:34 UTC
2005-08-23  Owen Taylor  <otaylor@redhat.com>

        * src/cairo-win32-font.c (_cairo_win32_scaled_font_show_glyphs):
        Check for AlphaBlend() with GetProcAddress() to support older
        compilation environments like MSVC 6. (Also fixes this portion
        of the code to run on Win98 and Win95, but much of the rest
        of cairo-win32-* won't work in that environment)
        (#3926, Hans Breuer, Christian Biesinger, based on code
        originally from Mozilla)

        * src/cairo-win32-private.h: Remove WINVER define, since it
        was (hopefully) there only for AlphaBlend().

I'm trusting you that we don't need the WINVER define for anything else,
Hans :-)


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.