/* Drawing on the DC */ static void print_file(const char *file_name, HDC hdc, int width, int height) { #define MAX_BUF_SIZE 1024 /* An arbitrary maximum */ #define X_OFFSET 5 #define Y_OFFSET 5 FILE* fh1; size_t results; int cnt=0, y_pos = Y_OFFSET, y_cnt = 0; char buf[MAX_BUF_SIZE]; char ch; TEXTMETRIC tm; int max_chars_per_line, max_lines_per_page; SetMapMode(hdc, MM_LOMETRIC); GetTextMetrics(hdc, &tm); max_chars_per_line = MIN(width / (tm.tmMaxCharWidth + 1), MAX_BUF_SIZE); max_lines_per_page = height / (tm.tmHeight + 1); SetMapMode(hdc, MM_TEXT); GetTextMetrics(hdc, &tm); fh1 = ws_fopen(file_name, "r"); if (!fh1) { MessageBox(NULL, "Open failed on input file", "Error", MB_APPLMODAL | MB_OK); return; } while ((results = fread(&ch, 1, 1, fh1)) != 0) { /* end of page (form feed)? */ if (ch == 0x0c) { /* send buffer */ buf[cnt] = 0; TextOut(hdc, X_OFFSET,y_pos, buf, (int) strlen(buf)); y_pos += tm.tmHeight; cnt = 0; /* reset page */ EndPage(hdc); StartPage(hdc); y_pos = Y_OFFSET; y_cnt = 0; continue; } /* end of line (line feed)? */ if (ch == 0x0a) { /* send buffer */ buf[cnt] = 0; TextOut(hdc, X_OFFSET,y_pos, buf, (int) strlen(buf)); y_pos += tm.tmHeight; cnt = 0; /* last line on page? -> reset page */ if (++y_cnt == max_lines_per_page) { EndPage(hdc); StartPage(hdc); y_pos = Y_OFFSET; y_cnt = 0; } continue; } /* buffer full? */ if (cnt == (max_chars_per_line - 1)) { /* send buffer */ buf[cnt] = 0; TextOut(hdc, X_OFFSET, y_pos, buf, (int) strlen(buf)); y_pos += tm.tmHeight; cnt = 0; /* last line on page? -> reset page */ if (++y_cnt == max_lines_per_page) { EndPage(hdc); StartPage(hdc); y_pos = Y_OFFSET; y_cnt = 0; } } buf[cnt++] = ch; } /* while */ /* Print the remaining text if needed */ if (cnt > 0) { buf[cnt] = 0; TextOut(hdc, 0,y_pos, buf, (int) strlen(buf)); } fclose(fh1); }
printer newprinter(double width, double height, const char *name) { DOCINFO docinfo; printer obj; HDC hDC; double dd,AL; int ww,hh,x0,y0; if(strlen(name)) { OSVERSIONINFO verinfo; verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&verinfo); switch(verinfo.dwPlatformId) { case VER_PLATFORM_WIN32_NT: hDC = CreateDC("WINSPOOL", name, NULL, NULL); default: hDC = CreateDC(NULL, name, NULL, NULL); } } else hDC = chooseprinter(); if ( !hDC ) return NULL; obj = new_object(PrinterObject, (HANDLE) hDC, get_printer_base()); if ( !obj ) { R_ShowMessage(_("Insufficient memory for new printer")); DeleteDC(hDC); return NULL; } if ((width == 0.0) && (height == 0.0)) { ww = GetDeviceCaps(hDC, HORZRES); hh = GetDeviceCaps(hDC, VERTRES); } else { if (width < 0.1) width = 0.1; if (height < 0.1) height = 0.1; dd = GetDeviceCaps(hDC, HORZSIZE) / width; AL = (dd < 1.0) ? dd : 1.0; dd = GetDeviceCaps(hDC, VERTSIZE) / height; AL = (dd < AL) ? dd : AL; ww = (AL * width) * GetDeviceCaps(hDC, LOGPIXELSX) / 25.4; hh = (AL * height) * GetDeviceCaps(hDC, LOGPIXELSY) / 25.4; } x0 = (GetDeviceCaps(hDC, HORZRES) - ww) / 2; y0 = (GetDeviceCaps(hDC, VERTRES) - hh) / 2; obj->rect = rect(x0, y0, ww, hh); obj->depth = GetDeviceCaps(hDC, BITSPIXEL)* GetDeviceCaps(hDC, PLANES); obj->die = private_delprinter; obj->drawstate = copydrawstate(); obj->drawstate->dest = obj; docinfo.cbSize = sizeof(DOCINFO); /* set this size... */ docinfo.lpszDocName = "GraphAppPrintJob"; docinfo.lpszOutput = 0; /* no file output... */ docinfo.lpszDatatype = 0; docinfo.fwType = 0; if (StartDoc(hDC, &docinfo) <= 0) { R_ShowMessage(_("Unable to start the print job")); del(obj); return NULL; } StartPage(hDC); return obj; }
void DocReport::SetCount(int n) { page.SetCount(n); StartPage(); }
void Report::RestartPage() { page.SetCount(pagei + 1); StartPage(pagei); }
/** ** Higher-level interface: Windows print it (-m emp) **/ int to_emp(const GEN_PAR * pg, const OUT_PAR * po) { DEVMODE *dev; PRINTDLG pd; DOCINFO di = { 0 }; int xpix, ypix; //DPI int yprinter, xprinter, err; // Initialize PRINTDLG ZeroMemory(&pd, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = NULL; pd.hDevMode = NULL; // Don't forget to free or store hDevMode pd.hDevNames = NULL; // Don't forget to free or store hDevNames pd.Flags = PD_RETURNDEFAULT; // gives default printer pd.nCopies = 1; pd.nFromPage = 0xFFFF; pd.nToPage = 0xFFFF; pd.nMinPage = 1; pd.nMaxPage = 0xFFFF; PrintDlg(&pd); // first call to fill devmode struct from default printer dev = GlobalLock(pd.hDevMode); //Auto orient paper if (fabs(po->xmax - po->xmin) < fabs(po->ymax - po->ymin)) dev->dmOrientation = DMORIENT_PORTRAIT; else dev->dmOrientation = DMORIENT_LANDSCAPE; GlobalUnlock(pd.hDevMode); pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; // now check which printer he wants if (PrintDlg(&pd) != TRUE) return 0; Eprintf("\n\n- Printing it -\n"); GlobalFree(pd.hDevMode); GlobalFree(pd.hDevNames); xprinter = GetDeviceCaps(pd.hDC, HORZRES); // papper width in pixels yprinter = GetDeviceCaps(pd.hDC, VERTRES); // height in pixels xpix = GetDeviceCaps(pd.hDC, LOGPIXELSX); // DPI x to be checked ypix = GetDeviceCaps(pd.hDC, LOGPIXELSY); // DPI y // the following code is an attempt to compensate for printers with different // X and y resolution ( Not tested !!!) if (xpix < ypix) { xprinter = (int) (xprinter * ((float) xpix) / ypix); } else if (xpix > ypix) { yprinter = (int) (yprinter * ((float) ypix) / xpix); } SetScale(pd.hDC, yprinter, xprinter, po); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "HPGL File"; // Begin a print job by calling the StartDoc function. StartDoc(pd.hDC, &di); // Inform the driver that the application is about to begin // sending data. StartPage(pd.hDC); err = plotit(pd.hDC, pg, po); EndPage(pd.hDC); EndDoc(pd.hDC); DeleteDC(pd.hDC); if (!pg->quiet) { Eprintf("\nlines=%d moves=%d", lines, moves); Eprintf("\n"); } return err; }
static cairo_surface_t * _cairo_boilerplate_win32_printing_create_surface (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, void **closure) { win32_target_closure_t *ptc; cairo_surface_t *surface; DOCINFO di; if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) content = CAIRO_CONTENT_COLOR_ALPHA; *closure = ptc = xmalloc (sizeof (win32_target_closure_t)); xasprintf (&ptc->filename, "%s.out.ps", name); xunlink (ptc->filename); memset (&di, 0, sizeof (DOCINFO)); di.cbSize = sizeof (DOCINFO); di.lpszDocName = ptc->filename; di.lpszOutput = ptc->filename; ptc->width = width; ptc->height = height; create_printer_dc (ptc); if (ptc->dc == NULL) { printf("\nFailed to create printer\n"); free (ptc->filename); free (ptc); return NULL; } StartDoc (ptc->dc, &di); StartPage (ptc->dc); surface = cairo_win32_printing_surface_create (ptc->dc); if (cairo_surface_status (surface)) { free (ptc->filename); free (ptc); return NULL; } cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); } else { ptc->target = NULL; } if (cairo_surface_set_user_data (surface, &win32_closure_key, ptc, NULL) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); if (ptc->target != NULL) cairo_surface_destroy (ptc->target); free (ptc->filename); free (ptc); return NULL; } return surface; }
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static DOCINFO di = { sizeof (DOCINFO), TEXT ("Font Demo: Printing") } ; static int cxClient, cyClient ; static PRINTDLG pd = { sizeof (PRINTDLG) } ; BOOL fSuccess ; HDC hdc, hdcPrn ; int cxPage, cyPage ; PAINTSTRUCT ps ; switch (message) { case WM_COMMAND: switch (wParam) { case IDM_PRINT: // Get printer DC pd.hwndOwner = hwnd ; pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION ; if (!PrintDlg (&pd)) return 0 ; if (NULL == (hdcPrn = pd.hDC)) { MessageBox (hwnd, TEXT ("Cannot obtain Printer DC"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; } // Get size of printable area of page cxPage = GetDeviceCaps (hdcPrn, HORZRES) ; cyPage = GetDeviceCaps (hdcPrn, VERTRES) ; fSuccess = FALSE ; // Do the printer page SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; if ((StartDoc (hdcPrn, &di) > 0) && (StartPage (hdcPrn) > 0)) { PaintRoutine (hwnd, hdcPrn, cxPage, cyPage) ; if (EndPage (hdcPrn) > 0) { fSuccess = TRUE ; EndDoc (hdcPrn) ; } } DeleteDC (hdcPrn) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (!fSuccess) MessageBox (hwnd, TEXT ("Error encountered during printing"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; case IDM_ABOUT: MessageBox (hwnd, TEXT ("Font Demonstration Program\n") TEXT ("(c) Charles Petzold, 1998"), szAppName, MB_ICONINFORMATION | MB_OK); return 0 ; } break ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; PaintRoutine (hwnd, hdc, cxClient, cyClient) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
const char *SurfacePrint(SDL_Surface * surf, const char *printcfg, int showdialog) { const char *res = NULL; HWND hWnd; DOCINFO di; int nError; SDL_SysWMinfo wminfo; BITMAPINFOHEADER bmih; SDL_Surface *surf24 = NULL; RECT rcDst; float sX, sY; int pageWidth, pageHeight; int hDCCaps; HBITMAP hbm = NULL; HDC hdcMem = NULL; int scaling = SCALE_TO_FIT; SDL_VERSION(&wminfo.version); if (!SDL_GetWMInfo(&wminfo)) return "win32_print: SDL_GetWMInfo() failed."; hWnd = wminfo.window; if (!GetPrinterDC(hWnd, printcfg, showdialog)) { ShowWindow(hWnd, SW_SHOWNORMAL); return NULL; } if (!hDCprinter) return "win32_print: GetPrinterDC() failed."; EnableWindow(hWnd, FALSE); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "Tux Paint"; di.lpszOutput = (LPTSTR) NULL; di.lpszDatatype = (LPTSTR) NULL; di.fwType = 0; nError = StartDoc(hDCprinter, &di); if (nError == SP_ERROR) { res = "win32_print: StartDoc() failed."; goto error; } nError = StartPage(hDCprinter); if (nError <= 0) { res = "win32_print: StartPage() failed."; goto error; } ////////////////////////////////////////////////////////////////////////////////////// surf24 = make24bitDIB(surf); if (!surf24) { res = "win32_print: make24bitDIB() failed."; goto error; } memset(&bmih, 0, sizeof(bmih)); bmih.biSize = sizeof(bmih); bmih.biPlanes = 1; bmih.biCompression = BI_RGB; bmih.biBitCount = 24; bmih.biWidth = surf24->w; bmih.biHeight = surf24->h; pageWidth = GetDeviceCaps(hDCprinter, HORZRES); pageHeight = GetDeviceCaps(hDCprinter, VERTRES); sX = GetDeviceCaps(hDCprinter, LOGPIXELSX); sY = GetDeviceCaps(hDCprinter, LOGPIXELSY); switch (scaling) { case STRETCH_TO_FIT: { /* stretches x and y dimensions independently to fit the page */ /* doesn't preserve image aspect-ratio */ rcDst.top = 0; rcDst.left = 0; rcDst.bottom = pageHeight; rcDst.right = pageWidth; break; } case SCALE_TO_FIT: { /* maximises image size on the page */ /* preserves aspect-ratio, alignment is top and center */ int width = bmih.biWidth; int height = bmih.biHeight; if (width < pageWidth && height < pageHeight) { float dW = (float)pageWidth / width; float dH = (float)pageHeight / height; if (dW < dH) { width = pageWidth; height = (int)((height * dW * (sY/sX)) + 0.5f); } else { width = (int)((width * dH * (sX/sY)) + 0.5f); height = pageHeight; } } if (width > pageWidth) { height= height*width/pageWidth; width = pageWidth; } if (height > pageHeight) { width= width*height/pageHeight; height = pageHeight; } rcDst.top = 0; rcDst.left = (pageWidth-width)/2; rcDst.bottom = rcDst.top+height; rcDst.right = rcDst.left+width; break; } default: res = "win32_print: invalid scaling option."; goto error; } hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS); if (hDCCaps & RC_PALETTE) { res = "win32_print: printer context requires palette."; goto error; } if (hDCCaps & RC_STRETCHDIB) { SetStretchBltMode(hDCprinter, COLORONCOLOR); nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top, rcDst.right - rcDst.left, rcDst.bottom - rcDst.top, 0, 0, bmih.biWidth, bmih.biHeight, surf24->pixels, (BITMAPINFO *) & bmih, DIB_RGB_COLORS, SRCCOPY); if (nError == GDI_ERROR) { res = "win32_print: StretchDIBits() failed."; goto error; } } else { res = "win32_print: StretchDIBits() not available."; goto error; } ////////////////////////////////////////////////////////////////////////////////////// nError = EndPage(hDCprinter); if (nError <= 0) { res = "win32_print: EndPage() failed."; goto error; } EndDoc(hDCprinter); error: if (hdcMem) DeleteDC(hdcMem); if (hbm) DeleteObject(hbm); if (surf24) SDL_FreeSurface(surf24); EnableWindow(hWnd, TRUE); ShowWindow(hWnd, SW_SHOWNORMAL); DeleteDC(hDCprinter); return res; }
int Print(HWND win) { BOOL rv = TRUE; int start, end; PRINTDLG pd; HWND hDlgCancel = 0; memset(&pd, 0, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.hwndOwner = hwndFrame; pd.Flags = PD_NOPAGENUMS | PD_RETURNDC | PD_COLLATE ; pd.hInstance = hInstance; SendDlgItemMessage(win, ID_EDITCHILD, EM_GETSEL, (WPARAM) &start, (LPARAM) &end); tabSetting = PropGetInt(NULL, "TAB_INDENT"); leftmargin = PropGetInt(NULL, "PRINTER_LEFT"); rightmargin = PropGetInt(NULL, "PRINTER_RIGHT"); topmargin = PropGetInt(NULL, "PRINTER_TOP"); bottommargin = PropGetInt(NULL, "PRINTER_BOTTOM"); PropGetString(NULL, "PRINTER_HEADER", printHeader, sizeof(printHeader)); PropGetString(NULL, "PRINTER_FOOTER", printFooter, sizeof(printFooter)); if (tabSetting <= 0) tabSetting = 4; if (end != start) pd.Flags |= PD_SELECTION; if (PrintDlg(&pd)) { DOCINFO di; HWND child; char *buf, *pos, *savepos1; if (pd.Flags &PD_SELECTION) { if (end <= start) return TRUE ; } child = GetDlgItem(win, ID_EDITCHILD); buf = GetEditData(child); if (!buf) return TRUE ; if (pd.Flags &PD_SELECTION) { savepos1 = pos = buf + start; buf[end] = 0; } else savepos1 = pos = buf; printing = TRUE; memset(&di, 0, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = (char*)SendMessage(win, WM_FILETITLE, 0, 0); if (pd.Flags &PD_PRINTTOFILE) di.lpszOutput = "FILE:"; SetAbortProc(pd.hDC, &AbortProc); if (StartDoc(pd.hDC, &di) > 0) { int pelsx, pelsy; int width, height, rows, cols; int done = FALSE; char headerLeft[256],headerRight[256],headerCenter[256]; char FooterLeft[256],FooterRight[256],FooterCenter[256]; SIZE strsize ; HFONT hFont, oldhFont; pelsx = GetDeviceCaps(pd.hDC, LOGPIXELSX); pelsy = GetDeviceCaps(pd.hDC, LOGPIXELSY); fontdata.lfHeight = - MulDiv(11, pelsx, 72); hFont = CreateFontIndirect(&fontdata); oldhFont = SelectObject(pd.hDC, hFont); GetTextExtentPoint32(pd.hDC, "A", 1, &strsize); width = GetDeviceCaps(pd.hDC, HORZRES); height = GetDeviceCaps(pd.hDC, VERTRES); // buf = GetEditData(win); rows = (height - (topmargin + bottommargin) *pelsy * 10 / 254) / strsize.cy ; cols = (width - (leftmargin + rightmargin) *pelsx * 10 / 254) / strsize.cx; if (rows <= 0 || cols <= 0) { AbortDoc(pd.hDC); free(buf); DeleteObject(hFont); if (pd.hDC != NULL) DeleteDC(pd.hDC); if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); return FALSE; } SelectObject(pd.hDC, oldhFont); if (printHeader[0]) rows -= 2; if (printFooter[0]) rows -= 2; total_pages = countPages(savepos1, rows, cols); setTimeFormats(); split(printHeader, headerLeft, headerRight, headerCenter); split(printFooter, FooterLeft, FooterRight, FooterCenter); hDlgCancel = CreateDialog(hInstance, "PRINTABORTDLG", 0, (DLGPROC) CancelProc); EnableWindow(hwndFrame, FALSE); do { int colcount = pd.nCopies; int pagenum = 1; pos = savepos1; while (printing && *pos && StartPage(pd.hDC) > 0) { int i, j, k; int hdrlines = 0; char line[512]; char *savepos2 = pos; oldhFont = SelectObject(pd.hDC, hFont); if (printHeader[0]) { char buf[256]; int cx ; int cy = topmargin * pelsy * 10/ 254; cx = subs(pd.hDC, buf, headerLeft, di.lpszDocName, pagenum); cx = leftmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, headerCenter, di.lpszDocName, pagenum); cx = (width - cx)/2 ; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, headerRight, di.lpszDocName, pagenum); cx = width - cx - rightmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); hdrlines = 2; } for (i = 0; i < rows; i++) { int count = 0; if (*pos == '\n') { pos++; } else if (*pos == '\f') { pos += 2; break; } else { for (j = 0; j < cols; j++) { if (*pos == '\t') { int n = tabSetting - j % tabSetting; pos++; for (k = 0; k < n; k++) line[count++] = ' '; j += n - 1; } else { if (*pos < 32 || *pos > 126) { if (*pos == '\n') pos++; break; } line[count++] = *pos++; } } TextOut(pd.hDC, leftmargin *pelsx * 10 / 254, (i + hdrlines) *strsize.cy + topmargin * pelsy * 10 / 254, line, count); } if (! *pos) break; } if (printFooter[0]) { char buf[256]; int cx ; int cy = height - strsize.cy - bottommargin * pelsy * 10 / 254; cx = subs(pd.hDC, buf, FooterLeft, di.lpszDocName, pagenum); cx = leftmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, FooterCenter, di.lpszDocName, pagenum); cx = (width - cx) / 2; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, FooterRight, di.lpszDocName, pagenum); cx = width - cx - rightmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); } SelectObject(pd.hDC, oldhFont); if (printing) if (EndPage(pd.hDC) <= 0) goto doneprinting; if (!(pd.Flags &PD_COLLATE)) { if (--colcount) { pos = savepos2; } else { colcount = pd.nCopies; pagenum++; } } else { pagenum++; } } } while (printing && (pd.Flags &PD_COLLATE) && --pd.nCopies) ; if (!printing) AbortDoc(pd.hDC); doneprinting: if (printing) EndDoc(pd.hDC); EnableWindow(hwndFrame, TRUE); if (hDlgCancel) DestroyWindow(hDlgCancel); DeleteObject(hFont); } FreeEditData(buf); } if (pd.hDC != NULL) DeleteDC(pd.hDC); if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); return rv; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int fd; /* File descriptor */ cups_raster_t *ras; /* Raster stream for printing */ cups_page_header2_t header; /* Page header from file */ unsigned y; /* Current line */ ppd_file_t *ppd; /* PPD file */ int num_options; /* Number of options */ cups_option_t *options; /* Options */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Make sure status messages are not buffered... */ setbuf(stderr, NULL); /* * Check command-line... */ if (argc < 6 || argc > 7) { /* * We don't have the correct number of arguments; write an error message * and return. */ _cupsLangPrintFilter(stderr, "ERROR", _("%s job-id user title copies options [file]"), "rastertolabel"); return (1); } /* * Open the page stream... */ if (argc == 7) { if ((fd = open(argv[6], O_RDONLY)) == -1) { _cupsLangPrintError("ERROR", _("Unable to open raster file")); sleep(1); return (1); } } else fd = 0; ras = cupsRasterOpen(fd, CUPS_RASTER_READ); /* * Register a signal handler to eject the current page if the * job is cancelled. */ Canceled = 0; #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGTERM, CancelJob); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_handler = CancelJob; sigaction(SIGTERM, &action, NULL); #else signal(SIGTERM, CancelJob); #endif /* HAVE_SIGSET */ /* * Open the PPD file and apply options... */ num_options = cupsParseOptions(argv[5], 0, &options); ppd = ppdOpenFile(getenv("PPD")); if (!ppd) { ppd_status_t status; /* PPD error */ int linenum; /* Line number */ _cupsLangPrintFilter(stderr, "ERROR", _("The PPD file could not be opened.")); status = ppdLastError(&linenum); fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum); return (1); } ppdMarkDefaults(ppd); cupsMarkOptions(ppd, num_options, options); /* * Initialize the print device... */ Setup(ppd); /* * Process pages as needed... */ Page = 0; while (cupsRasterReadHeader2(ras, &header)) { /* * Write a status message with the page number and number of copies. */ if (Canceled) break; Page ++; fprintf(stderr, "PAGE: %d 1\n", Page); _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), Page); /* * Start the page... */ StartPage(ppd, &header); /* * Loop for each line on the page... */ for (y = 0; y < header.cupsHeight && !Canceled; y ++) { /* * Let the user know how far we have progressed... */ if (Canceled) break; if ((y & 15) == 0) { _cupsLangPrintFilter(stderr, "INFO", _("Printing page %d, %u%% complete."), Page, 100 * y / header.cupsHeight); fprintf(stderr, "ATTR: job-media-progress=%u\n", 100 * y / header.cupsHeight); } /* * Read a line of graphics... */ if (cupsRasterReadPixels(ras, Buffer, header.cupsBytesPerLine) < 1) break; /* * Write it to the printer... */ OutputLine(ppd, &header, y); } /* * Eject the page... */ _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), Page); EndPage(ppd, &header); if (Canceled) break; } /* * Close the raster stream... */ cupsRasterClose(ras); if (fd != 0) close(fd); /* * Close the PPD file and free the options... */ ppdClose(ppd); cupsFreeOptions(num_options, options); /* * If no pages were printed, send an error message... */ if (Page == 0) { _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found.")); return (1); } else return (0); }
static BOOL PrintIt( int iTotalPages, int iLinesPerPage, int iTotalLines, int iCharsPerLine, int yChar, LPCTSTR pstrBuffer, HWND hwnd) { WORD iColCopy, iNoiColCopy; int iPage, iLine, iLineNum; HWND hwndEdit; struct statusWindowData *theStatusData; struct displayWindowData *theDisplayData; ATOM theAtom = (unsigned short) GetClassLongPtr(hwnd,GCW_ATOM); void *valuePtr; int count; int dummy, displayStart; if (theAtom == EditAtomClass) { hwndEdit = GetDlgItem(hwnd,ID_EDIT_CONTROL); } else if (theAtom == StatusAtomClass) { theStatusData = (struct statusWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theStatusData == NULL) { return TRUE; } } else if (theAtom == DisplayAtomClass) { theDisplayData = (struct displayWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theDisplayData == NULL) { return TRUE; } DisplayLineCountAndStart(hwnd,&dummy,&displayStart); } else { return TRUE; } /*========================================================*/ /* If we're collating and there are multiple copies, then */ /* print in the order (1,2,3,1,2,3...), otherwise print */ /* in the order (1,1,...2,2,...,3,3,...). */ /*========================================================*/ for (iColCopy = 0; iColCopy < ((WORD) PrintDialog.Flags & PD_COLLATE ? PrintDialog.nCopies : 1); iColCopy++) { for (iPage = 0 ; iPage < iTotalPages ; iPage++) { if (PrintDialog.Flags & PD_PAGENUMS) { if (((iPage + 1) < PrintDialog.nFromPage) || ((iPage + 1) > PrintDialog.nToPage)) { continue; } } for (iNoiColCopy = 0; iNoiColCopy < (PrintDialog.Flags & PD_COLLATE ? 1 : PrintDialog.nCopies); iNoiColCopy++) { if (StartPage(PrintDialog.hDC) < 0) { return(FALSE); } if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == EditAtomClass) { for (iLine = 0 ; iLine < iLinesPerPage ; iLine++) { iLineNum = iLinesPerPage * iPage + iLine ; if (iLineNum > iTotalLines) { break; } *(int *) pstrBuffer = iCharsPerLine; TextOut(PrintDialog.hDC,0,yChar * iLine,pstrBuffer, (int) SendMessage(hwndEdit,EM_GETLINE,(WPARAM) iLineNum, (LPARAM) pstrBuffer)) ; } } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == StatusAtomClass) { iLineNum = iLinesPerPage * iPage; iLine = 0; for (valuePtr = (*theStatusData->getNextValue)(GetCurrentEnvironment(),NULL), count = 0; valuePtr != NULL; valuePtr = (*theStatusData->getNextValue)(GetCurrentEnvironment(),valuePtr), count++) { if (count < iLineNum) continue; if (count > (iLineNum + iLinesPerPage)) break; if (count > iTotalLines) break; (*theStatusData->getPPForm)(GetCurrentEnvironment(),(char *) pstrBuffer,(unsigned) iCharsPerLine,valuePtr); TextOut(PrintDialog.hDC,0,yChar * iLine,pstrBuffer,(int) strlen(pstrBuffer)); iLine++; } } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == DisplayAtomClass) { iLineNum = (iLinesPerPage * iPage) + displayStart; if (iLineNum > DIALOG_SIZE) { iLineNum -= DIALOG_SIZE; } for (iLine = 0 ; iLine < iLinesPerPage ; iLine++) { if (theDisplayData->terminal[iLineNum] == NULL) { break; } TextOut(PrintDialog.hDC,0,yChar * iLine, theDisplayData->terminal[iLineNum], (int) strlen(theDisplayData->terminal[iLineNum])); iLineNum++; if (iLineNum > DIALOG_SIZE) { iLineNum = 0; } if (iLineNum == displayStart) { break; } } } if (EndPage(PrintDialog.hDC) < 0) { return(FALSE); } if (bUserAbort) { return(TRUE); } } if (bUserAbort) { return(TRUE); } } if (bUserAbort) { return(TRUE); } } return(TRUE); }
LRESULT CALLBACK MyPrintProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch(message){ case WM_INITDIALOG: { hDialog = hDlg; SetDlgItemText(hDlg,IDC_PM_LEFT,"15"); SetDlgItemText(hDlg,IDC_PM_RIGHT,"15"); SetDlgItemText(hDlg,IDC_PM_TOP,"21"); SetDlgItemText(hDlg,IDC_PM_BOTTOM,"21"); SetDlgItemText(hDlg,IDC_BAIRITU,"100"); HWND hOk = GetDlgItem(hDlg,IDOK); if(hPrintDC == NULL){ EnableWindow(hOk,FALSE); } SendDlgItemMessage(hDlg,IDOK,WM_COMMAND,(WPARAM)(BN_DISABLE),(LPARAM)0); HWND hPreview = GetDlgItem(hDlg,IDC_PREVIEW); oldMyPrintPreviewProc = (WNDPROC)SetWindowLongPtr(hPreview,GWL_WNDPROC,(LONG)MyPrintPreviewProc); char printername[256]; GetCurrentPrinterName(printername); SetDlgItemText(hDlg,IDC_SELECTEDPRINTER,printername); } break; case WM_VSCROLL: { int iId = LOWORD(wParam); int id = GetDlgCtrlID((HWND)lParam); HWND hChange = NULL; int maximum = -1; int minimum = -1; if(id == IDC_SCR_BAIRITU){ hChange = GetDlgItem(hDlg,IDC_BAIRITU); minimum = 1; }else if(id == IDC_PM_SCR_LEFT){ hChange = GetDlgItem(hDlg,IDC_PM_LEFT); minimum = 0; }else if(id == IDC_PM_SCR_RIGHT){ hChange = GetDlgItem(hDlg,IDC_PM_RIGHT); minimum = 0; }else if(id == IDC_PM_SCR_TOP){ hChange = GetDlgItem(hDlg,IDC_PM_TOP); minimum = 0; }else if(id == IDC_PM_SCR_BOTTOM){ hChange = GetDlgItem(hDlg,IDC_PM_BOTTOM); minimum = 0; } if(hChange != NULL){ DoWhenVscroll(hChange,iId,minimum,maximum); } } break; case WM_COMMAND: { int iEvent = HIWORD(wParam); int iId = LOWORD(wParam); switch(iId){ case IDC_SETTOKYOUGI: { char buf[32]; double bai = 74.0 / (double)currentdesign.height * 600.0; sprintf(buf,"%.4f",bai); SetDlgItemText(hDlg,IDC_BAIRITU,buf); } break; case IDC_PM_LEFT: case IDC_PM_RIGHT: case IDC_PM_TOP: case IDC_PM_BOTTOM: case IDC_BAIRITU: { if(iEvent == EN_CHANGE && hPrintDC != NULL){ HWND h = GetDlgItem(hDlg,IDC_PREVIEW); InvalidateRect(h,NULL,FALSE); UpdateWindow(h); int pages = CountPages(hDlg,hPrintDC); char buf[16]; wsprintf(buf,"%d",pages); SetDlgItemText(hDlg,IDC_PAGENUM,buf); } } break; case IDC_SELPRINTER: { SelPrinter(hDlg); HWND hPreview = GetDlgItem(hDlg,IDC_PREVIEW); InvalidateRect(hPreview,NULL,TRUE); UpdateWindow(hPreview); HWND hOk = GetDlgItem(hDlg,IDOK); if(hPrintDC != NULL){ EnableWindow(hOk,TRUE); int pages = CountPages(hDlg,hPrintDC); char buf[16]; wsprintf(buf,"%d",pages); SetDlgItemText(hDlg,IDC_PAGENUM,buf); }else{ EnableWindow(hOk,FALSE); } char printername[256]; GetCurrentPrinterName(printername); SetDlgItemText(hDlg,IDC_SELECTEDPRINTER,printername); } break; case IDOK: { if(hPrintDC == NULL){ break; } char buf[512]; char printername[256]; GetCurrentPrinterName(printername); int pages = CountPages(hDlg,hPrintDC); int nCopies = GetCurrentPrinterCopies(); wsprintf(buf,"プリンタ名: [ %s ]\r\n一部当たり [ %d ページ ] で\r\n全部で [ %d 部 ] 印刷します\r\nよろしいですか?",printername,pages,nCopies); if(MessageBox(hDlg,buf,"確認",MB_YESNO)==IDYES){ ChangeDisplayColorToMax(); DOCINFO di; ZeroMemory(&di,sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "KAZESOMISO"; double dotpermm_x = GetDeviceCaps(hPrintDC,LOGPIXELSX) / 25.4; double dotpermm_y = GetDeviceCaps(hPrintDC,LOGPIXELSY) / 25.4; double bairitu = GetFudaBairitu(hDlg); fudascale_x = bairitu * dotpermm_x; fudascale_y = bairitu * dotpermm_y; if(!gdiplus_useable){ fudascale = fudascale_y; }else{ fudascale = bairitu; } LoadImageToDC(hPrintDC,currentdesign); fudaunit = Gdiplus::UnitMillimeter; StartDoc(hPrintDC,&di); int rows,cols,sukima_x,sukima_y; CountOnePageFudaNum(hDlg,hPrintDC,&cols,&rows); GetFudaSukima(hDlg,hPrintDC,&sukima_x,&sukima_y); int left,right,top,bottom; GetPrintMargin(hDlg,&left,&top,&right,&bottom); int maxfudanum = 0; if(tori_or_yomi == TORI){ maxfudanum = torifuda.size(); }else{ maxfudanum = yomifuda.size(); } int fudanum = 0; for(int p = 0; p < pages; p++){ StartPage(hPrintDC); for(int i = cols -1 ; i >= 0; i --){ for(int j = 0; j < rows; j ++){ for(; fudanum < maxfudanum; fudanum++){ if(tori_or_yomi == TORI && torifuda[fudanum].saveasimage || tori_or_yomi == YOMI && yomifuda[fudanum].saveasimage ){ break; } } if(fudanum >= maxfudanum){ break; } class ToriYomiDesign design; if(tori_or_yomi == TORI){ design.simonoku = torifuda[fudanum].simonoku; design.kimariji = torifuda[fudanum].kimariji; design.tori = currentdesign.tori; }else{ design.waka = yomifuda[fudanum].waka; design.yomi = currentdesign.yomi; } design.UpdateSize(); double x,y; if(!gdiplus_useable){ x = left / bairitu + i * ( design.width + sukima_x / (bairitu * dotpermm_x) ); y = top / bairitu + j * ( design.height + sukima_y / (bairitu * dotpermm_y)); }else{ x = left / fudascale+ i * ( design.width + sukima_x / (dotpermm_x*fudascale) ); y = top / fudascale + j * ( design.height + sukima_y / (dotpermm_y*fudascale)); } MYRECT rect; rect.left = x; rect.top = y; rect.right = -1; rect.bottom = -1; DrawFuda(design,hPrintDC,&rect); fudanum++; } } EndPage(hPrintDC); } EndDoc(hPrintDC); fudaunit = Gdiplus::UnitDisplay; fudascale = -1.0; HDC hdc = GetDC(hWndMain); LoadImageToDC(hdc,currentdesign); ReleaseDC(hWndMain,hdc); MessageBox(hDlg,"プリンタに出力しました。","完了",MB_OK); } } break; case IDCANCEL: { EndDialog(hDlg,0); } break; } } break; } return FALSE; }
VOID DIALOG_FilePrint(VOID) { DOCINFO di; TEXTMETRIC tm; PRINTDLG printer; SIZE szMetric; int border; int xLeft, yTop, pagecount, dopage, copycount; unsigned int i; LOGFONT hdrFont; HFONT font, old_font=0; DWORD size; LPTSTR pTemp; static const TCHAR times_new_roman[] = _T("Times New Roman"); RECT rcPrintRect; /* Get a small font and print some header info on each page */ ZeroMemory(&hdrFont, sizeof(hdrFont)); hdrFont.lfHeight = 100; hdrFont.lfWeight = FW_BOLD; hdrFont.lfCharSet = ANSI_CHARSET; hdrFont.lfOutPrecision = OUT_DEFAULT_PRECIS; hdrFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; hdrFont.lfQuality = PROOF_QUALITY; hdrFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN; _tcscpy(hdrFont.lfFaceName, times_new_roman); font = CreateFontIndirect(&hdrFont); /* Get Current Settings */ ZeroMemory(&printer, sizeof(printer)); printer.lStructSize = sizeof(printer); printer.hwndOwner = Globals.hMainWnd; printer.hInstance = Globals.hInstance; /* Set some default flags */ printer.Flags = PD_RETURNDC | PD_SELECTION; /* Disable the selection radio button if there is no text selected */ if (!GetSelectionTextLength(Globals.hEdit)) { printer.Flags = printer.Flags | PD_NOSELECTION; } printer.nFromPage = 0; printer.nMinPage = 1; /* we really need to calculate number of pages to set nMaxPage and nToPage */ printer.nToPage = (WORD)-1; printer.nMaxPage = (WORD)-1; /* Let commdlg manage copy settings */ printer.nCopies = (WORD)PD_USEDEVMODECOPIES; printer.hDevMode = Globals.hDevMode; printer.hDevNames = Globals.hDevNames; if (!PrintDlg(&printer)) { DeleteObject(font); return; } Globals.hDevMode = printer.hDevMode; Globals.hDevNames = printer.hDevNames; assert(printer.hDC != 0); /* initialize DOCINFO */ di.cbSize = sizeof(DOCINFO); di.lpszDocName = Globals.szFileTitle; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; if (StartDoc(printer.hDC, &di) <= 0) { DeleteObject(font); return; } /* Get the file text */ if (printer.Flags & PD_SELECTION) { size = GetSelectionTextLength(Globals.hEdit) + 1; } else { size = GetWindowTextLength(Globals.hEdit) + 1; } pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(TCHAR)); if (!pTemp) { EndDoc(printer.hDC); DeleteObject(font); ShowLastError(); return; } if (printer.Flags & PD_SELECTION) { size = GetSelectionText(Globals.hEdit, pTemp, size); } else { size = GetWindowText(Globals.hEdit, pTemp, size); } /* Get the current printing area */ rcPrintRect = GetPrintingRect(printer.hDC, Globals.lMargins); /* Ensure that each logical unit maps to one pixel */ SetMapMode(printer.hDC, MM_TEXT); /* Needed to get the correct height of a text line */ GetTextMetrics(printer.hDC, &tm); border = 15; for (copycount=1; copycount <= printer.nCopies; copycount++) { i = 0; pagecount = 1; do { /* Don't start a page if none of the conditions below are true */ dopage = 0; /* The user wants to print the current selection */ if (printer.Flags & PD_SELECTION) { dopage = 1; } /* The user wants to print the entire document */ if (!(printer.Flags & PD_PAGENUMS) && !(printer.Flags & PD_SELECTION)) { dopage = 1; } /* The user wants to print a specified range of pages */ if ((pagecount >= printer.nFromPage && pagecount <= printer.nToPage)) { dopage = 1; } old_font = SelectObject(printer.hDC, font); if (dopage) { if (StartPage(printer.hDC) <= 0) { SelectObject(printer.hDC, old_font); EndDoc(printer.hDC); DeleteDC(printer.hDC); HeapFree(GetProcessHeap(), 0, pTemp); DeleteObject(font); AlertPrintError(); return; } SetViewportOrgEx(printer.hDC, rcPrintRect.left, rcPrintRect.top, NULL); /* Write a rectangle and header at the top of each page */ Rectangle(printer.hDC, border, border, rcPrintRect.right - border, border + tm.tmHeight * 2); /* I don't know what's up with this TextOut command. This comes out kind of mangled. */ TextOut(printer.hDC, border * 2, border + tm.tmHeight / 2, Globals.szFileTitle, lstrlen(Globals.szFileTitle)); } /* The starting point for the main text */ xLeft = 0; yTop = border + tm.tmHeight * 4; SelectObject(printer.hDC, old_font); /* Since outputting strings is giving me problems, output the main * text one character at a time. */ do { if (pTemp[i] == '\n') { xLeft = 0; yTop += tm.tmHeight; } else if (pTemp[i] != '\r') { if (dopage) TextOut(printer.hDC, xLeft, yTop, &pTemp[i], 1); /* We need to get the width for each individual char, since a proportional font may be used */ GetTextExtentPoint32(printer.hDC, &pTemp[i], 1, &szMetric); xLeft += szMetric.cx; /* Insert a line break if the current line does not fit into the printing area */ if (xLeft > rcPrintRect.right) { xLeft = 0; yTop = yTop + tm.tmHeight; } } } while (i++ < size && yTop < rcPrintRect.bottom); if (dopage) EndPage(printer.hDC); pagecount++; } while (i < size); } if (old_font != 0) SelectObject(printer.hDC, old_font); EndDoc(printer.hDC); DeleteDC(printer.hDC); HeapFree(GetProcessHeap(), 0, pTemp); DeleteObject(font); }
static void test_abort_proc(void) { HDC print_dc; RECT rect = {0, 0, 100, 100}; DOCINFOA doc_info = {0}; PRINTDLGA pd = {0}; char filename[MAX_PATH]; if (!GetTempFileNameA(".", "prn", 0, filename)) { skip("Failed to create a temporary file name\n"); return; } pd.lStructSize = sizeof(pd); pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE; pd.nFromPage = 1; pd.nToPage = 1; pd.nCopies = 1; if (!PrintDlgA(&pd)) { skip("No default printer available.\n"); ok(DeleteFileA(filename), "Failed to delete temporary file\n"); return; } ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n"); if (!(print_dc = pd.hDC)) { ok(DeleteFileA(filename), "Failed to delete temporary file\n"); return; } ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n"); abort_proc_called = FALSE; doc_info.cbSize = sizeof(doc_info); doc_info.lpszDocName = "Some document"; doc_info.lpszOutput = filename; ok(StartDocA(print_dc, &doc_info) > 0, "StartDocA failed\n"); ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n"); abort_proc_called = FALSE; ok(StartPage(print_dc) > 0, "StartPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n"); abort_proc_called = FALSE; ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n"); abort_proc_called = FALSE; ok(EndPage(print_dc) > 0, "EndPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n"); abort_proc_called = FALSE; ok(EndDoc(print_dc) > 0, "EndDoc failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n"); abort_proc_called = FALSE; ok(DeleteDC(print_dc), "DeleteDC failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n"); abort_proc_called = FALSE; ok(DeleteFileA(filename), "Failed to delete temporary file\n"); }
static BOOL notepad_print_page(HDC hdc, RECT *rc, BOOL dopage, int page, LPTEXTINFO tInfo) { int b, y; TEXTMETRICW tm; SIZE szMetrics; WCHAR *footer_text = NULL; footer_text = expand_header_vars(Globals.szFooter, page); if (footer_text == NULL) return FALSE; if (dopage) { if (StartPage(hdc) <= 0) { static const WCHAR failedW[] = { 'S','t','a','r','t','P','a','g','e',' ','f','a','i','l','e','d',0 }; static const WCHAR errorW[] = { 'P','r','i','n','t',' ','E','r','r','o','r',0 }; MessageBoxW(Globals.hMainWnd, failedW, errorW, MB_ICONEXCLAMATION); HeapFree(GetProcessHeap(), 0, footer_text); return FALSE; } } GetTextMetricsW(hdc, &tm); y = rc->top + notepad_print_header(hdc, rc, dopage, TRUE, page, Globals.szFileName) * tm.tmHeight; b = rc->bottom - 2 * notepad_print_header(hdc, rc, FALSE, FALSE, page, footer_text) * tm.tmHeight; do { INT m, n; if (!tInfo->len) { /* find the end of the line */ while (tInfo->mptr < tInfo->mend && *tInfo->mptr != '\n' && *tInfo->mptr != '\r') { if (*tInfo->mptr == '\t') { /* replace tabs with spaces */ for (m = 0; m < SPACES_IN_TAB; m++) { if (tInfo->len < PRINT_LEN_MAX) tInfo->lptr[tInfo->len++] = ' '; else if (Globals.bWrapLongLines) break; } } else if (tInfo->len < PRINT_LEN_MAX) tInfo->lptr[tInfo->len++] = *tInfo->mptr; if (tInfo->len >= PRINT_LEN_MAX && Globals.bWrapLongLines) break; tInfo->mptr++; } } /* Find out how much we should print if line wrapping is enabled */ if (Globals.bWrapLongLines) { GetTextExtentExPointW(hdc, tInfo->lptr, tInfo->len, rc->right - rc->left, &n, NULL, &szMetrics); if (n < tInfo->len && tInfo->lptr[n] != ' ') { m = n; /* Don't wrap words unless it's a single word over the entire line */ while (m && tInfo->lptr[m] != ' ') m--; if (m > 0) n = m + 1; } } else n = tInfo->len; if (dopage) ExtTextOutW(hdc, rc->left, y, ETO_CLIPPED, rc, tInfo->lptr, n, NULL); tInfo->len -= n; if (tInfo->len) { memcpy(tInfo->lptr, tInfo->lptr + n, tInfo->len * sizeof(WCHAR)); y += tm.tmHeight + tm.tmExternalLeading; } else { /* find the next line */ while (tInfo->mptr < tInfo->mend && y < b && (*tInfo->mptr == '\n' || *tInfo->mptr == '\r')) { if (*tInfo->mptr == '\n') y += tm.tmHeight + tm.tmExternalLeading; tInfo->mptr++; } } } while (tInfo->mptr < tInfo->mend && y < b); notepad_print_header(hdc, rc, dopage, FALSE, page, footer_text); if (dopage) { EndPage(hdc); } HeapFree(GetProcessHeap(), 0, footer_text); return TRUE; }
static void cdcreatecanvas(cdCanvas* canvas, void *data) { char *data_str = (char*) data; char docname[256] = "CD - Canvas Draw Document"; int dialog = 0; /* Inicializa parametros */ if (data_str == NULL) return; if (data_str[0] != 0) { const char *ptr = strstr(data_str, "-d"); if (ptr != NULL) dialog = 1; if (data_str[0] != '-') { strcpy(docname, data_str); if (dialog) docname[ptr - data_str - 1] = 0; } } PRINTDLG pd; ZeroMemory(&pd, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.nCopies = 1; if (dialog) { pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE | PD_NOPAGENUMS | PD_NOSELECTION; pd.hwndOwner = GetForegroundWindow(); } else { pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT; } if (!PrintDlg(&pd)) { if(pd.hDevMode) GlobalFree(pd.hDevMode); if(pd.hDevNames) GlobalFree(pd.hDevNames); return; } HDC hDC = pd.hDC; DEVMODE* devideMode = (DEVMODE*)GlobalLock(pd.hDevMode); HANDLE printerHandle; OpenPrinter((char*)devideMode->dmDeviceName, &printerHandle, NULL); GlobalUnlock(pd.hDevMode); { /* Inicializa documento */ DOCINFO docInfo; ZeroMemory(&docInfo, sizeof(docInfo)); docInfo.cbSize = sizeof(docInfo); docInfo.lpszDocName = docname; StartDoc(hDC, &docInfo); } StartPage(hDC); canvas->w = GetDeviceCaps(hDC, HORZRES); canvas->h = GetDeviceCaps(hDC, VERTRES); canvas->bpp = GetDeviceCaps(hDC, BITSPIXEL); Graphics* graphics = new Graphics(hDC, printerHandle); /* Inicializa driver WIN32 */ cdCtxCanvas* ctxcanvas = cdwpCreateCanvas(canvas, graphics, CDW_EMF); ctxcanvas->hDC = hDC; ctxcanvas->printerHandle = printerHandle; if(pd.hDevMode) GlobalFree(pd.hDevMode); if(pd.hDevNames) GlobalFree(pd.hDevNames); }
// Sends the bitmap extracted from the View window to a printer of your choice // This function provides a useful reference for printing bitmaps in general void CDoc::Print() { // Get the dimensions of the View window CRect rcView = GetView().GetClientRect(); int Width = rcView.Width(); int Height = rcView.Height(); // Copy the bitmap from the View window CClientDC ViewDC(GetView()); CMemDC MemDC(ViewDC); CBitmap bmView; bmView.CreateCompatibleBitmap(ViewDC, Width, Height); MemDC.SelectObject(bmView); MemDC.BitBlt(0, 0, Width, Height, ViewDC, 0, 0, SRCCOPY); CPrintDialog PrintDlg; try { // Bring up a dialog to choose the printer if (PrintDlg.DoModal(GetView()) == IDOK) // throws exception if there is no default printer { // Zero and then initialize the members of a DOCINFO structure. DOCINFO di; memset(&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = _T("Scribble Printout"); di.lpszOutput = (LPTSTR)NULL; di.lpszDatatype = (LPTSTR)NULL; di.fwType = 0; // Begin a print job by calling the StartDoc function. CDC dcPrint = PrintDlg.GetPrinterDC(); if (SP_ERROR == StartDoc(dcPrint, &di)) throw CUserException(_T("Failed to start print job")); // Inform the driver that the application is about to begin sending data. if (0 > StartPage(dcPrint)) throw CUserException(_T("StartPage failed")); BITMAPINFOHEADER bi; ZeroMemory(&bi, sizeof(BITMAPINFOHEADER)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biHeight = Height; bi.biWidth = Width; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = BI_RGB; // Note: BITMAPINFO and BITMAPINFOHEADER are the same for 24 bit bitmaps // Get the size of the image data MemDC.GetDIBits(bmView, 0, Height, NULL, reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS); // Retrieve the image data std::vector<byte> vBits(bi.biSizeImage, 0); // a vector to hold the byte array byte* pByteArray = &vBits.front(); MemDC.GetDIBits(bmView, 0, Height, pByteArray, reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS); // Determine the scaling factors required to print the bitmap and retain its original proportions. float fLogPelsX1 = (float)ViewDC.GetDeviceCaps(LOGPIXELSX); float fLogPelsY1 = (float)ViewDC.GetDeviceCaps(LOGPIXELSY); float fLogPelsX2 = (float)GetDeviceCaps(dcPrint, LOGPIXELSX); float fLogPelsY2 = (float)GetDeviceCaps(dcPrint, LOGPIXELSY); float fScaleX = MAX(fLogPelsX1, fLogPelsX2) / MIN(fLogPelsX1, fLogPelsX2); float fScaleY = MAX(fLogPelsY1, fLogPelsY2) / MIN(fLogPelsY1, fLogPelsY2); // Compute the coordinates of the upper left corner of the centered bitmap. int cWidthPels = GetDeviceCaps(dcPrint, HORZRES); int xLeft = ((cWidthPels / 2) - ((int)(((float)Width) * fScaleX)) / 2); int cHeightPels = GetDeviceCaps(dcPrint, VERTRES); int yTop = ((cHeightPels / 2) - ((int)(((float)Height) * fScaleY)) / 2); // Use StretchDIBits to scale the bitmap and maintain its original proportions if (GDI_ERROR == (UINT)StretchDIBits(dcPrint, xLeft, yTop, (int)((float)Width * fScaleX), (int)((float)Height * fScaleY), 0, 0, Width, Height, pByteArray, reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS, SRCCOPY)) { throw CUserException(_T("Failed to resize image for printing")); } // Inform the driver that the page is finished. if (0 > EndPage(dcPrint)) throw CUserException(_T("EndPage failed")); // Inform the driver that document has ended. if (0 > EndDoc(dcPrint)) throw CUserException(_T("EndDoc failed")); } } catch (const CException& e) { // Display a message box indicating why printing failed. CString strMsg = CString(e.GetText()) + CString("\n") + e.GetErrorString(); CString strType = CString(e.what()); ::MessageBox(NULL, strMsg, strType, MB_ICONWARNING); } }
VOID DIALOG_FilePrint(VOID) { DOCINFO di; PRINTDLG printer; SIZE szMetric; int cWidthPels, cHeightPels, border; int xLeft, yTop, pagecount, dopage, copycount; unsigned int i; LOGFONT hdrFont; HFONT font, old_font=0; DWORD size; LPWSTR pTemp; WCHAR cTemp[PRINT_LEN_MAX]; static const WCHAR print_fontW[] = { 'C','o','u','r','i','e','r',0 }; static const WCHAR letterM[] = { 'M',0 }; /* Get a small font and print some header info on each page */ hdrFont.lfHeight = -35; hdrFont.lfWidth = 0; hdrFont.lfEscapement = 0; hdrFont.lfOrientation = 0; hdrFont.lfWeight = FW_BOLD; hdrFont.lfItalic = 0; hdrFont.lfUnderline = 0; hdrFont.lfStrikeOut = 0; hdrFont.lfCharSet = ANSI_CHARSET; hdrFont.lfOutPrecision = OUT_DEFAULT_PRECIS; hdrFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; hdrFont.lfQuality = PROOF_QUALITY; hdrFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN; lstrcpy(hdrFont.lfFaceName, print_fontW); font = CreateFontIndirect(&hdrFont); /* Get Current Settings */ ZeroMemory(&printer, sizeof(printer)); printer.lStructSize = sizeof(printer); printer.hwndOwner = Globals.hMainWnd; printer.hDevMode = Globals.hDevMode; printer.hDevNames = Globals.hDevNames; printer.hInstance = Globals.hInstance; /* Set some default flags */ printer.Flags = PD_RETURNDC | PD_NOSELECTION; printer.nFromPage = 0; printer.nMinPage = 1; /* we really need to calculate number of pages to set nMaxPage and nToPage */ printer.nToPage = 0; printer.nMaxPage = -1; /* Let commdlg manage copy settings */ printer.nCopies = (WORD)PD_USEDEVMODECOPIES; if (!PrintDlg(&printer)) return; Globals.hDevMode = printer.hDevMode; Globals.hDevNames = printer.hDevNames; assert(printer.hDC != 0); /* initialize DOCINFO */ di.cbSize = sizeof(DOCINFO); di.lpszDocName = Globals.szFileTitle; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; if (StartDoc(printer.hDC, &di) <= 0) return; /* Get the page dimensions in pixels. */ cWidthPels = GetDeviceCaps(printer.hDC, HORZRES); cHeightPels = GetDeviceCaps(printer.hDC, VERTRES); /* Get the file text */ size = GetWindowTextLength(Globals.hEdit) + 1; pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); if (!pTemp) { ShowLastError(); return; } size = GetWindowText(Globals.hEdit, pTemp, size); border = 150; old_font = SelectObject(printer.hDC, Globals.hFont); GetTextExtentPoint32(printer.hDC, letterM, 1, &szMetric); for (copycount=1; copycount <= printer.nCopies; copycount++) { i = 0; pagecount = 1; do { if (printer.Flags & PD_PAGENUMS) { /* a specific range of pages is selected, so * skip pages that are not to be printed */ if (pagecount > printer.nToPage) break; else if (pagecount >= printer.nFromPage) dopage = 1; else dopage = 0; } else dopage = 1; if (dopage) { if (StartPage(printer.hDC) <= 0) { static const WCHAR failedW[] = { 'S','t','a','r','t','P','a','g','e',' ','f','a','i','l','e','d',0 }; static const WCHAR errorW[] = { 'P','r','i','n','t',' ','E','r','r','o','r',0 }; MessageBox(Globals.hMainWnd, failedW, errorW, MB_ICONEXCLAMATION); return; } /* Write a rectangle and header at the top of each page */ SelectObject(printer.hDC, font); Rectangle(printer.hDC, border, border, cWidthPels-border, border+szMetric.cy*2); TextOut(printer.hDC, border*2, border+szMetric.cy/2, Globals.szFileTitle, lstrlen(Globals.szFileTitle)); } SelectObject(printer.hDC, Globals.hFont); /* The starting point for the main text */ xLeft = border; yTop = border+szMetric.cy*4; do { int k=0, m; /* find the end of the line */ while (i < size && pTemp[i] != '\n' && pTemp[i] != '\r') { if (pTemp[i] == '\t') { /* replace tabs with spaces */ for (m=0; m<SPACES_IN_TAB; m++) { if (k < PRINT_LEN_MAX) cTemp[k++] = ' '; } } else if (k < PRINT_LEN_MAX) cTemp[k++] = pTemp[i]; i++; } if (dopage) TextOut(printer.hDC, xLeft, yTop, cTemp, k); /* find the next line */ while (i < size && (pTemp[i] == '\n' || pTemp[i] == '\r')) { if (pTemp[i] == '\n') yTop += szMetric.cy; i++; } } while (i<size && yTop<(cHeightPels-border*2)); if (dopage) EndPage(printer.hDC); pagecount++; } while (i<size); } SelectObject(printer.hDC, old_font); EndDoc(printer.hDC); DeleteDC(printer.hDC); HeapFree(GetProcessHeap(), 0, pTemp); }
extern "C" BOOL EditPrint(HWND hwnd,LPCWSTR pszDocTitle,LPCWSTR pszPageFormat) { // Don't print empty documents if (SendMessage(hwnd,SCI_GETLENGTH,0,0) == 0) { MsgBox(MBWARN,IDS_PRINT_EMPTY); return TRUE; } int startPos; int endPos; HDC hdc; RECT rectMargins; RECT rectPhysMargins; RECT rectSetup; POINT ptPage; POINT ptDpi; //RECT rectSetup; TEXTMETRIC tm; int headerLineHeight; HFONT fontHeader; int footerLineHeight; HFONT fontFooter; WCHAR dateString[MIDSZ_BUFFER] = { L'\0' }; DOCINFO di = {sizeof(DOCINFO), nullptr, nullptr, nullptr, 0}; int lengthDoc; int lengthDocMax; int lengthPrinted; struct Sci_RangeToFormat frPrint; int pageNum; BOOL printPage; WCHAR pageString[32] = { L'\0' }; HPEN pen; HPEN penOld; PRINTDLG pdlg = { sizeof(PRINTDLG), nullptr, nullptr, nullptr, nullptr, 0, 0, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; pdlg.hwndOwner = GetParent(hwnd); pdlg.hInstance = g_hInstance; pdlg.Flags = PD_USEDEVMODECOPIES | PD_ALLPAGES | PD_RETURNDC; pdlg.nFromPage = 1; pdlg.nToPage = 1; pdlg.nMinPage = 1; pdlg.nMaxPage = 0xffffU; pdlg.nCopies = 1; pdlg.hDC = nullptr; pdlg.hDevMode = hDevMode; pdlg.hDevNames = hDevNames; startPos = (int)SendMessage(hwnd,SCI_GETSELECTIONSTART,0,0); endPos = (int)SendMessage(hwnd,SCI_GETSELECTIONEND,0,0); if (startPos == endPos) { pdlg.Flags |= PD_NOSELECTION; } else { pdlg.Flags |= PD_SELECTION; } // |= 0 - Don't display dialog box, just use the default printer and options pdlg.Flags |= (flagPrintFileAndLeave == 1) ? PD_RETURNDEFAULT : 0; if (!PrintDlg(&pdlg)) { return TRUE; // False means error... } hDevMode = pdlg.hDevMode; hDevNames = pdlg.hDevNames; hdc = pdlg.hDC; // Get printer resolution ptDpi.x = GetDeviceCaps(hdc, LOGPIXELSX); // dpi in X direction ptDpi.y = GetDeviceCaps(hdc, LOGPIXELSY); // dpi in Y direction // Start by getting the physical page size (in device units). ptPage.x = GetDeviceCaps(hdc, PHYSICALWIDTH); // device units ptPage.y = GetDeviceCaps(hdc, PHYSICALHEIGHT); // device units // Get the dimensions of the unprintable // part of the page (in device units). rectPhysMargins.left = GetDeviceCaps(hdc, PHYSICALOFFSETX); rectPhysMargins.top = GetDeviceCaps(hdc, PHYSICALOFFSETY); // To get the right and lower unprintable area, // we take the entire width and height of the paper and // subtract everything else. rectPhysMargins.right = ptPage.x // total paper width - GetDeviceCaps(hdc, HORZRES) // printable width - rectPhysMargins.left; // left unprintable margin rectPhysMargins.bottom = ptPage.y // total paper height - GetDeviceCaps(hdc, VERTRES) // printable height - rectPhysMargins.top; // right unprintable margin // At this point, rectPhysMargins contains the widths of the // unprintable regions on all four sides of the page in device units. // Take in account the page setup given by the user (if one value is not null) if (pagesetupMargin.left != 0 || pagesetupMargin.right != 0 || pagesetupMargin.top != 0 || pagesetupMargin.bottom != 0) { // Convert the hundredths of millimeters (HiMetric) or // thousandths of inches (HiEnglish) margin values // from the Page Setup dialog to device units. // (There are 2540 hundredths of a mm in an inch.) WCHAR localeInfo[3]; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3); if (localeInfo[0] == L'0') { // Metric system. L'1' is US System rectSetup.left = MulDiv (pagesetupMargin.left, ptDpi.x, 2540); rectSetup.top = MulDiv (pagesetupMargin.top, ptDpi.y, 2540); rectSetup.right = MulDiv(pagesetupMargin.right, ptDpi.x, 2540); rectSetup.bottom = MulDiv(pagesetupMargin.bottom, ptDpi.y, 2540); } else { rectSetup.left = MulDiv(pagesetupMargin.left, ptDpi.x, 1000); rectSetup.top = MulDiv(pagesetupMargin.top, ptDpi.y, 1000); rectSetup.right = MulDiv(pagesetupMargin.right, ptDpi.x, 1000); rectSetup.bottom = MulDiv(pagesetupMargin.bottom, ptDpi.y, 1000); } // Dont reduce margins below the minimum printable area rectMargins.left = max(rectPhysMargins.left, rectSetup.left); rectMargins.top = max(rectPhysMargins.top, rectSetup.top); rectMargins.right = max(rectPhysMargins.right, rectSetup.right); rectMargins.bottom = max(rectPhysMargins.bottom, rectSetup.bottom); } else { rectMargins.left = rectPhysMargins.left; rectMargins.top = rectPhysMargins.top; rectMargins.right = rectPhysMargins.right; rectMargins.bottom = rectPhysMargins.bottom; } // rectMargins now contains the values used to shrink the printable // area of the page. // Convert device coordinates into logical coordinates DPtoLP(hdc, (LPPOINT)&rectMargins, 2); DPtoLP(hdc, (LPPOINT)&rectPhysMargins, 2); // Convert page size to logical units and we're done! DPtoLP(hdc, (LPPOINT) &ptPage, 1); headerLineHeight = MulDiv(8,ptDpi.y, 72); fontHeader = CreateFont(headerLineHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial"); SelectObject(hdc, fontHeader); GetTextMetrics(hdc, &tm); headerLineHeight = tm.tmHeight + tm.tmExternalLeading; if (iPrintHeader == 3) headerLineHeight = 0; footerLineHeight = MulDiv(7,ptDpi.y, 72); fontFooter = CreateFont(footerLineHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial"); SelectObject(hdc, fontFooter); GetTextMetrics(hdc, &tm); footerLineHeight = tm.tmHeight + tm.tmExternalLeading; if (iPrintFooter == 1) footerLineHeight = 0; di.lpszDocName = pszDocTitle; di.lpszOutput = nullptr; di.lpszDatatype = nullptr; di.fwType = 0; if (StartDoc(hdc, &di) < 0) { DeleteDC(hdc); if (fontHeader) DeleteObject(fontHeader); if (fontFooter) DeleteObject(fontFooter); return FALSE; } // Get current date... SYSTEMTIME st; GetLocalTime(&st); GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,nullptr,dateString,MIDSZ_BUFFER); // Get current time... if (iPrintHeader == 0) { WCHAR timeString[SMALL_BUFFER] = { L'\0' }; GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,nullptr,timeString,SMALL_BUFFER); StringCchCat(dateString,COUNTOF(dateString),L" "); StringCchCat(dateString,COUNTOF(dateString),timeString); } // Set print color mode int printColorModes[5] = { SC_PRINT_NORMAL, SC_PRINT_INVERTLIGHT, SC_PRINT_BLACKONWHITE, SC_PRINT_COLOURONWHITE, SC_PRINT_COLOURONWHITEDEFAULTBG }; SendMessage(hwnd,SCI_SETPRINTCOLOURMODE,printColorModes[iPrintColor],0); // Set print zoom... SendMessage(hwnd,SCI_SETPRINTMAGNIFICATION,(WPARAM)iPrintZoom,0); lengthDoc = (int)SendMessage(hwnd,SCI_GETLENGTH,0,0); lengthDocMax = lengthDoc; lengthPrinted = 0; // Requested to print selection if (pdlg.Flags & PD_SELECTION) { if (startPos > endPos) { lengthPrinted = endPos; lengthDoc = startPos; } else { lengthPrinted = startPos; lengthDoc = endPos; } if (lengthPrinted < 0) lengthPrinted = 0; if (lengthDoc > lengthDocMax) lengthDoc = lengthDocMax; } // We must substract the physical margins from the printable area frPrint.hdc = hdc; frPrint.hdcTarget = hdc; frPrint.rc.left = rectMargins.left - rectPhysMargins.left; frPrint.rc.top = rectMargins.top - rectPhysMargins.top; frPrint.rc.right = ptPage.x - rectMargins.right - rectPhysMargins.left; frPrint.rc.bottom = ptPage.y - rectMargins.bottom - rectPhysMargins.top; frPrint.rcPage.left = 0; frPrint.rcPage.top = 0; frPrint.rcPage.right = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1; frPrint.rcPage.bottom = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1; frPrint.rc.top += headerLineHeight + headerLineHeight / 2; frPrint.rc.bottom -= footerLineHeight + footerLineHeight / 2; // Print each page pageNum = 1; while (lengthPrinted < lengthDoc) { printPage = (!(pdlg.Flags & PD_PAGENUMS) || (pageNum >= pdlg.nFromPage) && (pageNum <= pdlg.nToPage)); StringCchPrintf(pageString,COUNTOF(pageString),pszPageFormat,pageNum); if (printPage) { // Show wait cursor... SendMessage(g_hwndEdit, SCI_SETCURSOR, (WPARAM)SC_CURSORWAIT, 0); // Display current page number in Statusbar StatusUpdatePrintPage(pageNum); StartPage(hdc); SetTextColor(hdc, RGB(0,0,0)); SetBkColor(hdc, RGB(0xFF, 0xFF, 0xFF)); SelectObject(hdc, fontHeader); UINT ta = SetTextAlign(hdc, TA_BOTTOM); RECT rcw = {frPrint.rc.left, frPrint.rc.top - headerLineHeight - headerLineHeight / 2, frPrint.rc.right, frPrint.rc.top - headerLineHeight / 2}; rcw.bottom = rcw.top + headerLineHeight; if (iPrintHeader < 3) { ExtTextOut(hdc, frPrint.rc.left + 5, frPrint.rc.top - headerLineHeight / 2, /*ETO_OPAQUE*/0, &rcw, pszDocTitle, lstrlen(pszDocTitle), nullptr); } // Print date in header if (iPrintHeader == 0 || iPrintHeader == 1) { SIZE sizeInfo; SelectObject(hdc,fontFooter); GetTextExtentPoint32(hdc,dateString,StringCchLenW(dateString,COUNTOF(dateString)),&sizeInfo); ExtTextOut(hdc, frPrint.rc.right - 5 - sizeInfo.cx, frPrint.rc.top - headerLineHeight / 2, /*ETO_OPAQUE*/0, &rcw, dateString, StringCchLenW(dateString,COUNTOF(dateString)), nullptr); } if (iPrintHeader < 3) { SetTextAlign(hdc, ta); pen = CreatePen(0, 1, RGB(0,0,0)); penOld = (HPEN)SelectObject(hdc, pen); MoveToEx(hdc, frPrint.rc.left, frPrint.rc.top - headerLineHeight / 4, nullptr); LineTo(hdc, frPrint.rc.right, frPrint.rc.top - headerLineHeight / 4); SelectObject(hdc, penOld); DeleteObject(pen); } } frPrint.chrg.cpMin = lengthPrinted; frPrint.chrg.cpMax = lengthDoc; lengthPrinted = (int)SendMessage(hwnd, SCI_FORMATRANGE, printPage, (LPARAM)&frPrint); if (printPage) { SetTextColor(hdc, RGB(0,0,0)); SetBkColor(hdc, RGB(0xFF, 0xFF, 0xFF)); SelectObject(hdc, fontFooter); UINT ta = SetTextAlign(hdc, TA_TOP); RECT rcw = {frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 2, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight + footerLineHeight / 2}; if (iPrintFooter == 0) { SIZE sizeFooter; GetTextExtentPoint32(hdc,pageString,StringCchLenW(pageString,COUNTOF(pageString)),&sizeFooter); ExtTextOut(hdc, frPrint.rc.right - 5 - sizeFooter.cx, frPrint.rc.bottom + footerLineHeight / 2, /*ETO_OPAQUE*/0, &rcw, pageString, StringCchLenW(pageString,COUNTOF(pageString)), nullptr); SetTextAlign(hdc, ta); pen = ::CreatePen(0, 1, RGB(0,0,0)); penOld = (HPEN)SelectObject(hdc, pen); SetBkColor(hdc, RGB(0,0,0)); MoveToEx(hdc, frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 4, nullptr); LineTo(hdc, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight / 4); SelectObject(hdc, penOld); DeleteObject(pen); } EndPage(hdc); } pageNum++; if ((pdlg.Flags & PD_PAGENUMS) && (pageNum > pdlg.nToPage)) break; } SendMessage(hwnd,SCI_FORMATRANGE, FALSE, 0); EndDoc(hdc); DeleteDC(hdc); if (fontHeader) DeleteObject(fontHeader); if (fontFooter) DeleteObject(fontFooter); // Reset Statusbar to default mode StatusSetSimple(g_hwndStatus,FALSE); // Remove wait cursor... { POINT pt; SendMessage(g_hwndEdit, SCI_SETCURSOR, (WPARAM)SC_CURSORNORMAL, 0); GetCursorPos(&pt); SetCursorPos(pt.x, pt.y); } return TRUE; }
/************************************************************************ * Escape [GDI32.@] */ INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data ) { INT ret; POINT *pt; switch (escape) { case ABORTDOC: return AbortDoc( hdc ); case ENDDOC: return EndDoc( hdc ); case GETPHYSPAGESIZE: pt = out_data; pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH ); pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT ); return 1; case GETPRINTINGOFFSET: pt = out_data; pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX ); pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY ); return 1; case GETSCALINGFACTOR: pt = out_data; pt->x = GetDeviceCaps( hdc, SCALINGFACTORX ); pt->y = GetDeviceCaps( hdc, SCALINGFACTORY ); return 1; case NEWFRAME: return EndPage( hdc ); case SETABORTPROC: return SetAbortProc( hdc, (ABORTPROC)in_data ); case STARTDOC: { DOCINFOA doc; char *name = NULL; /* in_data may not be 0 terminated so we must copy it */ if (in_data) { name = HeapAlloc( GetProcessHeap(), 0, in_count+1 ); memcpy( name, in_data, in_count ); name[in_count] = 0; } /* out_data is actually a pointer to the DocInfo structure and used as * a second input parameter */ if (out_data) doc = *(DOCINFOA *)out_data; else { doc.cbSize = sizeof(doc); doc.lpszOutput = NULL; doc.lpszDatatype = NULL; doc.fwType = 0; } doc.lpszDocName = name; ret = StartDocA( hdc, &doc ); HeapFree( GetProcessHeap(), 0, name ); if (ret > 0) ret = StartPage( hdc ); return ret; } case QUERYESCSUPPORT: { const INT *ptr = (const INT *)in_data; if (in_count < sizeof(INT)) return 0; switch(*ptr) { case ABORTDOC: case ENDDOC: case GETPHYSPAGESIZE: case GETPRINTINGOFFSET: case GETSCALINGFACTOR: case NEWFRAME: case QUERYESCSUPPORT: case SETABORTPROC: case STARTDOC: return TRUE; } break; } } /* if not handled internally, pass it to the driver */ return ExtEscape( hdc, escape, in_count, in_data, 0, out_data ); }
/* Implement ide_winprint print_text. */ static int winprint_print_command (ClientData cd, Tcl_Interp *interp, int argc, char **argv) { struct winprint_data *wd = (struct winprint_data *) cd; char *queryproc; char *textproc; struct print_text_options pto; PRINTDLG pd; int cancelled; int top, bottom, left; TEXTMETRIC tm; POINT pt; int lineheight; int pageno; int error=0, done, needquery; struct { short len; /* Defined to be 16 bits.... */ char buffer[PRINT_BUFSIZE+1]; } indata; queryproc = argv[2]; textproc = argv[3]; if (winprint_print_text_options (wd, interp, argc, argv, &pto) != TCL_OK) return TCL_ERROR; if (winprint_print_text_dialog (wd, interp, &pto, &pd, &cancelled) != TCL_OK) return TCL_ERROR; if (cancelled) return TCL_OK; if (pto.postscript) { int eps_printing = 33; int result; short bresult = 1; /* EPS printing download suppressed */ result = Escape (pd.hDC, eps_printing, sizeof (BOOL), (LPCSTR)&bresult, NULL); if ( result < 0 ) { /* The EPSPRINTING escape failed! */ Tcl_AppendElement(interp, "ide_winprint: EPSPRINTING escape implemented but failed"); DeleteDC (pd.hDC); return TCL_ERROR; } } else { winprint_get_margins(wd, &pd, &top, &left, &bottom); } if (winprint_start (wd, interp, &pd, &pto, &cancelled) != TCL_OK) { DeleteDC (pd.hDC); return TCL_ERROR; } if (cancelled) { DeleteDC (pd.hDC); return TCL_OK; } /* init and start init-procedure if available */ if (pto.initproc != NULL) { Tcl_DString initStr; char buf[64]; Tcl_DStringInit (&initStr); Tcl_DStringAppend (&initStr, pto.initproc, -1); /* Here we must pass the customer selection from the PrintDialog * as parameters for the init command, */ /* From page */ Tcl_DStringAppendElement (&initStr, "-frompage"); sprintf (buf, "%i", pd.nFromPage); Tcl_DStringAppendElement (&initStr, buf); /* To Page */ Tcl_DStringAppendElement (&initStr, "-topage"); sprintf (buf, "%i", pd.nToPage); Tcl_DStringAppendElement (&initStr, buf); /* # Copies */ Tcl_DStringAppendElement (&initStr, "-copies"); sprintf (buf, "%i", pd.nCopies); Tcl_DStringAppendElement (&initStr, buf); /* Print Selection? */ Tcl_DStringAppendElement (&initStr, "-selection"); Tcl_DStringAppendElement (&initStr, (pd.Flags&PD_SELECTION) ? "1" : "0"); /* Execute tcl/command */ if (Tcl_Eval (interp, Tcl_DStringValue(&initStr)) != TCL_OK) { Tcl_DStringFree (&initStr); return TCL_ERROR; } Tcl_DStringFree (&initStr); } if (pto.postscript) { Tcl_DString pageStr; int status, retval, len, i; char *l, msgbuf[128]; enum winprint_query q = 0; /* Note: NT 4.0 seems to leave the default CTM quite tiny! */ strcpy (indata.buffer, "\r\nsave\r\ninitmatrix\r\n"); indata.len = strlen(indata.buffer); Escape(pd.hDC, PASSTHROUGH, 0, (LPCSTR)&indata, NULL); /* Init command for page-procedure */ if (pto.pageproc != NULL) { Tcl_DStringInit (&pageStr); Tcl_DStringAppend (&pageStr, pto.pageproc, -1); Tcl_DStringAppendElement (&pageStr, "-1"); } /* Start printing */ while (1) { /* Run page-procedure to update the display */ status = winprint_print_text_invoke (interp, Tcl_DStringValue(&pageStr), "page", &q); if (status != TCL_OK || q == Q_DONE) { error = 1; break; } /* query next characters to send to printer */ if (winprint_print_text_invoke (interp, queryproc, "query", &q) != TCL_OK) { error = 1; break; } if (q != Q_CONTINUE) { done = 1; break; } if (Tcl_Eval (interp, textproc) == TCL_ERROR) { error = 1; break; } l = Tcl_GetStringFromObj (Tcl_GetObjResult (interp), &len); for (i=0; i<len; i+=PRINT_BUFSIZE) { int lpos = min (PRINT_BUFSIZE, len-i); strncpy (indata.buffer, l+i, lpos); indata.buffer[lpos] = 0; indata.len = lpos; retval = Escape (pd.hDC, PASSTHROUGH, 0, (LPCSTR)&indata, NULL); if (retval < 0) { Tcl_AppendElement(interp, "ide_winprint: PASSTHROUGH Escape failed"); error = 1; break; } else if (retval != indata.len) { sprintf(msgbuf, "ide_winprint: Short write (%d vs. %d)", retval, indata.len); Tcl_AppendElement(interp, msgbuf); error = 1; break; } } } strcpy (indata.buffer, "\r\nrestore\r\n"); indata.len = strlen(indata.buffer); Escape(pd.hDC, PASSTHROUGH, 0, (LPCSTR)&indata, NULL); } else { GetTextMetrics (pd.hDC, &tm); pt.x = 0; pt.y = tm.tmHeight + tm.tmExternalLeading; LPtoDP (pd.hDC, &pt, 1); lineheight = pt.y; pageno = 1; /* The main print loop. */ done = 0; error = 0; needquery = 1; while (1) { int y; if (wd->aborted) break; /* Start a new page. */ if (pto.pageproc != NULL) { Tcl_DString ds; char buf[20]; enum winprint_query q; int status; Tcl_DStringInit (&ds); Tcl_DStringAppend (&ds, pto.pageproc, -1); sprintf (buf, "%d", pageno); Tcl_DStringAppendElement (&ds, buf); status = winprint_print_text_invoke (interp, Tcl_DStringValue (&ds), "page", &q); Tcl_DStringFree (&ds); if (status != TCL_OK) { error = 1; break; } if (q == Q_DONE) { done = 1; break; } } if (needquery) { enum winprint_query q; if (winprint_print_text_invoke (interp, queryproc, "query", &q) != TCL_OK) { error = 1; break; } if (q == Q_DONE) { done = 1; break; } /* Ignore Q_NEWPAGE, since we're about to start a new page anyhow. */ needquery = 0; } if (StartPage (pd.hDC) <= 0) { windows_error (interp, "StartPage"); error = 1; break; } y = top; /* Print a page. */ while (1) { char *l; int len; enum winprint_query q; if (Tcl_Eval (interp, textproc) == TCL_ERROR) { error = 1; break; } l = Tcl_GetStringFromObj (Tcl_GetObjResult (interp), &len); TextOut (pd.hDC, left, y, l, len); y += lineheight; if (y >= bottom) { needquery = 1; break; } if (winprint_print_text_invoke (interp, queryproc, "query", &q) != TCL_OK) { error = 1; break; } if (q == Q_DONE) { done = 1; break; } else if (q == Q_NEWPAGE) break; } if (error) break; if (EndPage (pd.hDC) <= 0) { /* It's OK for EndPage to return an error if the print job was cancelled. */ if (! wd->aborted) { windows_error (interp, "EndPage"); error = 1; } break; } if (done) break; ++pageno; } } if (winprint_finish (wd, interp, &pd, error) != TCL_OK) error = 1; if (error) return TCL_ERROR; Tcl_ResetResult (interp); return TCL_OK; }
int PrintText( const char * Text ) { int return_code = 0 ; PRINTDLG pd; DOCINFO di; int i, TextLen = 0, Index1 = 0, Index2 = 2, Exit = 0 ; char* LinePrint = NULL ; char* szMessage = NULL ; if( Text == NULL ) return 1 ; if( strlen( Text ) == 0 ) return 1 ; memset (&pd, 0, sizeof(PRINTDLG)); memset (&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "Test"; pd.lStructSize = sizeof(PRINTDLG); pd.Flags = PD_PAGENUMS | PD_RETURNDC; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 1; pd.nMaxPage = 1; szMessage = 0; if( PrintDlg( &pd ) ) { if( pd.hDC ) { if (StartDoc (pd.hDC, &di) != SP_ERROR) { TextLen = strlen( Text ) ; if( TextLen > 0 ) { LinePrint = (char*) malloc( TextLen + 2 ) ; Index1 = 0 ; Index2 = 2 ; Exit = 0 ; for( i = 0 ; i < TextLen ; i++ ) { if( Text[i]=='\r' ) i++; LinePrint[Index1] = Text[i] ; if( Text[i] == '\n' ) { Index2++ ; LinePrint[Index1] = '\0' ; TextOut(pd.hDC,100, Index2*PrintCharSize, LinePrint, strlen(LinePrint) ) ; Index1 = 0 ; } else if( Index1>=PrintMaxCharPerLine ) { Index2++ ; LinePrint[Index1+1] = '\0' ; TextOut(pd.hDC,100, Index2*PrintCharSize, LinePrint, strlen(LinePrint) ) ; Index1 = 0 ; } else { Index1++ ; } if( Index2 >= PrintMaxLinePerPage ) { EndPage( pd.hDC ) ; //EndDoc(pd.hDC) ; //StartDoc(pd.hDC, &di) ; StartPage( pd.hDC ) ; Index2 = 2 ; } } Index2++ ; LinePrint[Index1] = '\0'; // Impression de la dernière page TextOut(pd.hDC,100, Index2*PrintCharSize, LinePrint, strlen(LinePrint)) ; EndPage(pd.hDC) ; EndDoc(pd.hDC) ; szMessage = "Print successful"; free( LinePrint ) ; } else { return_code = 1 ; /* Chaine vide */ } } else { // Problème StartDoc szMessage = "ERROR Type 1" ; return_code = 2 ; } } else { // Probleme pd.hDC szMessage = "ERROR Type 2." ; return_code = 3 ; } } else { // Problème PrintDlg //szMessage = "Impression annulé par l'utilisateur" ; return_code = 4 ; } if (szMessage) { MessageBox (NULL, szMessage, "Print report", MB_OK) ; } return return_code ; }
VOID DIALOG_FilePrint(VOID) { DOCINFO di; PRINTDLG printer; SIZE szMetric; int cWidthPels, cHeightPels, border; int xLeft, yTop, pagecount, dopage, copycount; unsigned int i; LOGFONT hdrFont; HFONT font, old_font=0; DWORD size; LPTSTR pTemp; static const TCHAR times_new_roman[] = _T("Times New Roman"); /* Get a small font and print some header info on each page */ ZeroMemory(&hdrFont, sizeof(hdrFont)); hdrFont.lfHeight = 100; hdrFont.lfWeight = FW_BOLD; hdrFont.lfCharSet = ANSI_CHARSET; hdrFont.lfOutPrecision = OUT_DEFAULT_PRECIS; hdrFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; hdrFont.lfQuality = PROOF_QUALITY; hdrFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN; _tcscpy(hdrFont.lfFaceName, times_new_roman); font = CreateFontIndirect(&hdrFont); /* Get Current Settings */ ZeroMemory(&printer, sizeof(printer)); printer.lStructSize = sizeof(printer); printer.hwndOwner = Globals.hMainWnd; printer.hInstance = Globals.hInstance; /* Set some default flags */ printer.Flags = PD_RETURNDC | PD_SELECTION; /* Disable the selection radio button if there is no text selected */ if (!GetSelectionTextLength(Globals.hEdit)) { printer.Flags = printer.Flags | PD_NOSELECTION; } printer.nFromPage = 0; printer.nMinPage = 1; /* we really need to calculate number of pages to set nMaxPage and nToPage */ printer.nToPage = 0; printer.nMaxPage = (WORD)-1; /* Let commdlg manage copy settings */ printer.nCopies = (WORD)PD_USEDEVMODECOPIES; printer.hDevMode = Globals.hDevMode; printer.hDevNames = Globals.hDevNames; if (!PrintDlg(&printer)) { DeleteObject(font); return; } Globals.hDevMode = printer.hDevMode; Globals.hDevNames = printer.hDevNames; assert(printer.hDC != 0); /* initialize DOCINFO */ di.cbSize = sizeof(DOCINFO); di.lpszDocName = Globals.szFileTitle; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; if (StartDoc(printer.hDC, &di) <= 0) { DeleteObject(font); return; } /* Get the page dimensions in pixels. */ cWidthPels = GetDeviceCaps(printer.hDC, HORZRES); cHeightPels = GetDeviceCaps(printer.hDC, VERTRES); /* Get the file text */ if (printer.Flags & PD_SELECTION) { size = GetSelectionTextLength(Globals.hEdit) + 1; } else { size = GetWindowTextLength(Globals.hEdit) + 1; } pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(TCHAR)); if (!pTemp) { EndDoc(printer.hDC); DeleteObject(font); ShowLastError(); return; } if (printer.Flags & PD_SELECTION) { size = GetSelectionText(Globals.hEdit, pTemp, size); } else { size = GetWindowText(Globals.hEdit, pTemp, size); } border = 150; for (copycount=1; copycount <= printer.nCopies; copycount++) { i = 0; pagecount = 1; do { static const TCHAR letterM[] = _T("M"); if (pagecount >= printer.nFromPage && /* ((printer.Flags & PD_PAGENUMS) == 0 || pagecount <= printer.nToPage))*/ pagecount <= printer.nToPage) dopage = 1; else dopage = 0; old_font = SelectObject(printer.hDC, font); GetTextExtentPoint32(printer.hDC, letterM, 1, &szMetric); if (dopage) { if (StartPage(printer.hDC) <= 0) { SelectObject(printer.hDC, old_font); EndDoc(printer.hDC); DeleteDC(printer.hDC); HeapFree(GetProcessHeap(), 0, pTemp); DeleteObject(font); AlertPrintError(); return; } /* Write a rectangle and header at the top of each page */ Rectangle(printer.hDC, border, border, cWidthPels-border, border+szMetric.cy*2); /* I don't know what's up with this TextOut command. This comes out kind of mangled. */ TextOut(printer.hDC, border * 2, border + szMetric.cy / 2, Globals.szFileTitle, lstrlen(Globals.szFileTitle)); } /* The starting point for the main text */ xLeft = border * 2; yTop = border + szMetric.cy * 4; SelectObject(printer.hDC, old_font); GetTextExtentPoint32(printer.hDC, letterM, 1, &szMetric); /* Since outputting strings is giving me problems, output the main * text one character at a time. */ do { if (pTemp[i] == '\n') { xLeft = border * 2; yTop += szMetric.cy; } else if (pTemp[i] != '\r') { if (dopage) TextOut(printer.hDC, xLeft, yTop, &pTemp[i], 1); xLeft += szMetric.cx; } } while (i++ < size && yTop < (cHeightPels - border * 2)); if (dopage) EndPage(printer.hDC); pagecount++; } while (i < size); } if (old_font != 0) SelectObject(printer.hDC, old_font); EndDoc(printer.hDC); DeleteDC(printer.hDC); HeapFree(GetProcessHeap(), 0, pTemp); DeleteObject(font); }
boolean shellprint (WindowPtr w, boolean fldialog) { /* 9/5/90 dmb: open and close print resources each time we're called. also, make sure we close each page opened, even when errors occur 9/28/91 dmb: for exit of edit mode before printing 4/24/92 dmb: make sure bJDocLoop is bSpoolLoop before calling PrPicFile, as per IM II-155. otherwise, we can get bogus PrErrors */ PRINTDLG pd; DOCINFO di; HDC printport; hdlwindowinfo hinfo; short i; boolean fl = false; if (w == nil) /*defensive driving*/ return (false); fl = false; /*until sucessfull print, this is return value*/ ZeroMemory (&pd, sizeof (PRINTDLG)); pd.lStructSize = sizeof (PRINTDLG); pd.hwndOwner = hwndMDIClient; pd.Flags = PD_RETURNDC; if (!fldialog) pd.Flags = pd.Flags | PD_RETURNDEFAULT; if (! PrintDlg (&pd)) { goto exit; } setcursortype (cursoriswatch); shellupdateallnow (); /*update all windows that were dirtied by the print dialog*/ shellpushglobals (w); (*shellglobals.settextmoderoutine) (false); /*make sure editing changes are accepted*/ di.cbSize = sizeof(DOCINFO); di.lpszDocName = "Frontier Document"; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; shellprintinfo.printport = printport = pd.hDC; shellprintinfo.scaleMult = GetDeviceCaps(pd.hDC, LOGPIXELSX); shellprintinfo.scaleDiv = GetDeviceCaps(getcurrentDC (), LOGPIXELSX); StartDoc (printport, &di); winpushport (w, printport); currentprintport = w; getwindowinfo (w, &hinfo); /*prepares for printing*/ (*shellglobals.beginprintroutine) (); /*fills in fields of printinfo record*/ (*shellglobals.setprintinfoproutine) (); //this only counts the number of pages. for (i = 1; i <= shellprintinfo.ctpages; i++) { /*print one page*/ if (StartPage(shellprintinfo.printport) > 0) { fl = (*shellglobals.printroutine) (i); } EndPage (shellprintinfo.printport); if (!fl) break; } /*for*/ EndDoc (printport); winpopport(); currentprintport = NULL; DeleteDC (printport); (*shellglobals.endprintroutine) (); shellpopglobals (); exit: currentprintport = NULL; return (fl); } /*shellprint*/
void nextpage(printer p) { if (!p || (p->kind != PrinterObject)) return; EndPage((HDC) p->handle); StartPage((HDC) p->handle); }
static bool PrintToDevice(PrintData& pd, ProgressUpdateUI *progressUI=NULL, AbortCookieManager *abortCookie=NULL) { AssertCrash(pd.engine); if (!pd.engine) return false; AssertCrash(pd.printerName); if (!pd.printerName) return false; BaseEngine& engine = *pd.engine; ScopedMem<WCHAR> fileName; DOCINFO di = { 0 }; di.cbSize = sizeof (DOCINFO); if (gPluginMode) { fileName.Set(ExtractFilenameFromURL(gPluginURL)); // fall back to a generic "filename" instead of the more confusing temporary filename di.lpszDocName = fileName ? fileName : L"filename"; } else di.lpszDocName = engine.FileName(); int current = 1, total = 0; if (pd.sel.Count() == 0) { for (size_t i = 0; i < pd.ranges.Count(); i++) { if (pd.ranges.At(i).nToPage < pd.ranges.At(i).nFromPage) total += pd.ranges.At(i).nFromPage - pd.ranges.At(i).nToPage + 1; else total += pd.ranges.At(i).nToPage - pd.ranges.At(i).nFromPage + 1; } } else { for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) { if (!BoundSelectionOnPage(pd.sel, pageNo).IsEmpty()) total++; } } AssertCrash(total > 0); if (0 == total) return false; if (progressUI) progressUI->UpdateProgress(current, total); // cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1882 // According to our crash dumps, Cannon printer drivers (caprenn.dll etc.) // are buggy and like to crash during printing with DEP violation // We disable dep during printing to hopefully not crash // TODO: even better would be to print in a separate process so that // crashes during printing wouldn't affect the main process. It's also // much more complicated to implement ScopeDisableDEP scopeNoDEP; // cf. http://blogs.msdn.com/b/oldnewthing/archive/2012/11/09/10367057.aspx ScopeHDC hdc(CreateDC(pd.driverName, pd.printerName, pd.portName, pd.devMode)); if (!hdc) return false; if (StartDoc(hdc, &di) <= 0) return false; // MM_TEXT: Each logical unit is mapped to one device pixel. // Positive x is to the right; positive y is down. SetMapMode(hdc, MM_TEXT); const SizeI paperSize(GetDeviceCaps(hdc, PHYSICALWIDTH), GetDeviceCaps(hdc, PHYSICALHEIGHT)); const RectI printable(GetDeviceCaps(hdc, PHYSICALOFFSETX), GetDeviceCaps(hdc, PHYSICALOFFSETY), GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES)); const float dpiFactor = min(GetDeviceCaps(hdc, LOGPIXELSX) / engine.GetFileDPI(), GetDeviceCaps(hdc, LOGPIXELSY) / engine.GetFileDPI()); bool bPrintPortrait = paperSize.dx < paperSize.dy; if (pd.devMode && (pd.devMode.Get()->dmFields & DM_ORIENTATION)) bPrintPortrait = DMORIENT_PORTRAIT == pd.devMode.Get()->dmOrientation; if (pd.sel.Count() > 0) { for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) { RectD bounds = BoundSelectionOnPage(pd.sel, pageNo); if (bounds.IsEmpty()) continue; if (progressUI) progressUI->UpdateProgress(current, total); StartPage(hdc); SizeT<float> bSize = bounds.Size().Convert<float>(); float zoom = min((float)printable.dx / bSize.dx, (float)printable.dy / bSize.dy); // use the correct zoom values, if the page fits otherwise // and the user didn't ask for anything else (default setting) if (PrintScaleShrink == pd.advData.scale) zoom = min(dpiFactor, zoom); else if (PrintScaleNone == pd.advData.scale) zoom = dpiFactor; for (size_t i = 0; i < pd.sel.Count(); i++) { if (pd.sel.At(i).pageNo != pageNo) continue; RectD *clipRegion = &pd.sel.At(i).rect; PointI offset((int)((clipRegion->x - bounds.x) * zoom), (int)((clipRegion->y - bounds.y) * zoom)); if (!pd.advData.asImage) { RectI rc((int)(printable.dx - bSize.dx * zoom) / 2 + offset.x, (int)(printable.dy - bSize.dy * zoom) / 2 + offset.y, (int)(clipRegion->dx * zoom), (int)(clipRegion->dy * zoom)); engine.RenderPage(hdc, rc, pd.sel.At(i).pageNo, zoom, pd.rotation, clipRegion, Target_Print, abortCookie ? &abortCookie->cookie : NULL); if (abortCookie) abortCookie->Clear(); } else { RenderedBitmap *bmp = NULL; short shrink = 1; do { bmp = engine.RenderBitmap(pd.sel.At(i).pageNo, zoom / shrink, pd.rotation, clipRegion, Target_Print, abortCookie ? &abortCookie->cookie : NULL); if (abortCookie) abortCookie->Clear(); if (!bmp || !bmp->GetBitmap()) { shrink *= 2; delete bmp; bmp = NULL; } } while (!bmp && shrink < 32 && !(progressUI && progressUI->WasCanceled())); if (bmp) { RectI rc((int)(paperSize.dx - bSize.dx * zoom) / 2 + offset.x, (int)(paperSize.dy - bSize.dy * zoom) / 2 + offset.y, bmp->Size().dx * shrink, bmp->Size().dy * shrink); bmp->StretchDIBits(hdc, rc); delete bmp; } } } if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) { AbortDoc(hdc); return false; } current++; } EndDoc(hdc); return false; } // print all the pages the user requested for (size_t i = 0; i < pd.ranges.Count(); i++) { int dir = pd.ranges.At(i).nFromPage > pd.ranges.At(i).nToPage ? -1 : 1; for (DWORD pageNo = pd.ranges.At(i).nFromPage; pageNo != pd.ranges.At(i).nToPage + dir; pageNo += dir) { if ((PrintRangeEven == pd.advData.range && pageNo % 2 != 0) || (PrintRangeOdd == pd.advData.range && pageNo % 2 == 0)) continue; if (progressUI) progressUI->UpdateProgress(current, total); StartPage(hdc); SizeT<float> pSize = engine.PageMediabox(pageNo).Size().Convert<float>(); int rotation = 0; // Turn the document by 90 deg if it isn't in portrait mode if (pSize.dx > pSize.dy) { rotation += 90; swap(pSize.dx, pSize.dy); } // make sure not to print upside-down rotation = (rotation % 180) == 0 ? 0 : 270; // finally turn the page by (another) 90 deg in landscape mode if (!bPrintPortrait) { rotation = (rotation + 90) % 360; swap(pSize.dx, pSize.dy); } // dpiFactor means no physical zoom float zoom = dpiFactor; // offset of the top-left corner of the page from the printable area // (negative values move the page into the left/top margins, etc.); // offset adjustments are needed because the GDI coordinate system // starts at the corner of the printable area and we rather want to // center the page on the physical paper (default behavior) PointI offset(-printable.x, -printable.y); if (pd.advData.scale != PrintScaleNone) { // make sure to fit all content into the printable area when scaling // and the whole document page on the physical paper RectD rect = engine.PageContentBox(pageNo, Target_Print); RectT<float> cbox = engine.Transform(rect, pageNo, 1.0, rotation).Convert<float>(); zoom = min((float)printable.dx / cbox.dx, min((float)printable.dy / cbox.dy, min((float)paperSize.dx / pSize.dx, (float)paperSize.dy / pSize.dy))); // use the correct zoom values, if the page fits otherwise // and the user didn't ask for anything else (default setting) if (PrintScaleShrink == pd.advData.scale && dpiFactor < zoom) zoom = dpiFactor; // make sure that no content lies in the non-printable paper margins RectT<float> onPaper((paperSize.dx - pSize.dx * zoom) / 2 + cbox.x * zoom, (paperSize.dy - pSize.dy * zoom) / 2 + cbox.y * zoom, cbox.dx * zoom, cbox.dy * zoom); if (onPaper.x < printable.x) offset.x += (int)(printable.x - onPaper.x); else if (onPaper.BR().x > printable.BR().x) offset.x -= (int)(onPaper.BR().x - printable.BR().x); if (onPaper.y < printable.y) offset.y += (int)(printable.y - onPaper.y); else if (onPaper.BR().y > printable.BR().y) offset.y -= (int)(onPaper.BR().y - printable.BR().y); } if (!pd.advData.asImage) { RectI rc = RectI::FromXY((int)(paperSize.dx - pSize.dx * zoom) / 2 + offset.x, (int)(paperSize.dy - pSize.dy * zoom) / 2 + offset.y, paperSize.dx, paperSize.dy); engine.RenderPage(hdc, rc, pageNo, zoom, rotation, NULL, Target_Print, abortCookie ? &abortCookie->cookie : NULL); if (abortCookie) abortCookie->Clear(); } else { RenderedBitmap *bmp = NULL; short shrink = 1; do { bmp = engine.RenderBitmap(pageNo, zoom / shrink, rotation, NULL, Target_Print, abortCookie ? &abortCookie->cookie : NULL); if (abortCookie) abortCookie->Clear(); if (!bmp || !bmp->GetBitmap()) { shrink *= 2; delete bmp; bmp = NULL; } } while (!bmp && shrink < 32 && !(progressUI && progressUI->WasCanceled())); if (bmp) { RectI rc((paperSize.dx - bmp->Size().dx * shrink) / 2 + offset.x, (paperSize.dy - bmp->Size().dy * shrink) / 2 + offset.y, bmp->Size().dx * shrink, bmp->Size().dy * shrink); bmp->StretchDIBits(hdc, rc); delete bmp; } } if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) { AbortDoc(hdc); return false; } current++; } } EndDoc(hdc); return true; }
void DocReport::NextPage() { EndPage(); WhenNewPage(); StartPage(); }
BOOL SciEdit::Print(LPCTSTR szTitle) { // Mostly taken from Notepad2 http://www.flos-freeware.ch // Don't print empty documents if (Call(SCI_GETLENGTH, 0, 0) == 0) { return FALSE; } int startPos; int endPos; HDC hdc; RECT rectMargins; RECT rectPhysMargins; POINT ptPage; POINT ptDpi; TEXTMETRIC tm; int headerLineHeight; int footerLineHeight; HFONT fontFooter; char dateString[256]; DOCINFO di = {sizeof(DOCINFO), 0, 0, 0, 0}; LONG lengthDoc; LONG lengthDocMax; LONG lengthPrinted; struct RangeToFormat frPrint; int pageNum; BOOL printPage; char pageString[32]; HPEN pen; HPEN penOld; PRINTDLG pdlg = { sizeof(PRINTDLG), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; pdlg.hwndOwner = GetParent(m_hwndEditor); pdlg.hInstance = m_hInst; pdlg.Flags = PD_USEDEVMODECOPIES | PD_ALLPAGES | PD_RETURNDC; pdlg.nFromPage = 1; pdlg.nToPage = 1; pdlg.nMinPage = 1; pdlg.nMaxPage = 0xffffU; pdlg.nCopies = 1; pdlg.hDC = 0; pdlg.hDevMode = hDevMode; pdlg.hDevNames = hDevNames; startPos = Call(SCI_GETSELECTIONSTART, 0, 0); endPos = Call(SCI_GETSELECTIONEND, 0, 0); if (startPos == endPos) { pdlg.Flags |= PD_NOSELECTION; } else { pdlg.Flags |= PD_SELECTION; } if (1) { // Don't display dialog box, just use the default printer and options pdlg.Flags |= PD_RETURNDEFAULT; } if (!PrintDlg(&pdlg)) { return TRUE; // False means error... } hDevMode = pdlg.hDevMode; hDevNames = pdlg.hDevNames; hdc = pdlg.hDC; // Get printer resolution ptDpi.x = GetDeviceCaps(hdc, LOGPIXELSX); // dpi in X direction ptDpi.y = GetDeviceCaps(hdc, LOGPIXELSY); // dpi in Y direction // Start by getting the physical page size (in device units). ptPage.x = GetDeviceCaps(hdc, PHYSICALWIDTH); // device units ptPage.y = GetDeviceCaps(hdc, PHYSICALHEIGHT); // device units // Get the dimensions of the unprintable // part of the page (in device units). rectPhysMargins.left = GetDeviceCaps(hdc, PHYSICALOFFSETX); rectPhysMargins.top = GetDeviceCaps(hdc, PHYSICALOFFSETY); // To get the right and lower unprintable area, // we take the entire width and height of the paper and // subtract everything else. rectPhysMargins.right = ptPage.x // total paper width - GetDeviceCaps(hdc, HORZRES) // printable width - rectPhysMargins.left; // left unprintable margin rectPhysMargins.bottom = ptPage.y // total paper height - GetDeviceCaps(hdc, VERTRES) // printable height - rectPhysMargins.top; // right unprintable margin // At this point, rectPhysMargins contains the widths of the // unprintable regions on all four sides of the page in device units. rectMargins.left = rectPhysMargins.left; rectMargins.top = rectPhysMargins.top; rectMargins.right = rectPhysMargins.right; rectMargins.bottom = rectPhysMargins.bottom; // rectMargins now contains the values used to shrink the printable // area of the page. // Convert device coordinates into logical coordinates DPtoLP(hdc, (LPPOINT)&rectMargins, 2); DPtoLP(hdc, (LPPOINT)&rectPhysMargins, 2); // Convert page size to logical units and we're done! DPtoLP(hdc, (LPPOINT) &ptPage, 1); // Leave blank headerLineHeight = 0; footerLineHeight = MulDiv(7,ptDpi.y, 72); fontFooter = CreateFont(footerLineHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); SelectObject(hdc, fontFooter); GetTextMetrics(hdc, &tm); footerLineHeight = tm.tmHeight + tm.tmExternalLeading; di.lpszDocName = szTitle; di.lpszOutput = 0; di.lpszDatatype = 0; di.fwType = 0; if (StartDoc(hdc, &di) < 0) { DeleteDC(hdc); if (fontFooter) DeleteObject(fontFooter); return FALSE; } // Get current date... SYSTEMTIME st; GetLocalTime(&st); GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,dateString,256); // Set print color mode int printColorModes[5] = { SC_PRINT_NORMAL, SC_PRINT_INVERTLIGHT, SC_PRINT_BLACKONWHITE, SC_PRINT_COLOURONWHITE, SC_PRINT_COLOURONWHITEDEFAULTBG }; Call(SCI_SETPRINTCOLOURMODE, printColorModes[0], 0); // Set print zoom... Call(SCI_SETPRINTMAGNIFICATION, (WPARAM)0, 0); lengthDoc = Call(SCI_GETLENGTH, 0, 0); lengthDocMax = lengthDoc; lengthPrinted = 0; // Requested to print selection if (pdlg.Flags & PD_SELECTION) { if (startPos > endPos) { lengthPrinted = endPos; lengthDoc = startPos; } else { lengthPrinted = startPos; lengthDoc = endPos; } if (lengthPrinted < 0) lengthPrinted = 0; if (lengthDoc > lengthDocMax) lengthDoc = lengthDocMax; } // We must substract the physical margins from the printable area frPrint.hdc = hdc; frPrint.hdcTarget = hdc; frPrint.rc.left = rectMargins.left - rectPhysMargins.left; frPrint.rc.top = rectMargins.top - rectPhysMargins.top; frPrint.rc.right = ptPage.x - rectMargins.right - rectPhysMargins.left; frPrint.rc.bottom = ptPage.y - rectMargins.bottom - rectPhysMargins.top; frPrint.rcPage.left = 0; frPrint.rcPage.top = 0; frPrint.rcPage.right = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1; frPrint.rcPage.bottom = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1; frPrint.rc.top += headerLineHeight + headerLineHeight / 2; frPrint.rc.bottom -= footerLineHeight + footerLineHeight / 2; // Print each page pageNum = 1; WaitCursor wait; while (lengthPrinted < lengthDoc) { printPage = (!(pdlg.Flags & PD_PAGENUMS) || (pageNum >= pdlg.nFromPage) && (pageNum <= pdlg.nToPage)); sprintf_s(pageString, "Page %d", pageNum); if (printPage) { StartPage(hdc); SetTextColor(hdc, RGB(0,0,0)); SetBkColor(hdc, RGB(255,255,255)); UINT ta = SetTextAlign(hdc, TA_BOTTOM); RECT rcw = {frPrint.rc.left, frPrint.rc.top - headerLineHeight - headerLineHeight / 2, frPrint.rc.right, frPrint.rc.top - headerLineHeight / 2}; rcw.bottom = rcw.top + headerLineHeight; } frPrint.chrg.cpMin = lengthPrinted; frPrint.chrg.cpMax = lengthDoc; lengthPrinted = Call(SCI_FORMATRANGE, printPage, (LPARAM)&frPrint); if (printPage) { SetTextColor(hdc, RGB(0,0,0)); SetBkColor(hdc, RGB(255,255,255)); SelectObject(hdc, fontFooter); UINT ta = SetTextAlign(hdc, TA_TOP); RECT rcw = {frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 2, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight + footerLineHeight / 2}; // Frint Footer Page num SIZE sizeFooter; GetTextExtentPoint32(hdc,pageString,lstrlen(pageString),&sizeFooter); ExtTextOut(hdc, frPrint.rc.right - 5 - sizeFooter.cx, frPrint.rc.bottom + footerLineHeight / 2, /*ETO_OPAQUE*/0, &rcw, pageString, lstrlen(pageString), NULL); SetTextAlign(hdc, ta); pen = ::CreatePen(0, 1, RGB(0,0,0)); penOld = (HPEN)SelectObject(hdc, pen); SetBkColor(hdc, RGB(0,0,0)); MoveToEx(hdc, frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 4, NULL); LineTo(hdc, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight / 4); SelectObject(hdc, penOld); DeleteObject(pen); EndPage(hdc); } pageNum++; if ((pdlg.Flags & PD_PAGENUMS) && (pageNum > pdlg.nToPage)) break; } Call(SCI_FORMATRANGE, FALSE, 0); EndDoc(hdc); DeleteDC(hdc); if (fontFooter) DeleteObject(fontFooter); return TRUE; }
DocReport& DocReport::SetPageSize(int cx, int cy) { pgsz = Size(cx, cy); StartPage(); return *this; }
BOOL KCanvasWindow::Print(void) { HDC hDCPrinter; int iEntries; if (hMetaFile == NULL) return FALSE; // if (SpoolFile.PlaySpoolFile(CurEmfFileName, NULL, NULL, NULL)) // return TRUE; { PRINTDLG pd; memset(&pd, 0, sizeof(pd)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = m_hWnd; pd.Flags = PD_RETURNDC; pd.hInstance = hInstance; if (!PrintDlg(&pd) || (pd.hDC==NULL)) return FALSE; hDCPrinter = pd.hDC; } // EmfScope.UnlinkClientServer(); { DOCINFO DocInfo; char title[128]; // put a special tag before the title so spehon32 can ignore it strcpy(title, ItsMe); GetEnhMetaFileDescription(hMetaFile, sizeof(title)-strlen(title), title+strlen(title)); memset(&DocInfo, 0, sizeof(DocInfo)); DocInfo.cbSize = sizeof(DOCINFO); DocInfo.lpszDocName = title; DocInfo.lpszOutput = NULL; StartDoc(hDCPrinter, &DocInfo); } StartPage(hDCPrinter); iEntries = GetEnhMetaFilePaletteEntries(hMetaFile, 0, NULL); if (iEntries) { PLOGPALETTE plogPal; PBYTE pjTmp; HPALETTE hPal; if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { MessageBox(m_hWnd, "Failed in Creating Palette!", "Error", MB_OK); } plogPal->palVersion = 0x300; plogPal->palNumEntries = (WORD) iEntries; pjTmp = (PBYTE) plogPal; pjTmp += 8; GetEnhMetaFilePaletteEntries(hMetaFile, iEntries, (PPALETTEENTRY)pjTmp); hPal = CreatePalette(plogPal); GlobalFree(plogPal); SelectPalette(hDCPrinter, hPal, FALSE); RealizePalette(hDCPrinter); } { RECT rc; ENHMETAHEADER EnhMetaHdr; GetEnhMetaFileHeader(hMetaFile, sizeof(ENHMETAHEADER), &EnhMetaHdr); rc.top = 0; rc.left = 0; rc.right = EnhMetaHdr.szlDevice.cx; rc.bottom = EnhMetaHdr.szlDevice.cy; if (!PlayEnhMetaFile(hDCPrinter, hMetaFile, &rc)) { char text[128]; wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); MessageBox(0, text, "Play", MB_OK); } } EndPage(hDCPrinter); EndDoc(hDCPrinter); // EmfScope.LinkClientServer(); return TRUE; }