| /* |
| * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
| * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #import "config.h" |
| #import "Frame.h" |
| |
| #import "BlockExceptions.h" |
| #import "ColorMac.h" |
| #import "Cursor.h" |
| #import "DOMInternal.h" |
| #import "Event.h" |
| #import "FrameLoaderClient.h" |
| #import "FrameView.h" |
| #import "GraphicsContext.h" |
| #import "HTMLNames.h" |
| #import "HTMLTableCellElement.h" |
| #import "HitTestRequest.h" |
| #import "HitTestResult.h" |
| #import "KeyboardEvent.h" |
| #import "Logging.h" |
| #import "MouseEventWithHitTestResults.h" |
| #import "Page.h" |
| #import "PlatformKeyboardEvent.h" |
| #import "PlatformWheelEvent.h" |
| #import "RegularExpression.h" |
| #import "RenderTableCell.h" |
| #import "RenderView.h" |
| #import "Scrollbar.h" |
| #import "SimpleFontData.h" |
| #import "visible_units.h" |
| #import <wtf/StdLibExtras.h> |
| |
| @interface NSView (WebCoreHTMLDocumentView) |
| - (void)drawSingleRect:(NSRect)rect; |
| @end |
| |
| using namespace std; |
| |
| namespace WebCore { |
| |
| using namespace HTMLNames; |
| |
| NSImage* Frame::imageFromRect(NSRect rect) const |
| { |
| PaintBehavior oldBehavior = m_view->paintBehavior(); |
| m_view->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); |
| |
| BEGIN_BLOCK_OBJC_EXCEPTIONS; |
| |
| NSImage* resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease]; |
| |
| if (rect.size.width != 0 && rect.size.height != 0) { |
| [resultImage setFlipped:YES]; |
| [resultImage lockFocus]; |
| |
| GraphicsContext graphicsContext((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]); |
| graphicsContext.save(); |
| graphicsContext.translate(-rect.origin.x, -rect.origin.y); |
| m_view->paintContents(&graphicsContext, IntRect(rect)); |
| graphicsContext.restore(); |
| |
| [resultImage unlockFocus]; |
| [resultImage setFlipped:NO]; |
| } |
| |
| m_view->setPaintBehavior(oldBehavior); |
| return resultImage; |
| |
| END_BLOCK_OBJC_EXCEPTIONS; |
| |
| m_view->setPaintBehavior(oldBehavior); |
| return nil; |
| } |
| |
| NSImage* Frame::selectionImage(bool forceBlackText) const |
| { |
| m_view->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0)); |
| m_doc->updateLayout(); |
| NSImage* result = imageFromRect(selection()->bounds()); |
| m_view->setPaintBehavior(PaintBehaviorNormal); |
| return result; |
| } |
| |
| NSImage *Frame::rangeImage(Range* range, bool forceBlackText) const |
| { |
| m_view->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0)); |
| m_doc->updateLayout(); |
| RenderView* view = contentRenderer(); |
| if (!view) |
| return nil; |
| |
| Position start = range->startPosition(); |
| Position candidate = start.downstream(); |
| if (candidate.deprecatedNode() && candidate.deprecatedNode()->renderer()) |
| start = candidate; |
| |
| Position end = range->endPosition(); |
| candidate = end.upstream(); |
| if (candidate.deprecatedNode() && candidate.deprecatedNode()->renderer()) |
| end = candidate; |
| |
| if (start.isNull() || end.isNull() || start == end) |
| return nil; |
| |
| RenderObject* savedStartRenderer; |
| int savedStartOffset; |
| RenderObject* savedEndRenderer; |
| int savedEndOffset; |
| view->getSelection(savedStartRenderer, savedStartOffset, savedEndRenderer, savedEndOffset); |
| |
| RenderObject* startRenderer = start.deprecatedNode()->renderer(); |
| if (!startRenderer) |
| return nil; |
| |
| RenderObject* endRenderer = end.deprecatedNode()->renderer(); |
| if (!endRenderer) |
| return nil; |
| |
| view->setSelection(startRenderer, start.deprecatedEditingOffset(), endRenderer, end.deprecatedEditingOffset(), RenderView::RepaintNothing); |
| NSImage* result = imageFromRect(view->selectionBounds()); |
| view->setSelection(savedStartRenderer, savedStartOffset, savedEndRenderer, savedEndOffset, RenderView::RepaintNothing); |
| |
| m_view->setPaintBehavior(PaintBehaviorNormal); |
| return result; |
| } |
| |
| NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* elementRect) const |
| { |
| RenderObject* renderer = node->renderer(); |
| if (!renderer) |
| return nil; |
| |
| renderer->updateDragState(true); // mark dragged nodes (so they pick up the right CSS) |
| m_doc->updateLayout(); // forces style recalc - needed since changing the drag state might |
| // imply new styles, plus JS could have changed other things |
| |
| |
| // Document::updateLayout may have blown away the original RenderObject. |
| renderer = node->renderer(); |
| if (!renderer) |
| return nil; |
| |
| LayoutRect topLevelRect; |
| NSRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect)); |
| |
| m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode |
| NSImage* result = imageFromRect(paintingRect); |
| renderer->updateDragState(false); |
| m_doc->updateLayout(); |
| m_view->setNodeToDraw(0); |
| |
| if (elementRect) |
| *elementRect = pixelSnappedIntRect(topLevelRect); |
| if (imageRect) |
| *imageRect = paintingRect; |
| return result; |
| } |
| |
| DragImageRef Frame::nodeImage(Node* node) |
| { |
| m_doc->updateLayout(); // forces style recalc |
| |
| RenderObject* renderer = node->renderer(); |
| if (!renderer) |
| return nil; |
| LayoutRect topLevelRect; |
| NSRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect)); |
| |
| m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode |
| NSImage* result = imageFromRect(paintingRect); |
| m_view->setNodeToDraw(0); |
| |
| return result; |
| } |
| |
| DragImageRef Frame::dragImageForSelection() |
| { |
| if (!selection()->isRange()) |
| return nil; |
| return selectionImage(); |
| } |
| |
| } // namespace WebCore |