summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRodrigo Arias Mallo <rodarima@gmail.com>2024-05-31 19:53:14 +0200
committerRodrigo Arias Mallo <rodarima@gmail.com>2024-10-05 09:46:55 +0200
commitac56aa678cfe1666b60821f342ccb7b3d3fa7a0d (patch)
tree2887de1a5a21c8550e4bd52ea8867c18a5e2bac9 /src
parentee32215fc1937e8a5e3c26b646ca8563e8de92e9 (diff)
Define CssLength as struct instead of int
The int type doesn't have a fixed size, and is only guarantee to hold 16 bits. The current implementation assumes a size of at least 32 bits, an uses three bits to encode the type of information stored in the rest. To add more types of lengths we would need to take more bits from the value itself. A simpler approach is just to use a enumeration to take care of the type of length and a union to encapsulate the different lengths values.
Diffstat (limited to 'src')
-rw-r--r--src/css.hh71
-rw-r--r--src/cssparser.cc9
-rw-r--r--src/html.cc28
-rw-r--r--src/html_common.hh15
-rw-r--r--src/styleengine.cc56
-rw-r--r--src/styleengine.hh6
6 files changed, 95 insertions, 90 deletions
diff --git a/src/css.hh b/src/css.hh
index 44328c42..1f670c35 100644
--- a/src/css.hh
+++ b/src/css.hh
@@ -67,28 +67,9 @@ typedef enum {
} CssValueType;
/**
- * Lengths are represented as int in the following way:
- *
- * @verbatim
- *
- * | <------ integer value ------> |
- *
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * | integer part | type |
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * | integer part | decimal fraction | type |
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * n-1 15 14 3 2 1 0
- *
- * | <------ fixed point value ------> |
- *
- * @endverbatim
- *
- * where type is one of the CSS_LENGTH_TYPE_* values.
- * CSS_LENGTH_TYPE_PX values are stored as
- * 29 bit signed integer, all other types as fixed point values.
+ * CSS lengths are represented by the CssLength struct, which can hold
+ * different types of values.
*/
-typedef int CssLength;
typedef enum {
CSS_LENGTH_TYPE_NONE,
@@ -103,53 +84,56 @@ typedef enum {
CSS_LENGTH_TYPE_AUTO /**< This can be used as a simple value. */
} CssLengthType;
-inline CssLength CSS_CREATE_LENGTH (float v, CssLengthType t) {
- static const int CSS_LENGTH_FRAC_MAX = (1 << (32 - 15 - 1)) - 1;
- static const int CSS_LENGTH_INT_MAX = (1 << (32 - 4)) - 1;
- int iv;
+/* Aligned to 64 bits */
+typedef struct {
+ CssLengthType type;
+ union {
+ int i;
+ float f;
+ };
+} CssLength;
+inline CssLength CSS_CREATE_LENGTH (float v, CssLengthType t) {
+ CssLength l;
+ l.type = t;
switch (t) {
case CSS_LENGTH_TYPE_PX:
- iv = lout::misc::roundInt(v);
- if (iv > CSS_LENGTH_INT_MAX)
- iv = CSS_LENGTH_INT_MAX;
- else if (iv < -CSS_LENGTH_INT_MAX)
- iv = -CSS_LENGTH_INT_MAX;
- return iv << 3 | t;
+ l.i = lout::misc::roundInt(v);
+ break;
case CSS_LENGTH_TYPE_NONE:
case CSS_LENGTH_TYPE_MM:
case CSS_LENGTH_TYPE_EM:
case CSS_LENGTH_TYPE_EX:
case CSS_LENGTH_TYPE_PERCENTAGE:
case CSS_LENGTH_TYPE_RELATIVE:
- if (v > CSS_LENGTH_FRAC_MAX)
- v = CSS_LENGTH_FRAC_MAX;
- else if (v < -CSS_LENGTH_FRAC_MAX)
- v = -CSS_LENGTH_FRAC_MAX;
- return ((int) (v * (1 << 15)) & ~7 ) | t;
+ l.f = v;
+ break;
case CSS_LENGTH_TYPE_AUTO:
- return t;
+ l.i = 0;
+ break;
default:
assert(false);
- return CSS_LENGTH_TYPE_AUTO;
+ break;
}
+
+ return l;
}
inline CssLengthType CSS_LENGTH_TYPE (CssLength l) {
- return (CssLengthType) (l & 7);
+ return l.type;
}
inline float CSS_LENGTH_VALUE (CssLength l) {
switch (CSS_LENGTH_TYPE(l)) {
case CSS_LENGTH_TYPE_PX:
- return (float) (l >> 3);
+ return (float) l.i;
case CSS_LENGTH_TYPE_NONE:
case CSS_LENGTH_TYPE_MM:
case CSS_LENGTH_TYPE_EM:
case CSS_LENGTH_TYPE_EX:
case CSS_LENGTH_TYPE_PERCENTAGE:
case CSS_LENGTH_TYPE_RELATIVE:
- return ((float)(l & ~7)) / (1 << 15);
+ return l.f;
case CSS_LENGTH_TYPE_AUTO:
return 0.0;
default:
@@ -251,12 +235,13 @@ typedef enum {
} CssPropertyName;
typedef struct {
- int32_t posX;
- int32_t posY;
+ CssLength posX;
+ CssLength posY;
} CssBackgroundPosition;
typedef union {
int32_t intVal;
+ CssLength lenVal;
char *strVal;
CssBackgroundPosition *posVal;
} CssPropertyValue;
diff --git a/src/cssparser.cc b/src/cssparser.cc
index 1e5c5731..0fb240f2 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -3,6 +3,7 @@
*
* Copyright 2004 Sebastian Geerken <sgeerken@dillo.org>
* Copyright 2008-2009 Johannes Hofmann <Johannes.Hofmann@gmx.de>
+ * Copyright 2024 Rodrigo Arias Mallo <rodarima@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -988,7 +989,7 @@ bool CssParser::parseValue(CssPropertyName prop,
(type == CSS_TYPE_LENGTH_PERCENTAGE_NUMBER || fval == 0.0))
ret = true;
- val->intVal = CSS_CREATE_LENGTH(fval, lentype);
+ val->lenVal = CSS_CREATE_LENGTH(fval, lentype);
}
break;
@@ -1091,7 +1092,7 @@ bool CssParser::parseValue(CssPropertyName prop,
// possibilities are tested in parallel.
bool h[2], v[2];
- int pos[2];
+ CssLength pos[2];
h[0] = v[0] = h[1] = v[1] = false;
// First: collect values in pos[0] and pos[1], and determine whether
@@ -1134,10 +1135,10 @@ bool CssParser::parseValue(CssPropertyName prop,
// We can assume <length> or <percentage> here ...
CssPropertyValue valTmp;
if (parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &valTmp)) {
- pos[i] = valTmp.intVal;
+ pos[i] = valTmp.lenVal;
ret = true;
} else if (parseValue(prop, CSS_TYPE_SIGNED_LENGTH, &valTmp)) {
- pos[i] = valTmp.intVal;
+ pos[i] = valTmp.lenVal;
ret = true;
} else
// ... but something may still fail.
diff --git a/src/html.cc b/src/html.cc
index ac5dd1ab..1c5a08f4 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -2205,32 +2205,32 @@ static bool Html_load_image(BrowserWindow *bw, DilloUrl *url,
static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
{
- int space, border;
+ int border;
const char *attrbuf;
a_Html_common_image_attrs(html, tag, tagsize);
/* Spacing to the left and right */
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "hspace"))) {
- space = strtol(attrbuf, NULL, 10);
+ int space = strtol(attrbuf, NULL, 10);
if (space > 0) {
- space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
+ CssLength len = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_LEFT,
- CSS_TYPE_LENGTH_PERCENTAGE, space);
+ CSS_TYPE_LENGTH_PERCENTAGE, len);
html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_RIGHT,
- CSS_TYPE_LENGTH_PERCENTAGE, space);
+ CSS_TYPE_LENGTH_PERCENTAGE, len);
}
}
/* Spacing at the top and bottom */
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "vspace"))) {
- space = strtol(attrbuf, NULL, 10);
+ int space = strtol(attrbuf, NULL, 10);
if (space > 0) {
- space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
+ CssLength len = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_TOP,
- CSS_TYPE_LENGTH_PERCENTAGE, space);
+ CSS_TYPE_LENGTH_PERCENTAGE, len);
html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_BOTTOM,
- CSS_TYPE_LENGTH_PERCENTAGE, space);
+ CSS_TYPE_LENGTH_PERCENTAGE, len);
}
}
@@ -2238,15 +2238,15 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "border"))) {
border = strtol(attrbuf, NULL, 10);
if (border >= 0) {
- border = CSS_CREATE_LENGTH(border, CSS_LENGTH_TYPE_PX);
+ CssLength b = CSS_CREATE_LENGTH(border, CSS_LENGTH_TYPE_PX);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
+ CSS_TYPE_LENGTH_PERCENTAGE, b);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
+ CSS_TYPE_LENGTH_PERCENTAGE, b);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
+ CSS_TYPE_LENGTH_PERCENTAGE, b);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
+ CSS_TYPE_LENGTH_PERCENTAGE, b);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_STYLE,
CSS_TYPE_ENUM, BORDER_SOLID);
diff --git a/src/html_common.hh b/src/html_common.hh
index cf99d8e6..de685d46 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -1,3 +1,16 @@
+/*
+ * File: html_common.hh
+ *
+ * Copyright (C) 2008-2016 Jorge Arellano Cid <jcid@dillo.org>
+ * Copyright (C) 2008-2014 Johannes Hofmann <Johannes.Hofmann@gmx.de>
+ * Copyright (C) 2024 Rodrigo Arias Mallo <rodarima@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
#ifndef __HTML_COMMON_HH__
#define __HTML_COMMON_HH__
@@ -268,7 +281,7 @@ void a_Html_pop_tag(DilloHtml *html, int TagIdx);
void a_Html_stash_init(DilloHtml *html);
int32_t a_Html_color_parse(DilloHtml *html, const char *str,
int32_t default_color);
-dw::core::style::Length a_Html_parse_length (DilloHtml *html,
+CssLength a_Html_parse_length (DilloHtml *html,
const char *attr);
void a_Html_tag_set_align_attr(DilloHtml *html, const char *tag, int tagsize);
bool a_Html_tag_set_valign_attr(DilloHtml *html,
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 5fe410b6..ea818f85 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -442,7 +442,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
assert(false); // invalid font-size enum
}
} else {
- computeValue (&fontAttrs.size, p->value.intVal, parentFont,
+ computeValue (&fontAttrs.size, p->value.lenVal, parentFont,
parentFont->size);
}
@@ -494,7 +494,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
fontAttrs.letterSpacing = 0;
}
} else {
- computeValue (&fontAttrs.letterSpacing, p->value.intVal,
+ computeValue (&fontAttrs.letterSpacing, p->value.lenVal,
parentFont, parentFont->size);
}
@@ -589,11 +589,11 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
computeBorderWidth (&attrs->borderWidth.top, p, attrs->font);
break;
case CSS_PROPERTY_BORDER_SPACING:
- computeValue (&attrs->hBorderSpacing, p->value.intVal,attrs->font);
- computeValue (&attrs->vBorderSpacing, p->value.intVal,attrs->font);
+ computeValue (&attrs->hBorderSpacing, p->value.lenVal,attrs->font);
+ computeValue (&attrs->vBorderSpacing, p->value.lenVal,attrs->font);
break;
case CSS_PROPERTY_BOTTOM:
- computeLength (&attrs->bottom, p->value.intVal, attrs->font);
+ computeLength (&attrs->bottom, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_CLEAR:
attrs->clear = (ClearType) p->value.intVal;
@@ -613,16 +613,16 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->vloat = (FloatType) p->value.intVal;
break;
case CSS_PROPERTY_LEFT:
- computeLength (&attrs->left, p->value.intVal, attrs->font);
+ computeLength (&attrs->left, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_LINE_HEIGHT:
if (p->type == CSS_TYPE_ENUM) { //only valid enum value is "normal"
attrs->lineHeight = dw::core::style::LENGTH_AUTO;
} else if (p->type == CSS_TYPE_LENGTH_PERCENTAGE_NUMBER) {
- if (CSS_LENGTH_TYPE (p->value.intVal) == CSS_LENGTH_TYPE_NONE) {
+ if (CSS_LENGTH_TYPE (p->value.lenVal) == CSS_LENGTH_TYPE_NONE) {
attrs->lineHeight =
- createPerLength(CSS_LENGTH_VALUE(p->value.intVal));
- } else if (computeValue (&lineHeight, p->value.intVal,
+ createPerLength(CSS_LENGTH_VALUE(p->value.lenVal));
+ } else if (computeValue (&lineHeight, p->value.lenVal,
attrs->font, attrs->font->size)) {
attrs->lineHeight = createAbsLength(lineHeight);
}
@@ -635,22 +635,22 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->listStyleType = (ListStyleType) p->value.intVal;
break;
case CSS_PROPERTY_MARGIN_BOTTOM:
- computeValue (&attrs->margin.bottom, p->value.intVal, attrs->font);
+ computeValue (&attrs->margin.bottom, p->value.lenVal, attrs->font);
if (attrs->margin.bottom < 0) // \todo fix negative margins in dw/*
attrs->margin.bottom = 0;
break;
case CSS_PROPERTY_MARGIN_LEFT:
- computeValue (&attrs->margin.left, p->value.intVal, attrs->font);
+ computeValue (&attrs->margin.left, p->value.lenVal, attrs->font);
if (attrs->margin.left < 0) // \todo fix negative margins in dw/*
attrs->margin.left = 0;
break;
case CSS_PROPERTY_MARGIN_RIGHT:
- computeValue (&attrs->margin.right, p->value.intVal, attrs->font);
+ computeValue (&attrs->margin.right, p->value.lenVal, attrs->font);
if (attrs->margin.right < 0) // \todo fix negative margins in dw/*
attrs->margin.right = 0;
break;
case CSS_PROPERTY_MARGIN_TOP:
- computeValue (&attrs->margin.top, p->value.intVal, attrs->font);
+ computeValue (&attrs->margin.top, p->value.lenVal, attrs->font);
if (attrs->margin.top < 0) // \todo fix negative margins in dw/*
attrs->margin.top = 0;
break;
@@ -658,22 +658,22 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->overflow = (Overflow) p->value.intVal;
break;
case CSS_PROPERTY_PADDING_TOP:
- computeValue (&attrs->padding.top, p->value.intVal, attrs->font);
+ computeValue (&attrs->padding.top, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_PADDING_BOTTOM:
- computeValue (&attrs->padding.bottom, p->value.intVal,attrs->font);
+ computeValue (&attrs->padding.bottom, p->value.lenVal,attrs->font);
break;
case CSS_PROPERTY_PADDING_LEFT:
- computeValue (&attrs->padding.left, p->value.intVal, attrs->font);
+ computeValue (&attrs->padding.left, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_PADDING_RIGHT:
- computeValue (&attrs->padding.right, p->value.intVal, attrs->font);
+ computeValue (&attrs->padding.right, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_POSITION:
attrs->position = (Position) p->value.intVal;
break;
case CSS_PROPERTY_RIGHT:
- computeLength (&attrs->right, p->value.intVal, attrs->font);
+ computeLength (&attrs->right, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_TEXT_ALIGN:
attrs->textAlign = (TextAlignType) p->value.intVal;
@@ -682,13 +682,13 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->textDecoration |= p->value.intVal;
break;
case CSS_PROPERTY_TEXT_INDENT:
- computeLength (&attrs->textIndent, p->value.intVal, attrs->font);
+ computeLength (&attrs->textIndent, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_TEXT_TRANSFORM:
attrs->textTransform = (TextTransform) p->value.intVal;
break;
case CSS_PROPERTY_TOP:
- computeLength (&attrs->top, p->value.intVal, attrs->font);
+ computeLength (&attrs->top, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_VERTICAL_ALIGN:
attrs->valign = (VAlignType) p->value.intVal;
@@ -697,10 +697,10 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->whiteSpace = (WhiteSpace) p->value.intVal;
break;
case CSS_PROPERTY_WIDTH:
- computeLength (&attrs->width, p->value.intVal, attrs->font);
+ computeLength (&attrs->width, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_HEIGHT:
- computeLength (&attrs->height, p->value.intVal, attrs->font);
+ computeLength (&attrs->height, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_WORD_SPACING:
if (p->type == CSS_TYPE_ENUM) {
@@ -708,7 +708,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->wordSpacing = 0;
}
} else {
- computeValue(&attrs->wordSpacing, p->value.intVal, attrs->font);
+ computeValue(&attrs->wordSpacing, p->value.lenVal, attrs->font);
}
/* Limit to reasonable values to avoid overflows */
@@ -718,16 +718,16 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
attrs->wordSpacing = -1000;
break;
case CSS_PROPERTY_MIN_WIDTH:
- computeLength (&attrs->minWidth, p->value.intVal, attrs->font);
+ computeLength (&attrs->minWidth, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_MAX_WIDTH:
- computeLength (&attrs->maxWidth, p->value.intVal, attrs->font);
+ computeLength (&attrs->maxWidth, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_MIN_HEIGHT:
- computeLength (&attrs->minHeight, p->value.intVal, attrs->font);
+ computeLength (&attrs->minHeight, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_MAX_HEIGHT:
- computeLength (&attrs->maxHeight, p->value.intVal, attrs->font);
+ computeLength (&attrs->maxHeight, p->value.lenVal, attrs->font);
break;
case CSS_PROPERTY_Z_INDEX:
if (p->type == CSS_LENGTH_TYPE_AUTO)
@@ -862,7 +862,7 @@ void StyleEngine::computeBorderWidth (int *dest, CssProperty *p,
assert(false);
}
} else {
- computeValue (dest, p->value.intVal, font);
+ computeValue (dest, p->value.lenVal, font);
}
}
diff --git a/src/styleengine.hh b/src/styleengine.hh
index 9a78869b..3bed02bf 100644
--- a/src/styleengine.hh
+++ b/src/styleengine.hh
@@ -108,6 +108,12 @@ class StyleEngine {
v.strVal = dStrdup(value);
setNonCssHint (name, type, v);
}
+ inline void setNonCssHint(CssPropertyName name, CssValueType type,
+ CssLength value) {
+ CssPropertyValue v;
+ v.lenVal = value;
+ setNonCssHint (name, type, v);
+ }
void inheritNonCssHints ();
void clearNonCssHints ();
void restyle (BrowserWindow *bw);