WebCore/platform/Length.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2     Copyright (C) 1999 Lars Knoll (knoll@kde.org)
       
     3     Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Library General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Library General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Library General Public License
       
    16     along with this library; see the file COPYING.LIB.  If not, write to
       
    17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    18     Boston, MA 02110-1301, USA.
       
    19 */
       
    20 
       
    21 #ifndef Length_h
       
    22 #define Length_h
       
    23 
       
    24 #include <wtf/Assertions.h>
       
    25 #include <wtf/FastAllocBase.h>
       
    26 #include <wtf/MathExtras.h>
       
    27 
       
    28 namespace WebCore {
       
    29 
       
    30 class String;
       
    31 
       
    32 const int undefinedLength = -1;
       
    33 const int percentScaleFactor = 128;
       
    34 
       
    35 enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
       
    36 
       
    37 struct Length : FastAllocBase {
       
    38     Length()
       
    39         : m_value(0)
       
    40     {
       
    41     }
       
    42 
       
    43     Length(LengthType t)
       
    44         : m_value(t)
       
    45     {
       
    46     }
       
    47 
       
    48     Length(int v, LengthType t, bool q = false)
       
    49         : m_value((v * 16) | (q << 3) | t) // FIXME: Doesn't work if the passed-in value is very large!
       
    50     {
       
    51         ASSERT(t != Percent);
       
    52     }
       
    53 
       
    54     Length(double v, LengthType t, bool q = false)
       
    55         : m_value(static_cast<int>(v * percentScaleFactor) * 16 | (q << 3) | t)
       
    56     {
       
    57         ASSERT(t == Percent);
       
    58     }
       
    59 
       
    60     bool operator==(const Length& o) const { return m_value == o.m_value; }
       
    61     bool operator!=(const Length& o) const { return m_value != o.m_value; }
       
    62 
       
    63     int value() const {
       
    64         ASSERT(type() != Percent);
       
    65         return rawValue();
       
    66     }
       
    67 
       
    68     int rawValue() const { return (m_value & ~0xF) / 16; }
       
    69 
       
    70     double percent() const
       
    71     {
       
    72         ASSERT(type() == Percent);
       
    73         return static_cast<double>(rawValue()) / percentScaleFactor;
       
    74     }
       
    75 
       
    76     LengthType type() const { return static_cast<LengthType>(m_value & 7); }
       
    77     bool quirk() const { return (m_value >> 3) & 1; }
       
    78 
       
    79     void setValue(LengthType t, int value)
       
    80     {
       
    81         ASSERT(t != Percent);
       
    82         setRawValue(t, value);
       
    83     }
       
    84 
       
    85     void setRawValue(LengthType t, int value) { m_value = value * 16 | (m_value & 0x8) | t; }
       
    86 
       
    87     void setValue(int value)
       
    88     {
       
    89         ASSERT(!value || type() != Percent);
       
    90         setRawValue(value);
       
    91     }
       
    92 
       
    93     void setRawValue(int value) { m_value = value * 16 | (m_value & 0xF); }
       
    94 
       
    95     void setValue(LengthType t, double value)
       
    96     {
       
    97         ASSERT(t == Percent);
       
    98         m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0x8) | t;
       
    99     }
       
   100 
       
   101     void setValue(double value)
       
   102     {
       
   103         ASSERT(type() == Percent);
       
   104         m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0xF);
       
   105     }
       
   106 
       
   107     // note: works only for certain types, returns undefinedLength otherwise
       
   108     int calcValue(int maxValue, bool roundPercentages = false) const
       
   109     {
       
   110         switch (type()) {
       
   111             case Fixed:
       
   112                 return value();
       
   113             case Percent:
       
   114                 if (roundPercentages)
       
   115                     return static_cast<int>(round(maxValue * percent() / 100.0));
       
   116                 return maxValue * rawValue() / (100 * percentScaleFactor);
       
   117             case Auto:
       
   118                 return maxValue;
       
   119             default:
       
   120                 return undefinedLength;
       
   121         }
       
   122     }
       
   123 
       
   124     int calcMinValue(int maxValue, bool roundPercentages = false) const
       
   125     {
       
   126         switch (type()) {
       
   127             case Fixed:
       
   128                 return value();
       
   129             case Percent:
       
   130                 if (roundPercentages)
       
   131                     return static_cast<int>(round(maxValue * percent() / 100.0));
       
   132                 return maxValue * rawValue() / (100 * percentScaleFactor);
       
   133             case Auto:
       
   134             default:
       
   135                 return 0;
       
   136         }
       
   137     }
       
   138 
       
   139     float calcFloatValue(int maxValue) const
       
   140     {
       
   141         switch (type()) {
       
   142             case Fixed:
       
   143                 return static_cast<float>(value());
       
   144             case Percent:
       
   145                 return static_cast<float>(maxValue * percent() / 100.0);
       
   146             case Auto:
       
   147                 return static_cast<float>(maxValue);
       
   148             default:
       
   149                 return static_cast<float>(undefinedLength);
       
   150         }
       
   151     }
       
   152 
       
   153     bool isUndefined() const { return rawValue() == undefinedLength; }
       
   154     bool isZero() const { return !(m_value & ~0xF); }
       
   155     bool isPositive() const { return rawValue() > 0; }
       
   156     bool isNegative() const { return rawValue() < 0; }
       
   157 
       
   158     bool isAuto() const { return type() == Auto; }
       
   159     bool isRelative() const { return type() == Relative; }
       
   160     bool isPercent() const { return type() == Percent; }
       
   161     bool isFixed() const { return type() == Fixed; }
       
   162     bool isStatic() const { return type() == Static; }
       
   163     bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; }
       
   164 
       
   165     Length blend(const Length& from, double progress) const
       
   166     {
       
   167         // Blend two lengths to produce a new length that is in between them.  Used for animation.
       
   168         if (!from.isZero() && !isZero() && from.type() != type())
       
   169             return *this;
       
   170 
       
   171         if (from.isZero() && isZero())
       
   172             return *this;
       
   173         
       
   174         LengthType resultType = type();
       
   175         if (isZero())
       
   176             resultType = from.type();
       
   177         
       
   178         if (resultType == Percent) {
       
   179             double fromPercent = from.isZero() ? 0. : from.percent();
       
   180             double toPercent = isZero() ? 0. : percent();
       
   181             return Length(fromPercent + (toPercent - fromPercent) * progress, Percent);
       
   182         } 
       
   183             
       
   184         int fromValue = from.isZero() ? 0 : from.value();
       
   185         int toValue = isZero() ? 0 : value();
       
   186         return Length(int(fromValue + (toValue - fromValue) * progress), resultType);
       
   187     }
       
   188 
       
   189 private:
       
   190     int m_value;
       
   191 };
       
   192 
       
   193 Length* newCoordsArray(const String&, int& len);
       
   194 Length* newLengthArray(const String&, int& len);
       
   195 
       
   196 } // namespace WebCore
       
   197 
       
   198 #endif // Length_h