summaryrefslogtreecommitdiffstats
path: root/zbar/window/win.c
diff options
context:
space:
mode:
Diffstat (limited to 'zbar/window/win.c')
-rw-r--r--zbar/window/win.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/zbar/window/win.c b/zbar/window/win.c
new file mode 100644
index 0000000..458e1d9
--- /dev/null
+++ b/zbar/window/win.c
@@ -0,0 +1,321 @@
+/*------------------------------------------------------------------------
+ * Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ * This file is part of the ZBar Bar Code Reader.
+ *
+ * The ZBar Bar Code Reader is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The ZBar Bar Code Reader 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 Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser Public License
+ * along with the ZBar Bar Code Reader; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <ctype.h>
+
+#include "window.h"
+#include "image.h"
+
+#include "win.h"
+
+int _zbar_window_vfw_init(zbar_window_t *w);
+int _zbar_window_dib_init(zbar_window_t *w);
+
+int _zbar_window_resize(zbar_window_t *w)
+{
+ LOGBRUSH lb = {
+ 0,
+ };
+ int x0, y0, by0, bh, i;
+ window_state_t *win = w->state;
+ int lbw;
+
+ static const int bx[5] = { -6, -3, -1, 2, 5 };
+ static const int bw[5] = { 1, 1, 2, 2, 1 };
+ static const int zx[4] = { -7, 7, -7, 7 };
+ static const int zy[4] = { -8, -8, 8, 8 };
+
+ if (w->height * 8 / 10 <= w->width)
+ lbw = w->height / 36;
+ else
+ lbw = w->width * 5 / 144;
+ if (lbw < 1)
+ lbw = 1;
+ win->logo_scale = lbw;
+ zprintf(7, "%dx%d scale=%d\n", w->width, w->height, lbw);
+ if (win->logo_zbars) {
+ DeleteObject(win->logo_zbars);
+ win->logo_zbars = NULL;
+ }
+ if (win->logo_zpen)
+ DeleteObject(win->logo_zpen);
+ if (win->logo_zbpen)
+ DeleteObject(win->logo_zbpen);
+
+ lb.lbStyle = BS_SOLID;
+ lb.lbColor = RGB(0xd7, 0x33, 0x33);
+ win->logo_zpen =
+ ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_ROUND,
+ lbw * 2, &lb, 0, NULL);
+
+ lb.lbColor = RGB(0xa4, 0x00, 0x00);
+ win->logo_zbpen =
+ ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_ROUND,
+ lbw * 2, &lb, 0, NULL);
+
+ x0 = w->width / 2;
+ y0 = w->height / 2;
+ by0 = y0 - 54 * lbw / 5;
+ bh = 108 * lbw / 5;
+
+ for (i = 0; i < 5; i++) {
+ int x = x0 + lbw * bx[i];
+ HRGN bar = CreateRectRgn(x, by0, x + lbw * bw[i], by0 + bh);
+ if (win->logo_zbars) {
+ CombineRgn(win->logo_zbars, win->logo_zbars, bar, RGN_OR);
+ DeleteObject(bar);
+ } else
+ win->logo_zbars = bar;
+ }
+
+ for (i = 0; i < 4; i++) {
+ win->logo_z[i].x = x0 + lbw * zx[i];
+ win->logo_z[i].y = y0 + lbw * zy[i];
+ }
+ return (0);
+}
+
+int _zbar_window_attach(zbar_window_t *w, void *display, unsigned long unused)
+{
+ HDC hdc;
+ int height;
+ HFONT font;
+ TEXTMETRIC tm;
+ window_state_t *win = w->state;
+ if (w->display) {
+ /* FIXME cleanup existing resources */
+ w->display = NULL;
+ }
+
+ if (!display) {
+ if (win) {
+ free(win);
+ w->state = NULL;
+ }
+ return (0);
+ }
+
+ if (!win)
+ win = w->state = calloc(1, sizeof(window_state_t));
+
+ w->display = display;
+
+ win->bih.biSize = sizeof(win->bih);
+ win->bih.biPlanes = 1;
+
+ hdc = GetDC(w->display);
+ if (!hdc)
+ return (-1 /*FIXME*/);
+ win->bih.biXPelsPerMeter =
+ 1000L * GetDeviceCaps(hdc, HORZRES) / GetDeviceCaps(hdc, HORZSIZE);
+ win->bih.biYPelsPerMeter =
+ 1000L * GetDeviceCaps(hdc, VERTRES) / GetDeviceCaps(hdc, VERTSIZE);
+
+ height = -MulDiv(11, GetDeviceCaps(hdc, LOGPIXELSY), 96);
+ font = CreateFontW(height, 0, 0, 0, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0,
+ FF_MODERN | FIXED_PITCH, NULL);
+
+ SelectObject(hdc, font);
+ DeleteObject(font);
+
+ GetTextMetrics(hdc, &tm);
+ win->font_height = tm.tmHeight;
+
+ ReleaseDC(w->display, hdc);
+
+ return (_zbar_window_dib_init(w));
+}
+
+int _zbar_window_begin(zbar_window_t *w)
+{
+ HDC hdc = w->state->hdc = GetDC(w->display);
+ if (!hdc || !SaveDC(hdc))
+ return (-1 /*FIXME*/);
+ return (0);
+}
+
+int _zbar_window_end(zbar_window_t *w)
+{
+ HDC hdc = w->state->hdc;
+ w->state->hdc = NULL;
+ RestoreDC(hdc, -1);
+ ReleaseDC(w->display, hdc);
+ ValidateRect(w->display, NULL);
+ return (0);
+}
+
+int _zbar_window_clear(zbar_window_t *w)
+{
+ RECT r = { 0, 0, w->width, w->height };
+ HDC hdc = GetDC(w->display);
+ if (!hdc)
+ return (-1 /*FIXME*/);
+
+ FillRect(hdc, &r, GetStockObject(BLACK_BRUSH));
+
+ ReleaseDC(w->display, hdc);
+ ValidateRect(w->display, NULL);
+ return (0);
+}
+
+static inline void win_set_rgb(HDC hdc, uint32_t rgb)
+{
+ SelectObject(hdc, GetStockObject(DC_PEN));
+ SetDCPenColor(hdc,
+ RGB((rgb & 4) * 0x33, (rgb & 2) * 0x66, (rgb & 1) * 0xcc));
+}
+
+int _zbar_window_draw_polygon(zbar_window_t *w, uint32_t rgb,
+ const point_t *pts, int npts)
+{
+ point_t org;
+ POINT *gdipts;
+ int i;
+ HDC hdc = w->state->hdc;
+ win_set_rgb(hdc, rgb);
+
+ org = w->scaled_offset;
+ gdipts = (POINT *)calloc(npts + 1, sizeof(*gdipts));
+ for (i = 0; i < npts; i++) {
+ point_t p = window_scale_pt(w, pts[i]);
+ gdipts[i].x = p.x + org.x;
+ gdipts[i].y = p.y + org.y;
+ }
+ gdipts[npts] = gdipts[0];
+
+ Polyline(hdc, gdipts, npts + 1);
+ free(gdipts);
+ return (0);
+}
+
+int _zbar_window_draw_marker(zbar_window_t *w, uint32_t rgb, point_t p)
+{
+ HDC hdc = w->state->hdc;
+ static const DWORD npolys[3] = { 5, 2, 2 };
+ POINT polys[9] = {
+ { p.x - 2, p.y - 2 }, { p.x - 2, p.y + 2 }, { p.x + 2, p.y + 2 },
+ { p.x + 2, p.y - 2 }, { p.x - 2, p.y - 2 },
+
+ { p.x - 3, p.y }, { p.x + 4, p.y },
+
+ { p.x, p.y - 3 }, { p.x, p.y + 4 },
+ };
+
+ win_set_rgb(hdc, rgb);
+
+ PolyPolyline(hdc, polys, npolys, 3);
+ return (0);
+}
+
+int _zbar_window_draw_text(zbar_window_t *w, uint32_t rgb, point_t p,
+ const char *text)
+{
+ int n = 0;
+ HDC hdc = w->state->hdc;
+ SetTextColor(hdc,
+ RGB((rgb & 4) * 0x33, (rgb & 2) * 0x66, (rgb & 1) * 0xcc));
+ SetBkMode(hdc, TRANSPARENT);
+
+ while (n < 32 && text[n] && isprint(text[n]))
+ n++;
+
+ if (p.x >= 0)
+ SetTextAlign(hdc, TA_BASELINE | TA_CENTER);
+ else {
+ SetTextAlign(hdc, TA_BASELINE | TA_RIGHT);
+ p.x += w->width;
+ }
+
+ if (p.y < 0)
+ p.y = w->height + p.y * w->state->font_height * 5 / 4;
+
+ TextOut(hdc, p.x, p.y, text, n);
+ return (0);
+}
+
+int _zbar_window_fill_rect(zbar_window_t *w, uint32_t rgb, point_t org,
+ point_t size)
+{
+ RECT r = { org.x, org.y, org.x + size.x, org.y + size.y };
+ HDC hdc = w->state->hdc;
+ SetDCBrushColor(hdc,
+ RGB((rgb & 4) * 0x33, (rgb & 2) * 0x66, (rgb & 1) * 0xcc));
+
+ FillRect(hdc, &r, GetStockObject(DC_BRUSH));
+
+ return (0);
+}
+
+int _zbar_window_draw_logo(zbar_window_t *w)
+{
+ HDC hdc = w->state->hdc;
+
+ window_state_t *win = w->state;
+
+ /* FIXME buffer offscreen */
+ HRGN rgn = CreateRectRgn(0, 0, w->width, w->height);
+ CombineRgn(rgn, rgn, win->logo_zbars, RGN_DIFF);
+ FillRgn(hdc, rgn, GetStockObject(WHITE_BRUSH));
+ DeleteObject(rgn);
+
+ FillRgn(hdc, win->logo_zbars, GetStockObject(BLACK_BRUSH));
+
+ SelectObject(hdc, win->logo_zpen);
+ Polyline(hdc, win->logo_z, 4);
+
+ ExtSelectClipRgn(hdc, win->logo_zbars, RGN_AND);
+ SelectObject(hdc, win->logo_zbpen);
+ Polyline(hdc, win->logo_z, 4);
+ return (0);
+}
+
+int _zbar_window_bih_init(zbar_window_t *w, zbar_image_t *img)
+{
+ window_state_t *win = w->state;
+ switch (w->format) {
+ case fourcc('J', 'P', 'E', 'G'): {
+ win->bih.biBitCount = 0;
+ win->bih.biCompression = BI_JPEG;
+ break;
+ }
+ case fourcc('B', 'G', 'R', '3'): {
+ win->bih.biBitCount = 24;
+ win->bih.biCompression = BI_RGB;
+ break;
+ }
+ case fourcc('B', 'G', 'R', '4'): {
+ win->bih.biBitCount = 32;
+ win->bih.biCompression = BI_RGB;
+ break;
+ }
+ default:
+ assert(0);
+ /* FIXME PNG? */
+ }
+ win->bih.biSizeImage = img->datalen;
+
+ zprintf(20, "biCompression=%d biBitCount=%d\n", (int)win->bih.biCompression,
+ win->bih.biBitCount);
+
+ return (0);
+}