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