📄 render_style.cpp
字号:
font == o.font && color == o.color && border_hspacing == o.border_hspacing && border_vspacing == o.border_vspacing && quotes == o.quotes && widows == o.widows && orphans == o.orphans ; // doesn't work because structs are not packed //return memcmp(this, &o, sizeof(*this))==0;}RenderStyle::RenderStyle(){// counter++; if (!_default) _default = new RenderStyle(true); box = _default->box; visual = _default->visual; background = _default->background; surround = _default->surround; css3NonInheritedData = _default->css3NonInheritedData; css3InheritedData = _default->css3InheritedData; inherited = _default->inherited; setBitDefaults(); pseudoStyle = 0; content = 0; counter_reset = 0; counter_increment = 0;}RenderStyle::RenderStyle(bool){ setBitDefaults(); box.init(); visual.init(); background.init(); surround.init(); css3NonInheritedData.init();#ifdef APPLE_CHANGES // ### yet to be merged css3NonInheritedData.access()->flexibleBox.init();#endif css3NonInheritedData.access()->marquee.init(); css3InheritedData.init(); inherited.init(); pseudoStyle = 0; content = 0; counter_reset = 0; counter_increment = 0;}RenderStyle::RenderStyle(const RenderStyle& o) : Shared<RenderStyle>(), inherited_flags( o.inherited_flags ), noninherited_flags( o.noninherited_flags ), box( o.box ), visual( o.visual ), background( o.background ), surround( o.surround ), css3NonInheritedData( o.css3NonInheritedData ), css3InheritedData( o.css3InheritedData ), inherited( o.inherited ), pseudoStyle( 0 ), content( o.content ), counter_reset(o.counter_reset), counter_increment(o.counter_increment){ if (counter_reset) counter_reset->ref(); if (counter_increment) counter_increment->ref();}void RenderStyle::inheritFrom(const RenderStyle* inheritParent){ css3InheritedData = inheritParent->css3InheritedData; inherited = inheritParent->inherited; inherited_flags = inheritParent->inherited_flags; // Simulate ":after,:before { white-space: pre-line }" if (styleType() == AFTER || styleType() == BEFORE) setWhiteSpace(PRE_LINE);}RenderStyle::~RenderStyle(){ RenderStyle *ps = pseudoStyle; RenderStyle *prev = 0; while (ps) { prev = ps; ps = ps->pseudoStyle; // to prevent a double deletion. // this works only because the styles below aren't really shared // Dirk said we need another construct as soon as these are shared prev->pseudoStyle = 0; prev->deref(); } delete content; if (counter_reset) counter_reset->deref(); if (counter_increment) counter_increment->deref();}bool RenderStyle::operator==(const RenderStyle& o) const{// compare everything except the pseudoStyle pointer return (inherited_flags == o.inherited_flags && noninherited_flags == o.noninherited_flags && box == o.box && visual == o.visual && background == o.background && surround == o.surround && css3NonInheritedData == o.css3NonInheritedData && css3InheritedData == o.css3InheritedData && inherited == o.inherited);}RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid){ RenderStyle *ps = 0; if (noninherited_flags.f._styleType==NOPSEUDO) for (ps = pseudoStyle; ps; ps = ps->pseudoStyle) if (ps->noninherited_flags.f._styleType==pid) break; return ps;}RenderStyle* RenderStyle::addPseudoStyle(PseudoId pid){ RenderStyle *ps = getPseudoStyle(pid); if (!ps) { switch (pid) { case FIRST_LETTER: // pseudo-elements (FIRST_LINE has a special handling) case BEFORE: case AFTER: ps = new RenderStyle(); break; default: ps = new RenderStyle(*this); // use the real copy constructor to get an identical copy } ps->ref(); ps->noninherited_flags.f._styleType = pid; ps->pseudoStyle = pseudoStyle; pseudoStyle = ps; } return ps;}void RenderStyle::removePseudoStyle(PseudoId pid){ RenderStyle *ps = pseudoStyle; RenderStyle *prev = this; while (ps) { if (ps->noninherited_flags.f._styleType==pid) { prev->pseudoStyle = ps->pseudoStyle; ps->deref(); return; } prev = ps; ps = ps->pseudoStyle; }}bool RenderStyle::inheritedNotEqual( RenderStyle *other ) const{ return ( inherited_flags != other->inherited_flags || inherited != other->inherited || css3InheritedData != other->css3InheritedData );}/* compares two styles. The result gives an idea of the action that needs to be taken when replacing the old style with a new one. CbLayout: The containing block of the object needs a relayout. Layout: the RenderObject needs a relayout after the style change Visible: The change is visible, but no relayout is needed NonVisible: The object does need neither repaint nor relayout after the change. ### TODO: A lot can be optimised here based on the display type, lots of optimisations are unimplemented, and currently result in the worst case result causing a relayout of the containing block.*/RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const{ // we anyway assume they are the same// EDisplay _display : 5; // NonVisible:// ECursor _cursor_style : 4;// EUserInput _user_input : 2; as long as :enabled is not impl'd// ### this needs work to know more exactly if we need a relayout// or just a repaint// non-inherited attributes// DataRef<StyleBoxData> box;// DataRef<StyleVisualData> visual;// DataRef<StyleSurroundData> surround;// inherited attributes// DataRef<StyleInheritedData> inherited; if ( *box.get() != *other->box.get() || *visual.get() != *other->visual.get() || *surround.get() != *other->surround.get() || !(inherited->indent == other->inherited->indent) || !(inherited->line_height == other->inherited->line_height) || !(inherited->style_image == other->inherited->style_image) || !(inherited->font == other->inherited->font) || !(inherited->border_hspacing == other->inherited->border_hspacing) || !(inherited->border_vspacing == other->inherited->border_vspacing) || !(inherited_flags.f._visuallyOrdered == other->inherited_flags.f._visuallyOrdered) || !(inherited_flags.f._htmlHacks == other->inherited_flags.f._htmlHacks) ) return CbLayout; // changes causing Layout changes:// only for tables:// _border_collapse// EEmptyCell _empty_cells : 2 ;// ECaptionSide _caption_side : 2;// ETableLayout _table_layout : 1;// EPosition _position : 2;// EFloat _floating : 2; if ( ((int)noninherited_flags.f._display) >= TABLE ) { if ( !(inherited_flags.f._empty_cells == other->inherited_flags.f._empty_cells) || !(inherited_flags.f._caption_side == other->inherited_flags.f._caption_side) || !(inherited_flags.f._border_collapse == other->inherited_flags.f._border_collapse) || !(noninherited_flags.f._table_layout == other->noninherited_flags.f._table_layout) || !(noninherited_flags.f._position == other->noninherited_flags.f._position) || !(noninherited_flags.f._floating == other->noninherited_flags.f._floating) || !(noninherited_flags.f._flowAroundFloats == other->noninherited_flags.f._flowAroundFloats) || !(noninherited_flags.f._unicodeBidi == other->noninherited_flags.f._unicodeBidi) ) return CbLayout; }// only for lists:// EListStyleType _list_style_type : 5 ;// EListStylePosition _list_style_position :1; if (noninherited_flags.f._display == LIST_ITEM ) { if ( !(inherited_flags.f._list_style_type == other->inherited_flags.f._list_style_type) || !(inherited_flags.f._list_style_position == other->inherited_flags.f._list_style_position) ) return Layout; }// ### These could be better optimised// ETextAlign _text_align : 3;// ETextTransform _text_transform : 4;// EDirection _direction : 1;// EWhiteSpace _white_space : 2;// EClear _clear : 2; if ( !(inherited_flags.f._text_align == other->inherited_flags.f._text_align) || !(inherited_flags.f._text_transform == other->inherited_flags.f._text_transform) || !(inherited_flags.f._direction == other->inherited_flags.f._direction) || !(inherited_flags.f._white_space == other->inherited_flags.f._white_space) || !(noninherited_flags.f._clear == other->noninherited_flags.f._clear) ) return Layout;// only for inline:// EVerticalAlign _vertical_align : 4; if ( !(noninherited_flags.f._display == INLINE) && !(noninherited_flags.f._vertical_align == other->noninherited_flags.f._vertical_align) ) return Layout; // Visible:// EVisibility _visibility : 2;// EOverflow _overflow : 4 ;// int _text_decorations : 4;// DataRef<StyleBackgroundData> background; if (inherited->color != other->inherited->color || !(inherited_flags.f._visibility == other->inherited_flags.f._visibility) || !(noninherited_flags.f._overflow == other->noninherited_flags.f._overflow) || !(inherited_flags.f._text_decorations == other->inherited_flags.f._text_decorations) || !(noninherited_flags.f._hasClip == other->noninherited_flags.f._hasClip) || visual->textDecoration != other->visual->textDecoration || *background.get() != *other->background.get() || css3NonInheritedData->opacity != other->css3NonInheritedData->opacity || !css3InheritedData->shadowDataEquivalent(*other->css3InheritedData.get()) ) return Visible; return Equal;}RenderStyle* RenderStyle::_default = 0;void RenderStyle::cleanup(){ delete _default; _default = 0;}void RenderStyle::setPaletteColor(QPalette::ColorGroup g, QColorGroup::ColorRole r, const QColor& c){ visual.access()->palette.setColor(g,r,c);}void RenderStyle::adjustBackgroundLayers(){ if (backgroundLayers()->next()) { // First we cull out layers that have no properties set. accessBackgroundLayers()->cullEmptyLayers(); // Next we repeat patterns into layers that don't have some properties set. accessBackgroundLayers()->fillUnsetProperties(); }}void RenderStyle::setClip( Length top, Length right, Length bottom, Length left ){ StyleVisualData *data = visual.access(); data->clip.top = top; data->clip.right = right; data->clip.bottom = bottom; data->clip.left = left;}void RenderStyle::setQuotes(DOM::QuotesValueImpl* q){ DOM::QuotesValueImpl *t = inherited->quotes; inherited.access()->quotes = q; if (q) q->ref(); if (t) t->deref();}QString RenderStyle::openQuote(int level) const{ if (inherited->quotes) return inherited->quotes->openQuote(level); else return "\""; // 0 is default quotes}QString RenderStyle::closeQuote(int level) const{ if (inherited->quotes) return inherited->quotes->closeQuote(level); else return "\""; // 0 is default quotes}bool RenderStyle::contentDataEquivalent(RenderStyle* otherStyle){ ContentData* c1 = content; ContentData* c2 = otherStyle->content; while (c1 && c2) { if (c1->_contentType != c2->_contentType) return false; if (c1->_contentType == CONTENT_TEXT) { DOM::DOMString c1Str(c1->_content.text); DOM::DOMString c2Str(c2->_content.text); if (c1Str != c2Str) return false; } else if (c1->_contentType == CONTENT_OBJECT) { if (c1->_content.object != c2->_content.object) return false; } else if (c1->_contentType == CONTENT_COUNTER) { if (c1->_content.counter != c2->_content.counter) return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -