diff -r 000000000000 -r 4f2f89ce4247 WebCore/platform/Length.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/platform/Length.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,198 @@ +/* + Copyright (C) 1999 Lars Knoll (knoll@kde.org) + Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef Length_h +#define Length_h + +#include +#include +#include + +namespace WebCore { + +class String; + +const int undefinedLength = -1; +const int percentScaleFactor = 128; + +enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; + +struct Length : FastAllocBase { + Length() + : m_value(0) + { + } + + Length(LengthType t) + : m_value(t) + { + } + + Length(int v, LengthType t, bool q = false) + : m_value((v * 16) | (q << 3) | t) // FIXME: Doesn't work if the passed-in value is very large! + { + ASSERT(t != Percent); + } + + Length(double v, LengthType t, bool q = false) + : m_value(static_cast(v * percentScaleFactor) * 16 | (q << 3) | t) + { + ASSERT(t == Percent); + } + + bool operator==(const Length& o) const { return m_value == o.m_value; } + bool operator!=(const Length& o) const { return m_value != o.m_value; } + + int value() const { + ASSERT(type() != Percent); + return rawValue(); + } + + int rawValue() const { return (m_value & ~0xF) / 16; } + + double percent() const + { + ASSERT(type() == Percent); + return static_cast(rawValue()) / percentScaleFactor; + } + + LengthType type() const { return static_cast(m_value & 7); } + bool quirk() const { return (m_value >> 3) & 1; } + + void setValue(LengthType t, int value) + { + ASSERT(t != Percent); + setRawValue(t, value); + } + + void setRawValue(LengthType t, int value) { m_value = value * 16 | (m_value & 0x8) | t; } + + void setValue(int value) + { + ASSERT(!value || type() != Percent); + setRawValue(value); + } + + void setRawValue(int value) { m_value = value * 16 | (m_value & 0xF); } + + void setValue(LengthType t, double value) + { + ASSERT(t == Percent); + m_value = static_cast(value * percentScaleFactor) * 16 | (m_value & 0x8) | t; + } + + void setValue(double value) + { + ASSERT(type() == Percent); + m_value = static_cast(value * percentScaleFactor) * 16 | (m_value & 0xF); + } + + // note: works only for certain types, returns undefinedLength otherwise + int calcValue(int maxValue, bool roundPercentages = false) const + { + switch (type()) { + case Fixed: + return value(); + case Percent: + if (roundPercentages) + return static_cast(round(maxValue * percent() / 100.0)); + return maxValue * rawValue() / (100 * percentScaleFactor); + case Auto: + return maxValue; + default: + return undefinedLength; + } + } + + int calcMinValue(int maxValue, bool roundPercentages = false) const + { + switch (type()) { + case Fixed: + return value(); + case Percent: + if (roundPercentages) + return static_cast(round(maxValue * percent() / 100.0)); + return maxValue * rawValue() / (100 * percentScaleFactor); + case Auto: + default: + return 0; + } + } + + float calcFloatValue(int maxValue) const + { + switch (type()) { + case Fixed: + return static_cast(value()); + case Percent: + return static_cast(maxValue * percent() / 100.0); + case Auto: + return static_cast(maxValue); + default: + return static_cast(undefinedLength); + } + } + + bool isUndefined() const { return rawValue() == undefinedLength; } + bool isZero() const { return !(m_value & ~0xF); } + bool isPositive() const { return rawValue() > 0; } + bool isNegative() const { return rawValue() < 0; } + + bool isAuto() const { return type() == Auto; } + bool isRelative() const { return type() == Relative; } + bool isPercent() const { return type() == Percent; } + bool isFixed() const { return type() == Fixed; } + bool isStatic() const { return type() == Static; } + bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; } + + Length blend(const Length& from, double progress) const + { + // Blend two lengths to produce a new length that is in between them. Used for animation. + if (!from.isZero() && !isZero() && from.type() != type()) + return *this; + + if (from.isZero() && isZero()) + return *this; + + LengthType resultType = type(); + if (isZero()) + resultType = from.type(); + + if (resultType == Percent) { + double fromPercent = from.isZero() ? 0. : from.percent(); + double toPercent = isZero() ? 0. : percent(); + return Length(fromPercent + (toPercent - fromPercent) * progress, Percent); + } + + int fromValue = from.isZero() ? 0 : from.value(); + int toValue = isZero() ? 0 : value(); + return Length(int(fromValue + (toValue - fromValue) * progress), resultType); + } + +private: + int m_value; +}; + +Length* newCoordsArray(const String&, int& len); +Length* newLengthArray(const String&, int& len); + +} // namespace WebCore + +#endif // Length_h