1/*
2    Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3    Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
4    Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
5    Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
6    Copyright (C) 2012 Motorola Mobility, Inc. All rights reserved.
7
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Library General Public
10    License as published by the Free Software Foundation; either
11    version 2 of the License, or (at your option) any later version.
12
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Library General Public License for more details.
17
18    You should have received a copy of the GNU Library General Public License
19    along with this library; see the file COPYING.LIB.  If not, write to
20    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.
22*/
23
24#include "config.h"
25#include "LengthFunctions.h"
26
27#include "LayoutUnit.h"
28#include "Length.h"
29#include "RenderView.h"
30
31namespace WebCore {
32
33int minimumIntValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
34{
35    return static_cast<int>(minimumValueForLength(length, maximumValue, renderView, roundPercentages));
36}
37
38int intValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
39{
40    return static_cast<int>(valueForLength(length, maximumValue, renderView, roundPercentages));
41}
42
43LayoutUnit minimumValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
44{
45    switch (length.type()) {
46    case Fixed:
47        return length.value();
48    case Percent:
49        if (roundPercentages)
50            return static_cast<LayoutUnit>(round(maximumValue * length.percent() / 100.0f));
51        // Don't remove the extra cast to float. It is needed for rounding on 32-bit Intel machines that use the FPU stack.
52        return static_cast<LayoutUnit>(static_cast<float>(maximumValue * length.percent() / 100.0f));
53    case Calculated:
54        return length.nonNanCalculatedValue(maximumValue);
55    case ViewportPercentageWidth:
56        if (renderView)
57            return static_cast<LayoutUnit>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f);
58        return 0;
59    case ViewportPercentageHeight:
60        if (renderView)
61            return static_cast<LayoutUnit>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f);
62        return 0;
63    case ViewportPercentageMin:
64        if (renderView) {
65            IntSize viewportSize = renderView->viewportSize();
66            return static_cast<LayoutUnit>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
67        }
68        return 0;
69    case ViewportPercentageMax:
70        if (renderView) {
71            IntSize viewportSize = renderView->viewportSize();
72            return static_cast<LayoutUnit>(std::max(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
73        }
74        return 0;
75    case FillAvailable:
76    case Auto:
77        return 0;
78    case Relative:
79    case Intrinsic:
80    case MinIntrinsic:
81    case MinContent:
82    case MaxContent:
83    case FitContent:
84    case Undefined:
85        ASSERT_NOT_REACHED();
86        return 0;
87    }
88    ASSERT_NOT_REACHED();
89    return 0;
90}
91
92LayoutUnit valueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
93{
94    switch (length.type()) {
95    case Fixed:
96    case Percent:
97    case Calculated:
98    case ViewportPercentageWidth:
99    case ViewportPercentageHeight:
100    case ViewportPercentageMin:
101    case ViewportPercentageMax:
102        return minimumValueForLength(length, maximumValue, renderView, roundPercentages);
103    case FillAvailable:
104    case Auto:
105        return maximumValue;
106    case Relative:
107    case Intrinsic:
108    case MinIntrinsic:
109    case MinContent:
110    case MaxContent:
111    case FitContent:
112    case Undefined:
113        ASSERT_NOT_REACHED();
114        return 0;
115    }
116    ASSERT_NOT_REACHED();
117    return 0;
118}
119
120// FIXME: when subpixel layout is supported this copy of floatValueForLength() can be removed. See bug 71143.
121float floatValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView)
122{
123    switch (length.type()) {
124    case Fixed:
125        return length.getFloatValue();
126    case Percent:
127        return static_cast<float>(maximumValue * length.percent() / 100.0f);
128    case FillAvailable:
129    case Auto:
130        return static_cast<float>(maximumValue);
131    case Calculated:
132        return length.nonNanCalculatedValue(maximumValue);
133    case ViewportPercentageWidth:
134        if (renderView)
135            return static_cast<int>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f);
136        return 0;
137    case ViewportPercentageHeight:
138        if (renderView)
139            return static_cast<int>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f);
140        return 0;
141    case ViewportPercentageMin:
142        if (renderView) {
143            IntSize viewportSize = renderView->viewportSize();
144            return static_cast<int>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
145        }
146        return 0;
147    case ViewportPercentageMax:
148        if (renderView) {
149            IntSize viewportSize = renderView->viewportSize();
150            return static_cast<int>(std::max(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
151        }
152        return 0;
153    case Relative:
154    case Intrinsic:
155    case MinIntrinsic:
156    case MinContent:
157    case MaxContent:
158    case FitContent:
159    case Undefined:
160        ASSERT_NOT_REACHED();
161        return 0;
162    }
163    ASSERT_NOT_REACHED();
164    return 0;
165}
166
167float floatValueForLength(const Length& length, float maximumValue, RenderView* renderView)
168{
169    switch (length.type()) {
170    case Fixed:
171        return length.getFloatValue();
172    case Percent:
173        return static_cast<float>(maximumValue * length.percent() / 100.0f);
174    case FillAvailable:
175    case Auto:
176        return static_cast<float>(maximumValue);
177    case Calculated:
178        return length.nonNanCalculatedValue(maximumValue);
179    case ViewportPercentageWidth:
180        if (renderView)
181            return static_cast<int>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f);
182        return 0;
183    case ViewportPercentageHeight:
184        if (renderView)
185            return static_cast<int>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f);
186        return 0;
187    case ViewportPercentageMin:
188        if (renderView) {
189            IntSize viewportSize = renderView->viewportSize();
190            return static_cast<int>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
191        }
192        return 0;
193    case ViewportPercentageMax:
194        if (renderView) {
195            IntSize viewportSize = renderView->viewportSize();
196            return static_cast<int>(std::max(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f);
197        }
198        return 0;
199    case Relative:
200    case Intrinsic:
201    case MinIntrinsic:
202    case MinContent:
203    case MaxContent:
204    case FitContent:
205    case Undefined:
206        ASSERT_NOT_REACHED();
207        return 0;
208    }
209    ASSERT_NOT_REACHED();
210    return 0;
211}
212
213} // namespace WebCore
214