2
* Copyright (C) 2012 Igalia S.L.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
* THE POSSIBILITY OF SUCH DAMAGE.
27
#include "WebPrintOperationGtk.h"
29
#include "WebCoreArgumentCoders.h"
31
#include "WebPageProxyMessages.h"
32
#include <WebCore/ErrorsGtk.h>
33
#include <WebCore/IntRect.h>
34
#include <WebCore/NotImplemented.h>
35
#include <WebCore/PlatformContextCairo.h>
36
#include <WebCore/PrintContext.h>
37
#include <WebCore/ResourceError.h>
39
#include <wtf/Vector.h>
40
#include <wtf/gobject/GOwnPtr.h>
42
#ifdef HAVE_GTK_UNIX_PRINTING
43
#include <cairo-pdf.h>
45
#include <gtk/gtkunixprint.h>
50
#ifdef HAVE_GTK_UNIX_PRINTING
51
class WebPrintOperationGtkUnix: public WebPrintOperationGtk {
53
WebPrintOperationGtkUnix(WebPage* page, const PrintInfo& printInfo)
54
: WebPrintOperationGtk(page, printInfo)
59
static gboolean enumeratePrintersFunction(GtkPrinter* printer, WebPrintOperationGtkUnix* printOperation)
61
const char* printerName = gtk_print_settings_get_printer(printOperation->printSettings());
62
if ((printerName && strcmp(printerName, gtk_printer_get_name(printer)))
63
|| (!printerName && !gtk_printer_is_default(printer)))
66
static int jobNumber = 0;
67
const char* applicationName = g_get_application_name();
68
GOwnPtr<char>jobName(g_strdup_printf("%s job #%d", applicationName ? applicationName : "WebKit", ++jobNumber));
69
printOperation->m_printJob = adoptGRef(gtk_print_job_new(jobName.get(), printer,
70
printOperation->printSettings(),
71
printOperation->pageSetup()));
75
static void enumeratePrintersFinished(WebPrintOperationGtkUnix* printOperation)
77
if (!printOperation->m_printJob) {
78
printOperation->printDone(printerNotFoundError(printOperation->m_printContext));
82
GOwnPtr<GError> error;
83
cairo_surface_t* surface = gtk_print_job_get_surface(printOperation->m_printJob.get(), &error.outPtr());
85
printOperation->printDone(printError(printOperation->m_printContext, error->message));
90
printOperation->m_pageRanges = gtk_print_job_get_page_ranges(printOperation->m_printJob.get(), &rangesCount);
91
printOperation->m_pageRangesCount = rangesCount;
92
printOperation->m_pagesToPrint = gtk_print_job_get_pages(printOperation->m_printJob.get());
93
printOperation->m_needsRotation = gtk_print_job_get_rotate(printOperation->m_printJob.get());
95
// Manual capabilities.
96
printOperation->m_numberUp = gtk_print_job_get_n_up(printOperation->m_printJob.get());
97
printOperation->m_numberUpLayout = gtk_print_job_get_n_up_layout(printOperation->m_printJob.get());
98
printOperation->m_pageSet = gtk_print_job_get_page_set(printOperation->m_printJob.get());
99
printOperation->m_reverse = gtk_print_job_get_reverse(printOperation->m_printJob.get());
100
printOperation->m_copies = gtk_print_job_get_num_copies(printOperation->m_printJob.get());
101
printOperation->m_collateCopies = gtk_print_job_get_collate(printOperation->m_printJob.get());
102
printOperation->m_scale = gtk_print_job_get_scale(printOperation->m_printJob.get());
104
printOperation->print(surface, 72, 72);
107
void startPrint(WebCore::PrintContext* printContext, uint64_t callbackID)
109
m_printContext = printContext;
110
m_callbackID = callbackID;
111
gtk_enumerate_printers(reinterpret_cast<GtkPrinterFunc>(enumeratePrintersFunction), this,
112
reinterpret_cast<GDestroyNotify>(enumeratePrintersFinished), FALSE);
115
void startPage(cairo_t* cr)
117
if (!currentPageIsFirstPageOfSheet())
120
GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(m_pageSetup.get());
121
double width = gtk_paper_size_get_width(paperSize, GTK_UNIT_POINTS);
122
double height = gtk_paper_size_get_height(paperSize, GTK_UNIT_POINTS);
124
cairo_surface_t* surface = gtk_print_job_get_surface(m_printJob.get(), 0);
125
cairo_surface_type_t surfaceType = cairo_surface_get_type(surface);
126
if (surfaceType == CAIRO_SURFACE_TYPE_PS) {
127
cairo_ps_surface_set_size(surface, width, height);
128
cairo_ps_surface_dsc_begin_page_setup(surface);
130
switch (gtk_page_setup_get_orientation(m_pageSetup.get())) {
131
case GTK_PAGE_ORIENTATION_PORTRAIT:
132
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
133
cairo_ps_surface_dsc_comment(surface, "%%PageOrientation: Portrait");
135
case GTK_PAGE_ORIENTATION_LANDSCAPE:
136
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
137
cairo_ps_surface_dsc_comment(surface, "%%PageOrientation: Landscape");
140
} else if (surfaceType == CAIRO_SURFACE_TYPE_PDF)
141
cairo_pdf_surface_set_size(surface, width, height);
144
void endPage(cairo_t* cr)
146
if (currentPageIsLastPageOfSheet())
150
static void printJobComplete(GtkPrintJob* printJob, WebPrintOperationGtkUnix* printOperation, const GError* error)
152
printOperation->printDone(error ? printError(printOperation->m_printContext, error->message) : WebCore::ResourceError());
153
printOperation->m_printJob = 0;
156
static void printJobFinished(WebPrintOperationGtkUnix* printOperation)
158
printOperation->deref();
163
cairo_surface_finish(gtk_print_job_get_surface(m_printJob.get(), 0));
164
// Make sure the operation is alive until the job is sent.
166
gtk_print_job_send(m_printJob.get(), reinterpret_cast<GtkPrintJobCompleteFunc>(printJobComplete), this,
167
reinterpret_cast<GDestroyNotify>(printJobFinished));
170
GRefPtr<GtkPrintJob> m_printJob;
175
class WebPrintOperationGtkWin32: public WebPrintOperationGtk {
177
WebPrintOperationGtkWin32(WebPage* page, const PrintInfo& printInfo)
178
: WebPrintOperationGtk(page, printInfo)
182
void startPrint(WebCore::PrintContext* printContext, uint64_t callbackID)
184
m_printContext = printContext;
185
m_callbackID = callbackID;
189
void startPage(cairo_t* cr)
194
void endPage(cairo_t* cr)
206
struct PrintPagesData {
207
PrintPagesData(WebPrintOperationGtk* printOperation)
208
: printOperation(printOperation)
212
, firstSheetNumber(0)
214
, firstPagePosition(0)
220
if (printOperation->collateCopies()) {
221
collatedCopies = printOperation->copies();
222
uncollatedCopies = 1;
225
uncollatedCopies = printOperation->copies();
228
if (printOperation->pagesToPrint() == GTK_PRINT_PAGES_RANGES) {
229
Vector<GtkPageRange> pageRanges;
230
GtkPageRange* ranges = printOperation->pageRanges();
231
size_t rangesCount = printOperation->pageRangesCount();
232
int pageCount = printOperation->pageCount();
234
pageRanges.reserveCapacity(rangesCount);
235
for (size_t i = 0; i < rangesCount; ++i) {
236
if (ranges[i].start >= 0 && ranges[i].start < pageCount && ranges[i].end >= 0 && ranges[i].end < pageCount)
237
pageRanges.append(ranges[i]);
238
else if (ranges[i].start >= 0 && ranges[i].start < pageCount && ranges[i].end >= pageCount) {
239
pageRanges.append(ranges[i]);
240
pageRanges.last().end = pageCount - 1;
241
} else if (ranges[i].end >= 0 && ranges[i].end < pageCount && ranges[i].start < 0) {
242
pageRanges.append(ranges[i]);
243
pageRanges.last().start = 0;
247
for (size_t i = 0; i < pageRanges.size(); ++i) {
248
for (int j = pageRanges[i].start; j <= pageRanges[i].end; ++j)
253
for (int i = 0; i < printOperation->pageCount(); ++i)
261
printOperation->setNumberOfPagesToPrint(pages.size());
263
size_t numberUp = printOperation->numberUp();
265
numberOfSheets = (pages.size() % numberUp) ? pages.size() / numberUp + 1 : pages.size() / numberUp;
267
numberOfSheets = pages.size();
269
bool reverse = printOperation->reverse();
270
switch (printOperation->pageSet()) {
271
case GTK_PAGE_SET_ODD:
273
lastPagePosition = std::min(numberUp - 1, pages.size() - 1);
274
sheetNumber = (numberOfSheets - 1) - (numberOfSheets - 1) % 2;
276
lastPagePosition = std::min(((numberOfSheets - 1) - ((numberOfSheets - 1) % 2)) * numberUp - 1, pages.size() - 1);
278
case GTK_PAGE_SET_EVEN:
280
lastPagePosition = std::min(2 * numberUp - 1, pages.size() - 1);
281
sheetNumber = (numberOfSheets - 1) - (1 - (numberOfSheets - 1) % 2);
283
lastPagePosition = std::min(((numberOfSheets - 1) - (1 - (numberOfSheets - 1) % 2)) * numberUp - 1, pages.size() - 1);
284
sheetNumber = numberOfSheets > 1 ? 1 : -1;
287
case GTK_PAGE_SET_ALL:
289
lastPagePosition = std::min(numberUp - 1, pages.size() - 1);
290
sheetNumber = pages.size() - 1;
292
lastPagePosition = pages.size() - 1;
296
if (sheetNumber * numberUp >= pages.size()) {
301
printOperation->setPagePosition(sheetNumber * numberUp);
302
pageNumber = pages[printOperation->pagePosition()];
303
firstPagePosition = printOperation->pagePosition();
304
firstSheetNumber = sheetNumber;
307
size_t collatedCopiesLeft()
309
return collatedCopies > 1 ? collatedCopies - collated - 1 : 0;
312
size_t uncollatedCopiesLeft()
314
return uncollatedCopies > 1 ? uncollatedCopies - uncollated - 1 : 0;
319
return collatedCopiesLeft() + uncollatedCopiesLeft();
322
void incrementPageSequence()
324
if (totalPrinted == -1) {
329
size_t pagePosition = printOperation->pagePosition();
330
if (pagePosition == lastPagePosition && !copiesLeft()) {
335
if (pagePosition == lastPagePosition && uncollatedCopiesLeft()) {
336
pagePosition = firstPagePosition;
337
sheetNumber = firstSheetNumber;
339
} else if (printOperation->currentPageIsLastPageOfSheet()) {
340
if (!collatedCopiesLeft()) {
341
int step = printOperation->pageSet() == GTK_PAGE_SET_ALL ? 1 : 2;
342
step *= printOperation->reverse() ? -1 : 1;
347
pagePosition = sheetNumber * printOperation->numberUp();
350
printOperation->setPagePosition(pagePosition);
352
if (pagePosition >= pages.size() || sheetNumber >= numberOfSheets) {
356
pageNumber = pages[pagePosition];
360
RefPtr<WebPrintOperationGtk> printOperation;
365
Vector<size_t> pages;
367
size_t firstSheetNumber;
368
size_t numberOfSheets;
369
size_t firstPagePosition;
370
size_t lastPagePosition;
373
size_t collatedCopies;
374
size_t uncollatedCopies;
380
PassRefPtr<WebPrintOperationGtk> WebPrintOperationGtk::create(WebPage* page, const PrintInfo& printInfo)
382
#ifdef HAVE_GTK_UNIX_PRINTING
383
return adoptRef(new WebPrintOperationGtkUnix(page, printInfo));
384
#elif defined(G_OS_WIN32)
385
return adoptRef(new WebPrintOperationGtkWin32(page, printInfo));
391
WebPrintOperationGtk::WebPrintOperationGtk(WebPage* page, const PrintInfo& printInfo)
393
, m_printSettings(printInfo.printSettings.get())
394
, m_pageSetup(printInfo.pageSetup.get())
399
, m_printPagesIdleId(0)
400
, m_numberOfPagesToPrint(0)
401
, m_pagesToPrint(GTK_PRINT_PAGES_ALL)
404
, m_pageRangesCount(0)
405
, m_needsRotation(false)
407
, m_numberUpLayout(0)
408
, m_pageSet(GTK_PAGE_SET_ALL)
411
, m_collateCopies(false)
416
WebPrintOperationGtk::~WebPrintOperationGtk()
418
if (m_printPagesIdleId)
419
g_source_remove(m_printPagesIdleId);
422
int WebPrintOperationGtk::pageCount() const
424
return m_printContext ? m_printContext->pageCount() : 0;
427
bool WebPrintOperationGtk::currentPageIsFirstPageOfSheet() const
429
return (m_numberUp < 2 || !((m_pagePosition) % m_numberUp));
432
bool WebPrintOperationGtk::currentPageIsLastPageOfSheet() const
434
return (m_numberUp < 2 || !((m_pagePosition + 1) % m_numberUp) || m_pagePosition == m_numberOfPagesToPrint - 1);
437
void WebPrintOperationGtk::rotatePageIfNeeded()
439
if (!m_needsRotation)
442
GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(m_pageSetup.get());
443
double width = gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH) * m_xDPI;
444
double height = gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH) * m_yDPI;
446
cairo_matrix_t matrix;
447
switch (gtk_page_setup_get_orientation(m_pageSetup.get())) {
448
case GTK_PAGE_ORIENTATION_LANDSCAPE:
449
cairo_translate(m_cairoContext.get(), 0, height);
450
cairo_matrix_init(&matrix, 0, -1, 1, 0, 0, 0);
451
cairo_transform(m_cairoContext.get(), &matrix);
453
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
454
cairo_translate(m_cairoContext.get(), width, height);
455
cairo_matrix_init(&matrix, -1, 0, 0, -1, 0, 0);
456
cairo_transform(m_cairoContext.get(), &matrix);
458
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
459
cairo_translate(m_cairoContext.get(), width, 0);
460
cairo_matrix_init(&matrix, 0, 1, -1, 0, 0, 0);
461
cairo_transform(m_cairoContext.get(), &matrix);
463
case GTK_PAGE_ORIENTATION_PORTRAIT:
469
void WebPrintOperationGtk::getRowsAndColumnsOfPagesPerSheet(size_t& rows, size_t& columns)
471
switch (m_numberUp) {
499
void WebPrintOperationGtk::getPositionOfPageInSheet(size_t rows, size_t columns, int& x, int&y)
501
switch (m_numberUpLayout) {
502
case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM:
503
x = m_pagePosition % columns;
504
y = (m_pagePosition / columns) % rows;
506
case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP:
507
x = m_pagePosition % columns;
508
y = rows - 1 - (m_pagePosition / columns) % rows;
510
case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM:
511
x = columns - 1 - m_pagePosition % columns;
512
y = (m_pagePosition / columns) % rows;
514
case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP:
515
x = columns - 1 - m_pagePosition % columns;
516
y = rows - 1 - (m_pagePosition / columns) % rows;
518
case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT:
519
x = (m_pagePosition / rows) % columns;
520
y = m_pagePosition % rows;
522
case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT:
523
x = columns - 1 - (m_pagePosition / rows) % columns;
524
y = m_pagePosition % rows;
526
case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT:
527
x = (m_pagePosition / rows) % columns;
528
y = rows - 1 - m_pagePosition % rows;
530
case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT:
531
x = columns - 1 - (m_pagePosition / rows) % columns;
532
y = rows - 1 - m_pagePosition % rows;
537
void WebPrintOperationGtk::prepareContextToDraw()
539
if (m_numberUp < 2) {
540
double left = gtk_page_setup_get_left_margin(m_pageSetup.get(), GTK_UNIT_INCH);
541
double top = gtk_page_setup_get_top_margin(m_pageSetup.get(), GTK_UNIT_INCH);
543
cairo_scale(m_cairoContext.get(), m_scale, m_scale);
544
rotatePageIfNeeded();
545
cairo_translate(m_cairoContext.get(), left * m_xDPI, top * m_yDPI);
550
rotatePageIfNeeded();
552
// Multiple pages per sheet.
553
double marginLeft = gtk_page_setup_get_left_margin(m_pageSetup.get(), GTK_UNIT_POINTS);
554
double marginRight = gtk_page_setup_get_right_margin(m_pageSetup.get(), GTK_UNIT_POINTS);
555
double marginTop = gtk_page_setup_get_top_margin(m_pageSetup.get(), GTK_UNIT_POINTS);
556
double marginBottom = gtk_page_setup_get_bottom_margin(m_pageSetup.get(), GTK_UNIT_POINTS);
558
double paperWidth = gtk_page_setup_get_paper_width(m_pageSetup.get(), GTK_UNIT_POINTS);
559
double paperHeight = gtk_page_setup_get_paper_height(m_pageSetup.get(), GTK_UNIT_POINTS);
561
size_t rows, columns;
562
getRowsAndColumnsOfPagesPerSheet(rows, columns);
564
GtkPageOrientation orientation = gtk_page_setup_get_orientation(m_pageSetup.get());
565
double pageWidth = 0, pageHeight = 0;
566
switch (orientation) {
567
case GTK_PAGE_ORIENTATION_PORTRAIT:
568
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
569
pageWidth = paperWidth - (marginLeft + marginRight);
570
pageHeight = paperHeight - (marginTop + marginBottom);
571
cairo_translate(m_cairoContext.get(), marginLeft, marginTop);
573
case GTK_PAGE_ORIENTATION_LANDSCAPE:
574
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
575
pageWidth = paperWidth - (marginTop + marginBottom);
576
pageHeight = paperHeight - (marginLeft + marginRight);
577
cairo_translate(m_cairoContext.get(), marginTop, marginLeft);
579
size_t tmp = columns;
586
getPositionOfPageInSheet(rows, columns, x, y);
588
switch (m_numberUp) {
592
double scaleX = pageWidth / (columns * paperWidth);
593
double scaleY = pageHeight / (rows * paperHeight);
594
double scale = std::min(scaleX, scaleY);
596
double stepX = paperWidth * (scaleX / scale);
597
double stepY = paperHeight * (scaleY / scale);
599
double width = gtk_page_setup_get_page_width(m_pageSetup.get(), GTK_UNIT_INCH) * m_xDPI;
600
double height = gtk_page_setup_get_page_height(m_pageSetup.get(), GTK_UNIT_INCH) * m_yDPI;
602
double offsetX, offsetY;
603
if (marginLeft + marginRight > 0) {
604
offsetX = marginLeft * (stepX - width) / (marginLeft + marginRight);
605
offsetY = marginTop * (stepY - height) / (marginTop + marginBottom);
607
offsetX = (stepX - width) / 2.0;
608
offsetY = (stepY - height) / 2.0;
611
cairo_scale(m_cairoContext.get(), scale, scale);
612
cairo_translate(m_cairoContext.get(), x * stepX + offsetX, y * stepY + offsetY);
614
cairo_scale(m_cairoContext.get(), m_scale, m_scale);
619
double scaleX = pageHeight / (columns * paperWidth);
620
double scaleY = pageWidth / (rows * paperHeight);
621
double scale = std::min(scaleX, scaleY);
623
double stepX = paperWidth * (scaleX / scale);
624
double stepY = paperHeight * (scaleY / scale);
626
double offsetX = ((stepX - paperWidth) / 2.0 * columns) - marginRight;
627
double offsetY = ((stepY - paperHeight) / 2.0 * rows) + marginTop;
629
cairo_scale(m_cairoContext.get(), scale, scale);
630
cairo_translate(m_cairoContext.get(), y * paperHeight + offsetY, (columns - x) * paperWidth + offsetX);
632
cairo_scale(m_cairoContext.get(), m_scale, m_scale);
633
cairo_rotate(m_cairoContext.get(), -G_PI / 2);
641
void WebPrintOperationGtk::renderPage(int pageNumber)
643
startPage(m_cairoContext.get());
644
cairo_save(m_cairoContext.get());
646
prepareContextToDraw();
648
double pageWidth = gtk_page_setup_get_page_width(m_pageSetup.get(), GTK_UNIT_INCH) * m_xDPI;
649
WebCore::PlatformContextCairo platformContext(m_cairoContext.get());
650
WebCore::GraphicsContext graphicsContext(&platformContext);
651
m_printContext->spoolPage(graphicsContext, pageNumber, pageWidth / m_scale);
653
cairo_restore(m_cairoContext.get());
654
endPage(m_cairoContext.get());
657
gboolean WebPrintOperationGtk::printPagesIdle(gpointer userData)
659
PrintPagesData* data = static_cast<PrintPagesData*>(userData);
661
data->incrementPageSequence();
665
data->printOperation->renderPage(data->pageNumber);
669
void WebPrintOperationGtk::printPagesIdleDone(gpointer userData)
671
PrintPagesData* data = static_cast<PrintPagesData*>(userData);
673
data->printOperation->printPagesDone();
677
void WebPrintOperationGtk::printPagesDone()
679
m_printPagesIdleId = 0;
684
void WebPrintOperationGtk::printDone(const WebCore::ResourceError& error)
686
if (m_printPagesIdleId)
687
g_source_remove(m_printPagesIdleId);
688
m_printPagesIdleId = 0;
690
// Print finished or failed, notify the UI process that we are done.
691
m_webPage->send(Messages::WebPageProxy::PrintFinishedCallback(error, m_callbackID));
694
void WebPrintOperationGtk::print(cairo_surface_t* surface, double xDPI, double yDPI)
696
ASSERT(m_printContext);
698
OwnPtr<PrintPagesData> data = adoptPtr(new PrintPagesData(this));
699
if (!data->isValid) {
700
cairo_surface_finish(surface);
701
printDone(invalidPageRangeToPrint(m_printContext));
707
m_cairoContext = adoptRef(cairo_create(surface));
708
m_printPagesIdleId = gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE + 10, printPagesIdle,
709
data.leakPtr(), printPagesIdleDone);