15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_document.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/page_number.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_pages_source.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_page.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/units.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_device.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimpleModifyWorldTransform(HDC context,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int offset_x,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int offset_y,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                double shrink_factor) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XFORM xform = { 0 };
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xform.eDx = static_cast<float>(offset_x);
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xform.eDy = static_cast<float>(offset_y);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xform.eM11 = xform.eM22 = static_cast<float>(1. / shrink_factor);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BOOL res = ModifyWorldTransform(context, &xform, MWT_LEFTMULTIPLY);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(res, 0);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DrawRect(HDC context, gfx::Rect rect) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Rectangle(context, rect.x(), rect.y(), rect.right(), rect.bottom());
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintedDocument::RenderPrintedPage(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PrintedPage& page, gfx::NativeDrawingContext context) const {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the page is from our list.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(lock_);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(&page == mutable_.pages_.find(page.page_number() - 1)->second.get());
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PageSetup& page_setup(immutable_.settings_.page_setup_device_units());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect content_area;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page.GetCenteredPageContentRect(page_setup.physical_size(), &content_area);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the state to make sure the context this function call does not modify
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the device context.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int saved_state = SaveDC(context);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(saved_state, 0);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skia::InitializeDC(context);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save the state (again) to apply the necessary world transformation.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int saved_state = SaveDC(context);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(saved_state, 0);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Setup the matrix to translate and scale to the right place. Take in
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // account the actual shrinking factor.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that the printing output is relative to printable area of the page.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // That is 0,0 is offset by PHYSICALOFFSETX/Y from the page.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleModifyWorldTransform(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        context,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_area.x() - page_setup.printable_area().x(),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_area.y() - page_setup.printable_area().y(),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        page.shrink_factor());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ::StartPage(context);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!page.metafile()->SafePlayback(context)) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ::EndPage(context);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BOOL res = RestoreDC(context, saved_state);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(res, 0);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int res = RestoreDC(context, saved_state);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(res, 0);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
87