1/* 2 * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies) 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library 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 program 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 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this program; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21#include "config.h" 22#include "qquickwebpage_p.h" 23 24#include "QtWebPageEventHandler.h" 25#include "QtWebPageSGNode.h" 26#include "TransformationMatrix.h" 27#include "qquickwebpage_p_p.h" 28#include "qquickwebview_p.h" 29#include "qquickwebview_p_p.h" 30#include "qwebkittest_p.h" 31#include <QQuickWindow> 32#include <WKPage.h> 33#include <WebCore/CoordinatedGraphicsScene.h> 34 35using namespace WebKit; 36 37QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem) 38 : QQuickItem(viewportItem->contentItem()) 39 , d(new QQuickWebPagePrivate(this, viewportItem)) 40{ 41 setFlag(ItemHasContents); 42 setClip(true); 43 44 // We do the transform from the top left so the viewport can assume the position 0, 0 45 // is always where rendering starts. 46 setTransformOrigin(TopLeft); 47} 48 49QQuickWebPage::~QQuickWebPage() 50{ 51 delete d; 52} 53 54QQuickWebPagePrivate::QQuickWebPagePrivate(QQuickWebPage* q, QQuickWebView* viewportItem) 55 : q(q) 56 , viewportItem(viewportItem) 57 , paintingIsInitialized(false) 58 , contentsScale(1) 59{ 60} 61 62void QQuickWebPagePrivate::paint(QPainter* painter) 63{ 64 if (WebCore::CoordinatedGraphicsScene* scene = QQuickWebViewPrivate::get(viewportItem)->coordinatedGraphicsScene()) 65 scene->paintToGraphicsContext(painter); 66} 67 68 69QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) 70{ 71 QQuickWebViewPrivate* webViewPrivate = QQuickWebViewPrivate::get(d->viewportItem); 72 73 WebCore::CoordinatedGraphicsScene* scene = webViewPrivate->coordinatedGraphicsScene(); 74 if (!scene) 75 return oldNode; 76 77 QtWebPageSGNode* node = static_cast<QtWebPageSGNode*>(oldNode); 78 79 const QWindow* window = this->window(); 80 ASSERT(window); 81 82 WKPageRef pageRef = webViewPrivate->webPage.get(); 83 if (window && WKPageGetBackingScaleFactor(pageRef) != window->devicePixelRatio()) { 84 WKPageSetCustomBackingScaleFactor(pageRef, window->devicePixelRatio()); 85 // This signal is queued since if we are running a threaded renderer. This might cause failures 86 // if tests are reading the new value between the property change and the signal emission. 87 emit d->viewportItem->experimental()->test()->devicePixelRatioChanged(); 88 } 89 90 if (!node) 91 node = new QtWebPageSGNode; 92 93 node->setCoordinatedGraphicsScene(scene); 94 95 node->setScale(d->contentsScale); 96 node->setDevicePixelRatio(window->devicePixelRatio()); 97 QColor backgroundColor = webViewPrivate->transparentBackground() ? Qt::transparent : Qt::white; 98 QRectF backgroundRect(QPointF(0, 0), d->contentsSize); 99 node->setBackground(backgroundRect, backgroundColor); 100 101 return node; 102} 103 104void QQuickWebPage::setContentsSize(const QSizeF& size) 105{ 106 if (size.isEmpty() || d->contentsSize == size) 107 return; 108 109 d->contentsSize = size; 110 d->updateSize(); 111 emit d->viewportItem->experimental()->test()->contentsSizeChanged(); 112} 113 114const QSizeF& QQuickWebPage::contentsSize() const 115{ 116 return d->contentsSize; 117} 118 119void QQuickWebPage::setContentsScale(qreal scale) 120{ 121 ASSERT(scale > 0); 122 d->contentsScale = scale; 123 d->updateSize(); 124 emit d->viewportItem->experimental()->test()->contentsScaleChanged(); 125} 126 127qreal QQuickWebPage::contentsScale() const 128{ 129 ASSERT(d->contentsScale > 0); 130 return d->contentsScale; 131} 132 133QTransform QQuickWebPage::transformFromItem() const 134{ 135 return transformToItem().inverted(); 136} 137 138QTransform QQuickWebPage::transformToItem() const 139{ 140 qreal xPos = x(); 141 qreal yPos = y(); 142 143 if (d->viewportItem->experimental()->flickableViewportEnabled()) { 144 // Flickable moves its contentItem so we need to take that position into 145 // account, as well as the potential displacement of the page on the 146 // contentItem because of additional QML items. 147 xPos += d->viewportItem->contentItem()->x(); 148 yPos += d->viewportItem->contentItem()->y(); 149 } 150 151 return QTransform(d->contentsScale, 0, 0, 0, d->contentsScale, 0, xPos, yPos, 1); 152} 153 154void QQuickWebPagePrivate::updateSize() 155{ 156 QSizeF scaledSize = contentsSize * contentsScale; 157 158 q->setSize(scaledSize); 159 160 if (viewportItem->experimental()->flickableViewportEnabled()) { 161 // Make sure that the content is sized to the page if the user did not 162 // add other flickable items. If that is not the case, the user needs to 163 // disable the default content item size property on the WebView and 164 // bind the contentWidth and contentHeight accordingly, in accordance 165 // accordance with normal Flickable behaviour. 166 if (viewportItem->experimental()->useDefaultContentItemSize()) { 167 viewportItem->setContentWidth(scaledSize.width()); 168 viewportItem->setContentHeight(scaledSize.height()); 169 } 170 } 171} 172 173QQuickWebPagePrivate::~QQuickWebPagePrivate() 174{ 175} 176 177#include "moc_qquickwebpage_p.cpp" 178