Mercurial > vba-clojure
comparison src/win32/GBPrinterDlg.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // GBPrinter.cpp : implementation file | |
2 // | |
3 | |
4 #include "stdafx.h" | |
5 #include "resource.h" | |
6 #include "GBPrinterDlg.h" | |
7 #include "FileDlg.h" | |
8 #include "Reg.h" | |
9 #include "WinResUtil.h" | |
10 #include "VBA.h" | |
11 | |
12 //#include "../common/System.h" | |
13 #include "../NLS.h" | |
14 #include "../common/Util.h" | |
15 | |
16 extern "C" { | |
17 #include <png.h> | |
18 } | |
19 | |
20 ///////////////////////////////////////////////////////////////////////////// | |
21 // GBPrinter dialog | |
22 | |
23 GBPrinterDlg::GBPrinterDlg(CWnd*pParent /*=NULL*/) | |
24 : CDialog(GBPrinterDlg::IDD, pParent) | |
25 { | |
26 //{{AFX_DATA_INIT(GBPrinterDlg) | |
27 m_scale = -1; | |
28 //}}AFX_DATA_INIT | |
29 bitmap = (BITMAPINFO *)bitmapHeader; | |
30 | |
31 bitmap->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
32 bitmap->bmiHeader.biWidth = 160; | |
33 bitmap->bmiHeader.biHeight = -144; | |
34 bitmap->bmiHeader.biPlanes = 1; | |
35 bitmap->bmiHeader.biBitCount = 8; | |
36 bitmap->bmiHeader.biCompression = BI_RGB; | |
37 bitmap->bmiHeader.biSizeImage = 160*144; | |
38 bitmap->bmiHeader.biXPelsPerMeter = 0; | |
39 bitmap->bmiHeader.biYPelsPerMeter = 0; | |
40 bitmap->bmiHeader.biClrUsed = 4; | |
41 bitmap->bmiHeader.biClrImportant = 4; | |
42 bitmap->bmiColors[0].rgbBlue = | |
43 bitmap->bmiColors[0].rgbGreen = | |
44 bitmap->bmiColors[0].rgbRed = | |
45 255; | |
46 bitmap->bmiColors[0].rgbReserved = 0; | |
47 bitmap->bmiColors[1].rgbBlue = | |
48 bitmap->bmiColors[1].rgbGreen = | |
49 bitmap->bmiColors[1].rgbRed = | |
50 168; | |
51 bitmap->bmiColors[1].rgbReserved = 0; | |
52 bitmap->bmiColors[2].rgbBlue = | |
53 bitmap->bmiColors[2].rgbGreen = | |
54 bitmap->bmiColors[2].rgbRed = | |
55 96; | |
56 bitmap->bmiColors[2].rgbReserved = 0; | |
57 bitmap->bmiColors[3].rgbBlue = | |
58 bitmap->bmiColors[3].rgbGreen = | |
59 bitmap->bmiColors[3].rgbRed = | |
60 0; | |
61 bitmap->bmiColors[3].rgbReserved = 0; | |
62 } | |
63 | |
64 void GBPrinterDlg::DoDataExchange(CDataExchange*pDX) | |
65 { | |
66 CDialog::DoDataExchange(pDX); | |
67 //{{AFX_DATA_MAP(GBPrinterDlg) | |
68 DDX_Radio(pDX, IDC_1X, m_scale); | |
69 //}}AFX_DATA_MAP | |
70 } | |
71 | |
72 BEGIN_MESSAGE_MAP(GBPrinterDlg, CDialog) | |
73 //{{AFX_MSG_MAP(GBPrinterDlg) | |
74 ON_BN_CLICKED(ID_SAVE, OnSave) | |
75 ON_BN_CLICKED(ID_PRINT, OnPrint) | |
76 ON_BN_CLICKED(ID_OK, OnOk) | |
77 ON_BN_CLICKED(IDC_1X, On1x) | |
78 ON_BN_CLICKED(IDC_2X, On2x) | |
79 ON_BN_CLICKED(IDC_3X, On3x) | |
80 ON_BN_CLICKED(IDC_4X, On4x) | |
81 ON_WM_PAINT() | |
82 //}}AFX_MSG_MAP | |
83 END_MESSAGE_MAP() | |
84 | |
85 ///////////////////////////////////////////////////////////////////////////// | |
86 // GBPrinter message handlers | |
87 | |
88 void GBPrinterDlg::saveAsBMP(const char *name) | |
89 { | |
90 u8 writeBuffer[512 * 3]; | |
91 | |
92 FILE *fp = fopen(name, "wb"); | |
93 | |
94 if (!fp) | |
95 { | |
96 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name); | |
97 return; | |
98 } | |
99 | |
100 struct | |
101 { | |
102 u8 ident[2]; | |
103 u8 filesize[4]; | |
104 u8 reserved[4]; | |
105 u8 dataoffset[4]; | |
106 u8 headersize[4]; | |
107 u8 width[4]; | |
108 u8 height[4]; | |
109 u8 planes[2]; | |
110 u8 bitsperpixel[2]; | |
111 u8 compression[4]; | |
112 u8 datasize[4]; | |
113 u8 hres[4]; | |
114 u8 vres[4]; | |
115 u8 colors[4]; | |
116 u8 importantcolors[4]; | |
117 u8 pad[2]; | |
118 } bmpheader; | |
119 memset(&bmpheader, 0, sizeof(bmpheader)); | |
120 | |
121 bmpheader.ident[0] = 'B'; | |
122 bmpheader.ident[1] = 'M'; | |
123 | |
124 u32 fsz = sizeof(bmpheader) + 160*144*3; | |
125 utilPutDword(bmpheader.filesize, fsz); | |
126 utilPutDword(bmpheader.dataoffset, 0x38); | |
127 utilPutDword(bmpheader.headersize, 0x28); | |
128 utilPutDword(bmpheader.width, 160); | |
129 utilPutDword(bmpheader.height, 144); | |
130 utilPutDword(bmpheader.planes, 1); | |
131 utilPutDword(bmpheader.bitsperpixel, 24); | |
132 utilPutDword(bmpheader.datasize, 160*144); | |
133 | |
134 fwrite(&bmpheader, 1, sizeof(bmpheader), fp); | |
135 | |
136 u8 *b = writeBuffer; | |
137 u8 *data = (u8 *)bitmapData; | |
138 u8 *p = data + (160*143); | |
139 for (int y = 0; y < 144; y++) | |
140 { | |
141 for (int x = 0; x < 160; x++) | |
142 { | |
143 u8 c = *p++; | |
144 | |
145 *b++ = bitmap->bmiColors[c].rgbBlue; | |
146 *b++ = bitmap->bmiColors[c].rgbGreen; | |
147 *b++ = bitmap->bmiColors[c].rgbRed; | |
148 } | |
149 p -= 2*(160); | |
150 fwrite(writeBuffer, 1, 3*160, fp); | |
151 | |
152 b = writeBuffer; | |
153 } | |
154 | |
155 fclose(fp); | |
156 } | |
157 | |
158 void GBPrinterDlg::saveAsPNG(const char *name) | |
159 { | |
160 u8 writeBuffer[160 * 3]; | |
161 | |
162 FILE *fp = fopen(name, "wb"); | |
163 | |
164 if (!fp) | |
165 { | |
166 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", | |
167 name); | |
168 return; | |
169 } | |
170 | |
171 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, | |
172 NULL, | |
173 NULL, | |
174 NULL); | |
175 if (!png_ptr) | |
176 { | |
177 fclose(fp); | |
178 return; | |
179 } | |
180 | |
181 png_infop info_ptr = png_create_info_struct(png_ptr); | |
182 | |
183 if (!info_ptr) | |
184 { | |
185 png_destroy_write_struct(&png_ptr, NULL); | |
186 fclose(fp); | |
187 return; | |
188 } | |
189 | |
190 if (setjmp(png_ptr->jmpbuf)) | |
191 { | |
192 png_destroy_write_struct(&png_ptr, NULL); | |
193 fclose(fp); | |
194 return; | |
195 } | |
196 | |
197 png_init_io(png_ptr, fp); | |
198 | |
199 png_set_IHDR(png_ptr, | |
200 info_ptr, | |
201 160, | |
202 144, | |
203 8, | |
204 PNG_COLOR_TYPE_RGB, | |
205 PNG_INTERLACE_NONE, | |
206 PNG_COMPRESSION_TYPE_DEFAULT, | |
207 PNG_FILTER_TYPE_DEFAULT); | |
208 | |
209 png_write_info(png_ptr, info_ptr); | |
210 | |
211 u8 *b = writeBuffer; | |
212 | |
213 int sizeX = 160; | |
214 int sizeY = 144; | |
215 | |
216 u8 *pixU8 = (u8 *)bitmapData; | |
217 for (int y = 0; y < sizeY; y++) | |
218 { | |
219 for (int x = 0; x < sizeX; x++) | |
220 { | |
221 u8 c = *pixU8++; | |
222 *b++ = bitmap->bmiColors[c].rgbRed; | |
223 *b++ = bitmap->bmiColors[c].rgbGreen; | |
224 *b++ = bitmap->bmiColors[c].rgbBlue; | |
225 } | |
226 png_write_row(png_ptr, writeBuffer); | |
227 | |
228 b = writeBuffer; | |
229 } | |
230 | |
231 png_write_end(png_ptr, info_ptr); | |
232 | |
233 png_destroy_write_struct(&png_ptr, &info_ptr); | |
234 | |
235 fclose(fp); | |
236 } | |
237 | |
238 void GBPrinterDlg::OnSave() | |
239 { | |
240 CString captureBuffer; | |
241 | |
242 if (theApp.captureFormat == 0) | |
243 captureBuffer = "printer.png"; | |
244 else | |
245 captureBuffer = "printer.bmp"; | |
246 | |
247 LPCTSTR exts[] = {".png", ".bmp", NULL }; | |
248 | |
249 CString filter = winResLoadFilter(IDS_FILTER_PNG); | |
250 CString title = winResLoadString(IDS_SELECT_CAPTURE_NAME); | |
251 | |
252 FileDlg dlg(this, | |
253 captureBuffer, | |
254 filter, | |
255 theApp.captureFormat ? 2 : 1, | |
256 theApp.captureFormat ? "BMP" : "PNG", | |
257 exts, | |
258 "", | |
259 title, | |
260 true); | |
261 | |
262 if (dlg.DoModal() == IDCANCEL) | |
263 { | |
264 return; | |
265 } | |
266 | |
267 captureBuffer = dlg.GetPathName(); | |
268 | |
269 if (dlg.getFilterIndex() == 2) | |
270 saveAsBMP(captureBuffer); | |
271 else | |
272 saveAsPNG(captureBuffer); | |
273 } | |
274 | |
275 void GBPrinterDlg::OnPrint() | |
276 { | |
277 CPrintDialog dlg(FALSE); | |
278 | |
279 dlg.m_pd.nFromPage = 1; | |
280 dlg.m_pd.nToPage = 1; | |
281 dlg.m_pd.nMinPage = 1; | |
282 dlg.m_pd.nMaxPage = 1; | |
283 dlg.m_pd.nCopies = 1; | |
284 | |
285 if (dlg.DoModal() == IDOK) | |
286 { | |
287 DOCINFO di; | |
288 float fLogPelsX1 = 0; | |
289 float fLogPelsX2 = 0; | |
290 float fLogPelsY1 = 0; | |
291 float fLogPelsY2 = 0; | |
292 float fScaleX = 0, fScaleY = 0; | |
293 CDC * winDC = NULL; | |
294 memset(&di, 0, sizeof(di)); | |
295 di.cbSize = sizeof(DOCINFO); | |
296 CString docName = winResLoadString(IDS_POCKET_PRINTER); | |
297 di.lpszDocName = docName; | |
298 CDC dc; | |
299 dc.Attach(dlg.GetPrinterDC()); | |
300 int nError = dc.StartDoc(&di); | |
301 | |
302 if (nError == SP_ERROR) | |
303 { | |
304 systemMessage(IDS_ERROR_ON_STARTDOC, "Error on StartDoc"); | |
305 goto error; | |
306 } | |
307 nError = dc.StartPage(); | |
308 if (nError <= 0) | |
309 { | |
310 systemMessage(IDS_ERROR_ON_STARTPAGE, "Error on StartPage"); | |
311 goto error; | |
312 } | |
313 | |
314 winDC = GetDC(); | |
315 fLogPelsX1 = (float)winDC->GetDeviceCaps(LOGPIXELSX); | |
316 fLogPelsY1 = (float)winDC->GetDeviceCaps(LOGPIXELSY); | |
317 ReleaseDC(winDC); | |
318 | |
319 fLogPelsX2 = (float)dc.GetDeviceCaps(LOGPIXELSX); | |
320 fLogPelsY2 = (float)dc.GetDeviceCaps(LOGPIXELSY); | |
321 | |
322 if (fLogPelsX1 > fLogPelsX2) | |
323 fScaleX = fLogPelsX1 / fLogPelsX2; | |
324 else | |
325 fScaleX = fLogPelsX2 / fLogPelsX1; | |
326 | |
327 if (fLogPelsY1 > fLogPelsY2) | |
328 fScaleY = fLogPelsY1 / fLogPelsY2; | |
329 else | |
330 fScaleY = fLogPelsY2 / fLogPelsY1; | |
331 | |
332 fScaleX *= (scale+1); | |
333 fScaleY *= (scale+1); | |
334 | |
335 if (StretchDIBits(dc, | |
336 0, | |
337 0, | |
338 (int)((float)160*fScaleX), | |
339 (int)((float)144*fScaleY), | |
340 0, | |
341 0, | |
342 160, | |
343 144, | |
344 bitmapData, | |
345 bitmap, | |
346 DIB_RGB_COLORS, | |
347 SRCCOPY) == GDI_ERROR) | |
348 { | |
349 systemMessage(IDS_ERROR_PRINTING_ON_STRETCH, | |
350 "Error printing on StretchDIBits"); | |
351 } | |
352 | |
353 nError = dc.EndPage(); | |
354 | |
355 if (nError <= 0) | |
356 { | |
357 systemMessage(IDS_ERROR_ON_ENDPAGE, "Error on EndPage"); | |
358 goto error; | |
359 } | |
360 | |
361 nError = dc.EndDoc(); | |
362 | |
363 if (nError <= 0) | |
364 systemMessage(IDS_ERROR_ON_ENDDOC, "Error on EndDoc"); | |
365 error: | |
366 dc.DeleteDC(); | |
367 } | |
368 } | |
369 | |
370 void GBPrinterDlg::processData(u8 *data) | |
371 { | |
372 for (int y = 0; y < 0x12; y++) | |
373 { | |
374 for (int x = 0; x < 0x14; x++) | |
375 { | |
376 for (int k = 0; k < 8; k++) | |
377 { | |
378 int a = *data++; | |
379 int b = *data++; | |
380 for (int j = 0; j < 8; j++) | |
381 { | |
382 int mask = 1 << (7-j); | |
383 int c = 0; | |
384 if (a & mask) | |
385 c++; | |
386 if (b & mask) | |
387 c += 2; | |
388 bitmapData[x*8+j + 160*(y*8+k)] = c; | |
389 } | |
390 } | |
391 } | |
392 } | |
393 } | |
394 | |
395 BOOL GBPrinterDlg::OnInitDialog() | |
396 { | |
397 CDialog::OnInitDialog(); | |
398 | |
399 scale = regQueryDwordValue("printerScale", 0); | |
400 if (scale < 0 || scale > 3) | |
401 scale = 0; | |
402 m_scale = scale; | |
403 UpdateData(FALSE); | |
404 | |
405 CenterWindow(); | |
406 | |
407 return TRUE; // return TRUE unless you set the focus to a control | |
408 // EXCEPTION: OCX Property Pages should return FALSE | |
409 } | |
410 | |
411 void GBPrinterDlg::OnOk() | |
412 { | |
413 EndDialog(TRUE); | |
414 } | |
415 | |
416 void GBPrinterDlg::On1x() | |
417 { | |
418 regSetDwordValue("printerScale", 0); | |
419 scale = 0; | |
420 } | |
421 | |
422 void GBPrinterDlg::On2x() | |
423 { | |
424 regSetDwordValue("printerScale", 1); | |
425 scale = 1; | |
426 } | |
427 | |
428 void GBPrinterDlg::On3x() | |
429 { | |
430 regSetDwordValue("printerScale", 2); | |
431 scale = 2; | |
432 } | |
433 | |
434 void GBPrinterDlg::On4x() | |
435 { | |
436 regSetDwordValue("printerScale", 3); | |
437 scale = 3; | |
438 } | |
439 | |
440 void GBPrinterDlg::OnPaint() | |
441 { | |
442 CPaintDC dc(this); // device context for painting | |
443 | |
444 RECT rect; | |
445 CWnd *h = GetDlgItem(IDC_GB_PRINTER); | |
446 h->GetWindowRect(&rect); | |
447 POINT p; | |
448 p.x = rect.left; | |
449 p.y = rect.top; | |
450 ScreenToClient((POINT *)&p); | |
451 rect.left = p.x+1; | |
452 rect.top = p.y+1; | |
453 p.x = rect.right; | |
454 p.y = rect.bottom; | |
455 ScreenToClient((POINT *)&p); | |
456 rect.right = p.x-1; | |
457 rect.bottom = p.y-1; | |
458 | |
459 StretchDIBits(dc, | |
460 rect.left, | |
461 rect.top, | |
462 rect.right - rect.left, | |
463 rect.bottom - rect.top, | |
464 0, | |
465 0, | |
466 160, | |
467 144, | |
468 bitmapData, | |
469 bitmap, | |
470 DIB_RGB_COLORS, | |
471 SRCCOPY); | |
472 } | |
473 | |
474 void systemGbPrint(u8 *data, | |
475 int pages, | |
476 int feed, | |
477 int palette, | |
478 int contrast) | |
479 { | |
480 theApp.winCheckFullscreen(); | |
481 GBPrinterDlg printer; | |
482 printer.processData(data); | |
483 printer.DoModal(); | |
484 } | |
485 |