GNOME Bugzilla – Bug 94791
Render to bitmap without FT2
Last modified: 2005-07-21 22:17:14 UTC
A common reason to add a pangoft2 dependency is one simple facility: rendering text to a bitmap. The patch below shows that this at least can be done almost as easily with the win32 backend. It is tested against libgnomecanvas and Dia. What about allowing other backends to provide render to bitmap facility ? Here's the first version of the patch: diff --exclude-from=c:\util\tool\diff.ign -u -r from-cvs/pango/pango/pango-types.h my-gtk/pango/pango/pango-types.h --- from-cvs/pango/pango/pango-types.h Thu Sep 20 20:10:24 2001 +++ my-gtk/pango/pango/pango-types.h Thu Oct 03 15:03:14 2002 @@ -53,6 +53,18 @@ int height; }; +typedef struct _PangoBitmap PangoBitmap; + +struct _PangoBitmap +{ + int width; + int rows; + int pitch; + int num_grays; + char *buffer; +}; + + #define PANGO_SCALE 1024 #define PANGO_PIXELS(d) (((d) >= 0) ? \ ((d) + PANGO_SCALE / 2) / PANGO_SCALE : \ --- from-cvs/pango/pango/pangowin32.c Sun Sep 29 19:53:02 2002 +++ my-gtk/pango/pango/pangowin32.c Thu Oct 03 15:20:14 2002 @@ -780,6 +780,139 @@ } } +void +pango_win32_render_layout_to_bitmap (PangoBitmap *bitmap, + PangoLayout *layout, + int x, + int y) +{ + /* render into 8 bit given bitmap */ + /* maybe something along the line of + res = GetGlyphOutlineA (pango_win32_hdc, + glyph_index, + GGO_METRICS | GGO_GLYPH_INDEX, + &gm, + 0, NULL, + &m); + or : + */ + static HPALETTE grayPal = NULL; + struct + { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY palPalEntry[256]; + } logpal; + + static struct + { + BITMAPINFOHEADER bmiHeader; + WORD bmiColors[256]; + } bmi; + + HDC hMemDC; + HBITMAP hbm8, holdbmp; + char *pbits8; + int i; + + if (!grayPal) + { + + logpal.palVersion = 0x300; + logpal.palNumEntries = 256; + + for (i = 0; i < 256; i++) + { + logpal.palPalEntry[i].peRed = + logpal.palPalEntry[i].peGreen = + logpal.palPalEntry[i].peBlue = i; + logpal.palPalEntry[i].peFlags = 0; + + bmi.bmiColors[i] = i; + } + grayPal = CreatePalette ((LOGPALETTE *) &logpal); + g_return_if_fail (grayPal); + } + + hMemDC = CreateCompatibleDC (NULL); + g_return_if_fail (hMemDC); + + SelectPalette (hMemDC, grayPal, FALSE); + RealizePalette (hMemDC); + + /* Create a 8 bits depth bitmap and select it into the memory DC */ + bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = bitmap->pitch; + bmi.bmiHeader.biHeight = bitmap->rows; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 8; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 256; + bmi.bmiHeader.biClrImportant = 256; + + hbm8 = CreateDIBSection (hMemDC, (BITMAPINFO *)&bmi, + DIB_PAL_COLORS, &pbits8, NULL, 0); + + holdbmp = (HBITMAP) SelectObject (hMemDC, hbm8); + + /* erase background */ + { + HBRUSH hBr; + HRGN hRgn; + + hRgn = CreateRectRgn (0, 0, bitmap->pitch, bitmap->rows); + hBr = CreateSolidBrush ( RGB (0, 0, 0)); + + FillRgn (hMemDC, hRgn, hBr); + + DeleteObject (hBr); + DeleteObject (hRgn); + } + + /* text out prerequisites */ + SetBkColor (hMemDC, RGB (0,0,0)); + SetTextColor (hMemDC, RGB (255,255,255)); + + SetBkMode (hMemDC, TRANSPARENT); + SetTextAlign (hMemDC, TA_LEFT|TA_BASELINE|TA_NOUPDATECP); + + /* do it */ + pango_win32_render_layout (hMemDC, layout, x, y); + + GdiFlush (); /* make sure pbits8 is valid */ + + SelectObject (hMemDC, holdbmp); + /* copy data, its inverted */ + for (i = 0; i < bitmap->rows; i++) + memcpy (bitmap->buffer + (i * bitmap->pitch), + pbits8 + (bitmap->rows - i - 1) * bitmap->pitch, + bitmap->pitch); + + /* Test */ + if (0) + { + int i; + for (i = 0; i < bitmap->rows; i++) + if (i < (bitmap->rows / 2)) + { + memset (bitmap->buffer + (i * bitmap->pitch), 255, bitmap->pitch / 2); + memset (bitmap->buffer + (i * bitmap->pitch + bitmap->pitch / 2), 0, bitmap->pitch / 2); + } + else + { + memset (bitmap->buffer + (i * bitmap->pitch), 0, bitmap->pitch / 2); + memset (bitmap->buffer + (i * bitmap->pitch + bitmap->pitch / 2), 255, bitmap->pitch / 2); + } + } + + /* clean up */ + DeleteDC (hMemDC); + DeleteObject (hbm8); +} + /* This utility function is duplicated here and in pango-layout.c; should it be * public? Trouble is - what is the appropriate set of properties? */ diff --exclude-from=c:\util\tool\diff.ign -u -r from-cvs/pango/pango/pangowin32.def my-gtk/pango/pango/pangowin32.def --- from-cvs/pango/pango/pangowin32.def Fri Oct 05 18:51:14 2001 +++ my-gtk/pango/pango/pangowin32.def Thu Oct 03 14:59:30 2002 @@ -20,3 +20,5 @@ pango_win32_render_layout pango_win32_render_layout_line pango_win32_shutdown_display + + pango_win32_render_layout_to_bitmap diff --exclude-from=c:\util\tool\diff.ign -u -r from-cvs/pango/pango/pangowin32.h my-gtk/pango/pango/pangowin32.h --- from-cvs/pango/pango/pangowin32.h Sun Sep 29 19:53:02 2002 +++ my-gtk/pango/pango/pangowin32.h Thu Oct 03 14:57:06 2002 @@ -57,6 +57,11 @@ int x, int y); +void +pango_win32_render_layout_to_bitmap (PangoBitmap *bitmap, + PangoLayout *layout, + int x, + int y); #ifdef PANGO_ENABLE_ENGINE
Created attachment 16820 [details] [review] Updated patch
Hi Owen, what needs to be done to get _any_ comment on this issue ? What's the way to make inclusion more probable ? My initial attempt was to make a more abstract interface ("Pango Backend Abstraction"). http://mail.gnome.org/archives/gtk-devel-list/2001-August/msg00612.html The newest patch is a pangowin32 only thing cause the abstraction appeared not to be wanted. BTW: not only The GIMP but also Dia could be improved (given back their render to bitmap facility) with this patch.
It's just not an area that I feel that I have a good idea how it should work yet; I don't want to put something in that we are going to be unhappy with later. See: http://bugzilla.gnome.org/show_bug.cgi?id=107668 For limitations of the FT2 interface .
Is it really better to have nothing - or something the users are unhappy with at the application level ? Dia 0.91 depends on (Pango)Ft2 for rendering to libart bitmaps and to get font outlines to do PS rendering. There is some workaround on win32 cause there are two display renderers, one using high level Gdk - which works cross platform. The other workaround is a gdk-pixbuf based PNG exporter cause the libart based can't render text on win32 (without the patch). PS export is simply limited on win32 to do no outlines. Gimp 1.3 does depend on Ft2 for almost the same reason (rendering to bitmap now and some vague font vector plans in the future). The Gimp people already discarded the support of another backend. One of the result of the missing Pango support (or the existance of two font engines in one program) are homemade font widgets and inconsistencies between them and the ones provided by Gtk. Waiting for the ultimate abstraction (as #107668 suggests) does not look like the right solution to me cause I doubt it can exist. Simply using fontconfig/pangoft2 on win32 does not appeal to me either. To me the current incarnation of fontconfig simply does not match with the win32 platform concepts. BTW: Sodipodi has another solution. It simply has it's own font abstraction layer to convert from native or other font outlines to ArtBpath. See: sodipodi/src/libnrtype/nr-type-{ft2,gnome,w32,xft}.c Maybe Pango should depend on libart to provide bezier outlines _and_ rendering to offscreen bitmap ?
See also bug #107668 which IMHO proposes a nicer API.
IMO the other proposed extension would be useful on its own but has almost nothing to do with the render to bitmap facility - or I haven't understood it. Here are the two use cases I see : - Render to bitmap with backend facilties [this is what this bug is about] - Get on extended fon info like vectors, glyphs etc. IMHO this would best be done with some kind of renderer facilty via GInterface or other callback mechanism. Obviously with this facility it would be possible to write a render-to-bitmap e.g. via renderer using libarts vector to bitmap. But it would be slightly more difficult to implement and probably much slower ... Anyway, attached an updated version of my patch follows.
Created attachment 18463 [details] [review] PATCH: changes restricted to the win32 backend
any chance to get this back from milestone "future" (far, far away;) ?
I consider the Cairo support in Pango-1.9.x to address this need.