1 /* 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "Frame.h" 29 30 #include "Document.h" 31 #include "FloatRect.h" 32 #include "FrameView.h" 33 #include "GraphicsContext.h" 34 #include "HTMLIFrameElement.h" 35 #include "HTMLNames.h" 36 #include "HTMLTableCellElement.h" 37 #include "KeyboardEvent.h" 38 #include "NotImplemented.h" 39 #include "Page.h" 40 #include "RenderFrame.h" 41 #include "RenderLayer.h" 42 #include "RenderView.h" 43 #include "ResourceHandle.h" 44 45 #include <windows.h> 46 47 using std::min; 48 49 namespace WebCore { 50 51 using namespace HTMLNames; 52 53 extern HDC g_screenDC; 54 55 void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight) 56 { 57 ASSERT(frame); 58 59 pages.clear(); 60 outPageHeight = 0; 61 62 if (!frame->document() || !frame->view() || !frame->document()->renderer()) 63 return; 64 65 RenderView* root = toRenderView(frame->document()->renderer()); 66 67 if (!root) { 68 LOG_ERROR("document to be printed has no renderer"); 69 return; 70 } 71 72 if (userScaleFactor <= 0) { 73 LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); 74 return; 75 } 76 77 float ratio = (float)printRect.height() / (float)printRect.width(); 78 79 float pageWidth = (float) root->maxXLayoutOverflow(); 80 float pageHeight = pageWidth * ratio; 81 outPageHeight = (int) pageHeight; // this is the height of the page adjusted by margins 82 pageHeight -= (headerHeight + footerHeight); 83 84 if (pageHeight <= 0) { 85 LOG_ERROR("pageHeight has bad value %.2f", pageHeight); 86 return; 87 } 88 89 float currPageHeight = pageHeight / userScaleFactor; 90 float docHeight = root->layer()->height(); 91 float docWidth = root->layer()->width(); 92 float currPageWidth = pageWidth / userScaleFactor; 93 94 95 // always return at least one page, since empty files should print a blank page 96 float printedPagesHeight = 0.0; 97 do { 98 float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); 99 frame->view()->adjustPageHeightDeprecated(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); 100 currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); 101 102 pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight)); 103 printedPagesHeight += currPageHeight; 104 } while (printedPagesHeight < docHeight); 105 } 106 107 HBITMAP imageFromSelection(Frame* frame, bool forceBlackText) 108 { 109 if (!frame->view()) 110 return 0; 111 112 frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0)); 113 FloatRect fr = frame->selection()->bounds(); 114 IntRect ir((int)fr.x(), (int)fr.y(), (int)fr.width(), (int)fr.height()); 115 if (ir.isEmpty()) 116 return 0; 117 118 int w; 119 int h; 120 FrameView* view = frame->view(); 121 if (view->parent()) { 122 ir.setLocation(view->parent()->convertChildToSelf(view, ir.location())); 123 w = ir.width() * frame->pageZoomFactor() + 0.5; 124 h = ir.height() * frame->pageZoomFactor() + 0.5; 125 } else { 126 ir = view->contentsToWindow(ir); 127 w = ir.width(); 128 h = ir.height(); 129 } 130 131 OwnPtr<HDC> bmpDC(CreateCompatibleDC(g_screenDC)); 132 HBITMAP hBmp = CreateCompatibleBitmap(g_screenDC, w, h); 133 if (!hBmp) 134 return 0; 135 136 HGDIOBJ hbmpOld = SelectObject(bmpDC.get(), hBmp); 137 138 { 139 GraphicsContext gc(bmpDC.get()); 140 frame->document()->updateLayout(); 141 view->paint(&gc, ir); 142 } 143 144 SelectObject(bmpDC.get(), hbmpOld); 145 146 frame->view()->setPaintBehavior(PaintBehaviorNormal); 147 148 return hBmp; 149 } 150 151 DragImageRef Frame::nodeImage(Node*) 152 { 153 notImplemented(); 154 return 0; 155 } 156 157 DragImageRef Frame::dragImageForSelection() 158 { 159 if (selection()->isRange()) 160 return imageFromSelection(this, false); 161 162 return 0; 163 } 164 165 } // namespace WebCore 166