Proper implementation of 'wglUseFontBitmaps'
Lionel Ulmer
lionel.ulmer at free.fr
Sat Jul 6 03:46:01 CDT 2002
Well, there is a small bug in my patch (that only supports fonts that have a
width lower than 32).
Fixed in the attached patch.
Lionel
> Changelog:
> Support 'wglUseFontBitmapsA' when using client-side rendering
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: dlls/opengl32/wgl.c
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/wgl.c,v
retrieving revision 1.25
diff -u -r1.25 wgl.c
--- dlls/opengl32/wgl.c 3 Jul 2002 01:16:45 -0000 1.25
+++ dlls/opengl32/wgl.c 6 Jul 2002 08:40:43 -0000
@@ -461,7 +461,95 @@
TRACE("(%08x, %ld, %ld, %ld) using font %ld\n", hdc, first, count, listBase, fid);
- if (fid == 0) return FALSE;
+ if (fid == 0) {
+ /* We are running using client-side rendering fonts... */
+ GLYPHMETRICS gm;
+ static const MAT2 id = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
+ int glyph;
+ int size = 0;
+ void *bitmap = NULL, *gl_bitmap = NULL;
+ int org_alignment;
+
+ ENTER_GL();
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ LEAVE_GL();
+
+ for (glyph = first; glyph < first + count; glyph++) {
+ int needed_size = GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, &id);
+ int height, width_int;
+
+ if (needed_size == GDI_ERROR) goto error;
+ if (needed_size > size) {
+ size = needed_size;
+ if (bitmap) HeapFree(GetProcessHeap(), 0, bitmap);
+ if (gl_bitmap) HeapFree(GetProcessHeap(), 0, gl_bitmap);
+ bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ }
+ if (GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, &id) == GDI_ERROR) goto error;
+ if (TRACE_ON(opengl)) {
+ unsigned int height, width, bitmask;
+ unsigned char *bitmap_ = (unsigned char *) bitmap;
+
+ DPRINTF("Glyph : %d\n", glyph);
+ DPRINTF(" - bbox : %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY);
+ DPRINTF(" - origin : (%ld , %ld)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
+ DPRINTF(" - increment : %d - %d\n", gm.gmCellIncX, gm.gmCellIncY);
+ DPRINTF(" - size : %d\n", needed_size);
+ DPRINTF(" - bitmap : \n");
+ for (height = 0; height < gm.gmBlackBoxY; height++) {
+ DPRINTF(" ");
+ for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) {
+ if (bitmask == 0) {
+ bitmap_ += 1;
+ bitmask = 0x80;
+ }
+ if (*bitmap_ & bitmask)
+ DPRINTF("*");
+ else
+ DPRINTF(" ");
+ }
+ bitmap_ += (4 - (((unsigned int) bitmap_) & 0x03));
+ DPRINTF("\n");
+ }
+ }
+
+ /* For some obscure reasons, I seem to need to rotate the glyph for OpenGL to be happy.
+ As Wine does not seem to support the MAT2 field, I need to do it myself.... */
+ width_int = (gm.gmBlackBoxX + 31) / 32;
+ for (height = 0; height < gm.gmBlackBoxY; height++) {
+ int width;
+ for (width = 0; width < width_int; width++) {
+ ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] =
+ ((int *) bitmap)[height * width_int + width];
+ }
+ }
+
+ ENTER_GL();
+ glNewList(listBase++, GL_COMPILE);
+ glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmptGlyphOrigin.x, gm.gmBlackBoxY - gm.gmptGlyphOrigin.y, gm.gmCellIncX, gm.gmCellIncY, gl_bitmap);
+ glEndList();
+ LEAVE_GL();
+ }
+
+ ENTER_GL();
+ glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
+ LEAVE_GL();
+
+ if (bitmap) HeapFree(GetProcessHeap(), 0, bitmap);
+ if (gl_bitmap) HeapFree(GetProcessHeap(), 0, gl_bitmap);
+ return TRUE;
+
+ error:
+ ENTER_GL();
+ glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
+ LEAVE_GL();
+
+ if (bitmap) HeapFree(GetProcessHeap(), 0, bitmap);
+ if (gl_bitmap) HeapFree(GetProcessHeap(), 0, gl_bitmap);
+ return FALSE;
+ }
ENTER_GL();
/* I assume that the glyphs are at the same position for X and for Windows */
More information about the wine-patches
mailing list