2 * Copyright (C) 2012 Samsung Electronics
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.
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.
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.
23 #include "PageClientImpl.h"
24 #include "ewk_view_private.h"
26 #if ENABLE(TIZEN_WEBKIT2_TEXT_ZOOM)
27 #include "WebPageGroup.h"
28 #include "WebPreferences.h"
31 using namespace WebCore;
32 using namespace WebKit;
34 const double Zoom::s_scaleFactorThreshold = 0.01;
36 static IntPoint getNewScrollPosition(const IntPoint& scrollPosition, const IntPoint& basisPoint, double baseScaleFactor, double newScaleFactor)
41 double scaleDifference = newScaleFactor / baseScaleFactor;
42 int newScrollX = (scrollPosition.x() + basisPoint.x()) * scaleDifference - basisPoint.x();
43 int newScrollY = (scrollPosition.y() + basisPoint.y()) * scaleDifference - basisPoint.y();
45 return IntPoint(newScrollX, newScrollY);
48 static int getPointDistanceSquare(const IntPoint& point1, const IntPoint& point2)
50 int xDistance = point1.x() - point2.x();
51 int yDistance = point1.y() - point2.y();
52 return xDistance * xDistance + yDistance * yDistance;
55 Zoom::Zoom(Evas_Object* viewWidget)
56 : m_viewWidget(viewWidget)
58 , m_isZoomInformationUpdated(false)
59 , m_baseScaleFactor(0)
61 , m_currentScaleFactor(0)
62 , m_baseScrollPosition()
63 , m_newScrollPosition()
74 ecore_animator_del(m_zoomAnimator);
77 void Zoom::start(const IntPoint& centerPoint, const IntPoint& viewLocation)
79 PageClientImpl* pageClientImpl = ewkViewGetPageClient(m_viewWidget);
80 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
82 m_isZoomInformationUpdated = false;
83 m_baseScaleFactor = pageClientImpl->scaleFactor();
84 m_newScaleFactor = m_baseScaleFactor;
85 m_currentScaleFactor = m_baseScaleFactor;
86 m_newScrollPosition = m_baseScrollPosition = pageClientImpl->scrollPosition();
87 m_centerPoint = centerPoint;
89 evas_object_geometry_get(m_viewWidget, &viewX, &viewY, 0, 0);
90 m_viewLocation = IntPoint(viewX, viewY);
92 m_basisPoint.setX(centerPoint.x() - m_viewLocation.x());
93 m_basisPoint.setY(centerPoint.y() - m_viewLocation.y());
96 ecore_animator_del(m_zoomAnimator);
97 m_zoomAnimator = ecore_animator_add(zoomAnimatorCallback, this);
99 // Notify that zoom is started.
100 evas_object_smart_callback_call(m_viewWidget, "zoom,started", 0);
108 void Zoom::update(const double zoom, const IntPoint& centerPoint)
111 start(centerPoint, IntPoint());
113 PageClientImpl* pageClientImpl = ewkViewGetPageClient(m_viewWidget);
114 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
115 #if ENABLE(TIZEN_WEBKIT2_TEXT_ZOOM)
116 double newScaleFactor = m_baseScaleFactor * zoom;
117 if (!pageClientImpl->page()->pageGroup()->preferences()->textZoomEnabled())
118 newScaleFactor = pageClientImpl->adjustScaleWithViewport(newScaleFactor);
120 double newScaleFactor = pageClientImpl->adjustScaleWithViewport(m_baseScaleFactor * zoom);
123 if (fabs(newScaleFactor - m_newScaleFactor) > s_scaleFactorThreshold)
124 m_newScaleFactor = newScaleFactor;
125 else if (getPointDistanceSquare(m_centerPoint, centerPoint) <= s_zoomCenterDistanceSquareThreshold)
128 m_centerPoint = centerPoint;
129 m_isZoomInformationUpdated = true;
132 void Zoom::realStop()
134 if (m_zoomAnimator) {
135 ecore_animator_del(m_zoomAnimator);
139 PageClientImpl* pageClientImpl = ewkViewGetPageClient(m_viewWidget);
140 pageClientImpl->page()->scaleImage(m_newScaleFactor, m_newScrollPosition);
141 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
143 #if ENABLE(TIZEN_WEBKIT2_TEXT_ZOOM)
144 if (pageClientImpl->page()->pageGroup()->preferences()->textZoomEnabled()) {
145 double textScaleFactor = pageClientImpl->adjustScaleWithViewport(pageClientImpl->page()->textZoomFactor() * (m_newScaleFactor / m_baseScaleFactor));
146 pageClientImpl->page()->scale(m_baseScaleFactor, m_baseScrollPosition);
147 pageClientImpl->page()->setTextZoomFactor(textScaleFactor);
149 pageClientImpl->page()->scale(m_newScaleFactor, m_newScrollPosition);
151 pageClientImpl->page()->scale(m_newScaleFactor, m_newScrollPosition);
154 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
155 pageClientImpl->updateTextSelectionHandlesAndContextMenu(true);
158 // Notify that zoom is finished.
159 evas_object_smart_callback_call(m_viewWidget, "zoom,finished", 0);
162 Eina_Bool Zoom::zoomAnimatorCallback(void* data)
164 static_cast<Zoom*>(data)->process();
165 return ECORE_CALLBACK_RENEW;
170 if (!m_isZooming && (m_currentScaleFactor == m_newScaleFactor)) {
175 if (!m_isZoomInformationUpdated)
178 double scaleStep = m_currentScaleFactor / 6;
179 if (fabs(m_currentScaleFactor - m_newScaleFactor) > scaleStep) {
180 if (m_newScaleFactor > m_currentScaleFactor)
181 m_currentScaleFactor += scaleStep;
183 m_currentScaleFactor -= scaleStep;
185 m_currentScaleFactor = m_newScaleFactor;
187 m_newScrollPosition = getNewScrollPosition(m_baseScrollPosition, m_basisPoint, m_baseScaleFactor, m_currentScaleFactor);
188 m_newScrollPosition.setX(m_newScrollPosition.x() + m_basisPoint.x() - (m_centerPoint.x() - m_viewLocation.x()));
189 m_newScrollPosition.setY(m_newScrollPosition.y() + m_basisPoint.y() - (m_centerPoint.y() - m_viewLocation.y()));
191 PageClientImpl* pageClientImpl = ewkViewGetPageClient(m_viewWidget);
192 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
193 pageClientImpl->page()->scaleImage(m_currentScaleFactor, m_newScrollPosition);
195 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
196 pageClientImpl->updateTextSelectionHandlesAndContextMenu(false);
199 if (m_currentScaleFactor == m_newScaleFactor)
200 m_isZoomInformationUpdated = false;