1/*
2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "RenderHTMLCanvas.h"
28
29#include "CanvasRenderingContext.h"
30#include "Document.h"
31#include "Frame.h"
32#include "FrameView.h"
33#include "GraphicsContext.h"
34#include "HTMLCanvasElement.h"
35#include "HTMLNames.h"
36#include "Page.h"
37#include "PaintInfo.h"
38#include "RenderView.h"
39
40namespace WebCore {
41
42using namespace HTMLNames;
43
44RenderHTMLCanvas::RenderHTMLCanvas(HTMLCanvasElement& element, PassRef<RenderStyle> style)
45    : RenderReplaced(element, WTF::move(style), element.size())
46{
47    // Actual size is not known yet, report the default intrinsic size.
48    view().frameView().incrementVisuallyNonEmptyPixelCount(roundedIntSize(intrinsicSize()));
49}
50
51HTMLCanvasElement& RenderHTMLCanvas::canvasElement() const
52{
53    return toHTMLCanvasElement(nodeForNonAnonymous());
54}
55
56bool RenderHTMLCanvas::requiresLayer() const
57{
58    if (RenderReplaced::requiresLayer())
59        return true;
60
61    if (CanvasRenderingContext* context = canvasElement().renderingContext())
62        return context->isAccelerated();
63
64    return false;
65}
66
67void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
68{
69    GraphicsContext* context = paintInfo.context;
70
71    LayoutRect contentRect = contentBoxRect();
72    contentRect.moveBy(paintOffset);
73    LayoutRect paintRect = replacedContentRect(intrinsicSize());
74    paintRect.moveBy(paintOffset);
75
76    // Not allowed to overflow the content box.
77    bool clip = !contentRect.contains(paintRect);
78    GraphicsContextStateSaver stateSaver(*paintInfo.context, clip);
79    if (clip)
80        paintInfo.context->clip(pixelSnappedIntRect(contentRect));
81
82    if (Page* page = frame().page()) {
83        if (paintInfo.phase == PaintPhaseForeground)
84            page->addRelevantRepaintedObject(this, intersection(paintRect, contentRect));
85    }
86
87    bool useLowQualityScale = style().imageRendering() == ImageRenderingCrispEdges || style().imageRendering() == ImageRenderingOptimizeSpeed;
88    canvasElement().paint(context, paintRect, useLowQualityScale);
89}
90
91void RenderHTMLCanvas::canvasSizeChanged()
92{
93    IntSize canvasSize = canvasElement().size();
94    LayoutSize zoomedSize(canvasSize.width() * style().effectiveZoom(), canvasSize.height() * style().effectiveZoom());
95
96    if (zoomedSize == intrinsicSize())
97        return;
98
99    setIntrinsicSize(zoomedSize);
100
101    if (!parent())
102        return;
103
104    if (!preferredLogicalWidthsDirty())
105        setPreferredLogicalWidthsDirty(true);
106
107    LayoutSize oldSize = size();
108    updateLogicalWidth();
109    updateLogicalHeight();
110    if (oldSize == size())
111        return;
112
113    if (!selfNeedsLayout())
114        setNeedsLayout();
115}
116
117} // namespace WebCore
118