include/CSS/CSSUnit.hpp

Go to the documentation of this file.
00001 #ifndef hpp_CSSUnit_hpp
00002 #define hpp_CSSUnit_hpp
00003 
00004 // We need types 
00005 #include "../Types/Types.hpp"
00006 
00007 namespace CSS
00008 {
00010     struct BorderStyle
00011     {
00012         enum Style
00013         {
00014             None    = 1,  
00015             Hidden  = 2,  
00016             Dotted  = 3,  
00017             Dashed  = 4,  
00018             Solid   = 5,  
00019             Double  = 6,  
00020             Groove  = 7,  
00021             Ridge   = 8,  
00022             Inset   = 9,  
00023             Outset  = 10, 
00024         };
00025     };
00026 
00028     struct Position
00029     {
00031         enum Type
00032         {
00033             Static      = 0, 
00034             Relative    = 1, 
00035             Absolute    = 2, 
00036             Fixed       = 3, 
00037         };
00038     };
00039 
00043     struct DisplayMode
00044     {
00045         enum Type
00046         {
00047             Inline          = 0,    
00048             Block           = 1,
00049             ListItem        = 2,
00050             RunIn           = 3,
00051             Compact         = 4,
00052             Marker          = 5,
00053             Table           = 6, 
00054             InlineTable     = 7,
00055             TableRowGroup   = 8,
00056             TableHeaderGroup= 9,
00057             TableFooterGroup= 10,
00058             TableRow        = 11,
00059             TableColumnGroup= 12,
00060             TableColumn     = 13,
00061             TableCell       = 14,
00062             TableCaption    = 15,
00063             None            = 16                
00064         };
00065     };
00066 
00068     struct ClearAndFloat
00069     {
00070         enum Property
00071         {
00072             None        = 0,    
00073             Left        = 1,    
00074             Right       = 2,    
00075             Both        = 3,    
00076         };
00077     };
00078 
00080     struct TextAlign
00081     {
00082         enum Type
00083         {
00084             Left        = 1,    
00085             Right       = 2,    
00086             Center      = 3,    
00087             Justify     = 4,    
00088             String      = 5,    
00089         } type;
00090 
00092         TextAlign(const Type _type) : type(_type) {}
00093     };
00094 
00097     struct StringAlignedText : public TextAlign
00098     {
00100         char* split;
00101     };
00102 
00104     struct VerticalAlign
00105     {
00106         enum Type
00107         {
00108             Baseline    = 0,    
00109             Middle      = 1,    
00110             Sub         = 2,    
00111             Super       = 3,    
00112             TextTop     = 4,    
00113             TextBottom  = 5,    
00114             Top         = 6,    
00115             Bottom      = 7,    
00116             Number      = 8,    
00117         } type;
00118 
00120         VerticalAlign(const Type _type) : type(_type) {}
00121     };
00122 
00124     struct TextDecoration
00125     {
00126         enum Type
00127         {
00128             None        = 0,    
00129             Underline   = 1,    
00130             Overline    = 2,    
00131             LineThrough = 3,    
00132             Blink       = 4,    
00133         };
00134     };
00135 
00137     struct Length
00138     {
00139     protected:
00141         float   value;
00143         mutable int32  computedValue;
00145         mutable uint32  iteration;
00147         Length(const float _value) : value(_value), computedValue(0x80000000), iteration(0) {}
00148 
00149     public:
00151         virtual void setComputedValue(const int32 _value, const uint32 _iter)   { computedValue = _value; iteration = _iter;  }
00153         virtual const int32 getComputedValue() const        { return computedValue;     }
00154     
00157         virtual int32 getAsPixels(const uint32 currentIteration = 0) const { return 0; }
00159         virtual void setZero() { value = 0; }
00161         virtual bool isAuto() const { return false; }
00163         virtual bool isAbsolute() const { return false; }
00164 
00166         inline void setValue(const float val) { value = val; }
00167     };
00168 
00171     struct SpecifiedVerticalAlign : public VerticalAlign
00172     {
00174         Length *    value;
00176         SpecifiedVerticalAlign(Length * _value) : VerticalAlign(VerticalAlign::Number), value(_value) {}
00177     };
00178 
00180     struct AutoLength : public Length
00181     {
00182     public:
00184         AutoLength() : Length(0) {}
00186         AutoLength(const AutoLength & other) : Length(other.value) {}
00187 
00188         // Get this size in pixels
00189     public:
00191         virtual int32 getAsPixels(const uint32 currentIteration = 0) const
00192         {
00193             if (currentIteration <= iteration) return computedValue;
00194             iteration = currentIteration;
00195             throw "Using auto value before computing it";
00196         }
00197 
00199         virtual bool isAuto() const { return true; }
00200     };
00201 
00203     struct RelativeLength : public Length
00204     {
00205         // The enum
00206     public:    
00208         enum RelativeUnit
00209         {
00211             em,
00213             ex,
00215             percent,
00216         };
00217 
00218         // Members
00219     protected:    
00221         RelativeUnit        unit;
00223         const Length &      to;
00224 
00225         // Construction and destruction
00226     public:    
00228         RelativeLength(const float value, const RelativeUnit & relUnit, Length & relativeTo) : Length(value), unit(relUnit), to(relativeTo) {}
00230         RelativeLength(const RelativeLength & other) : Length(other.value), unit(other.unit), to(other.to) {}
00231 
00232         // Get this size in pixels
00233     public:
00235         virtual int32 getAsPixels(const uint32 currentIteration = 0) const
00236         {
00237             if (currentIteration <= iteration) return computedValue;
00238             iteration = currentIteration;
00239             int32 parentPixels = to.getAsPixels(currentIteration);
00240             switch(unit)
00241             {
00242             case em:
00243             case ex:
00244                 return computedValue = (int32)((float)parentPixels * value + 0.5f);
00245             case percent:
00246                 return computedValue = (int32)((float)parentPixels * value * 0.01f + 0.5f);
00247             }
00248             // No unit selected, return the parent 
00249             return computedValue = parentPixels;
00250         }
00251     };
00252 
00254     struct AbsoluteLength : public Length
00255     {
00257         enum AbsoluteUnit 
00258         {
00260             px, 
00262             in, 
00264             cm,
00266             mm,
00268             pt,
00270             pc,
00271         };
00272 
00273         // Members
00274     protected:    
00276         AbsoluteUnit        unit;
00278         static float        millimeterInPixels;     
00279 
00280         // Construction and destruction
00281     public:    
00283         AbsoluteLength(const float value, const AbsoluteUnit & relUnit) : Length(value), unit(relUnit) {}
00285         AbsoluteLength(const AbsoluteLength & other) : Length(other.value), unit(other.unit) {}
00286 
00287         // Get this size in pixels
00288     public:
00290         virtual int32 getAsPixels(const uint32 currentIteration = 0) const
00291         {
00292             if (currentIteration <= iteration) return computedValue;
00293             iteration = currentIteration;
00294             switch(unit)
00295             {
00296             case in:
00297                 return computedValue = (int32)(25.4f * value * millimeterInPixels + 0.5f);
00298             case cm:
00299                 return computedValue = (int32)(10.0f * value * millimeterInPixels + 0.5f);
00300             case mm:
00301                 return computedValue = (int32)(value * millimeterInPixels + 0.5f);
00302             case pt:
00303                 return computedValue = (int32)(0.352778f * value * millimeterInPixels + 0.5f);
00304             case pc:
00305                 return computedValue = (int32)(4.233333f * value * millimeterInPixels + 0.5f);
00306             case px:
00307             default:
00308                 return computedValue = (int32)value;
00309             }
00310         }
00311 
00313         virtual bool isAbsolute() const { return true; }
00314     }; 
00315 
00317     class Colour
00318     {
00319     public:
00321         uint8 R, G, B, A;
00322 
00323     public:
00325         Colour(const uint8 _R = 0, const uint8 _G = 0, const uint8 _B = 0, const uint8 _A = 0) : R(_R), G(_G), B(_B), A(_A) {}
00327         Colour(const char * const input, const int length) : R(0), G(0), B(0), A(0)
00328         {
00329             if (length && input[0] == '#') constructFromHex(&input[1], length - 1); 
00330             else constructFromHex(input, length);
00331         }
00332 
00336         inline bool fromString(const char * const input, const int length)
00337         {
00338             if (length && input[0] == '#') return constructFromHex(&input[1], length - 1); 
00339             return constructFromHex(input, length);
00340         }
00341 
00346         inline void toString(char * output, int & length)
00347         {
00348             if (length < 7 || !output) {  length = 7; return; }
00349             length = 7;
00350             output[0] = '#';
00351             toHex(R, output[1], output[2]);
00352             toHex(G, output[3], output[4]);
00353             toHex(B, output[5], output[6]);
00354         }
00355 
00357         inline const bool operator == (const Colour & colour) const { return R == colour.R && G == colour.G && B == colour.B && A == colour.A; }
00359         inline const bool operator != (const Colour & colour) const { return R != colour.R || G != colour.G || B != colour.B || A != colour.A; }
00360 
00361     private:
00363         inline bool constructFromHex(const char * const input, const int length) 
00364         {
00365             if (length == 6 && areHex(input, 6))
00366             {
00367                 R = fromHex(input[0], input[1]);
00368                 G = fromHex(input[2], input[3]);
00369                 B = fromHex(input[4], input[5]);
00370                 return true;
00371             } else if (length == 3 && areHex(input, 3))
00372             {
00373                 R = fromHex(input[0], input[0]);
00374                 G = fromHex(input[1], input[1]);
00375                 B = fromHex(input[2], input[2]);
00376                 return true;
00377             } else if (length > 7 && input[0] == 'r' && input[1] == 'g' && input[2] == 'b' && input[3] == '(')
00378             {
00379                 // Trim value read from here
00380                 Colour xTmp;
00381                 int pos = 4;
00382                 while (input[pos] == ' ') pos++;
00383                 int result = 0; 
00384 
00385                 // Read the Red value
00386                 int newPos = fromDecimal(&input[pos], length - pos, result);
00387                 if (newPos == -1) return false;
00388                 
00389                 pos += newPos;
00390                 xTmp.R = clipToByte(result);
00391 
00392                 if (input[pos++] != ',') return false;
00393                 while (input[pos] == ' ') pos++;
00394                 newPos = fromDecimal(&input[pos], length - pos, result);
00395                 if (newPos == -1) return false;
00396 
00397                 pos += newPos;
00398                 xTmp.G = clipToByte(result);
00399 
00400                 if (input[pos++] != ',') return false;
00401                 while (input[pos] == ' ') pos++;
00402                 newPos = fromDecimal(&input[pos], length - pos, result);
00403                 if (newPos == -1) return false;
00404 
00405                 pos += newPos;
00406                 xTmp.B = clipToByte(result);
00407                     
00408                 if (input[pos++] != ')') return false;
00409 
00410                 *this = xTmp;
00411                 return true;
00412             } else 
00413             {
00414                 R = G = B = A = 0;
00415                 return false;
00416             }
00417         }
00418 
00420         inline bool areHex(const char * input, const int length) const
00421         {
00422             const char * const ptr = input + length;
00423             while (input < ptr) if (!isHex(*input)) return false; else input++;
00424             return true;
00425         }
00426 
00428         inline bool isHex(const char ch) const { return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); }
00429 
00431         inline uint8 fromHex(char high, char low) const { if (high >= 'a') high -= 32; if (low >= 'a') low -= 32; return ((high > '9' ? (high - 'A' + 10) : high - '0') << 4) | (low > '9' ? (low - 'A' + 10) : low - '0'); }
00432         
00434         inline char toHex(uint8 halfVal) const { return halfVal > 9 ? ('A' + halfVal - 10) : ('0' + halfVal);}
00435 
00437         inline void toHex(uint8 value, char & high, char & low) const { high = toHex(value >> 4); low = toHex(value & 0xf); }
00438 
00440         inline bool isDigit(const char digit) const { return digit >= '0' && digit <= '9'; }
00441 
00445         int fromDecimal(const char * const input, const int length, int & result) const 
00446         {
00447             result = 0; 
00448             int pos = 0;
00449             bool bNegative = (input[pos] == '-');
00450             bool bPercent = false;
00451             if (bNegative) pos++;
00452 
00453             while (pos < length && (input[pos] != ',' && input[pos] != ')'))
00454             {
00455                 if (input[pos] != ' ')
00456                 {
00457                    if (isDigit(input[pos]) && !bPercent) result = result * 10 + (input[pos] - '0');
00458                    else if (input[pos] == '%') { result = (255 * result) / 100; bPercent = true; }
00459                    // Character error, so return
00460                    else { result = 0; return -1; }
00461                 }
00462                 pos++; 
00463             }
00464             
00465             if (bNegative) result = -result;
00466             return pos;
00467         }
00468 
00470         inline uint8 clipToByte(int value) const { return (uint8)(value < 0 ? 0 : (value > 255 ? 255 : value)); }
00471     };
00472 
00474     struct Colours
00475     {
00477         static Colour Black;
00478     };
00479 
00480 
00483     class Font
00484     {
00485     public:
00487         Length * size;
00490         uint32  UID;
00492         Colour  color;
00493 
00494         // Construction
00495     public:
00497         Font(Length * _size, const uint32 _UID, const Colour & _color = CSS::Colours::Black) : size(_size), UID(_UID), color(_color) {}
00498     };
00499 
00501     class LineHeight : public Length
00502     {
00503     private:
00505         Length *        length;
00507         bool            owned;
00508 
00509     public:
00511         LineHeight(Length * relativeTo = 0, bool _owned = false) : length(relativeTo), Length(0), owned(_owned) {}
00513         LineHeight(const LineHeight & other) : Length(0), length(other.length), owned(other.owned) {}
00514     
00515         // Our interface 
00516     public:
00518         int32 getHeightInPixels(CSS::Font * font, const uint32 currentIteration = 0)
00519         {
00520             Length * len = length ? length : (font && font->size ? font->size : 0);
00521             int32 parentPixels = len ? len->getAsPixels(currentIteration) : (font && font->size ? font->size->getAsPixels(currentIteration) : 0);
00522             // No unit selected, return the parent 
00523             setComputedValue(parentPixels, currentIteration);
00524             return parentPixels;
00525         }
00526 
00528         inline Length * setNotOwnedLength(Length * const len) { Length * ret = owned ? length : 0; length = len; owned = false; return ret; }
00530         inline Length * setOwnedLength(Length * const len) { Length * ret = owned ? length : 0; length = len; owned = true; return ret; }
00532         inline bool isSet() const { return length != 0; }
00533 
00534         // Length interface
00535     public:
00538         virtual int32 getAsPixels(const uint32 currentIteration = 0) const { return length ? length->getAsPixels(currentIteration) : 0; }
00540         virtual void setZero() { if (length) length->setZero(); }
00542         virtual bool isAuto() const { return length ? length->isAuto() : false; }
00544         virtual void setComputedValue(const int32 _value, const uint32 _iter)   { if (length) length->setComputedValue(_value, _iter);  }
00546         virtual const int32 getComputedValue() const        { return length ? length->getComputedValue() : 0;     }
00548         virtual bool isAbsolute() const { return length ? length->isAbsolute() : true; }
00549     };
00550 
00551 
00554     struct Unit
00555     {
00556         struct Base
00557         {
00558         };
00559 
00561         struct Integer
00562         {
00563             int32 value;
00564         };
00565 
00566         struct Number
00567         {
00568             float value;
00569         };
00570     };
00571 
00573     struct StyleImplement
00574     {
00576         typedef CSS::Length                         Length;
00578         typedef CSS::Colour                         Colour;
00580         typedef CSS::BorderStyle::Style             BorderStyle; 
00582         typedef CSS::Position::Type                 PositionType;
00584         typedef CSS::DisplayMode::Type              DisplayMode;
00586         typedef CSS::ClearAndFloat::Property        ClearAndFloatType;
00588         typedef CSS::TextDecoration::Type           TextDecorationType;
00589 
00590 
00591 
00592         // Box model
00594         Length * contentWidth;
00596         Length * contentHeight;
00598         Length * paddingLeft;
00600         Length * paddingTop;
00602         Length * paddingBottom;
00604         Length * paddingRight;
00606         Length * marginLeft;
00608         Length * marginTop;
00610         Length * marginBottom;
00612         Length * marginRight;
00613 
00614         // Borders
00616         Length *    borderLeft;
00618         Colour      borderLeftColor;
00620         BorderStyle borderLeftStyle;
00622         Length *    borderRight;
00624         Colour      borderRightColor;
00626         BorderStyle borderRightStyle;
00628         Length *    borderTop;
00630         Colour      borderTopColor;
00632         BorderStyle borderTopStyle;
00634         Length *    borderBottom;
00636         Colour      borderBottomColor;
00638         BorderStyle borderBottomStyle;
00639 
00640         // Position
00642         PositionType    positionType;
00644         Length * positionLeft;
00646         Length * positionTop;
00648         Length * positionBottom;
00650         Length * positionRight;                
00651         
00652         // Display mode
00654         DisplayMode         displayMode;
00656         ClearAndFloatType   floating;
00658         ClearAndFloatType   clearing;
00660         bool                leftToRight;
00661 
00662         // The line height and font styles
00664         CSS::LineHeight     lineHeight;
00666         CSS::Font *         font;
00668         CSS::TextAlign *    textAlign;
00670         CSS::VerticalAlign* verticalAlign;
00672         TextDecorationType  textDecoration;
00673     };
00674 }
00675 
00676 #endif

(C) An X-Ryl669 project 2007

This document describes Unlimited Zooming Interface source code. UZI stands for Unlimited Zooming Interface, and source code license is