diff options
Diffstat (limited to 'printing')
-rw-r--r-- | printing/emf_win.cc | 85 | ||||
-rw-r--r-- | printing/print_settings.cc | 14 | ||||
-rw-r--r-- | printing/print_settings.h | 5 | ||||
-rw-r--r-- | printing/printed_document.cc | 3 | ||||
-rw-r--r-- | printing/printing_context.h | 4 |
5 files changed, 105 insertions, 6 deletions
diff --git a/printing/emf_win.cc b/printing/emf_win.cc index f69d4fa..62cc4a0 100644 --- a/printing/emf_win.cc +++ b/printing/emf_win.cc @@ -4,11 +4,29 @@ #include "printing/emf_win.h" +#include "app/gfx/codec/jpeg_codec.h" +#include "app/gfx/codec/png_codec.h" +#include "app/gfx/gdi_util.h" #include "base/gfx/rect.h" +#include "base/histogram.h" #include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/time.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace printing { +bool DIBFormatNativelySupported(HDC dc, uint32 escape, const BYTE* bits, + int size) { + BOOL supported = FALSE; + if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), + reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { + ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), + sizeof(supported), reinterpret_cast<LPSTR>(&supported)); + } + return !!supported; +} + Emf::Emf() : emf_(NULL), hdc_(NULL) { } @@ -65,7 +83,6 @@ bool Emf::SafePlayback(HDC context) const { NOTREACHED(); return false; } - return EnumEnhMetaFile(context, emf_, &Emf::SafePlaybackProc, @@ -209,9 +226,75 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { // I also use this opportunity to skip over eventual EMR_SETLAYOUT record that // could remain. // + // Another tweak we make is for JPEGs/PNGs in calls to StretchDIBits. + // (Our Pepper plugin code uses a JPEG). If the printer does not support + // JPEGs/PNGs natively we decompress the JPEG/PNG and then set it to the + // device. + // TODO(sanjeevr): We should also add JPEG/PNG support for SetSIBitsToDevice + // // Note: I should probably care about view ports and clipping, eventually. bool res; switch (record()->iType) { + case EMR_STRETCHDIBITS: { + const EMRSTRETCHDIBITS * sdib_record = + reinterpret_cast<const EMRSTRETCHDIBITS*>(record()); + const BYTE* record_start = reinterpret_cast<const BYTE *>(record()); + const BITMAPINFOHEADER *bmih = + reinterpret_cast<const BITMAPINFOHEADER *>(record_start + + sdib_record->offBmiSrc); + const BYTE* bits = record_start + sdib_record->offBitsSrc; + bool play_normally = true; + res = false; + HDC hdc = context_->hdc; + scoped_ptr<SkBitmap> bitmap; + if (bmih->biCompression == BI_JPEG) { + if (!DIBFormatNativelySupported(hdc, CHECKJPEGFORMAT, bits, + bmih->biSizeImage)) { + play_normally = false; + base::TimeTicks start_time = base::TimeTicks::Now(); + bitmap.reset(gfx::JPEGCodec::Decode(bits, bmih->biSizeImage)); + UMA_HISTOGRAM_TIMES("Printing.JPEGDecompressTime", + base::TimeTicks::Now() - start_time); + } + } else if (bmih->biCompression == BI_PNG) { + if (!DIBFormatNativelySupported(hdc, CHECKPNGFORMAT, bits, + bmih->biSizeImage)) { + play_normally = false; + bitmap.reset(new SkBitmap()); + base::TimeTicks start_time = base::TimeTicks::Now(); + gfx::PNGCodec::Decode(bits, bmih->biSizeImage, bitmap.get()); + UMA_HISTOGRAM_TIMES("Printing.PNGDecompressTime", + base::TimeTicks::Now() - start_time); + } + } + if (!play_normally) { + DCHECK(bitmap.get()); + if (bitmap.get()) { + SkAutoLockPixels lock(*bitmap.get()); + DCHECK_EQ(bitmap->getConfig(), SkBitmap::kARGB_8888_Config); + const uint32_t* pixels = + static_cast<const uint32_t*>(bitmap->getPixels()); + if (pixels == NULL) { + NOTREACHED(); + return false; + } + BITMAPINFOHEADER bmi = {0}; + gfx::CreateBitmapHeader(bitmap->width(), bitmap->height(), &bmi); + res = (0 != StretchDIBits(hdc, sdib_record->xDest, sdib_record->yDest, + sdib_record->cxDest, + sdib_record->cyDest, sdib_record->xSrc, + sdib_record->ySrc, + sdib_record->cxSrc, sdib_record->cySrc, + pixels, + reinterpret_cast<const BITMAPINFO *>(&bmi), + sdib_record->iUsageSrc, + sdib_record->dwRop)); + } + } else { + res = Play(); + } + break; + } case EMR_SETWORLDTRANSFORM: { DCHECK_EQ(record()->nSize, sizeof(DWORD) * 2 + sizeof(XFORM)); const XFORM* xform = reinterpret_cast<const XFORM*>(record()->dParm); diff --git a/printing/print_settings.cc b/printing/print_settings.cc index 4764952..77c4049 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc @@ -19,6 +19,7 @@ PrintSettings::PrintSettings() max_shrink(2.0), desired_dpi(72), selection_only(false), + use_overlays(true), dpi_(0), landscape_(false) { } @@ -120,16 +121,19 @@ void PrintSettings::SetPrinterPrintableArea( gfx::Size const& physical_size_pixels, gfx::Rect const& printable_area_pixels) { - // Hard-code text_height = 0.5cm = ~1/5 of inch. - int header_footer_text_height = ConvertUnit(500, kHundrethsMMPerInch, dpi_); - + int header_footer_text_height = 0; + int margin_printer_units = 0; + if (use_overlays) { + // Hard-code text_height = 0.5cm = ~1/5 of inch. + header_footer_text_height = ConvertUnit(500, kHundrethsMMPerInch, dpi_); + // Default margins 1.0cm = ~2/5 of an inch. + margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch, dpi_); + } // Start by setting the user configuration page_setup_pixels_.Init(physical_size_pixels, printable_area_pixels, header_footer_text_height); - // Default margins 1.0cm = ~2/5 of an inch. - int margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch, dpi_); // Apply default margins (not user configurable just yet). // Since the font height is half the margin we put the header and footers at diff --git a/printing/print_settings.h b/printing/print_settings.h index dd90007f..b5bb723 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h @@ -85,6 +85,11 @@ class PrintSettings { // Indicates if the user only wants to print the current selection. bool selection_only; + // Indicates whether we should use browser-controlled page overlays + // (header, footer, margins etc). If it is false, the overlays are + // controlled by the renderer. + bool use_overlays; + // Cookie generator. It is used to initialize PrintedDocument with its // associated PrintSettings, to be sure that each generated PrintedPage is // correctly associated with its corresponding PrintedDocument. diff --git a/printing/printed_document.cc b/printing/printed_document.cc index 5f5f53c..7857859 100644 --- a/printing/printed_document.cc +++ b/printing/printed_document.cc @@ -180,6 +180,9 @@ void PrintedDocument::PrintHeaderFooter(gfx::NativeDrawingContext context, PageOverlays::VerticalPosition y, const gfx::Font& font) const { const PrintSettings& settings = immutable_.settings_; + if (!settings.use_overlays) { + return; + } const std::wstring& line = settings.overlays.GetOverlay(x, y); if (line.empty()) { return; diff --git a/printing/printing_context.h b/printing/printing_context.h index 29c9478..a931c8b 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h @@ -54,6 +54,10 @@ class PrintingContext { // default device settings. Result UseDefaultSettings(); + void SetUseOverlays(bool use_overlays) { + settings_.use_overlays = use_overlays; + } + // Initializes with predefined settings. Result InitWithSettings(const PrintSettings& settings); |