10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2007-2009 Torch Mobile, Inc.
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * are met:
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 1. Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    documentation and/or other materials provided with the distribution.
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h"
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Frame.h"
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Document.h"
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FloatRect.h"
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FrameView.h"
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "GraphicsContext.h"
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "HTMLIFrameElement.h"
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "HTMLNames.h"
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "HTMLTableCellElement.h"
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "KeyboardEvent.h"
38e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "NotImplemented.h"
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Page.h"
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "RenderFrame.h"
41e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "RenderLayer.h"
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "RenderView.h"
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ResourceHandle.h"
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <windows.h>
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochusing std::min;
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore {
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochusing namespace HTMLNames;
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochextern HDC g_screenDC;
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight)
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(frame);
580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    pages.clear();
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    outPageHeight = 0;
610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!frame->document() || !frame->view() || !frame->document()->renderer())
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderView* root = toRenderView(frame->document()->renderer());
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!root) {
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        LOG_ERROR("document to be printed has no renderer");
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (userScaleFactor <= 0) {
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float ratio = (float)printRect.height() / (float)printRect.width();
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    float pageWidth  = (float) root->maxXLayoutOverflow();
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float pageHeight = pageWidth * ratio;
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    outPageHeight = (int) pageHeight;   // this is the height of the page adjusted by margins
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    pageHeight -= (headerHeight + footerHeight);
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (pageHeight <= 0) {
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float currPageHeight = pageHeight / userScaleFactor;
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float docHeight      = root->layer()->height();
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float docWidth       = root->layer()->width();
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float currPageWidth  = pageWidth / userScaleFactor;
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // always return at least one page, since empty files should print a blank page
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float printedPagesHeight = 0.0;
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    do {
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
9968513a70bcd92384395513322f1b801e7bf9c729Steve Block        frame->view()->adjustPageHeightDeprecated(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        printedPagesHeight += currPageHeight;
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } while (printedPagesHeight < docHeight);
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!frame->view())
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11268513a70bcd92384395513322f1b801e7bf9c729Steve Block    frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0));
11368513a70bcd92384395513322f1b801e7bf9c729Steve Block    FloatRect fr = frame->selection()->bounds();
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntRect ir((int)fr.x(), (int)fr.y(), (int)fr.width(), (int)fr.height());
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (ir.isEmpty())
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int w;
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int h;
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    FrameView* view = frame->view();
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (view->parent()) {
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ir.setLocation(view->parent()->convertChildToSelf(view, ir.location()));
12368513a70bcd92384395513322f1b801e7bf9c729Steve Block        w = ir.width() * frame->pageZoomFactor() + 0.5;
12468513a70bcd92384395513322f1b801e7bf9c729Steve Block        h = ir.height() * frame->pageZoomFactor() + 0.5;
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ir = view->contentsToWindow(ir);
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        w = ir.width();
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        h = ir.height();
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    OwnPtr<HDC> bmpDC(CreateCompatibleDC(g_screenDC));
132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    HBITMAP hBmp = CreateCompatibleBitmap(g_screenDC, w, h);
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!hBmp)
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    HGDIOBJ hbmpOld = SelectObject(bmpDC.get(), hBmp);
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        GraphicsContext gc(bmpDC.get());
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        frame->document()->updateLayout();
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        view->paint(&gc, ir);
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SelectObject(bmpDC.get(), hbmpOld);
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
14668513a70bcd92384395513322f1b801e7bf9c729Steve Block    frame->view()->setPaintBehavior(PaintBehaviorNormal);
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return hBmp;
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
151e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockDragImageRef Frame::nodeImage(Node*)
152e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
153e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    notImplemented();
154e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    return 0;
155e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
156e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDragImageRef Frame::dragImageForSelection()
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (selection()->isRange())
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return imageFromSelection(this, false);
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return 0;
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace WebCore
166