Another one. This one was big.

This commit is contained in:
2025-03-03 00:37:28 -05:00
parent 82fcd7c1f8
commit 865e176e5d
2 changed files with 58 additions and 56 deletions

View File

@ -29,6 +29,9 @@ using namespace dw::core::style;
* *
* \todo Not necessary for dw::Image? (dw::Image also implements * \todo Not necessary for dw::Image? (dw::Image also implements
* lout::signal::ObservedObject.) * lout::signal::ObservedObject.)
*
* @todo (adam) This may be a case where shared/weak pointers can
* dramatically simplify things. TBD.
*/ */
class StyleImageDeletionReceiver: class StyleImageDeletionReceiver:
public lout::signal::ObservedObject::DeletionReceiver public lout::signal::ObservedObject::DeletionReceiver
@ -66,7 +69,6 @@ StyleEngine::StyleEngine (dw::core::Layout *layout,
FontAttrs font_attrs; FontAttrs font_attrs;
doctree = new Doctree (); doctree = new Doctree ();
stack = new lout::misc::SimpleVector <Node> (1);
cssContext = new CssContext (); cssContext = new CssContext ();
buildUserStyle (); buildUserStyle ();
this->layout = layout; this->layout = layout;
@ -77,7 +79,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout,
this->zoom = zoom; this->zoom = zoom;
stackPush (); stackPush ();
Node *n = stack->getLastRef (); Node *n = &stack.back ();
/* Create a dummy font, attribute, and tag for the bottom of the stack. */ /* Create a dummy font, attribute, and tag for the bottom of the stack. */
font_attrs.name = prefs.font_sans_serif; font_attrs.name = prefs.font_sans_serif;
@ -104,12 +106,11 @@ StyleEngine::~StyleEngine () {
endElement (doctree->top ()->element); endElement (doctree->top ()->element);
stackPop (); // dummy node on the bottom of the stack stackPop (); // dummy node on the bottom of the stack
assert (stack->size () == 0); assert (stack.size () == 0);
a_Url_free(pageUrl); a_Url_free(pageUrl);
a_Url_free(baseUrl); a_Url_free(baseUrl);
delete stack;
delete doctree; delete doctree;
delete cssContext; delete cssContext;
} }
@ -118,12 +119,11 @@ void StyleEngine::stackPush () {
static const Node emptyNode = { static const Node emptyNode = {
NULL, NULL, NULL, NULL, NULL, NULL, false, false, NULL NULL, NULL, NULL, NULL, NULL, NULL, false, false, NULL
}; };
stack.push_back( emptyNode );
stack->setSize (stack->size () + 1, emptyNode);
} }
void StyleEngine::stackPop () { void StyleEngine::stackPop () {
Node *n = stack->getRef (stack->size () - 1); Node *n = &stack.at (stack.size () - 1);
delete n->styleAttrProperties; delete n->styleAttrProperties;
delete n->styleAttrPropertiesImportant; delete n->styleAttrPropertiesImportant;
@ -134,7 +134,7 @@ void StyleEngine::stackPop () {
n->wordStyle->unref (); n->wordStyle->unref ();
if (n->backgroundStyle) if (n->backgroundStyle)
n->backgroundStyle->unref (); n->backgroundStyle->unref ();
stack->setSize (stack->size () - 1); stack.pop_back();
} }
/** /**
@ -144,13 +144,13 @@ void StyleEngine::startElement (int element, BrowserWindow *bw) {
style (bw); // ensure that style of current node is computed style (bw); // ensure that style of current node is computed
stackPush (); stackPush ();
Node *n = stack->getLastRef (); Node *n = &stack.back ();
DoctreeNode *dn = doctree->push (); DoctreeNode *dn = doctree->push ();
dn->element = element; dn->element = element;
n->doctreeNode = dn; n->doctreeNode = dn;
if (stack->size () > 1) if (stack.size () > 1)
n->displayNone = stack->getRef (stack->size () - 2)->displayNone; n->displayNone = stack.at (stack.size () - 2).displayNone;
} }
void StyleEngine::startElement (const char *tagname, BrowserWindow *bw) { void StyleEngine::startElement (const char *tagname, BrowserWindow *bw) {
@ -195,7 +195,7 @@ void StyleEngine::setClass (const char *klass) {
} }
void StyleEngine::setStyle (const char *styleAttr) { void StyleEngine::setStyle (const char *styleAttr) {
Node *n = stack->getRef (stack->size () - 1); Node *n = &stack.at (stack.size () - 1);
assert (n->styleAttrProperties == NULL); assert (n->styleAttrProperties == NULL);
// parse style information from style="" attribute, if it exists // parse style information from style="" attribute, if it exists
if (styleAttr && prefs.parse_embedded_css) { if (styleAttr && prefs.parse_embedded_css) {
@ -214,10 +214,10 @@ void StyleEngine::setStyle (const char *styleAttr) {
* (e.g. border=1) also affect child elements like TD. * (e.g. border=1) also affect child elements like TD.
*/ */
void StyleEngine::inheritNonCssHints () { void StyleEngine::inheritNonCssHints () {
Node *pn = stack->getRef (stack->size () - 2); Node *pn = &stack.at (stack.size () - 2);
if (pn->nonCssProperties) { if (pn->nonCssProperties) {
Node *n = stack->getRef (stack->size () - 1); Node *n = &stack.at (stack.size () - 1);
CssPropertyList *origNonCssProperties = n->nonCssProperties; CssPropertyList *origNonCssProperties = n->nonCssProperties;
n->nonCssProperties = new CssPropertyList(*pn->nonCssProperties, true); n->nonCssProperties = new CssPropertyList(*pn->nonCssProperties, true);
@ -230,7 +230,7 @@ void StyleEngine::inheritNonCssHints () {
} }
void StyleEngine::clearNonCssHints () { void StyleEngine::clearNonCssHints () {
Node *n = stack->getRef (stack->size () - 1); Node *n = &stack.at (stack.size () - 1);
delete n->nonCssProperties; delete n->nonCssProperties;
n->nonCssProperties = NULL; n->nonCssProperties = NULL;
@ -243,12 +243,12 @@ void StyleEngine::clearNonCssHints () {
* don't draw any background. * don't draw any background.
*/ */
void StyleEngine::inheritBackgroundColor () { void StyleEngine::inheritBackgroundColor () {
stack->getRef (stack->size () - 1)->inheritBackgroundColor = true; stack.at (stack.size () - 1).inheritBackgroundColor = true;
} }
dw::core::style::Color *StyleEngine::backgroundColor () { dw::core::style::Color *StyleEngine::backgroundColor () {
for (int i = 1; i < stack->size (); i++) { for (std::size_t i = 1; i < stack.size (); i++) {
Node *n = stack->getRef (i); Node *n = &stack.at (i);
if (n->style && n->style->backgroundColor) if (n->style && n->style->backgroundColor)
return n->style->backgroundColor; return n->style->backgroundColor;
@ -262,8 +262,8 @@ dw::core::style::StyleImage *StyleEngine::backgroundImage
dw::core::style::BackgroundAttachment *bgAttachment, dw::core::style::BackgroundAttachment *bgAttachment,
dw::core::style::Length *bgPositionX, dw::core::style::Length *bgPositionX,
dw::core::style::Length *bgPositionY) { dw::core::style::Length *bgPositionY) {
for (int i = 1; i < stack->size (); i++) { for (std::size_t i = 1; i < stack.size (); i++) {
Node *n = stack->getRef (i); Node *n = &stack.at (i);
if (n->style && n->style->backgroundImage) { if (n->style && n->style->backgroundImage) {
*bgRepeat = n->style->backgroundRepeat; *bgRepeat = n->style->backgroundRepeat;
@ -305,21 +305,21 @@ void StyleEngine::endElement (int element) {
void StyleEngine::preprocessAttrs (dw::core::style::StyleAttrs *attrs) { void StyleEngine::preprocessAttrs (dw::core::style::StyleAttrs *attrs) {
/* workaround for styling of inline elements */ /* workaround for styling of inline elements */
if (stack->getRef (stack->size () - 2)->inheritBackgroundColor) { if (stack.at (stack.size () - 2).inheritBackgroundColor) {
attrs->backgroundColor = attrs->backgroundColor =
stack->getRef (stack->size () - 2)->style->backgroundColor; stack.at (stack.size () - 2).style->backgroundColor;
attrs->backgroundImage = attrs->backgroundImage =
stack->getRef (stack->size () - 2)->style->backgroundImage; stack.at (stack.size () - 2).style->backgroundImage;
attrs->backgroundRepeat = attrs->backgroundRepeat =
stack->getRef (stack->size () - 2)->style->backgroundRepeat; stack.at (stack.size () - 2).style->backgroundRepeat;
attrs->backgroundAttachment = attrs->backgroundAttachment =
stack->getRef (stack->size () - 2)->style->backgroundAttachment; stack.at (stack.size () - 2).style->backgroundAttachment;
attrs->backgroundPositionX = attrs->backgroundPositionX =
stack->getRef (stack->size () - 2)->style->backgroundPositionX; stack.at (stack.size () - 2).style->backgroundPositionX;
attrs->backgroundPositionY = attrs->backgroundPositionY =
stack->getRef (stack->size () - 2)->style->backgroundPositionY; stack.at (stack.size () - 2).style->backgroundPositionY;
attrs->valign = stack->getRef (stack->size () - 2)->style->valign; attrs->valign = stack.at (stack.size () - 2).style->valign;
} }
attrs->borderColor.top = (Color *) -1; attrs->borderColor.top = (Color *) -1;
attrs->borderColor.bottom = (Color *) -1; attrs->borderColor.bottom = (Color *) -1;
@ -364,7 +364,7 @@ void StyleEngine::postprocessAttrs (dw::core::style::StyleAttrs *attrs) {
void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
BrowserWindow *bw) { BrowserWindow *bw) {
FontAttrs fontAttrs = *attrs->font; FontAttrs fontAttrs = *attrs->font;
Font *parentFont = stack->get (i - 1).style->font; Font *parentFont = stack.at (i - 1).style->font;
char *c, *fontName; char *c, *fontName;
int lineHeight; int lineHeight;
DilloUrl *imgUrl = NULL; DilloUrl *imgUrl = NULL;
@ -607,7 +607,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
case CSS_PROPERTY_DISPLAY: case CSS_PROPERTY_DISPLAY:
attrs->display = (DisplayType) p->value.intVal; attrs->display = (DisplayType) p->value.intVal;
if (attrs->display == DISPLAY_NONE) if (attrs->display == DISPLAY_NONE)
stack->getRef (i)->displayNone = true; stack.at (i).displayNone = true;
break; break;
case CSS_PROPERTY_FLOAT: case CSS_PROPERTY_FLOAT:
attrs->vloat = (FloatType) p->value.intVal; attrs->vloat = (FloatType) p->value.intVal;
@ -757,7 +757,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
} }
if (imgUrl && prefs.load_background_images && if (imgUrl && prefs.load_background_images &&
!stack->getRef (i)->displayNone && !stack.at (i).displayNone &&
!(URL_FLAGS(pageUrl) & URL_SpamSafe)) !(URL_FLAGS(pageUrl) & URL_SpamSafe))
{ {
attrs->backgroundImage = StyleImage::create(); attrs->backgroundImage = StyleImage::create();
@ -808,10 +808,10 @@ bool StyleEngine::computeValue (int *dest, CssLength value, Font *font) {
*dest = roundInt (CSS_LENGTH_VALUE(value) * font->zeroWidth); *dest = roundInt (CSS_LENGTH_VALUE(value) * font->zeroWidth);
return true; return true;
case CSS_LENGTH_TYPE_REM: case CSS_LENGTH_TYPE_REM:
if (stack->size() < 2) { if (stack.size() < 2) {
*dest = 0; *dest = 0;
} else { } else {
dw::core::style::Style *root_style = stack->getRef (1)->style; dw::core::style::Style *root_style = stack.at (1).style;
if (root_style) if (root_style)
*dest = roundInt (CSS_LENGTH_VALUE(value) * root_style->font->size); *dest = roundInt (CSS_LENGTH_VALUE(value) * root_style->font->size);
else else
@ -898,17 +898,17 @@ void StyleEngine::computeBorderWidth (int *dest, CssProperty *p,
* background. This method ensures that backgroundColor is set. * background. This method ensures that backgroundColor is set.
*/ */
Style * StyleEngine::backgroundStyle (BrowserWindow *bw) { Style * StyleEngine::backgroundStyle (BrowserWindow *bw) {
if (!stack->getRef (stack->size () - 1)->backgroundStyle) { if (!stack.at (stack.size () - 1).backgroundStyle) {
StyleAttrs attrs = *style (bw); StyleAttrs attrs = *style (bw);
for (int i = stack->size () - 1; i >= 0 && ! attrs.backgroundColor; i--) for (int i = (int)stack.size () - 1; i >= 0 && ! attrs.backgroundColor; i--)
attrs.backgroundColor = stack->getRef (i)->style->backgroundColor; attrs.backgroundColor = stack.at (i).style->backgroundColor;
assert (attrs.backgroundColor); assert (attrs.backgroundColor);
stack->getRef (stack->size () - 1)->backgroundStyle = stack.at (stack.size () - 1).backgroundStyle =
Style::create (&attrs); Style::create (&attrs);
} }
return stack->getRef (stack->size () - 1)->backgroundStyle; return stack.at (stack.size () - 1).backgroundStyle;
} }
/** /**
@ -920,7 +920,7 @@ Style * StyleEngine::style0 (int i, BrowserWindow *bw) {
CssPropertyList props, *styleAttrProperties, *styleAttrPropertiesImportant; CssPropertyList props, *styleAttrProperties, *styleAttrPropertiesImportant;
CssPropertyList *nonCssProperties; CssPropertyList *nonCssProperties;
// get previous style from the stack // get previous style from the stack
StyleAttrs attrs = *stack->getRef (i - 1)->style; StyleAttrs attrs = *stack.at (i - 1).style;
// Ensure that StyleEngine::style0() has not been called before for // Ensure that StyleEngine::style0() has not been called before for
// this element. // this element.
@ -928,18 +928,18 @@ Style * StyleEngine::style0 (int i, BrowserWindow *bw) {
// If this assertion is hit, you need to rearrange the code that is // If this assertion is hit, you need to rearrange the code that is
// doing styleEngine calls to call setNonCssHint() before calling // doing styleEngine calls to call setNonCssHint() before calling
// style() or wordStyle() for each new element. // style() or wordStyle() for each new element.
assert (stack->getRef (i)->style == NULL); assert (stack.at (i).style == NULL);
// reset values that are not inherited according to CSS // reset values that are not inherited according to CSS
attrs.resetValues (); attrs.resetValues ();
preprocessAttrs (&attrs); preprocessAttrs (&attrs);
styleAttrProperties = stack->getRef (i)->styleAttrProperties; styleAttrProperties = stack.at (i).styleAttrProperties;
styleAttrPropertiesImportant = stack->getRef(i)->styleAttrPropertiesImportant; styleAttrPropertiesImportant = stack.at(i).styleAttrPropertiesImportant;
nonCssProperties = stack->getRef (i)->nonCssProperties; nonCssProperties = stack.at (i).nonCssProperties;
// merge style information // merge style information
cssContext->apply (&props, doctree, stack->getRef(i)->doctreeNode, cssContext->apply (&props, doctree, stack.at(i).doctreeNode,
styleAttrProperties, styleAttrPropertiesImportant, styleAttrProperties, styleAttrPropertiesImportant,
nonCssProperties); nonCssProperties);
@ -948,16 +948,16 @@ Style * StyleEngine::style0 (int i, BrowserWindow *bw) {
postprocessAttrs (&attrs); postprocessAttrs (&attrs);
stack->getRef (i)->style = Style::create (&attrs); stack.at (i).style = Style::create (&attrs);
return stack->getRef (i)->style; return stack.at (i).style;
} }
Style * StyleEngine::wordStyle0 (BrowserWindow *bw) { Style * StyleEngine::wordStyle0 (BrowserWindow *bw) {
StyleAttrs attrs = *style (bw); StyleAttrs attrs = *style (bw);
attrs.resetValues (); attrs.resetValues ();
if (stack->getRef (stack->size() - 1)->inheritBackgroundColor) { if (stack.at (stack.size() - 1).inheritBackgroundColor) {
attrs.backgroundColor = style (bw)->backgroundColor; attrs.backgroundColor = style (bw)->backgroundColor;
attrs.backgroundImage = style (bw)->backgroundImage; attrs.backgroundImage = style (bw)->backgroundImage;
attrs.backgroundRepeat = style (bw)->backgroundRepeat; attrs.backgroundRepeat = style (bw)->backgroundRepeat;
@ -968,8 +968,8 @@ Style * StyleEngine::wordStyle0 (BrowserWindow *bw) {
attrs.valign = style (bw)->valign; attrs.valign = style (bw)->valign;
stack->getRef(stack->size() - 1)->wordStyle = Style::create(&attrs); stack.at(stack.size() - 1).wordStyle = Style::create(&attrs);
return stack->getRef (stack->size () - 1)->wordStyle; return stack.at (stack.size () - 1).wordStyle;
} }
/** /**
@ -980,8 +980,8 @@ Style * StyleEngine::wordStyle0 (BrowserWindow *bw) {
* Note that restyle() does not change any styles in the widget tree. * Note that restyle() does not change any styles in the widget tree.
*/ */
void StyleEngine::restyle (BrowserWindow *bw) { void StyleEngine::restyle (BrowserWindow *bw) {
for (int i = 1; i < stack->size (); i++) { for (std::size_t i = 1; i < stack.size (); i++) {
Node *n = stack->getRef (i); Node *n = &stack.at (i);
if (n->style) { if (n->style) {
n->style->unref (); n->style->unref ();
n->style = NULL; n->style = NULL;

View File

@ -13,6 +13,8 @@
#ifndef __STYLEENGINE_HH__ #ifndef __STYLEENGINE_HH__
#define __STYLEENGINE_HH__ #define __STYLEENGINE_HH__
#include <vector>
class StyleEngine; class StyleEngine;
#include "dw/core.hh" #include "dw/core.hh"
@ -44,7 +46,7 @@ class StyleEngine {
}; };
dw::core::Layout *layout; dw::core::Layout *layout;
lout::misc::SimpleVector <Node> *stack; std::vector <Node> stack;
CssContext *cssContext; CssContext *cssContext;
Doctree *doctree; Doctree *doctree;
int importDepth; int importDepth;
@ -59,7 +61,7 @@ class StyleEngine {
dw::core::style::Style *wordStyle0 (BrowserWindow *bw); dw::core::style::Style *wordStyle0 (BrowserWindow *bw);
inline void setNonCssHint(CssPropertyName name, CssValueType type, inline void setNonCssHint(CssPropertyName name, CssValueType type,
CssPropertyValue value) { CssPropertyValue value) {
Node *n = stack->getRef (stack->size () - 1); Node *n = &stack.at (stack.size () - 1);
if (!n->nonCssProperties) if (!n->nonCssProperties)
n->nonCssProperties = new CssPropertyList (true); n->nonCssProperties = new CssPropertyList (true);
@ -127,15 +129,15 @@ class StyleEngine {
dw::core::style::Length *bgPositionY); dw::core::style::Length *bgPositionY);
inline dw::core::style::Style *style (BrowserWindow *bw) { inline dw::core::style::Style *style (BrowserWindow *bw) {
dw::core::style::Style *s = stack->getRef (stack->size () - 1)->style; dw::core::style::Style *s = stack.at (stack.size () - 1).style;
if (s) if (s)
return s; return s;
else else
return style0 (stack->size () - 1, bw); return style0 (stack.size () - 1, bw);
}; };
inline dw::core::style::Style *wordStyle (BrowserWindow *bw) { inline dw::core::style::Style *wordStyle (BrowserWindow *bw) {
dw::core::style::Style *s = stack->getRef(stack->size()-1)->wordStyle; dw::core::style::Style *s = stack.at(stack.size()-1).wordStyle;
if (s) if (s)
return s; return s;
else else