/* This file is part of the KDE libraries Copyright (C) 1999 Lars Knoll (knoll@kde.org) Copyright (C) 2006 Apple Computer, Inc. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef Length_h #define Length_h #include namespace WebCore { const int undefinedLength = -1; const int percentScaleFactor = 128; enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; struct Length { 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) const { switch (type()) { case Fixed: return value(); case Percent: return maxValue * rawValue() / (100 * percentScaleFactor); case Auto: return maxValue; default: return undefinedLength; } } int calcMinValue(int maxValue) const { switch (type()) { case Fixed: return value(); case Percent: return maxValue * rawValue() / (100 * percentScaleFactor); case Auto: default: return 0; } } 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; } private: int m_value; }; } // namespace WebCore #endif // Length_h