Permalink
Browse files

ugrr... Fixing printing scaling again.

Not the nicest fix, but it should do the job. Now, we'll try to use default scaling (72dpi) whenever we can.
If sceen resolution droped below the point where metafile can't accomodate whole PDF page anymore, we'll use this
hack to pass custom scale in the TLS for the upper layer.

BUG=125499
TEST=Print PDF using print preview and system print dialog. Same for webpage. Make screen resolution 800x600 and repeat.

Review URL: http://codereview.chromium.org/10348002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135241 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information...
1 parent 218a590 commit f99414401f2a423c8662576e0f0d6c69f6f968f1 gene@chromium.org committed May 3, 2012
@@ -12,6 +12,7 @@
#include "base/win/scoped_hdc.h"
#include "base/win/scoped_select_object.h"
#include "chrome/common/print_messages.h"
+#include "printing/custom_scaling.h"
#include "printing/metafile.h"
#include "printing/metafile_impl.h"
#include "printing/metafile_skia_wrapper.h"
@@ -114,46 +115,44 @@ void PrintWebViewHelper::PrintPageInternal(
// actual printing.
double actual_shrink = static_cast<float>(params.params.desired_dpi /
params.params.dpi);
- if (print_for_preview_) {
- // While printing from the preview, we are using PDF to print.
- // It creates a temp metafile based on screen DC. The standard scale factor
- // may not fit an entire content of the PDF to the metafile. It will cause
- // output to be cutoff.
- // (See http://code.google.com/p/chromium-os/issues/detail?id=16088 and
- // related Chrome bugs)
- // In such case we need to calculate the same scale ratio PDF plugin will
- // calculate during printing.
- // TODO(gene): Revisit current implementation and address comments below.
- // (http://code.google.com/p/chromium/issues/detail?id=123408)
- // Ideally, we should return this parameter from the plugin to avoid code
- // duplication. However, currently the call stack involves WebKit and at
- // some point shrink factor was cutoff and always returns 1.0.
- // webkit::ppapi::PluginInstance::PrintPDFOutput - ratio calculated here
- // webkit::ppapi::PluginInstance::PrintPageHelper
- // webkit::ppapi::PluginInstance::PrintPage
- // webkit::ppapi::WebPluginImpl::printPage
- // WebKit::WebPluginContainerImpl::printPage
- // WebKit::ChromePluginPrintContext::spoolPage - always return 1.0 scale
- // WebKit::WebFrameImpl::printPage
- // PrintWebViewHelper::RenderPage
- // PrintWebViewHelper::PrintPageInternal
- //
- // Another solution is to build in scaling factor into metafile itself
- // (for example, GDI comments), and make metafile playback to take care of
- // scaling automatically.
- actual_shrink = gfx::CalculatePageScale(
- metafile->context(),
- params.params.content_size.width(),
- params.params.content_size.height());
- }
-
gfx::Size page_size_in_dpi;
gfx::Rect content_area_in_dpi;
+
+ // If we are printing PDF, it may not fit into metafile using 72dpi.
+ // (Metafile is based on screen resolution here.)
+ // (See http://code.google.com/p/chromium-os/issues/detail?id=16088)
+ // If PDF plugin encounter this issue it will save custom scale in TLS,
+ // so we can apply the same scaling factor here.
+ // If will do so ONLY if default scaling does not work.
+ // TODO(gene): We should revisit this solution for the next versions.
+ // Two possible solutions:
+ // We can create metafile of the right size (or resizable)
+ // https://code.google.com/p/chromium/issues/detail?id=126037
+ // or
+ // We should return scale factor all the way from the plugin:
+ // webkit::ppapi::PluginInstance::PrintPDFOutput - scale calculated here
+ // webkit::ppapi::PluginInstance::PrintPageHelper
+ // webkit::ppapi::PluginInstance::PrintPage
+ // webkit::ppapi::WebPluginImpl::printPage
+ // WebKit::WebPluginContainerImpl::printPage
+ // WebKit::ChromePluginPrintContext::spoolPage - always return 1.0 scale
+ // WebKit::WebFrameImpl::printPage
+ // PrintWebViewHelper::RenderPage
+ // PrintWebViewHelper::PrintPageInternal
+
+ printing::ClearCustomPrintingPageScale();
+
// Render page for printing.
metafile.reset(RenderPage(params.params, page_number, frame, false,
metafile.get(), &actual_shrink, &page_size_in_dpi,
&content_area_in_dpi));
+ double custom_scale;
+ if (printing::GetCustomPrintingPageScale(&custom_scale)) {
+ actual_shrink = custom_scale;
+ printing::ClearCustomPrintingPageScale();
+ }
+
// Close the device context to retrieve the compiled metafile.
if (!metafile->FinishDocument())
NOTREACHED();
View
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "printing/custom_scaling.h"
+
+#include "base/threading/thread_local.h"
+
+namespace printing {
+
+static base::ThreadLocalPointer<double> gPrintingPageScale;
+
+bool GetCustomPrintingPageScale(double* scale) {
+ double* ptr = gPrintingPageScale.Get();
+ if (ptr != NULL) {
+ *scale = *ptr;
+ }
+ return ptr != NULL;
+}
+
+void SetCustomPrintingPageScale(double scale) {
+ ClearCustomPrintingPageScale();
+ double* ptr = new double;
+ *ptr = scale;
+ gPrintingPageScale.Set(ptr);
+}
+
+void ClearCustomPrintingPageScale() {
+ double* ptr = gPrintingPageScale.Get();
+ if (ptr != NULL) {
+ delete ptr;
+ }
+ gPrintingPageScale.Set(NULL);
+}
+
+} // namespace printing
+
View
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PRINTING_CUSTOM_SCALING_H_
+#define PRINTING_CUSTOM_SCALING_H_
+
+#include "printing/printing_export.h"
+
+namespace printing {
+
+// This set of function allows plugin to set custom printing scale in the
+// thread local storage. It is a hack to pass scale through this, but
+// alternative is to do major refactoring to pass this scale factor all the
+// from plugin through webkit to the upper level.
+// We should definitely revisit this approach in favor of better implementation
+// later. In the mean time, this looks like a simplest way fixing printing
+// issues now.
+
+// Gets custom printing scale from the TLS. Return false if it has not been
+// set.
+PRINTING_EXPORT bool GetCustomPrintingPageScale(double* scale);
+
+// Sets custom printing scale in TLS.
+PRINTING_EXPORT void SetCustomPrintingPageScale(double scale);
+
+// Clears custom printing scale in TLS.
+PRINTING_EXPORT void ClearCustomPrintingPageScale();
+
+} // namespace printing
+
+#endif // PRINTING_CUSTOM_SCALING_H_
+
View
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -32,6 +32,8 @@
'backend/print_backend_consts.cc',
'backend/print_backend_consts.h',
'backend/print_backend_dummy.cc',
+ 'custom_scaling.cc',
+ 'custom_scaling.h',
'emf_win.cc',
'emf_win.h',
'image.cc',
@@ -38,6 +38,7 @@
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_buffer_api.h"
+#include "printing/custom_scaling.h"
#include "printing/units.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRect.h"
@@ -1468,14 +1469,26 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output,
static_cast<int>(printing::kPointsPerInch),
current_print_settings_.dpi));
// We need to scale down DC to fit an entire page into DC available area.
+ // First, we'll try to use default scaling based on the 72dpi that is
+ // used in webkit for printing.
+ // If default scaling is not enough to fit the entire PDF without
// Current metafile is based on screen DC and have current screen size.
// Writing outside of those boundaries will result in the cut-off output.
// On metafiles (this is the case here), scaling down will still record
// original coordinates and we'll be able to print in full resolution.
// Before playback we'll need to counter the scaling up that will happen
// in the browser (printed_document_win.cc).
- gfx::ScaleDC(dc, gfx::CalculatePageScale(dc, size_in_pixels.width(),
- size_in_pixels.height()));
+ double dynamic_scale = gfx::CalculatePageScale(dc, size_in_pixels.width(),
+ size_in_pixels.height());
+ double page_scale = static_cast<double>(printing::kPointsPerInch) /
+ static_cast<double>(current_print_settings_.dpi);
+
+ if (dynamic_scale < page_scale) {
+ page_scale = dynamic_scale;
+ printing::SetCustomPrintingPageScale(page_scale);
+ }
+
+ gfx::ScaleDC(dc, page_scale);
ret = render_proc(static_cast<unsigned char*>(mapper.data()), mapper.size(),
0, dc, current_print_settings_.dpi,

0 comments on commit f994144

Please sign in to comment.