render_style.cpp Source File (khtml Library)

| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# render_style.cpp

    00001 /*
    00002  * This file is part of the DOM implementation for KDE.
    00003  *
    00004  * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
    00005  *
    00006  * This library is free software; you can redistribute it and/or
    00007  * modify it under the terms of the GNU Library General Public
    00008  * License as published by the Free Software Foundation; either
    00009  * version 2 of the License, or (at your option) any later version.
    00010  *
    00011  * This library is distributed in the hope that it will be useful,
    00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014  * Library General Public License for more details.
    00015  *
    00016  * You should have received a copy of the GNU Library General Public License
    00017  * along with this library; see the file COPYING.LIB.  If not, write to
    00018  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00019  * Boston, MA 02111-1307, USA.
    00020  *
    00021  * $Id: render_style.cpp,v 1.53.2.1 2003/02/04 21:35:54 mueller Exp $
    00022  */
    00023
    00024 #include "xml/dom_stringimpl.h"
    00025
    00026 #include "render_style.h"
    00027
    00028 #include "kdebug.h"
    00029
    00030 using namespace khtml;
    00031
    00032 /* CSS says Fixde for the default padding value, but we treat variable as 0 padding anyways, and like
    00033  * this is works fine for table paddings aswell
    00034  */
    00035 StyleSurroundData::StyleSurroundData()
    00036     : margin( Fixed ), padding( Variable )
    00037 {
    00038 }
    00039
    00040 StyleSurroundData::StyleSurroundData(const StyleSurroundData& o )
    00041     : Shared<StyleSurroundData>(),
    00042       offset( o.offset ), margin( o.margin ), padding( o.padding ),
    00043       border( o.border )
    00044 {
    00045 }
    00046
    00047 bool StyleSurroundData::operator==(const StyleSurroundData& o) const
    00048 {
    00049     return offset==o.offset && margin==o.margin &&
    00050         padding==o.padding && border==o.border;
    00051 }
    00052
    00053 StyleBoxData::StyleBoxData()
    00054     : z_index( ZAUTO )
    00055 {
    00056 }
    00057
    00058 StyleBoxData::StyleBoxData(const StyleBoxData& o )
    00059     : Shared<StyleBoxData>(),
    00060       width( o.width ), height( o.height ),
    00061       min_width( o.min_width ), max_width( o.max_width ),
    00062       min_height ( o.min_height ), max_height( o.max_height ),
    00063       z_index( o.z_index )
    00064 {
    00065 }
    00066
    00067 bool StyleBoxData::operator==(const StyleBoxData& o) const
    00068 {
    00069     return
    00070             width == o.width &&
    00071             height == o.height &&
    00072             min_width == o.min_width &&
    00073             max_width == o.max_width &&
    00074             min_height == o.min_height &&
    00075             max_height == o.max_height &&
    00076             z_index == o.z_index;
    00077 }
    00078
    00079 StyleVisualData::StyleVisualData()
    00080     : colspan( 1 ), counter_increment( 0 ), counter_reset( 0 ),
    00081       palette( QApplication::palette() )
    00082 {
    00083 }
    00084
    00085 StyleVisualData::~StyleVisualData() {
    00086 }
    00087
    00088 StyleVisualData::StyleVisualData(const StyleVisualData& o )
    00089     : Shared<StyleVisualData>(),
    00090       clip( o.clip ), colspan( o.colspan ),
    00091       counter_increment( o.counter_increment ), counter_reset( o.counter_reset ),
    00092       palette( o.palette )
    00093 {
    00094 }
    00095
    00096
    00097
    00098 StyleBackgroundData::StyleBackgroundData()
    00099     : image( 0 )
    00100 {
    00101 }
    00102
    00103 StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o )
    00104     : Shared<StyleBackgroundData>(),
    00105       color( o.color ), image( o.image ),
    00106       x_position( o.x_position ), y_position( o.y_position ),
    00107       outline( o.outline )
    00108 {
    00109 }
    00110
    00111 bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
    00112 {
    00113     return
    00114         color == o.color &&
    00115         image == o.image &&
    00116         x_position == o.x_position &&
    00117         y_position == o.y_position &&
    00118         outline == o.outline;
    00119 }
    00120
    00121
    00122
    00123 StyleInheritedData::StyleInheritedData()
    00124     : indent( Fixed ), line_height( -100, Percent ), style_image( 0 ),
    00125       font(), color( Qt::black ), decoration_color( Qt::black ), border_spacing( 0 )
    00126 {
    00127 }
    00128
    00129 StyleInheritedData::~StyleInheritedData()
    00130 {
    00131 }
    00132
    00133 StyleInheritedData::StyleInheritedData(const StyleInheritedData& o )
    00134     : Shared<StyleInheritedData>(),
    00135       indent( o.indent ), line_height( o.line_height ), style_image( o.style_image ),
    00136       font( o.font ), color( o.color ), decoration_color( o.decoration_color ),
    00137       border_spacing( o.border_spacing )
    00138 {
    00139 }
    00140
    00141 bool StyleInheritedData::operator==(const StyleInheritedData& o) const
    00142 {
    00143     return
    00144         indent == o.indent &&
    00145         line_height == o.line_height &&
    00146         border_spacing == o.border_spacing &&
    00147         style_image == o.style_image &&
    00148         font == o.font &&
    00149         color == o.color &&
    00150         decoration_color == o.decoration_color;
    00151
    00152     // doesn't work because structs are not packed
    00153     //return memcmp(this, &o, sizeof(*this))==0;
    00154 }
    00155
    00156 RenderStyle::RenderStyle()
    00157 {
    00158 //    counter++;
    00159     if (!_default)
    00160         _default = new RenderStyle(true);
    00161
    00162     box = _default->box;
    00163     visual = _default->visual;
    00164     background = _default->background;
    00165     surround = _default->surround;
    00166
    00167     inherited = _default->inherited;
    00168
    00169     setBitDefaults();
    00170
    00171     pseudoStyle = 0;
    00172     content = 0;
    00173 }
    00174
    00175 RenderStyle::RenderStyle(bool)
    00176 {
    00177     setBitDefaults();
    00178
    00179     box.init();
    00180     visual.init();
    00181     background.init();
    00182     surround.init();
    00183
    00184     inherited.init();
    00185
    00186     pseudoStyle = 0;
    00187     content = 0;
    00188 }
    00189
    00190 RenderStyle::RenderStyle(const RenderStyle& o)
    00191     : Shared<RenderStyle>(),
    00192       inherited_flags( o.inherited_flags ), noninherited_flags( o.noninherited_flags ),
    00193       box( o.box ), visual( o.visual ), background( o.background ), surround( o.surround ),
    00194       inherited( o.inherited ), pseudoStyle( 0 ), content( o.content )
    00195 {
    00196 }
    00197
    00198 void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
    00199 {
    00200     inherited = inheritParent->inherited;
    00201     inherited_flags = inheritParent->inherited_flags;
    00202 }
    00203
    00204 RenderStyle::~RenderStyle()
    00205 {
    00206     RenderStyle *ps = pseudoStyle;
    00207     RenderStyle *prev = 0;
    00208
    00209     while (ps) {
    00210         prev = ps;
    00211         ps = ps->pseudoStyle;
    00212         // to prevent a double deletion.
    00213         // this works only because the styles below aren't really shared
    00214         // Dirk said we need another construct as soon as these are shared
    00215         prev->pseudoStyle = 0;
    00216         prev->deref();
    00217     }
    00218     delete content;
    00219 }
    00220
    00221 bool RenderStyle::operator==(const RenderStyle& o) const
    00222 {
    00223 // compare everything except the pseudoStyle pointer
    00224     return (inherited_flags == o.inherited_flags &&
    00225             noninherited_flags == o.noninherited_flags &&
    00226             box == o.box &&
    00227             visual == o.visual &&
    00228             background == o.background &&
    00229             surround == o.surround &&
    00230             inherited == o.inherited);
    00231 }
    00232
    00233 RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
    00234 {
    00235     RenderStyle *ps = 0;
    00236     if (noninherited_flags.f._styleType==NOPSEUDO)
    00237         for (ps = pseudoStyle; ps; ps = ps->pseudoStyle)
    00238             if (ps->noninherited_flags.f._styleType==pid)
    00239                 break;
    00240     return ps;
    00241 }
    00242
    00243 RenderStyle* RenderStyle::addPseudoStyle(PseudoId pid)
    00244 {
    00245     RenderStyle *ps = getPseudoStyle(pid);
    00246
    00247     if (!ps)
    00248     {
    00249             ps = new RenderStyle(*this); // use the real copy constructor to get an identical copy
    00250         ps->ref();
    00251         ps->noninherited_flags.f._styleType = pid;
    00252         ps->pseudoStyle = pseudoStyle;
    00253
    00254         pseudoStyle = ps;
    00255     }
    00256
    00257     return ps;
    00258 }
    00259
    00260 void RenderStyle::removePseudoStyle(PseudoId pid)
    00261 {
    00262     RenderStyle *ps = pseudoStyle;
    00263     RenderStyle *prev = this;
    00264
    00265     while (ps) {
    00266         if (ps->noninherited_flags.f._styleType==pid) {
    00267             prev->pseudoStyle = ps->pseudoStyle;
    00268             ps->deref();
    00269             return;
    00270         }
    00271         prev = ps;
    00272         ps = ps->pseudoStyle;
    00273     }
    00274 }
    00275
    00276
    00277 bool RenderStyle::inheritedNotEqual( RenderStyle *other ) const
    00278 {
    00279     return
    00280         (
    00281             inherited_flags != other->inherited_flags ||
    00282             inherited != other->inherited
    00283             );
    00284 }
    00285
    00286 /*
    00287   compares two styles. The result gives an idea of the action that
    00288   needs to be taken when replacing the old style with a new one.
    00289
    00290   CbLayout: The containing block of the object needs a relayout.
    00291   Layout: the RenderObject needs a relayout after the style change
    00292   Visible: The change is visible, but no relayout is needed
    00293   NonVisible: The object does need neither repaint nor relayout after
    00294        the change.
    00295
    00296   ### TODO:
    00297   A lot can be optimised here based on the display type, lots of
    00298   optimisations are unimplemented, and currently result in the
    00299   worst case result causing a relayout of the containing block.
    00300 */
    00301 RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const
    00302 {
    00303     Diff d = Equal;
    00304
    00305     // we anyway assume they are the same
    00306 //      EDisplay _display : 5;
    00307
    00308     // NonVisible:
    00309 //      ECursor _cursor_style : 4;
    00310
    00311 // ### this needs work to know more exactly if we need a relayout
    00312 //     or just a repaint
    00313
    00314 // non-inherited attributes
    00315 //     DataRef<StyleBoxData> box;
    00316 //     DataRef<StyleVisualData> visual;
    00317 //     DataRef<StyleSurroundData> surround;
    00318
    00319 // inherited attributes
    00320 //     DataRef<StyleInheritedData> inherited;
    00321
    00322     if ( *box.get() != *other->box.get() ||
    00323          *visual.get() != *other->visual.get() ||
    00324          *surround.get() != *other->surround.get() ||
    00325          *inherited.get() != *other->inherited.get()
    00326         )
    00327         d = CbLayout;
    00328
    00329     if ( d == CbLayout )
    00330         return d;
    00331
    00332     // changes causing Layout changes:
    00333
    00334 // only for tables:
    00335 //      _border_collapse
    00336 //      EEmptyCell _empty_cells : 2 ;
    00337 //      ECaptionSide _caption_side : 2;
    00338 //     ETableLayout _table_layout : 1;
    00339 //     EPosition _position : 2;
    00340 //     EFloat _floating : 2;
    00341     if ( ((int)noninherited_flags.f._display) >= TABLE ) {
    00342         // Stupid gcc gives a compile error on
    00343         // a != other->b if a and b are bitflags. Using
    00344         // !(a== other->b) instead.
    00345         if ( !(inherited_flags.f._border_collapse == other->inherited_flags.f._border_collapse) ||
    00346              !(inherited_flags.f._empty_cells == other->inherited_flags.f._empty_cells) ||
    00347              !(inherited_flags.f._caption_side == other->inherited_flags.f._caption_side) ||
    00348              !(noninherited_flags.f._table_layout == other->noninherited_flags.f._table_layout) ||
    00349              !(noninherited_flags.f._position == other->noninherited_flags.f._position) ||
    00350              !(noninherited_flags.f._floating == other->noninherited_flags.f._floating) )
    00351
    00352             d = CbLayout;
    00353     }
    00354
    00355 // only for lists:
    00356 //      EListStyleType _list_style_type : 5 ;
    00357 //      EListStylePosition _list_style_position :1;
    00358     if (noninherited_flags.f._display == LIST_ITEM ) {
    00359         if ( !(inherited_flags.f._list_style_type == other->inherited_flags.f._list_style_type) ||
    00360              !(inherited_flags.f._list_style_position == other->inherited_flags.f._list_style_position) )
    00361             d = Layout;
    00362     }
    00363
    00364     if ( d == Layout )
    00365         return d;
    00366
    00367 // ### These could be better optimised
    00368 //      ETextAlign _text_align : 3;
    00369 //      ETextTransform _text_transform : 4;
    00370 //      EDirection _direction : 1;
    00371 //      EWhiteSpace _white_space : 2;
    00372 //      EFontVariant _font_variant : 1;
    00373 //     EClear _clear : 2;
    00374     if ( !(inherited_flags.f._text_align == other->inherited_flags.f._text_align) ||
    00375          !(inherited_flags.f._text_transform == other->inherited_flags.f._text_transform) ||
    00376          !(inherited_flags.f._direction == other->inherited_flags.f._direction) ||
    00377          !(inherited_flags.f._white_space == other->inherited_flags.f._white_space) ||
    00378          !(inherited_flags.f._font_variant == other->inherited_flags.f._font_variant) ||
    00379          !(noninherited_flags.f._clear == other->noninherited_flags.f._clear)
    00380         )
    00381         d = Layout;
    00382
    00383 // only for inline:
    00384 //     EVerticalAlign _vertical_align : 4;
    00385
    00386     if ( !(noninherited_flags.f._display == INLINE) ) {
    00387         if ( !(noninherited_flags.f._vertical_align == other->noninherited_flags.f._vertical_align))
    00388             d = Layout;
    00389     }
    00390
    00391     if ( d == Layout )
    00392         return d;
    00393
    00394
    00395     // Visible:
    00396 //      EVisibility _visibility : 2;
    00397 //     EOverflow _overflow : 4 ;
    00398 //     EBackgroundRepeat _bg_repeat : 2;
    00399 //     bool _bg_attachment : 1;
    00400 //      int _text_decoration : 4;
    00401 //     DataRef<StyleBackgroundData> background;
    00402     if ( !(inherited_flags.f._visibility == other->inherited_flags.f._visibility) ||
    00403          !(noninherited_flags.f._overflow == other->noninherited_flags.f._overflow) ||
    00404          !(noninherited_flags.f._bg_repeat == other->noninherited_flags.f._bg_repeat) ||
    00405          !(noninherited_flags.f._bg_attachment == other->noninherited_flags.f._bg_attachment) ||
    00406          !(noninherited_flags.f._clipSpecified == other->noninherited_flags.f._clipSpecified) ||
    00407          !(inherited_flags.f._text_decoration == other->inherited_flags.f._text_decoration) ||
    00408          *background.get() != *other->background.get()
    00409         )
    00410         d = Visible;
    00411
    00412     // Position:
    00413
    00414     return d;
    00415 }
    00416
    00417
    00418 RenderStyle* RenderStyle::_default = 0;
    00419 //int RenderStyle::counter = 0;
    00420 //int SharedData::counter = 0;
    00421
    00422 void RenderStyle::cleanup()
    00423 {
    00424     delete _default;
    00425     _default = 0;
    00426 //    counter = 0;
    00427 //    SharedData::counter = 0;
    00428 }
    00429
    00430 void RenderStyle::setContent(CachedObject* o)
    00431 {
    00432     if ( !content )
    00433         content = new ContentData;
    00434     else
    00435         content->clearContent();
    00436
    00437     content->_content.object = o;
    00438     content->_contentType = o ? CONTENT_OBJECT : CONTENT_NONE;
    00439 }
    00440
    00441
    00442 void RenderStyle::setPaletteColor(QPalette::ColorGroup g, QColorGroup::ColorRole r, const QColor& c)
    00443 {
    00444     visual.access()->palette.setColor(g,r,c);
    00445 }
    00446
    00447 void RenderStyle::setClip( Length top, Length right, Length bottom, Length left )
    00448 {
    00449     StyleVisualData *data = visual.access();
    00450     data->clip.top = top;
    00451     data->clip.right = right;
    00452     data->clip.bottom = bottom;
    00453     data->clip.left = left;
    00454 }
    00455
    00456 void RenderStyle::setContent(DOM::DOMStringImpl* s)
    00457 {
    00458     if ( !content )
    00459         content = new ContentData;
    00460     else
    00461         content->clearContent();
    00462
    00463     content->_content.text = s;
    00464
    00465     if (s) {
    00466         content->_content.text->ref();
    00467         content->_contentType = CONTENT_TEXT;
    00468     }
    00469     else
    00470         content->_contentType = CONTENT_NONE;
    00471 }
    00472
    00473 ContentData::~ContentData()
    00474 {
    00475     clearContent();
    00476 }
    00477
    00478 void ContentData::clearContent()
    00479 {
    00480     switch (_contentType)
    00481     {
    00482         case CONTENT_OBJECT:
    00483 //            _content.object->deref();
    00484             _content.object = 0;
    00485             break;
    00486         case CONTENT_TEXT:
    00487             _content.text->deref();
    00488             _content.text = 0;
    00489         default:
    00490             ;
    00491     }
    00492 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:34:40 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001