1/*
2 * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include "config.h"
20
21#if USE(ACCELERATED_COMPOSITING)
22
23#include "SelectionOverlay.h"
24
25#include "Frame.h"
26#include "GraphicsContext.h"
27#include "LayerMessage.h"
28#include "LayerWebKitThread.h"
29#include "Path.h"
30#include "RenderTheme.h"
31#include "RenderView.h"
32#include "WebPage_p.h"
33
34#include <BlackBerryPlatformMessageClient.h>
35
36using namespace WebCore;
37
38namespace BlackBerry {
39namespace WebKit {
40
41SelectionOverlay::SelectionOverlay(WebPagePrivate* page)
42    : m_page(page)
43{
44}
45
46SelectionOverlay::~SelectionOverlay()
47{
48}
49
50void SelectionOverlay::draw(const Selection& selection)
51{
52    ASSERT(BlackBerry::Platform::webKitThreadMessageClient()->isCurrentThread());
53
54    m_selection = selection;
55
56    while (m_layers.size() < static_cast<size_t>(m_selection.size()))
57        m_layers.append(GraphicsLayer::create(this));
58
59    m_layers.resize(m_selection.size());
60
61    size_t i = 0;
62    for (Selection::iterator it = m_selection.begin(); it != m_selection.end(); ++it, ++i) {
63        GraphicsLayer* parent = it->key;
64        GraphicsLayer* overlay = m_layers[i].get();
65
66        parent->platformLayer()->addOverlay(overlay->platformLayer());
67        overlay->setPosition(FloatPoint::zero());
68        if (parent == m_page->m_overlayLayer)
69            overlay->setSize(m_page->contentsSize());
70        else
71            overlay->setSize(parent->size());
72        overlay->setAnchorPoint(FloatPoint3D(0, 0, 0));
73        overlay->setDrawsContent(true);
74        overlay->setNeedsDisplay();
75    }
76}
77
78void SelectionOverlay::hide()
79{
80    ASSERT(BlackBerry::Platform::webKitThreadMessageClient()->isCurrentThread());
81
82    for (size_t i = 0; i < m_layers.size(); ++i)
83        m_layers[i]->platformLayer()->removeFromSuperlayer();
84    m_selection.clear();
85}
86
87void SelectionOverlay::notifyFlushRequired(const GraphicsLayer* layer)
88{
89    m_page->notifyFlushRequired(layer);
90}
91
92void SelectionOverlay::paintContents(const GraphicsLayer* layer, GraphicsContext& c, GraphicsLayerPaintingPhase, const IntRect& inClip)
93{
94    if (!layer->platformLayer()->superlayer())
95        return;
96
97    Selection::iterator it = m_selection.find(layer->platformLayer()->superlayer()->owner());
98    if (it == m_selection.end())
99        return;
100
101    const Vector<WebCore::FloatQuad>& quads = it->value;
102    GraphicsLayer* parent = it->key;
103
104    IntRect clip(inClip);
105    clip.move(parent->offsetFromRenderer().width(), parent->offsetFromRenderer().height());
106
107    c.save();
108
109    c.translate(-parent->offsetFromRenderer().width(), -parent->offsetFromRenderer().height());
110
111    Color color = RenderTheme::defaultTheme()->activeSelectionBackgroundColor();
112    c.setFillColor(color, ColorSpaceDeviceRGB);
113
114    for (unsigned i = 0; i < quads.size(); ++i) {
115        FloatRect rectToPaint = quads[i].boundingBox();
116
117        // Selection on non-composited sub-frames need to be adjusted.
118        if (!m_page->focusedOrMainFrame()->contentRenderer()->isComposited()) {
119            WebCore::IntPoint framePosition = m_page->frameOffset(m_page->focusedOrMainFrame());
120            rectToPaint.move(framePosition.x(), framePosition.y());
121        }
122
123        rectToPaint.intersect(clip);
124        if (rectToPaint.isEmpty())
125            continue;
126
127        c.fillRect(rectToPaint);
128    }
129
130    c.restore();
131}
132
133} // namespace WebKit
134} // namespace BlackBerry
135
136#endif // USE(ACCELERATED_COMPOSITING)
137