diff options
-rw-r--r-- | chrome/browser/resources/print_preview/print_preview.css | 8 | ||||
-rw-r--r-- | chrome/browser/resources/print_preview/print_preview.html | 2 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 176 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 6 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_linux.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_mac.mm | 38 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_win.cc | 2 | ||||
-rw-r--r-- | printing/print_job_constants.cc | 4 | ||||
-rw-r--r-- | printing/print_job_constants.h | 1 |
9 files changed, 170 insertions, 69 deletions
diff --git a/chrome/browser/resources/print_preview/print_preview.css b/chrome/browser/resources/print_preview/print_preview.css index 61a9915..96a0776 100644 --- a/chrome/browser/resources/print_preview/print_preview.css +++ b/chrome/browser/resources/print_preview/print_preview.css @@ -346,14 +346,6 @@ html[os=mac] input[type='checkbox']:checked::before { top: 2px; } -html[os=mac] #options-horizontal-separator { - display: none; -} - -html[os=mac] #options-option { - display: none; -} - input[type='radio'] { -webkit-box-shadow: inset 0 1px 2px white, 0 1px 2px rgba(0, 0, 0, .2); diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html index d29ebc5..eeb0d89 100644 --- a/chrome/browser/resources/print_preview/print_preview.html +++ b/chrome/browser/resources/print_preview/print_preview.html @@ -40,7 +40,7 @@ <include src="color_settings.html"></include> <hr> <include src="header_footer_settings.html"></include> - <hr id="options-horizontal-separator"> + <hr> <div id="system-dialog-div"> <button id="system-dialog-link" class="link-button" i18n-content="systemDialogOption"></button> diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 8d36b70..a0f58fd 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -4,12 +4,17 @@ #include "chrome/renderer/print_web_view_helper.h" +#if defined(OS_MACOSX) && !defined(USE_SKIA) +#include <CoreGraphics/CGContext.h> +#endif + #include <string> #include "base/command_line.h" #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/process_util.h" +#include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/print_messages.h" @@ -21,6 +26,8 @@ #include "printing/metafile_impl.h" #include "printing/print_job_constants.h" #include "printing/units.h" +#include "third_party/skia/include/core/SkRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" @@ -37,13 +44,18 @@ #endif #if defined(USE_SKIA) -#include "base/string_number_conversions.h" #include "skia/ext/vector_canvas.h" #include "skia/ext/vector_platform_device_skia.h" #include "third_party/skia/include/core/SkTypeface.h" -#endif // defined(USE_SKIA) +#elif defined(OS_MACOSX) +#include "base/mac/scoped_cftyperef.h" +#include "base/sys_string_conversions.h" +#include "ui/gfx/scoped_cg_context_save_gstate_mac.h" +#endif -using base::Time; +#if defined(OS_MACOSX) +using base::mac::ScopedCFTypeRef; +#endif using printing::ConvertPixelsToPoint; using printing::ConvertPixelsToPointDouble; using printing::ConvertUnit; @@ -61,8 +73,19 @@ using WebKit::WebView; namespace { +#if defined(USE_SKIA) +typedef SkPaint HeaderFooterPaint; +#elif defined(OS_MACOSX) +typedef CFDictionaryRef HeaderFooterPaint; +#endif + const double kMinDpi = 1.0; +#if defined(OS_MACOSX) && !defined(USE_SKIA) +const double kBlackGrayLevel = 0.0; +const double kOpaqueLevel = 1.0; +#endif // OS_MACOSX && !USE_SKIA + int GetDPI(const PrintMsg_Print_Params* print_params) { #if defined(OS_MACOSX) // On the Mac, the printable area is in points, don't do any scaling based @@ -115,24 +138,16 @@ void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params, print_params.desired_dpi)); } -#if defined(USE_SKIA) -// Given a text, the positions, and the paint object, this method gets the -// coordinates and prints the text at those coordinates on the canvas. -void PrintHeaderFooterText( - string16 text, - skia::VectorCanvas* canvas, - SkPaint paint, +// Get the (x, y) coordinate from where printing of the current text should +// start depending on the horizontal alignment (LEFT, RIGHT, CENTER) and +// vertical alignment (TOP, BOTTOM). +SkPoint GetHeaderFooterPosition( float webkit_scale_factor, const PageSizeMargins& page_layout, printing::HorizontalHeaderFooterPosition horizontal_position, printing::VerticalHeaderFooterPosition vertical_position, - SkScalar offset_to_baseline) { - size_t text_byte_length = text.length() * sizeof(char16); - // Get the (x, y) coordinate from where printing of the current text should - // start depending on the horizontal alignment (LEFT, RIGHT, CENTER) and - // vertical alignment (TOP, BOTTOM). - SkScalar text_width_in_points = paint.measureText(text.c_str(), - text_byte_length); + double offset_to_baseline, + double text_width_in_points) { SkScalar x = 0; switch (horizontal_position) { case printing::LEFT: { @@ -171,34 +186,95 @@ void PrintHeaderFooterText( NOTREACHED(); } - x = x / webkit_scale_factor; - y = y / webkit_scale_factor; - paint.setTextSize(paint.getTextSize() / webkit_scale_factor); - canvas->drawText(text.c_str(), text_byte_length, x, y, paint); + SkPoint point = SkPoint::Make(x / webkit_scale_factor, + y / webkit_scale_factor); + return point; +} + +// Given a text, the positions, and the paint object, this method gets the +// coordinates and prints the text at those coordinates on the canvas. +void PrintHeaderFooterText( + string16 text, + WebKit::WebCanvas* canvas, + HeaderFooterPaint paint, + float webkit_scale_factor, + const PageSizeMargins& page_layout, + printing::HorizontalHeaderFooterPosition horizontal_position, + printing::VerticalHeaderFooterPosition vertical_position, + double offset_to_baseline) { +#if defined(USE_SKIA) + size_t text_byte_length = text.length() * sizeof(char16); + double text_width_in_points = SkScalarToDouble(paint.measureText( + text.c_str(), text_byte_length)); + SkPoint point = GetHeaderFooterPosition(webkit_scale_factor, page_layout, + horizontal_position, + vertical_position, offset_to_baseline, + text_width_in_points); + paint.setTextSize(SkDoubleToScalar( + paint.getTextSize() / webkit_scale_factor)); + canvas->drawText(text.c_str(), text_byte_length, point.x(), point.y(), + paint); +#elif defined(OS_MACOSX) + ScopedCFTypeRef<CFStringRef> cf_text(base::SysUTF16ToCFStringRef(text)); + ScopedCFTypeRef<CFAttributedStringRef> cf_attr_text( + CFAttributedStringCreate(NULL, cf_text, paint)); + ScopedCFTypeRef<CTLineRef> line(CTLineCreateWithAttributedString( + cf_attr_text)); + double text_width_in_points = + CTLineGetTypographicBounds(line, NULL, NULL, NULL) * webkit_scale_factor; + SkPoint point = GetHeaderFooterPosition(webkit_scale_factor, + page_layout, horizontal_position, + vertical_position, offset_to_baseline, + text_width_in_points); + CGContextSetTextPosition(canvas, SkScalarToDouble(point.x()), + SkScalarToDouble(point.y())); + CTLineDraw(line, canvas); +#endif } -#endif // defined(USE_SKIA) } // namespace -#if defined(USE_SKIA) // static - Not anonymous so that platform implementations can use it. void PrintWebViewHelper::PrintHeaderAndFooter( - SkDevice* device, - skia::VectorCanvas* canvas, + WebKit::WebCanvas* canvas, int page_number, int total_pages, float webkit_scale_factor, const PageSizeMargins& page_layout, const DictionaryValue& header_footer_info) { - static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea( - SkPDFDevice::kMargin_DrawingArea); +#if defined(USE_SKIA) + skia::VectorPlatformDeviceSkia* device = + static_cast<skia::VectorPlatformDeviceSkia*>(canvas->getTopDevice()); + device->setDrawingArea(SkPDFDevice::kMargin_DrawingArea); SkPaint paint; paint.setColor(SK_ColorBLACK); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - paint.setTextSize(printing::kSettingHeaderFooterFontSize); + paint.setTextSize(SkDoubleToScalar(printing::kSettingHeaderFooterFontSize)); paint.setTypeface(SkTypeface::CreateFromName( printing::kSettingHeaderFooterFontFamilyName, SkTypeface::kNormal)); +#elif defined(OS_MACOSX) + gfx::ScopedCGContextSaveGState CGContextSaveGState(canvas); + CGContextSetCharacterSpacing(canvas, + printing::kSettingHeaderFooterCharacterSpacing); + CGContextSetTextDrawingMode(canvas, kCGTextFill); + CGContextSetGrayFillColor(canvas, kBlackGrayLevel, kOpaqueLevel); + CGContextSelectFont(canvas, printing::kSettingHeaderFooterFontName, + printing::kSettingHeaderFooterFontSize, + kCGEncodingFontSpecific); + ScopedCFTypeRef<CFStringRef> font_name(base::SysUTF8ToCFStringRef( + printing::kSettingHeaderFooterFontName)); + // Flip the text (makes it appear upright as we would expect it to). + const CGAffineTransform flip_text = CGAffineTransformMakeScale(1.0f, -1.0f); + ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithName( + font_name, + printing::kSettingHeaderFooterFontSize / webkit_scale_factor, + &flip_text)); + const void* keys[] = {kCTFontAttributeName}; + const void* values[] = {ct_font}; + ScopedCFTypeRef<CFDictionaryRef> paint(CFDictionaryCreate( + NULL, keys, values, sizeof(keys) / sizeof(keys[0]), NULL, NULL)); +#endif // Print the headers onto the |canvas| if there is enough space to print // them. @@ -212,17 +288,25 @@ void PrintWebViewHelper::PrintHeaderAndFooter( } string16 header_text = date + title; - SkRect header_bounds; + // Used for height calculations. Note that the width may be undefined. + SkRect header_vertical_bounds; +#if defined(USE_SKIA) paint.measureText(header_text.c_str(), header_text.length() * sizeof(char16), - &header_bounds, 0); - SkScalar text_height = - printing::kSettingHeaderFooterInterstice + header_bounds.height(); + &header_vertical_bounds, 0); +#elif defined(OS_MACOSX) + header_vertical_bounds.fTop = CTFontGetAscent(ct_font) * webkit_scale_factor; + header_vertical_bounds.fBottom = -CTFontGetDescent(ct_font) * + webkit_scale_factor; +#endif + double text_height = printing::kSettingHeaderFooterInterstice + + header_vertical_bounds.height(); if (text_height <= page_layout.margin_top) { PrintHeaderFooterText(date, canvas, paint, webkit_scale_factor, page_layout, - printing::LEFT, printing::TOP, header_bounds.top()); + printing::LEFT, printing::TOP, + header_vertical_bounds.top()); PrintHeaderFooterText(title, canvas, paint, webkit_scale_factor, page_layout, printing::CENTER, printing::TOP, - header_bounds.top()); + header_vertical_bounds.top()); } // Prints the footers onto the |canvas| if there is enough space to print @@ -237,24 +321,30 @@ void PrintWebViewHelper::PrintHeaderAndFooter( } string16 footer_text = page_of_total_pages + url; - SkRect footer_bounds; + // Used for height calculations. Note that the width may be undefined. + SkRect footer_vertical_bounds; +#if defined(USE_SKIA) paint.measureText(footer_text.c_str(), footer_text.length() * sizeof(char16), - &footer_bounds, 0); - text_height = - printing::kSettingHeaderFooterInterstice + footer_bounds.height(); + &footer_vertical_bounds, 0); +#elif defined(OS_MACOSX) + footer_vertical_bounds.fTop = header_vertical_bounds.fTop; + footer_vertical_bounds.fBottom = header_vertical_bounds.fBottom; +#endif + text_height = printing::kSettingHeaderFooterInterstice + + footer_vertical_bounds.height(); if (text_height <= page_layout.margin_bottom) { PrintHeaderFooterText(page_of_total_pages, canvas, paint, webkit_scale_factor, page_layout, printing::RIGHT, - printing::BOTTOM, footer_bounds.bottom()); + printing::BOTTOM, footer_vertical_bounds.bottom()); PrintHeaderFooterText(url, canvas, paint, webkit_scale_factor, page_layout, printing::LEFT, printing::BOTTOM, - footer_bounds.bottom()); + footer_vertical_bounds.bottom()); } - static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea( - SkPDFDevice::kContent_DrawingArea); +#if defined(USE_SKIA) + device->setDrawingArea(SkPDFDevice::kContent_DrawingArea); +#endif } -#endif // defined(USE_SKIA) PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( const PrintMsg_Print_Params& print_params, diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index cc04bd3..c4aea91 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -16,6 +16,7 @@ #include "content/renderer/render_view_observer_tracker.h" #include "printing/metafile.h" #include "printing/metafile_impl.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebViewClient.h" @@ -271,18 +272,15 @@ class PrintWebViewHelper : public RenderViewObserver, PrepareFrameAndViewForPrint* prepare, PrintMsg_Print_Params* params); -#if defined(USE_SKIA) // Given the |device| and |canvas| to draw on, prints the appropriate headers // and footers using strings from |header_footer_info| on to the canvas. static void PrintHeaderAndFooter( - SkDevice* device, - skia::VectorCanvas* canvas, + WebKit::WebCanvas* canvas, int page_number, int total_pages, float webkit_scale_factor, const PageSizeMargins& page_layout_in_points, const base::DictionaryValue& header_footer_info); -#endif // defined(USE_SKIA) bool GetPrintFrame(WebKit::WebFrame** frame); diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index c07f76b..d457aecb 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -212,7 +212,7 @@ void PrintWebViewHelper::PrintPageInternal( if (params.params.display_header_footer) { // |page_number| is 0-based, so 1 is added. // The scale factor on Linux is 1. - PrintHeaderAndFooter(device, canvas.get(), params.page_number + 1, + PrintHeaderAndFooter(canvas.get(), params.page_number + 1, print_preview_context_.total_page_count(), 1, page_layout_in_points, *header_footer_info_); } diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm index b6d28cb..3e5051f 100644 --- a/chrome/renderer/print_web_view_helper_mac.mm +++ b/chrome/renderer/print_web_view_helper_mac.mm @@ -135,8 +135,8 @@ void PrintWebViewHelper::RenderPage( SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device); canvas->unref(); // SkRefPtr and new both took a reference. - WebKit::WebCanvas* canvasPtr = canvas.get(); - printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvasPtr, metafile); + WebKit::WebCanvas* canvas_ptr = canvas.get(); + printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas_ptr, metafile); #else bool success = metafile->StartPage(page_size, content_area, scale_factor); DCHECK(success); @@ -145,18 +145,34 @@ void PrintWebViewHelper::RenderPage( // certain that there are no lingering references. base::mac::ScopedNSAutoreleasePool pool; CGContextRef cgContext = metafile->context(); - CGContextRef canvasPtr = cgContext; + CGContextRef canvas_ptr = cgContext; #endif - frame->printPage(page_number, canvasPtr); + + PageSizeMargins page_layout_in_points; + GetPageSizeAndMarginsInPoints(frame, page_number, + print_pages_params_->params, + &page_layout_in_points); + +#if !defined(USE_SKIA) + // For CoreGraphics, print in the margins before printing in the content + // area so that we don't spill over. Webkit draws a white background in the + // content area and this acts as a clip. + // TODO(aayushkumar): Combine the calls to PrintHeaderAndFooter once we + // can draw in the margins safely in Skia in any order. + if (print_pages_params_->params.display_header_footer) { + PrintHeaderAndFooter(canvas_ptr, page_number + 1, + print_preview_context_.total_page_count(), + scale_factor, page_layout_in_points, + *header_footer_info_); + } +#endif // !USE_SKIA + + frame->printPage(page_number, canvas_ptr); + #if defined(USE_SKIA) - const PrintMsg_Print_Params& printParams = - print_preview_context_.print_params(); - if (printParams.display_header_footer) { - PageSizeMargins page_layout_in_points; - GetPageSizeAndMarginsInPoints(frame, page_number, printParams, - &page_layout_in_points); + if (print_pages_params_->params.display_header_footer) { // |page_number| is 0-based, so 1 is added. - PrintHeaderAndFooter(device, canvas.get(), page_number + 1, + PrintHeaderAndFooter(canvas_ptr, page_number + 1, print_preview_context_.total_page_count(), scale_factor, page_layout_in_points, *header_footer_info_); diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc index cb70e43..2c3180a 100644 --- a/chrome/renderer/print_web_view_helper_win.cc +++ b/chrome/renderer/print_web_view_helper_win.cc @@ -190,7 +190,7 @@ Metafile* PrintWebViewHelper::RenderPage( if (params.display_header_footer) { // |page_number| is 0-based, so 1 is added. - PrintHeaderAndFooter(device, canvas.get(), page_number + 1, + PrintHeaderAndFooter(canvas.get(), page_number + 1, print_preview_context_.total_page_count(), webkit_scale_factor, page_layout_in_points, *header_footer_info_); diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index 436d656..abaf167 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc @@ -33,6 +33,10 @@ const char kSettingDuplexMode[] = "duplex"; // Option to print headers and Footers: true if selected, false if not. const char kSettingHeaderFooterEnabled[] = "headerFooterEnabled"; +// Default character spacing for text while printing headers and footers. +// (For CoreGraphics only). +const int kSettingHeaderFooterCharacterSpacing = 0; + // Default font family name for printing the headers and footers. const char kSettingHeaderFooterFontFamilyName[] = "sans"; diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index 89a6e64..f9188be 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h @@ -16,6 +16,7 @@ extern const char kSettingCopies[]; extern const char kSettingDeviceName[]; extern const char kSettingDuplexMode[]; extern const char kSettingHeaderFooterEnabled[]; +extern const int kSettingHeaderFooterCharacterSpacing; extern const char kSettingHeaderFooterFontFamilyName[]; extern const char kSettingHeaderFooterFontName[]; extern const int kSettingHeaderFooterFontSize; |