Pseudo elements
David Hyatt
hyatt at apple.com
Tue Oct 21 16:20:59 CEST 2003
This is the first of several patches to clean up pseudo element
handling. This patch is probably not something you can merge easily
yet, since it depends on changes that have been made since Safari v85,
but I'll log it here so that when we do get the newest WebCore pushed,
you'll be able to see the diff.
This patch changes style resolution on pseudo-element styles to be lazy
and to only happen if the front end explicitly asks for a pseudo-style.
It also paves the way for resolving styles relative to arbitrary
parent styles (necessary for first-line and first-letter).
My second patch is going to be a general first-line cleanup, and then
my third patch will be a general first-letter cleanup.
dave
(hyatt at apple.com)
-------------- next part --------------
Index: khtml/css/cssstyleselector.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssstyleselector.cpp,v
retrieving revision 1.101
diff -u -p -r1.101 khtml/css/cssstyleselector.cpp
--- khtml/css/cssstyleselector.cpp 2003/10/20 18:18:02 1.101
+++ khtml/css/cssstyleselector.cpp 2003/10/21 22:10:36
@@ -308,29 +308,39 @@ static inline void bubbleSort( CSSOrdere
}
}
-RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e)
+void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultParent)
{
- if (!e->getDocument()->haveStylesheetsLoaded()) {
- if (!styleNotYetAvailable) {
- styleNotYetAvailable = new RenderStyle();
- styleNotYetAvailable->setDisplay(NONE);
- styleNotYetAvailable->ref();
- }
- return styleNotYetAvailable;
- }
-
// set some variables we will need
::encodedurl = &encodedurl;
pseudoState = PseudoUnknown;
-
+
element = e;
parentNode = e->parentNode();
- parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;
+ if (defaultParent)
+ parentStyle = defaultParent;
+ else
+ parentStyle = (parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;
view = element->getDocument()->view();
isXMLDoc = !element->getDocument()->isHTMLDocument();
part = view->part();
settings = part->settings();
paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();
+
+ style = 0;
+}
+
+RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defaultParent)
+{
+ if (!e->getDocument()->haveStylesheetsLoaded()) {
+ if (!styleNotYetAvailable) {
+ styleNotYetAvailable = new RenderStyle();
+ styleNotYetAvailable->setDisplay(NONE);
+ styleNotYetAvailable->ref();
+ }
+ return styleNotYetAvailable;
+ }
+
+ initForStyleResolve(e, defaultParent);
style = new RenderStyle();
if( parentStyle )
@@ -339,8 +349,7 @@ RenderStyle *CSSStyleSelector::styleForE
parentStyle = style;
unsigned int numPropsToApply = 0;
- unsigned int numPseudoProps = 0;
-
+
// try to sort out most style rules as early as possible.
// ### implement CSS3 namespace support
int cssTagId = (e->id() & NodeImpl::IdLocalMask);
@@ -366,17 +375,9 @@ RenderStyle *CSSStyleSelector::styleForE
}
propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j];
}
- } else if ( selectorCache[i].state == AppliesPseudo ) {
- for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
- for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
- if (numPseudoProps >= pseudoPropsSize ) {
- pseudoPropsSize *= 2;
- pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
- }
- pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
- properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
- }
}
+ else if (selectorCache[i].state == AppliesPseudo)
+ style->setHasPseudoStyle((RenderStyle::PseudoId)selectors[i]->pseudoId);
}
else
selectorCache[i].state = Invalid;
@@ -392,8 +393,7 @@ RenderStyle *CSSStyleSelector::styleForE
numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );
bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
- bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
-
+
//qDebug("applying properties, count=%d", propsToApply->count() );
// we can't apply style rules without a view() and a part. This
@@ -422,63 +422,100 @@ RenderStyle *CSSStyleSelector::styleForE
// Clean up our style object's display and text decorations (among other fixups).
adjustRenderStyle(style, e);
+ }
+
+ // Now return the style.
+ return style;
+}
+
+RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudoStyle,
+ ElementImpl* e, RenderStyle* parentStyle)
+{
+ if (!e)
+ return 0;
+
+ if (!e->getDocument()->haveStylesheetsLoaded()) {
+ if (!styleNotYetAvailable) {
+ styleNotYetAvailable = new RenderStyle();
+ styleNotYetAvailable->setDisplay(NONE);
+ styleNotYetAvailable->ref();
+ }
+ return styleNotYetAvailable;
+ }
+
+ initForStyleResolve(e, parentStyle);
+
+ unsigned int numPseudoProps = 0;
+
+ // try to sort out most style rules as early as possible.
+ // ### implement CSS3 namespace support
+ int cssTagId = (e->id() & NodeImpl::IdLocalMask);
+ int schecked = 0;
+
+ for ( unsigned int i = 0; i < selectors_size; i++ ) {
+ int tag = selectors[i]->tag;
+ if ( cssTagId == tag || tag == -1 ) {
+ ++schecked;
+
+ checkSelector( i, e, pseudoStyle );
+
+ if ( selectorCache[i].state == AppliesPseudo ) {
+ for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
+ for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
+ if (numPseudoProps >= pseudoPropsSize ) {
+ pseudoPropsSize *= 2;
+ pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
+ }
+ pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
+ properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
+ }
+ }
+ }
+ else
+ selectorCache[i].state = Invalid;
+ }
+
+ if (numPseudoProps == 0)
+ return 0;
+
+ style = new RenderStyle();
+ if( parentStyle )
+ style->inheritFrom( parentStyle );
+ else
+ parentStyle = style;
+ style->noninherited_flags._styleType = pseudoStyle;
+ bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
+
+ // we can't apply style rules without a view() and a part. This
+ // tends to happen on delayed destruction of widget Renderobjects
+ if ( part ) {
+ fontDirty = false;
if ( numPseudoProps ) {
- fontDirty = false;
+ fontDirty = false;
//qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() );
for (unsigned int i = 0; i < numPseudoProps; ++i) {
- if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
- // we are past the font properties, time to update to the
- // correct font
- //We have to do this for all pseudo styles
- RenderStyle *pseudoStyle = style->pseudoStyle;
- while ( pseudoStyle ) {
- checkForGenericFamilyChange(pseudoStyle, style);
- pseudoStyle->htmlFont().update( paintDeviceMetrics );
- pseudoStyle = pseudoStyle->pseudoStyle;
- }
- fontDirty = false;
- }
-
- RenderStyle *pseudoStyle;
- pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId);
- if (!pseudoStyle)
- {
- pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId);
- if (pseudoStyle)
- pseudoStyle->inheritFrom( style );
- }
-
- RenderStyle* oldStyle = style;
- RenderStyle* oldParentStyle = parentStyle;
- parentStyle = style;
- style = pseudoStyle;
- if ( pseudoStyle ) {
- DOM::CSSProperty *prop = pseudoProps[i]->prop;
- applyRule( prop->m_id, prop->value() );
+ if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
+ // we are past the font properties, time to update to the
+ // correct font
+ style->htmlFont().update( paintDeviceMetrics );
+ fontDirty = false;
}
- style = oldStyle;
- parentStyle = oldParentStyle;
+
+ DOM::CSSProperty *prop = pseudoProps[i]->prop;
+ applyRule( prop->m_id, prop->value() );
}
-
- if ( fontDirty ) {
- RenderStyle *pseudoStyle = style->pseudoStyle;
- while ( pseudoStyle ) {
- checkForGenericFamilyChange(pseudoStyle, style);
- pseudoStyle->htmlFont().update( paintDeviceMetrics );
- pseudoStyle = pseudoStyle->pseudoStyle;
- }
- }
+
+ if ( fontDirty ) {
+ checkForGenericFamilyChange(style, parentStyle);
+ style->htmlFont().update( paintDeviceMetrics );
+ }
}
}
-
- // Now adjust all our pseudo-styles.
- RenderStyle *pseudoStyle = style->pseudoStyle;
- while (pseudoStyle) {
- adjustRenderStyle(pseudoStyle, 0);
- pseudoStyle = pseudoStyle->pseudoStyle;
- }
-
+
+ // Do the post-resolve fixups on the style.
+ adjustRenderStyle(style, 0);
+
// Now return the style.
return style;
}
@@ -685,7 +722,7 @@ static void checkPseudoState( DOM::Eleme
pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;
}
-void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e)
+void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e, RenderStyle::PseudoId pseudo)
{
dynamicPseudo = RenderStyle::NOPSEUDO;
@@ -704,8 +741,9 @@ void CSSStyleSelector::checkSelector(int
(sel->match == CSSSelector::Pseudo &&
(sel->pseudoType() == CSSSelector::PseudoHover ||
sel->pseudoType() == CSSSelector::PseudoActive)));
- bool affectedByHover = style->affectedByHoverRules();
- bool affectedByActive = style->affectedByActiveRules();
+ bool affectedByHover = style ? style->affectedByHoverRules() : false;
+ bool affectedByActive = style ? style->affectedByActiveRules() : false;
+ bool havePseudo = pseudo != RenderStyle::NOPSEUDO;
// first selector has to match
if(!checkOneSelector(sel, e)) return;
@@ -715,6 +753,12 @@ void CSSStyleSelector::checkSelector(int
while((sel = sel->tagHistory))
{
if (!n->isElementNode()) return;
+ if (relation != CSSSelector::SubSelector) {
+ subject = false;
+ if (havePseudo && dynamicPseudo != pseudo)
+ return;
+ }
+
switch(relation)
{
case CSSSelector::Descendant:
@@ -722,8 +766,7 @@ void CSSStyleSelector::checkSelector(int
bool found = false;
while(!found)
{
- subject = false;
- n = n->parentNode();
+ n = n->parentNode();
if(!n || !n->isElementNode()) return;
ElementImpl *elem = static_cast<ElementImpl *>(n);
if(checkOneSelector(sel, elem)) found = true;
@@ -732,7 +775,6 @@ void CSSStyleSelector::checkSelector(int
}
case CSSSelector::Child:
{
- subject = false;
n = n->parentNode();
if (!strictParsing)
while (n && n->implicitNode()) n = n->parentNode();
@@ -743,7 +785,6 @@ void CSSStyleSelector::checkSelector(int
}
case CSSSelector::Sibling:
{
- subject = false;
n = n->previousSibling();
while( n && !n->isElementNode() )
n = n->previousSibling();
@@ -773,6 +814,9 @@ void CSSStyleSelector::checkSelector(int
relation = sel->relation;
}
+ if (subject && havePseudo && dynamicPseudo != pseudo)
+ return;
+
// disallow *:hover, *:active, and *:hover:active except for links
if (onlyHoverActive && subject) {
if (pseudoState == PseudoUnknown)
@@ -799,7 +843,6 @@ void CSSStyleSelector::checkSelector(int
bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
{
-
if(!e)
return false;
@@ -985,7 +1028,7 @@ bool CSSStyleSelector::checkOneSelector(
// If we're in quirks mode, then hover should never match anchors with no
// href. This is important for sites like wsj.com.
if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
- if (element == e)
+ if (element == e && style)
style->setAffectedByHoverRules(true);
if (e->renderer()) {
if (element != e)
@@ -1005,7 +1048,7 @@ bool CSSStyleSelector::checkOneSelector(
// If we're in quirks mode, then :active should never match anchors with no
// href.
if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
- if (element == e)
+ if (element == e && style)
style->setAffectedByActiveRules(true);
else if (e->renderer())
e->renderer()->style()->setAffectedByActiveRules(true);
Index: khtml/css/cssstyleselector.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssstyleselector.h,v
retrieving revision 1.18
diff -u -p -r1.18 khtml/css/cssstyleselector.h
--- khtml/css/cssstyleselector.h 2003/08/20 22:03:24 1.18
+++ khtml/css/cssstyleselector.h 2003/10/21 22:10:36
@@ -125,8 +125,11 @@ namespace khtml
static void loadDefaultStyle(const KHTMLSettings *s = 0);
static void clear();
- RenderStyle *styleForElement(DOM::ElementImpl *e);
-
+ void initForStyleResolve(DOM::ElementImpl* e, RenderStyle* parentStyle);
+ RenderStyle *styleForElement(DOM::ElementImpl* e, RenderStyle* parentStyle=0);
+ RenderStyle* pseudoStyleForElement(RenderStyle::PseudoId pseudoStyle,
+ DOM::ElementImpl* e, RenderStyle* parentStyle=0);
+
QValueList<int> fontSizes() const { return m_fontSizes; }
bool strictParsing;
@@ -144,7 +147,8 @@ namespace khtml
/* checks if the complete selector (which can be build up from a few CSSSelector's
with given relationships matches the given Element */
- void checkSelector(int selector, DOM::ElementImpl *e);
+ void checkSelector(int selector, DOM::ElementImpl *e,
+ RenderStyle::PseudoId pseudo = RenderStyle::NOPSEUDO);
/* checks if the selector matches the given Element */
bool checkOneSelector(DOM::CSSSelector *selector, DOM::ElementImpl *e);
Index: khtml/rendering/render_block.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_block.cpp,v
retrieving revision 1.68
diff -u -p -r1.68 khtml/rendering/render_block.cpp
--- khtml/rendering/render_block.cpp 2003/10/20 07:07:54 1.68
+++ khtml/rendering/render_block.cpp 2003/10/21 22:10:36
@@ -103,8 +103,8 @@ void RenderBlock::addChildToFlow(RenderO
RenderStyle* pseudoStyle=0;
if ((!firstChild() || firstChild() == beforeChild) &&
- (newChild->isInline() || newChild->isText()) &&
- (pseudoStyle=style()->getPseudoStyle(RenderStyle::FIRST_LETTER)))
+ (newChild->isInline() || (newChild->isText() && !newChild->isBR())) &&
+ (pseudoStyle=getPseudoStyle(RenderStyle::FIRST_LETTER, style(true))))
{
// Drill into inlines looking for our first text child.
RenderObject* textChild = newChild;
Index: khtml/rendering/render_container.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_container.cpp,v
retrieving revision 1.45
diff -u -p -r1.45 khtml/rendering/render_container.cpp
--- khtml/rendering/render_container.cpp 2003/10/20 18:18:02 1.45
+++ khtml/rendering/render_container.cpp 2003/10/21 22:10:36
@@ -215,7 +215,7 @@ void RenderContainer::updatePseudoChild(
if (style()->styleType() == RenderStyle::BEFORE || style()->styleType() == RenderStyle::AFTER)
return;
- RenderStyle* pseudo = style()->getPseudoStyle(type);
+ RenderStyle* pseudo = getPseudoStyle(type);
// Whether or not we currently have generated content attached.
bool oldContentPresent = child && (child->style()->styleType() == type);
Index: khtml/rendering/render_object.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.cpp,v
retrieving revision 1.105
diff -u -p -r1.105 khtml/rendering/render_object.cpp
--- khtml/rendering/render_object.cpp 2003/10/17 22:32:13 1.105
+++ khtml/rendering/render_object.cpp 2003/10/21 22:10:36
@@ -29,6 +29,7 @@
#include "rendering/render_canvas.h"
#include "xml/dom_elementimpl.h"
#include "xml/dom_docimpl.h"
+#include "css/cssstyleselector.h"
#include "misc/htmlhashes.h"
#include <kdebug.h>
#include <qpainter.h>
@@ -1209,7 +1210,7 @@ void RenderObject::setStyle(RenderStyle
setShouldPaintBackgroundOrBorder(m_style->backgroundColor().isValid() ||
m_style->hasBorder() || nb );
- m_hasFirstLine = (style->getPseudoStyle(RenderStyle::FIRST_LINE) != 0);
+ m_hasFirstLine = getPseudoStyle(RenderStyle::FIRST_LINE);
if (affectsParentBlock)
handleDynamicFloatPositionChange();
@@ -1744,6 +1745,32 @@ InlineBox* RenderObject::createInlineBox
{
KHTMLAssert(!isRootLineBox);
return new (renderArena()) InlineBox(this);
+}
+
+RenderStyle* RenderObject::style(bool firstLine) const {
+ RenderStyle *s = m_style;
+ if (firstLine && hasFirstLine()) {
+ RenderStyle *pseudoStyle = getPseudoStyle(RenderStyle::FIRST_LINE);
+ if (pseudoStyle)
+ s = pseudoStyle;
+ }
+ return s;
+}
+
+RenderStyle* RenderObject::getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle) const
+{
+ if (!style()->hasPseudoStyle(pseudo))
+ return 0;
+
+ DOM::NodeImpl* node = element();
+ if (isText())
+ node = element()->parentNode();
+ if (!node) return 0;
+
+ if (!parentStyle)
+ parentStyle = style();
+
+ return document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node), parentStyle);
}
void RenderObject::getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
Index: khtml/rendering/render_object.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.h,v
retrieving revision 1.86
diff -u -p -r1.86 khtml/rendering/render_object.h
--- khtml/rendering/render_object.h 2003/10/17 22:32:13 1.86
+++ khtml/rendering/render_object.h 2003/10/21 22:10:36
@@ -253,6 +253,8 @@ public:
bool isSelectionBorder() const { return m_isSelectionBorder; }
bool recalcMinMax() const { return m_recalcMinMax; }
+ RenderStyle* getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle = 0) const;
+
RenderCanvas* canvas() const;
// don't even think about making this method virtual!
@@ -558,15 +560,7 @@ public:
virtual short maxWidth() const { return 0; }
RenderStyle* style() const { return m_style; }
- RenderStyle* style( bool firstLine ) const {
- RenderStyle *s = m_style;
- if( firstLine && hasFirstLine() ) {
- RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
- if ( pseudoStyle )
- s = pseudoStyle;
- }
- return s;
- }
+ RenderStyle* style( bool firstLine ) const;
void getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
QColor& linethrough, bool quirksMode=false);
Index: khtml/rendering/render_style.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.cpp,v
retrieving revision 1.29
diff -u -p -r1.29 khtml/rendering/render_style.cpp
--- khtml/rendering/render_style.cpp 2003/10/17 22:32:13 1.29
+++ khtml/rendering/render_style.cpp 2003/10/21 22:10:36
@@ -332,36 +332,59 @@ bool RenderStyle::isStyleAvailable() con
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 };
+
+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;
+ 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;
+ while (ps) {
+ if (ps->noninherited_flags._styleType==pid)
+ break;
+
+ ps = ps->pseudoStyle;
+ }
}
- }
return ps;
}
-RenderStyle* RenderStyle::addPseudoStyle(PseudoId pid)
+void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
{
- RenderStyle *ps = getPseudoStyle(pid);
-
- if (!ps)
- {
- ps = new RenderStyle(); // So that noninherited flags are reset.
- ps->ref();
- ps->noninherited_flags._styleType = pid;
- ps->pseudoStyle = pseudoStyle;
-
- pseudoStyle = ps;
- }
-
- return ps;
+ if (!pseudo) return;
+
+ pseudo->ref();
+ pseudo->pseudoStyle = pseudoStyle;
+ pseudoStyle = pseudo;
}
void RenderStyle::removePseudoStyle(PseudoId pid)
Index: khtml/rendering/render_style.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.h,v
retrieving revision 1.32
diff -u -p -r1.32 khtml/rendering/render_style.h
--- khtml/rendering/render_style.h 2003/10/17 22:32:13 1.32
+++ khtml/rendering/render_style.h 2003/10/21 22:10:36
@@ -685,6 +685,7 @@ protected:
(_styleType == other._styleType) &&
(_affectedByHover == other._affectedByHover) &&
(_affectedByActive == other._affectedByActive) &&
+ (_pseudoBits == other._pseudoBits) &&
(_unicodeBidi == other._unicodeBidi);
}
@@ -707,6 +708,7 @@ protected:
PseudoId _styleType : 3;
bool _affectedByHover : 1;
bool _affectedByActive : 1;
+ int _pseudoBits : 5;
EUnicodeBidi _unicodeBidi : 2;
} noninherited_flags;
@@ -723,7 +725,7 @@ protected:
// list of associated pseudo styles
RenderStyle* pseudoStyle;
-
+
// added this here, so we can get rid of the vptr in this class.
// makes up for the same size.
ContentData *content;
@@ -766,6 +768,7 @@ protected:
noninherited_flags._styleType = NOPSEUDO;
noninherited_flags._affectedByHover = false;
noninherited_flags._affectedByActive = false;
+ noninherited_flags._pseudoBits = 0;
noninherited_flags._unicodeBidi = UBNormal;
}
@@ -783,8 +786,7 @@ public:
PseudoId styleType() { return noninherited_flags._styleType; }
RenderStyle* getPseudoStyle(PseudoId pi);
- RenderStyle* addPseudoStyle(PseudoId pi);
- bool hasPseudoStyle() const { return pseudoStyle; }
+ void addPseudoStyle(RenderStyle* pseudo);
void removePseudoStyle(PseudoId pi);
bool affectedByHoverRules() const { return noninherited_flags._affectedByHover; }
@@ -803,6 +805,9 @@ public:
void setVisuallyOrdered(bool b) { inherited_flags._visuallyOrdered = b; }
bool isStyleAvailable() const;
+
+ bool hasPseudoStyle(PseudoId pseudo) const;
+ void setHasPseudoStyle(PseudoId pseudo);
// attribute getter methods
Index: khtml/rendering/render_text.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_text.cpp,v
retrieving revision 1.87
diff -u -p -r1.87 khtml/rendering/render_text.cpp
--- khtml/rendering/render_text.cpp 2003/10/20 07:07:54 1.87
+++ khtml/rendering/render_text.cpp 2003/10/21 22:10:37
@@ -86,7 +86,7 @@ void InlineTextBox::paintSelection(const
if (textColor == c)
c = QColor(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
- RenderStyle* pseudoStyle = object()->style()->getPseudoStyle(RenderStyle::SELECTION);
+ RenderStyle* pseudoStyle = object()->getPseudoStyle(RenderStyle::SELECTION);
if (pseudoStyle && pseudoStyle->backgroundColor().isValid())
c = pseudoStyle->backgroundColor();
p->setPen(c); // Don't draw text at all!
@@ -577,7 +577,7 @@ void RenderText::paintObject(QPainter *p
int tx, int ty, PaintAction paintAction)
{
int ow = style()->outlineWidth();
- RenderStyle* pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
+ RenderStyle* pseudoStyle = hasFirstLine() ? getPseudoStyle(RenderStyle::FIRST_LINE) : 0;
int d = style()->textDecorationsInEffect();
InlineTextBox f(0, y-ty);
int si = m_lines.findFirstMatching(&f);
@@ -701,7 +701,7 @@ void RenderText::paintObject(QPainter *p
QColor selectionColor = p->pen().color();
ShadowData* selectionTextShadow = 0;
if (haveSelection) {
- RenderStyle* pseudoStyle = style()->getPseudoStyle(RenderStyle::SELECTION);
+ RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);
if (pseudoStyle) {
if (pseudoStyle->color() != selectionColor || pseudoStyle->textShadow()) {
if (!paintSelectedTextOnly)
@@ -1338,7 +1338,7 @@ const Font *RenderText::htmlFont(bool fi
{
const Font *f = 0;
if( firstLine && hasFirstLine() ) {
- RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
+ RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::FIRST_LINE);
if ( pseudoStyle )
f = &pseudoStyle->htmlFont();
} else {
-------------- next part --------------
More information about the Khtml-devel
mailing list