1/*
2 * Copyright (C) 2012 Intel Corporation. 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 *
8 * 1. Redistributions of source code must retain the above
9 *    copyright notice, this list of conditions and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 *    copyright notice, this list of conditions and the following
13 *    disclaimer in the documentation and/or other materials
14 *    provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "ViewportStyleResolver.h"
32
33#if ENABLE(CSS_DEVICE_ADAPTATION)
34
35#include "CSSValueKeywords.h"
36#include "Document.h"
37#include "Page.h"
38#include "RenderView.h"
39#include "StylePropertySet.h"
40#include "StyleRule.h"
41#include "ViewportArguments.h"
42
43namespace WebCore {
44
45ViewportStyleResolver::ViewportStyleResolver(Document* document)
46    : m_document(document)
47{
48    ASSERT(m_document);
49}
50
51ViewportStyleResolver::~ViewportStyleResolver()
52{
53}
54
55void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule)
56{
57    StylePropertySet* propertySet = viewportRule->mutableProperties();
58
59    unsigned propertyCount = propertySet->propertyCount();
60    if (!propertyCount)
61        return;
62
63    if (!m_propertySet) {
64        m_propertySet = propertySet->mutableCopy();
65        return;
66    }
67
68    m_propertySet->mergeAndOverrideOnConflict(propertySet);
69}
70
71void ViewportStyleResolver::clearDocument()
72{
73    m_document = 0;
74}
75
76void ViewportStyleResolver::resolve()
77{
78    if (!m_document || !m_propertySet)
79        return;
80
81    ViewportArguments arguments(ViewportArguments::CSSDeviceAdaptation);
82
83    arguments.userZoom = getViewportArgumentValue(CSSPropertyUserZoom);
84    arguments.zoom = getViewportArgumentValue(CSSPropertyZoom);
85    arguments.minZoom = getViewportArgumentValue(CSSPropertyMinZoom);
86    arguments.maxZoom = getViewportArgumentValue(CSSPropertyMaxZoom);
87    arguments.minWidth = getViewportArgumentValue(CSSPropertyMinWidth);
88    arguments.maxWidth = getViewportArgumentValue(CSSPropertyMaxWidth);
89    arguments.minHeight = getViewportArgumentValue(CSSPropertyMinHeight);
90    arguments.maxHeight = getViewportArgumentValue(CSSPropertyMaxHeight);
91    arguments.orientation = getViewportArgumentValue(CSSPropertyOrientation);
92
93    m_document->setViewportArguments(arguments);
94    m_document->updateViewportArguments();
95
96    m_propertySet = 0;
97}
98
99float ViewportStyleResolver::getViewportArgumentValue(CSSPropertyID id) const
100{
101    float defaultValue = ViewportArguments::ValueAuto;
102
103    // UserZoom default value is CSSValueZoom, which maps to true, meaning that
104    // yes, it is user scalable. When the value is set to CSSValueFixed, we
105    // return false.
106    if (id == CSSPropertyUserZoom)
107        defaultValue = 1;
108
109    RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
110    if (!value || !value->isPrimitiveValue())
111        return defaultValue;
112
113    CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value.get());
114
115    if (primitiveValue->isNumber() || primitiveValue->isPx())
116        return primitiveValue->getFloatValue();
117
118    if (primitiveValue->isFontRelativeLength())
119        return primitiveValue->getFloatValue() * m_document->documentElement()->renderStyle()->fontDescription().computedSize();
120
121    if (primitiveValue->isPercentage()) {
122        float percentValue = primitiveValue->getFloatValue() / 100.0f;
123        switch (id) {
124        case CSSPropertyMaxHeight:
125        case CSSPropertyMinHeight:
126            ASSERT(m_document->initialViewportSize().height() > 0);
127            return percentValue * m_document->initialViewportSize().height();
128        case CSSPropertyMaxWidth:
129        case CSSPropertyMinWidth:
130            ASSERT(m_document->initialViewportSize().width() > 0);
131            return percentValue * m_document->initialViewportSize().width();
132        case CSSPropertyMaxZoom:
133        case CSSPropertyMinZoom:
134        case CSSPropertyZoom:
135            return percentValue;
136        default:
137            ASSERT_NOT_REACHED();
138            break;
139        }
140    }
141
142    switch (primitiveValue->getIdent()) {
143    case CSSValueAuto:
144        return defaultValue;
145    case CSSValueDeviceHeight:
146        return ViewportArguments::ValueDeviceHeight;
147    case CSSValueDeviceWidth:
148        return ViewportArguments::ValueDeviceWidth;
149    case CSSValueLandscape:
150        return ViewportArguments::ValueLandscape;
151    case CSSValuePortrait:
152        return ViewportArguments::ValuePortrait;
153    case CSSValueZoom:
154        return defaultValue;
155    case CSSValueFixed:
156        return 0;
157    default:
158        return defaultValue;
159    }
160}
161
162} // namespace WebCore
163
164#endif // ENABLE(CSS_DEVICE_ADAPTATION)
165