summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Breuer <hans@breuer.org>2001-08-09 23:40:54 +0000
committerHans Breuer <hans@src.gnome.org>2001-08-09 23:40:54 +0000
commit20cd4088fe5bab1cde436ab572a0cc8b38cb7418 (patch)
tree5086639592b55020d4029042ac6d8514742e9650
parent8634415d0e761d18210e54fb045f7b4af07bf046 (diff)
downloadpango-20cd4088fe5bab1cde436ab572a0cc8b38cb7418.tar.gz
restore the previously selected font into the device context.
2001-08-10 Hans Breuer <hans@breuer.org> * pango/pangowin32.c (pango_win32_render) : restore the previously selected font into the device context. (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs to be negative to get underlines right * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) : Don't g_assert_not_reached () on !family case. This is what the X version does as well. Testcase for win32: testfonts.c * pango/testfonts.c : (new file) simple test program for win32 which renders all or selected fonts into a bitmap * pango/makefile.msc : re-enable testfonts compiling
-rw-r--r--ChangeLog17
-rw-r--r--ChangeLog.pre-1-017
-rw-r--r--ChangeLog.pre-1-1017
-rw-r--r--ChangeLog.pre-1-217
-rw-r--r--ChangeLog.pre-1-417
-rw-r--r--ChangeLog.pre-1-617
-rw-r--r--ChangeLog.pre-1-817
-rw-r--r--pango/makefile.msc2
-rw-r--r--pango/pangowin32-fontmap.c2
-rw-r--r--pango/pangowin32.c8
-rw-r--r--pango/testfonts.c406
11 files changed, 532 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index dce54dee..2c35be31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-0
+++ b/ChangeLog.pre-1-0
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-2
+++ b/ChangeLog.pre-1-2
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-4
+++ b/ChangeLog.pre-1-4
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-6
+++ b/ChangeLog.pre-1-6
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index dce54dee..2c35be31 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,20 @@
+2001-08-10 Hans Breuer <hans@breuer.org>
+
+ * pango/pangowin32.c (pango_win32_render) : restore
+ the previously selected font into the device context.
+
+ (pango_win32_font_get_glyph_extents) : info->ink_rect.y needs
+ to be negative to get underlines right
+
+ * pango/pangowin32-fontmap.c (pango_win32_font_map_list_fonts) :
+ Don't g_assert_not_reached () on !family case. This is what
+ the X version does as well. Testcase for win32: testfonts.c
+
+ * pango/testfonts.c : (new file) simple test program for win32
+ which renders all or selected fonts into a bitmap
+
+ * pango/makefile.msc : re-enable testfonts compiling
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* pango/pango-layout.c (pango_layout_line_get_empty_extents):
diff --git a/pango/makefile.msc b/pango/makefile.msc
index 374469d1..3af4796c 100644
--- a/pango/makefile.msc
+++ b/pango/makefile.msc
@@ -15,7 +15,7 @@ PANGO_VER = 0.17
!IFNDEF PACKAGE
DLLS = pango pangowin32 # pangoft2
-EXES = querymodules # testfonts
+EXES = querymodules testfonts
#? test1 test2 test3 test4 test5
# The main target
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 7cdbefde..748100e9 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -342,7 +342,7 @@ pango_win32_font_map_list_fonts (PangoFontMap *fontmap,
else
{
/* FIXME: (Alex) What the heck is this? I think it should just be removed */
- g_assert_not_reached ();
+ /* HB: I don't think so, the X version does the same ... */
*n_descs = win32fontmap->n_fonts;
if (descs)
{
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 2e83aafb..3d04fb29 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -99,7 +99,7 @@ pango_win32_get_hfont (PangoFont *font)
SelectObject (pango_win32_hdc, win32font->hfont);
GetTextMetrics (pango_win32_hdc, &tm);
-
+
win32font->tm_overhang = tm.tmOverhang;
win32font->tm_descent = tm.tmDescent;
win32font->tm_ascent = tm.tmAscent;
@@ -246,7 +246,7 @@ pango_win32_render (HDC hdc,
if (!hfont)
return;
- hfont = SelectObject (hdc, hfont);
+ old_hfont = SelectObject (hdc, hfont);
glyph_indexes = g_new (guint16, glyphs->num_glyphs);
dX = g_new (INT, glyphs->num_glyphs);
@@ -263,6 +263,7 @@ pango_win32_render (HDC hdc,
glyph_indexes, glyphs->num_glyphs,
dX);
+ SelectObject (hdc, old_hfont); /* restore */
g_free (glyph_indexes);
g_free (dX);
}
@@ -320,7 +321,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font,
info->ink_rect.x = PANGO_SCALE * gm.gmptGlyphOrigin.x;
info->ink_rect.width = PANGO_SCALE * gm.gmBlackBoxX;
- info->ink_rect.y = PANGO_SCALE * gm.gmptGlyphOrigin.y;
+ info->ink_rect.y = - PANGO_SCALE * gm.gmptGlyphOrigin.y;
info->ink_rect.height = PANGO_SCALE * gm.gmBlackBoxY;
info->logical_rect.x = 0;
@@ -360,6 +361,7 @@ pango_win32_font_get_metrics (PangoFont *font,
{
SelectObject (pango_win32_hdc, hfont);
GetTextMetrics (pango_win32_hdc, &tm);
+
metrics->ascent = tm.tmAscent * PANGO_SCALE;
metrics->descent = tm.tmDescent * PANGO_SCALE;
metrics->approximate_digit_width = /* really an approximation ... */
diff --git a/pango/testfonts.c b/pango/testfonts.c
new file mode 100644
index 00000000..6cb11ea3
--- /dev/null
+++ b/pango/testfonts.c
@@ -0,0 +1,406 @@
+/* Pango
+ * Copyright (C) 1999 Red Hat Software
+ *
+ * testfonts.c:
+ * Copyright (C) 2001 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <gmodule.h>
+#include "pango.h"
+#include "pango-utils.h"
+#include "pangowin32.h"
+
+
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <locale.h>
+
+#include <windows.h>
+
+gchar*
+gtk_get_default_language (void)
+{
+ gchar *lang;
+ gchar *p;
+
+ lang = g_strdup (setlocale (LC_CTYPE, NULL));
+ p = strchr (lang, '.');
+ if (p)
+ *p = '\0';
+ p = strchr (lang, '@');
+ if (p)
+ *p = '\0';
+
+ return lang;
+}
+
+HDC pre_render (int width, int height);
+void post_render (HDC hdc, const char* sFile);
+
+float
+calc_duration (GTimeVal *tv1, GTimeVal *tv0)
+{
+ return ( ((float)tv1->tv_sec - tv0->tv_sec)
+ + (tv1->tv_usec - tv0->tv_usec) / 1000000.0);
+}
+
+int main (int argc, char **argv)
+{
+ PangoFontMap *fontmap = pango_win32_font_map_for_display();
+ PangoFontDescription** descs;
+ PangoCoverage * coverage = NULL;
+ PangoFont* font = NULL;
+ int nb;
+ int i;
+ gchar* family = NULL;
+ gchar** families;
+ gchar* lang = gtk_get_default_language ();
+ HDC hdc = NULL;
+ int line = 0;
+ GTimeVal tv0, tv1;
+ int my_font_size = 64;
+
+ printf ("# Pango Font Test\n"
+ "# Language: %s\n",
+ "#\n", lang);
+
+ /* FIXME: this wasn't necessary with previous version
+ * and isn't done with current gtk+ win32
+ *
+ * force initialization of built-in engines, otherwise
+ * the rendering get's really fast - too fast to work :-(
+ */
+ pango_win32_get_context ();
+
+ if (argc == 1) /* No arguments given */
+ {
+ PangoFontDescription *desc = pango_font_description_from_string("Sans 12");
+
+ font = pango_font_map_load_font (fontmap, desc);
+ }
+ else
+ {
+ PangoFontDescription *desc = NULL;
+ GString *s;
+
+ s = g_string_new (argv[1]);
+ for (i = 2; i < argc; i++)
+ {
+ s = g_string_append_c (s, ' ');
+ s = g_string_append (s, argv[i]);
+
+ if (0 != atoi (argv[i]))
+ my_font_size = atoi (argv[i]);
+ }
+
+ desc = pango_font_description_from_string(s->str);
+ family = g_strdup(desc->family_name);
+
+ font = pango_font_map_load_font (fontmap, desc);
+
+ coverage = pango_font_get_coverage (font, lang);
+
+ /* ... */
+
+ pango_coverage_unref (coverage);
+ pango_font_description_free (desc);
+ g_object_unref (G_OBJECT (font));
+ }
+
+ pango_font_map_list_fonts (fontmap, family, &descs, &nb);
+
+ hdc = pre_render(my_font_size * 64, 3 * my_font_size * nb / 2);
+
+ for (i = 0; i < nb; i++)
+ {
+ g_print ("Family: %s; Style: %d; Weight: %d\n",
+ descs[i]->family_name,
+ descs[i]->style,
+ descs[i]->weight);
+
+ /* give it an arbitray size to load it */
+ descs[i]->size = my_font_size * PANGO_SCALE;
+
+ g_get_current_time (&tv0);
+ font = pango_font_map_load_font (fontmap, descs[i]);
+ g_get_current_time (&tv1);
+ g_print ("\tpango_font_map_load_font took %.3f sec\n", calc_duration (&tv1, &tv0));
+
+ if (font)
+ {
+ PangoContext *context;
+ PangoLayout *layout;
+ PangoItem *item;
+ PangoGlyphString * glyphs;
+ char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "1234567890 -+*/!§$%&()[]{}<>|#=?@";
+
+ g_get_current_time (&tv0);
+ coverage = pango_font_get_coverage (font, lang);
+ g_get_current_time (&tv1);
+ g_print ("\tpango_font_get_coverage took %.3f sec\n", calc_duration (&tv1, &tv0));
+
+ /* ... */
+ context = pango_win32_get_context ();
+ pango_context_set_language (context, lang);
+ pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
+ pango_context_set_font_description (context, descs[i]);
+
+ glyphs = pango_glyph_string_new ();
+ item = pango_item_new ();
+
+ item->analysis.shape_engine = pango_font_find_shaper (font, lang, s[0]);
+ item->analysis.font = g_object_ref (G_OBJECT (font));
+ pango_shape ( s, sizeof(s), &(item->analysis), glyphs);
+
+ if (hdc)
+ {
+ /* the positioning isn't correct */
+ char * name = g_strdup_printf ("%s (%s%s)",
+ descs[i]->family_name,
+ descs[i]->weight == PANGO_WEIGHT_NORMAL ? "n" :
+ (descs[i]->weight == PANGO_WEIGHT_HEAVY ? "h" :
+ (descs[i]->weight > PANGO_WEIGHT_NORMAL ? "b" : "l")),
+ descs[i]->style == PANGO_STYLE_OBLIQUE ? "o" :
+ (descs[i]->style == PANGO_STYLE_ITALIC ? "i" : "n"));
+
+ TextOut (hdc, 0, line, name, strlen(name));
+ g_get_current_time (&tv0);
+ pango_win32_render (hdc, font, glyphs, 200, line);
+ g_get_current_time (&tv1);
+ g_print ("\tpango_win32_render took %.3f sec\n", calc_duration (&tv1, &tv0));
+ line += (3 * my_font_size / 2);
+ g_free(name);
+ }
+
+ /* free glyphs, ... */
+ pango_glyph_string_free (glyphs);
+ pango_item_free (item);
+
+ pango_coverage_unref (coverage);
+ g_object_unref (G_OBJECT (font));
+ }
+ }
+
+ if (hdc)
+ post_render (hdc, "pango-fonts.bmp");
+
+ pango_font_descriptions_free (descs, nb);
+
+ pango_font_map_list_families (fontmap, &families, &nb);
+ for (i = 0; i < nb; i++)
+ {
+ //g_print ("%s\n", families[i]);
+ }
+
+ pango_font_map_free_families (families, nb);
+
+ return 0;
+}
+
+/*
+ * Real Win32 specific render support
+ */
+static HBITMAP hbmpold = NULL;
+static HWND hwndRender = NULL;
+
+BOOL
+SaveBitmap(HBITMAP hBmp, char* pszFile);
+
+HDC pre_render (int width, int height)
+{
+
+ HDC hdc;
+ HBITMAP hbmp;
+ RECT r;
+ r.top = 0; r.left = 0;
+ r.right = width;
+ r.bottom = height;
+
+ hwndRender = CreateWindow ("EDIT",
+ "pango-render-window",
+ WS_DISABLED,
+ 0, 0, width, height,
+ GetDesktopWindow(),
+ NULL,
+ GetModuleHandle(NULL),
+ NULL);
+
+ hdc = CreateCompatibleDC (GetDC(hwndRender));
+ hbmp = CreateCompatibleBitmap (hdc, width, height);
+ hbmpold = SelectObject(hdc, hbmp);
+
+ FillRect (hdc, &r, GetStockObject(WHITE_BRUSH));
+ SetTextColor (hdc, RGB (0,0,0));
+ SetBkMode (hdc, TRANSPARENT);
+ return hdc;
+}
+
+void post_render (HDC hdc, char* sFile)
+{
+ HBITMAP hbmp = SelectObject(hdc, hbmpold);
+ if (sFile)
+ SaveBitmap (hbmp, sFile);
+ DeleteObject (hbmp);
+ DeleteDC (hdc);
+ ReleaseDC(hwndRender, GetDC(hwndRender));
+ DestroyWindow (hwndRender);
+}
+
+BOOL
+SaveBitmap(HBITMAP hBmp, char* pszFile)
+{
+ BITMAP bmp;
+ PBITMAPINFO pbmi;
+ WORD cClrBits;
+ /* Retrieve the bitmap's color format, width, and height. */
+ if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
+ return FALSE;
+ /* Convert the color format to a count of bits. */
+ cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
+ if (cClrBits == 1)
+ cClrBits = 1;
+ else if (cClrBits <= 4)
+ cClrBits = 4;
+ else if (cClrBits <= 8)
+ cClrBits = 8;
+ else if (cClrBits <= 16)
+ cClrBits = 16;
+ else if (cClrBits <= 24)
+ cClrBits = 24;
+ else
+ cClrBits = 32;
+ /*
+ * Allocate memory for the BITMAPINFO structure. (This structure
+ * contains a BITMAPINFOHEADER structure and an array of RGBQUAD data
+ * structures.) */
+ if (cClrBits != 24)
+ pbmi = (PBITMAPINFO) GlobalAlloc(LPTR,
+ sizeof(BITMAPINFOHEADER) +
+ sizeof(RGBQUAD) * (2^cClrBits));
+ /*
+ * There is no RGBQUAD array for the 24-bit-per-pixel format. */
+ else
+ pbmi = (PBITMAPINFO) GlobalAlloc(LPTR,
+ sizeof(BITMAPINFOHEADER));
+ /* Initialize the fields in the BITMAPINFO structure. */
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = bmp.bmWidth;
+ pbmi->bmiHeader.biHeight = bmp.bmHeight;
+ pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
+ pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
+ if (cClrBits < 24)
+ pbmi->bmiHeader.biClrUsed = 2^cClrBits;
+ /* If the bitmap is not compressed, set the BI_RGB flag. */
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ /*
+ * Compute the number of bytes in the array of color
+ * indices and store the result in biSizeImage.
+ */
+ pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8
+ * pbmi->bmiHeader.biHeight
+ * cClrBits;
+ /*
+ * Set biClrImportant to 0, indicating that all of the
+ * device colors are important.
+ */
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ { // C sucks
+ HANDLE hf; /* file handle */
+ BITMAPFILEHEADER hdr; /* bitmap file-header */
+ PBITMAPINFOHEADER pbih; /* bitmap info-header */
+ LPBYTE lpBits; /* memory pointer */
+ DWORD dwTotal; /* total count of bytes */
+ DWORD cb; /* incremental count of bytes */
+ DWORD dwTmp;
+ HDC hDC;
+
+ pbih = (PBITMAPINFOHEADER) pbmi;
+ lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
+ if (!lpBits)
+ return FALSE;
+ /*
+ * Retrieve the color table (RGBQUAD array) and the bits
+ * (array of palette indices) from the DIB.
+ */
+ hDC = CreateCompatibleDC(NULL);
+ if (!GetDIBits(hDC, hBmp, 0, (WORD) pbih->biHeight,
+ lpBits, pbmi, DIB_RGB_COLORS))
+ return FALSE;
+ /* Create the .BMP file. */
+ hf = CreateFile (pszFile,
+ GENERIC_READ | GENERIC_WRITE,
+ (DWORD) 0,
+ (LPSECURITY_ATTRIBUTES) NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ (HANDLE) NULL);
+
+ if (hf == INVALID_HANDLE_VALUE)
+ return FALSE;
+ hdr.bfType = 0x4d42; /* 0x42 = "B" 0x4d = "M" */
+ /* Compute the size of the entire file. */
+ hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER)
+ + pbih->biSize + pbih->biClrUsed
+ * sizeof(RGBQUAD) + pbih->biSizeImage);
+ hdr.bfReserved1 = 0;
+ hdr.bfReserved2 = 0;
+ /* Compute the offset to the array of color indices. */
+ hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER)
+ + pbih->biSize + pbih->biClrUsed
+ * sizeof (RGBQUAD);
+ /* Copy the BITMAPFILEHEADER into the .BMP file. */
+ if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
+ (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))
+ return FALSE;
+ /* Copy the BITMAPINFOHEADER and RGBQUAD array into the file. */
+ if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ + pbih->biClrUsed * sizeof (RGBQUAD),
+ (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))
+ return FALSE;
+ /* Copy the array of color indices into the .BMP file. */
+ dwTotal = cb = pbih->biSizeImage;
+
+ if (!WriteFile(hf, (LPSTR) lpBits, (int) cb,
+ (LPDWORD) &dwTotal, (LPOVERLAPPED) NULL))
+ return FALSE;
+
+ /* Close the .BMP file. */
+ if (!CloseHandle(hf))
+ return FALSE;
+
+ /* Free memory. */
+ GlobalFree((HGLOBAL)lpBits);
+ GlobalFree((HGLOBAL)pbmi);
+
+ DeleteDC(hDC);
+ } // C sucks
+ return TRUE;
+}