Changeset 28648 in webkit
- Timestamp:
- Dec 12, 2007 8:14:48 AM (16 years ago)
- Location:
- trunk/WebKit/gtk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKit/gtk/ChangeLog
r28645 r28648 1 2007-12-12 Alp Toker <alp@atoker.com> 2 3 Reviewed by Holger Freyther. 4 5 http://bugs.webkit.org/show_bug.cgi?id=15576 6 [GTK] Printing support 7 8 Add printing support. 9 10 The API will be kept internal for the time being, but printing can now 11 be triggered by Web pages or the JSC API using JavaScript. 12 13 The print spooler and pagination code is fairly abstract and could be 14 shared by other ports including Win and Qt once complete. It doesn't 15 have header/footer support yet. 16 17 * WebCoreSupport/ChromeClientGtk.cpp: 18 (WebKit::ChromeClient::print): 19 * WebView/webkitprivate.h: 20 * WebView/webkitwebframe.cpp: 21 (PrintContext::begin_print): 22 (PrintContext::draw_page): 23 (PrintContext::end_print): 24 (PrintContext::webkit_web_frame_print): 25 1 26 2007-12-12 Sam Weinig <sam@webkit.org> 2 27 -
trunk/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
r28490 r28648 298 298 } 299 299 300 void ChromeClient::print(Frame* )301 { 302 notImplemented();300 void ChromeClient::print(Frame* frame) 301 { 302 webkit_web_frame_print(kit(frame)); 303 303 } 304 304 -
trunk/WebKit/gtk/WebView/webkitprivate.h
r28634 r28648 94 94 WEBKIT_API gchar* 95 95 webkit_web_frame_get_inner_text (WebKitWebFrame* frame); 96 97 WEBKIT_API void 98 webkit_web_frame_print (WebKitWebFrame* frame); 96 99 } 97 100 -
trunk/WebKit/gtk/WebView/webkitwebframe.cpp
r28484 r28648 2 2 * Copyright (C) 2007 Holger Hans Peter Freyther 3 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2007 Apple Inc. 4 5 * 5 6 * This library is free software; you can redistribute it and/or … … 31 32 #include "FrameTree.h" 32 33 #include "FrameView.h" 34 #include "GraphicsContext.h" 33 35 #include "HTMLFrameOwnerElement.h" 36 #include "RenderView.h" 34 37 #include "kjs_binding.h" 35 38 #include "kjs_proxy.h" … … 416 419 } 417 420 418 } 421 422 #if GTK_CHECK_VERSION(2,10,0) 423 424 // This could be shared between ports once it's complete 425 class PrintContext 426 { 427 public: 428 PrintContext(Frame* frame) 429 : m_frame(frame) 430 { 431 } 432 433 ~PrintContext() 434 { 435 m_pageRects.clear(); 436 } 437 438 int pageCount() 439 { 440 return m_pageRects.size(); 441 } 442 443 void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) 444 { 445 m_pageRects.clear(); 446 outPageHeight = 0; 447 448 if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer()) 449 return; 450 451 RenderView* root = static_cast<RenderView*>(m_frame->document()->renderer()); 452 453 if (!root) { 454 LOG_ERROR("document to be printed has no renderer"); 455 return; 456 } 457 458 if (userScaleFactor <= 0) { 459 LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); 460 return; 461 } 462 463 float ratio = printRect.height() / printRect.width(); 464 465 float pageWidth = (float)root->docWidth(); 466 float pageHeight = pageWidth * ratio; 467 outPageHeight = pageHeight; // this is the height of the page adjusted by margins 468 pageHeight -= headerHeight + footerHeight; 469 470 if (pageHeight <= 0) { 471 LOG_ERROR("pageHeight has bad value %.2f", pageHeight); 472 return; 473 } 474 475 float currPageHeight = pageHeight / userScaleFactor; 476 float docHeight = root->layer()->height(); 477 float currPageWidth = pageWidth / userScaleFactor; 478 479 // always return at least one page, since empty files should print a blank page 480 float printedPagesHeight = 0.0; 481 do { 482 float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); 483 m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); 484 currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); 485 486 m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight)); 487 printedPagesHeight += currPageHeight; 488 } while (printedPagesHeight < docHeight); 489 } 490 491 // TODO: eliminate width param 492 void begin(float width) 493 { 494 // By imaging to a width a little wider than the available pixels, 495 // thin pages will be scaled down a little, matching the way they 496 // print in IE and Camino. This lets them use fewer sheets than they 497 // would otherwise, which is presumably why other browsers do this. 498 // Wide pages will be scaled down more than this. 499 const float PrintingMinimumShrinkFactor = 1.25f; 500 501 // This number determines how small we are willing to reduce the page content 502 // in order to accommodate the widest line. If the page would have to be 503 // reduced smaller to make the widest line fit, we just clip instead (this 504 // behavior matches MacIE and Mozilla, at least) 505 const float PrintingMaximumShrinkFactor = 2.0f; 506 507 float minLayoutWidth = width * PrintingMinimumShrinkFactor; 508 float maxLayoutWidth = width * PrintingMaximumShrinkFactor; 509 510 // FIXME: This will modify the rendering of the on-screen frame. 511 // Could lead to flicker during printing. 512 m_frame->setPrinting(true, minLayoutWidth, maxLayoutWidth, true); 513 } 514 515 // TODO: eliminate width param 516 void spoolPage(GraphicsContext& ctx, int pageNumber, float width) 517 { 518 IntRect pageRect = m_pageRects[pageNumber]; 519 float scale = width / pageRect.width(); 520 521 ctx.save(); 522 ctx.scale(FloatSize(scale, scale)); 523 ctx.translate(-pageRect.x(), -pageRect.y()); 524 ctx.clip(pageRect); 525 m_frame->paint(&ctx, pageRect); 526 ctx.restore(); 527 } 528 529 void end() 530 { 531 m_frame->setPrinting(false, 0, 0, true); 532 } 533 534 protected: 535 Frame* m_frame; 536 Vector<IntRect> m_pageRects; 537 }; 538 539 static void begin_print(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data) 540 { 541 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 542 543 float width = gtk_print_context_get_width(context); 544 float height = gtk_print_context_get_height(context); 545 FloatRect printRect = FloatRect(0, 0, width, height); 546 547 printContext->begin(width); 548 549 // TODO: Margin adjustments and header/footer support 550 float headerHeight = 0; 551 float footerHeight = 0; 552 float pageHeight; // height of the page adjusted by margins 553 printContext->computePageRects(printRect, headerHeight, footerHeight, 1.0, pageHeight); 554 gtk_print_operation_set_n_pages(op, printContext->pageCount()); 555 } 556 557 static void draw_page(GtkPrintOperation* op, GtkPrintContext* context, gint page_nr, gpointer user_data) 558 { 559 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 560 561 cairo_t* cr = gtk_print_context_get_cairo_context(context); 562 GraphicsContext ctx(cr); 563 float width = gtk_print_context_get_width(context); 564 printContext->spoolPage(ctx, page_nr, width); 565 } 566 567 static void end_print(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data) 568 { 569 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 570 printContext->end(); 571 } 572 573 void webkit_web_frame_print(WebKitWebFrame* frame) 574 { 575 GtkWidget* topLevel = gtk_widget_get_toplevel(GTK_WIDGET(webkit_web_frame_get_web_view(frame))); 576 if (!GTK_WIDGET_TOPLEVEL(topLevel)) 577 topLevel = NULL; 578 579 Frame* coreFrame = core(frame); 580 PrintContext printContext(coreFrame); 581 582 GtkPrintOperation* op = gtk_print_operation_new(); 583 g_signal_connect(G_OBJECT(op), "begin-print", G_CALLBACK(begin_print), &printContext); 584 g_signal_connect(G_OBJECT(op), "draw-page", G_CALLBACK(draw_page), &printContext); 585 g_signal_connect(G_OBJECT(op), "end-print", G_CALLBACK(end_print), &printContext); 586 GError *error = NULL; 587 gtk_print_operation_run(op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW(topLevel), &error); 588 g_object_unref(op); 589 590 if (error) { 591 GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(topLevel), 592 GTK_DIALOG_DESTROY_WITH_PARENT, 593 GTK_MESSAGE_ERROR, 594 GTK_BUTTONS_CLOSE, 595 "%s", error->message); 596 g_error_free(error); 597 598 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); 599 gtk_widget_show(dialog); 600 } 601 } 602 603 #else 604 605 void webkit_web_frame_print(WebKitWebFrame*) 606 { 607 g_warning("Printing support is not available in older versions of GTK+"); 608 } 609 610 #endif 611 612 }
Note: See TracChangeset
for help on using the changeset viewer.