📄 render_style.cpp
字号:
;
}
StyleCSS3InheritedData::StyleCSS3InheritedData()
:Shared<StyleCSS3InheritedData>(), textShadow(0), userModify(READ_ONLY), wordWrap(WBNORMAL),
nbspMode(NBNORMAL), khtmlLineBreak(LBNORMAL)
#if APPLE_CHANGES
, textSizeAdjust(RenderStyle::initialTextSizeAdjust())
#endif
{
}
StyleCSS3InheritedData::StyleCSS3InheritedData(const StyleCSS3InheritedData& o)
:Shared<StyleCSS3InheritedData>()
{
textShadow = o.textShadow ? new ShadowData(*o.textShadow) : 0;
userModify = o.userModify;
wordWrap = o.wordWrap;
nbspMode = o.nbspMode;
khtmlLineBreak = o.khtmlLineBreak;
#if APPLE_CHANGES
textSizeAdjust = o.textSizeAdjust;
#endif
}
StyleCSS3InheritedData::~StyleCSS3InheritedData()
{
delete textShadow;
}
bool StyleCSS3InheritedData::operator==(const StyleCSS3InheritedData& o) const
{
return (userModify == o.userModify) && shadowDataEquivalent(o) && (wordWrap == o.wordWrap) &&
(nbspMode == o.nbspMode) && (khtmlLineBreak == o.khtmlLineBreak)
#if APPLE_CHANGES
&& (textSizeAdjust == o.textSizeAdjust)
#endif
;
}
bool StyleCSS3InheritedData::shadowDataEquivalent(const StyleCSS3InheritedData& o) const
{
if (!textShadow && o.textShadow || textShadow && !o.textShadow)
return false;
if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
return false;
return true;
}
StyleInheritedData::StyleInheritedData()
: indent( RenderStyle::initialTextIndent() ), line_height( RenderStyle::initialLineHeight() ),
style_image( RenderStyle::initialListStyleImage() ),
cursor_image( 0 ), font(), color( RenderStyle::initialColor() ),
horizontal_border_spacing( RenderStyle::initialHorizontalBorderSpacing() ),
vertical_border_spacing( RenderStyle::initialVerticalBorderSpacing() ),
widows( RenderStyle::initialWidows() ), orphans( RenderStyle::initialOrphans() ),
page_break_inside( RenderStyle::initialPageBreak() )
{
}
StyleInheritedData::~StyleInheritedData()
{
}
StyleInheritedData::StyleInheritedData(const StyleInheritedData& o )
: Shared<StyleInheritedData>(),
indent( o.indent ), line_height( o.line_height ), style_image( o.style_image ),
cursor_image( o.cursor_image ), font( o.font ),
color( o.color ),
horizontal_border_spacing( o.horizontal_border_spacing ),
vertical_border_spacing( o.vertical_border_spacing ),
widows(o.widows), orphans(o.orphans), page_break_inside(o.page_break_inside)
{
}
bool StyleInheritedData::operator==(const StyleInheritedData& o) const
{
return
indent == o.indent &&
line_height == o.line_height &&
style_image == o.style_image &&
cursor_image == o.cursor_image &&
font == o.font &&
color == o.color &&
horizontal_border_spacing == o.horizontal_border_spacing &&
vertical_border_spacing == o.vertical_border_spacing &&
widows == o.widows &&
orphans == o.orphans &&
page_break_inside == o.page_break_inside;
}
// ----------------------------------------------------------
void* RenderStyle::operator new(size_t sz, RenderArena* renderArena) throw()
{
return renderArena->allocate(sz);
}
void RenderStyle::operator delete(void* ptr, size_t sz)
{
// Stash size where detach can find it.
*(size_t *)ptr = sz;
}
void RenderStyle::arenaDelete(RenderArena *arena)
{
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(arena);
}
delete content;
delete this;
// Recover the size left there for us by operator delete and free the memory.
arena->free(*(size_t *)this, this);
}
RenderStyle::RenderStyle()
:m_pseudoState(PseudoUnknown), m_affectedByAttributeSelectors(false)
{
m_ref = 0;
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;
}
RenderStyle::RenderStyle(bool)
:m_pseudoState(PseudoUnknown), m_affectedByAttributeSelectors(false)
{
setBitDefaults();
box.init();
visual.init();
background.init();
surround.init();
css3NonInheritedData.init();
css3NonInheritedData.access()->flexibleBox.init();
css3NonInheritedData.access()->marquee.init();
css3InheritedData.init();
inherited.init();
pseudoStyle = 0;
content = 0;
m_ref = 1;
}
RenderStyle::RenderStyle(const RenderStyle& o)
: 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 ), m_pseudoState(o.m_pseudoState),
m_affectedByAttributeSelectors(false)
{
m_ref = 0;
}
void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
{
css3InheritedData = inheritParent->css3InheritedData;
inherited = inheritParent->inherited;
inherited_flags = inheritParent->inherited_flags;
}
RenderStyle::~RenderStyle()
{
}
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);
}
bool RenderStyle::isStyleAvailable() const
{
return this != CSSStyleSelector::styleNotYetAvailable;
}
enum EPseudoBit { NO_BIT = 0x0, BEFORE_BIT = 0x1, AFTER_BIT = 0x2, FIRST_LINE_BIT = 0x4,
FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10, FIRST_LINE_INHERITED_BIT = 0x20 };
static int pseudoBit(RenderStyle::PseudoId pseudo)
{
switch (pseudo) {
case RenderStyle::BEFORE:
return BEFORE_BIT;
case RenderStyle::AFTER:
return AFTER_BIT;
case RenderStyle::FIRST_LINE:
return FIRST_LINE_BIT;
case RenderStyle::FIRST_LETTER:
return FIRST_LETTER_BIT;
case RenderStyle::SELECTION:
return SELECTION_BIT;
case RenderStyle::FIRST_LINE_INHERITED:
return FIRST_LINE_INHERITED_BIT;
default:
return NO_BIT;
}
}
bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
{
return (pseudoBit(pseudo) & noninherited_flags._pseudoBits) != 0;
}
void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
{
noninherited_flags._pseudoBits |= pseudoBit(pseudo);
}
RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
{
RenderStyle *ps = 0;
if (noninherited_flags._styleType==NOPSEUDO) {
ps = pseudoStyle;
while (ps) {
if (ps->noninherited_flags._styleType==pid)
break;
ps = ps->pseudoStyle;
}
}
return ps;
}
void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
{
if (!pseudo) return;
pseudo->ref();
pseudo->pseudoStyle = pseudoStyle;
pseudoStyle = pseudo;
}
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 _effectiveDisplay : 5;
// NonVisible:
// ECursor _cursor_style : 4;
// ### 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->width != other->box->width ||
box->min_width != other->box->min_width ||
box->max_width != other->box->max_width ||
box->height != other->box->height ||
box->min_height != other->box->min_height ||
box->max_height != other->box->max_height ||
box->vertical_align != other->box->vertical_align ||
!(surround->margin == other->surround->margin) ||
!(surround->padding == other->surround->padding) ||
css3NonInheritedData->marginTopCollapse != other->css3NonInheritedData->marginTopCollapse ||
css3NonInheritedData->marginBottomCollapse != other->css3NonInheritedData->marginBottomCollapse ||
*css3NonInheritedData->flexibleBox.get() != *other->css3NonInheritedData->flexibleBox.get() ||
#if APPLE_CHANGES
(css3NonInheritedData->lineClamp != other->css3NonInheritedData->lineClamp) ||
(css3InheritedData->textSizeAdjust != other->css3InheritedData->textSizeAdjust) ||
#endif
(css3InheritedData->wordWrap != other->css3InheritedData->wordWrap) ||
(css3InheritedData->nbspMode != other->css3InheritedData->nbspMode) ||
(css3InheritedData->khtmlLineBreak != other->css3InheritedData->khtmlLineBreak) ||
!(inherited->indent == other->inherited->indent) ||
!(inherited->line_height == other->inherited->line_height) ||
!(inherited->style_image == other->inherited->style_image) ||
!(inherited->cursor_image == other->inherited->cursor_image) ||
!(inherited->font == other->inherited->font) ||
!(inherited->horizontal_border_spacing == other->inherited->horizontal_border_spacing) ||
!(inherited->vertical_border_spacing == other->inherited->vertical_border_spacing) ||
!(inherited_flags._box_direction == other->inherited_flags._box_direction) ||
!(inherited_flags._visuallyOrdered == other->inherited_flags._visuallyOrdered) ||
!(inherited_flags._htmlHacks == other->inherited_flags._htmlHacks) ||
!(noninherited_flags._position == other->noninherited_flags._position) ||
!(noninherited_flags._floating == other->noninherited_flags._floating) ||
!(noninherited_flags._originalDisplay == other->noninherited_flags._originalDisplay) ||
visual->colspan != other->visual->colspan ||
visual->counter_increment != other->visual->counter_increment ||
visual->counter_reset != other->visual->counter_reset ||
css3NonInheritedData->textOverflow != other->css3NonInheritedData->textOverflow)
return Layout;
// 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._effectiveDisplay) >= TABLE ) {
// Stupid gcc gives a compile error on
// a != other->b if a and b are bitflags. Using
// !(a== other->b) instead.
if ( !(inherited_flags._border_collapse == other->inherited_flags._border_collapse) ||
!(inherited_flags._empty_cells == other->inherited_flags._empty_cells) ||
!(inherited_flags._caption_side == other->inherited_flags._caption_side) ||
!(noninherited_flags._table_layout == other->noninherited_flags._table_layout))
return Layout;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -