Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / dom / ViewportDescription.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
7  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
9  * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  *
26  */
27
28 #include "config.h"
29 #include "core/dom/ViewportDescription.h"
30
31 using namespace std;
32
33 namespace WebCore {
34
35 static const float& compareIgnoringAuto(const float& value1, const float& value2, const float& (*compare) (const float&, const float&))
36 {
37     if (value1 == ViewportDescription::ValueAuto)
38         return value2;
39
40     if (value2 == ViewportDescription::ValueAuto)
41         return value1;
42
43     return compare(value1, value2);
44 }
45
46 float ViewportDescription::resolveViewportLength(const Length& length, const FloatSize& initialViewportSize, Direction direction)
47 {
48     if (length.isAuto())
49         return ViewportDescription::ValueAuto;
50
51     if (length.isFixed())
52         return length.getFloatValue();
53
54     if (length.type() == ExtendToZoom)
55         return ViewportDescription::ValueExtendToZoom;
56
57     if (length.type() == Percent && direction == Horizontal)
58         return initialViewportSize.width() * length.getFloatValue() / 100.0f;
59
60     if (length.type() == Percent && direction == Vertical)
61         return initialViewportSize.height() * length.getFloatValue() / 100.0f;
62
63     if (length.type() == DeviceWidth)
64         return initialViewportSize.width();
65
66     if (length.type() == DeviceHeight)
67         return initialViewportSize.height();
68
69     ASSERT_NOT_REACHED();
70     return ViewportDescription::ValueAuto;
71 }
72
73 PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize) const
74 {
75     float resultWidth = ValueAuto;
76     float resultMaxWidth = resolveViewportLength(maxWidth, initialViewportSize, Horizontal);
77     float resultMinWidth = resolveViewportLength(minWidth, initialViewportSize, Horizontal);
78     float resultHeight = ValueAuto;
79     float resultMaxHeight = resolveViewportLength(maxHeight, initialViewportSize, Vertical);
80     float resultMinHeight = resolveViewportLength(minHeight, initialViewportSize, Vertical);
81
82     float resultZoom = zoom;
83     float resultMinZoom = minZoom;
84     float resultMaxZoom = maxZoom;
85     float resultUserZoom = userZoom;
86
87     // 1. Resolve min-zoom and max-zoom values.
88     if (resultMinZoom != ViewportDescription::ValueAuto && resultMaxZoom != ViewportDescription::ValueAuto)
89         resultMaxZoom = max(resultMinZoom, resultMaxZoom);
90
91     // 2. Constrain zoom value to the [min-zoom, max-zoom] range.
92     if (resultZoom != ViewportDescription::ValueAuto)
93         resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
94
95     float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min);
96
97     // 3. Resolve non-"auto" lengths to pixel lengths.
98     if (extendZoom == ViewportDescription::ValueAuto) {
99         if (resultMaxWidth == ViewportDescription::ValueExtendToZoom)
100             resultMaxWidth = ViewportDescription::ValueAuto;
101
102         if (resultMaxHeight == ViewportDescription::ValueExtendToZoom)
103             resultMaxHeight = ViewportDescription::ValueAuto;
104
105         if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
106             resultMinWidth = resultMaxWidth;
107
108         if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
109             resultMinHeight = resultMaxHeight;
110     } else {
111         float extendWidth = initialViewportSize.width() / extendZoom;
112         float extendHeight = initialViewportSize.height() / extendZoom;
113
114         if (resultMaxWidth == ViewportDescription::ValueExtendToZoom)
115             resultMaxWidth = extendWidth;
116
117         if (resultMaxHeight == ViewportDescription::ValueExtendToZoom)
118             resultMaxHeight = extendHeight;
119
120         if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
121             resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max);
122
123         if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
124             resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max);
125     }
126
127     // 4. Resolve initial width from min/max descriptors.
128     if (resultMinWidth != ViewportDescription::ValueAuto || resultMaxWidth != ViewportDescription::ValueAuto)
129         resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
130
131     // 5. Resolve initial height from min/max descriptors.
132     if (resultMinHeight != ViewportDescription::ValueAuto || resultMaxHeight != ViewportDescription::ValueAuto)
133         resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
134
135     // 6-7. Resolve width value.
136     if (resultWidth == ViewportDescription::ValueAuto) {
137         if (resultHeight == ViewportDescription::ValueAuto || !initialViewportSize.height())
138             resultWidth = initialViewportSize.width();
139         else
140             resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height());
141     }
142
143     // 8. Resolve height value.
144     if (resultHeight == ViewportDescription::ValueAuto) {
145         if (!initialViewportSize.width())
146             resultHeight = initialViewportSize.height();
147         else
148             resultHeight = resultWidth * initialViewportSize.height() / initialViewportSize.width();
149     }
150
151     // Resolve initial-scale value.
152     if (resultZoom == ViewportDescription::ValueAuto) {
153         if (resultWidth != ViewportDescription::ValueAuto && resultWidth > 0)
154             resultZoom = initialViewportSize.width() / resultWidth;
155         if (resultHeight != ViewportDescription::ValueAuto && resultHeight > 0) {
156             // if 'auto', the initial-scale will be negative here and thus ignored.
157             resultZoom = max<float>(resultZoom, initialViewportSize.height() / resultHeight);
158         }
159     }
160
161     // If user-scalable = no, lock the min/max scale to the computed initial
162     // scale.
163     if (!resultUserZoom)
164         resultMinZoom = resultMaxZoom = resultZoom;
165
166     // Only set initialScale to a value if it was explicitly set.
167     if (zoom == ViewportDescription::ValueAuto)
168         resultZoom = ViewportDescription::ValueAuto;
169
170     PageScaleConstraints result;
171     result.minimumScale = resultMinZoom;
172     result.maximumScale = resultMaxZoom;
173     result.initialScale = resultZoom;
174     result.layoutSize.setWidth(resultWidth);
175     result.layoutSize.setHeight(resultHeight);
176     return result;
177 }
178
179 } // namespace WebCore