From e9e6626c6da306aca310cc26c1a0e602095f3b52 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Wed, 2 Oct 2024 19:32:44 +0200 Subject: [PATCH] Add support for more CSS units Implements support for ch, rem, vw, vh, vmin and vmax units of CSS lengths. For now the units relative to the viewport are only computed once, and they won't change when the window is resized, but only when the page is reloaded. See: https://www.toomanyatoms.com/software/mobilized_dillo.html Authored-By: dogma --- ChangeLog | 1 + dw/fltkplatform.cc | 1 + dw/platform.hh | 9 +++++---- dw/style.hh | 1 + src/css.hh | 18 ++++++++++++++++++ src/cssparser.cc | 18 ++++++++++++++++++ src/styleengine.cc | 26 ++++++++++++++++++++++++++ 7 files changed, 70 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a60b249a0..eae4c8512 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ dillo-3.2.0 [Not released yet] - Fix use-after-free on errors in TLS connection. Patches: Rodrigo Arias Mallo +- Add primitive support for SVG using the nanosvg.h library. + - Add support for ch, rem, vw, vh, vmin and vmax CSS units. Patches: dogma, Rodrigo Arias Mallo +- Avoid expensive search for multipart/form-data boundaries. Patches: Xavier Del Campo Romero, Rodrigo Arias Mallo diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc index f5d686c45..21c0866a9 100644 --- a/dw/fltkplatform.cc +++ b/dw/fltkplatform.cc @@ -122,6 +122,7 @@ FltkFont::FltkFont (core::style::FontAttrs *attrs) int xx, xy, xw, xh; fl_text_extents("x", xx, xy, xw, xh); xHeight = xh; + zeroWidth = (int) fl_width("0"); descent = fl_descent(); ascent = fl_height() - descent; } diff --git a/dw/platform.hh b/dw/platform.hh index 227cda33c..be9b4a588 100644 --- a/dw/platform.hh +++ b/dw/platform.hh @@ -121,10 +121,11 @@ public: * is defined, which holds more platform dependent data. * * Also, this method must fill the attributes "font" (when needed), - * "ascent", "descent", "spaceSidth" and "xHeight". If "tryEverything" - * is true, several methods should be used to use another font, when - * the requested font is not available. Passing false is typically done, - * if the caller wants to test different variations. + * "ascent", "descent", "spaceSidth", "zeroWidth" and "xHeight". If + * "tryEverything" is true, several methods should be used to use + * another font, when the requested font is not available. Passing + * false is typically done, if the caller wants to test different + * variations. */ virtual style::Font *createFont (style::FontAttrs *attrs, bool tryEverything) = 0; diff --git a/dw/style.hh b/dw/style.hh index 12ca16643..12b7cbde1 100644 --- a/dw/style.hh +++ b/dw/style.hh @@ -715,6 +715,7 @@ public: int ascent, descent; int spaceWidth; int xHeight; + int zeroWidth; static Font *create (Layout *layout, FontAttrs *attrs); static bool exists (Layout *layout, const char *name); diff --git a/src/css.hh b/src/css.hh index 1f670c35d..e77d91e72 100644 --- a/src/css.hh +++ b/src/css.hh @@ -78,6 +78,12 @@ typedef enum { millimeters. */ CSS_LENGTH_TYPE_EM, CSS_LENGTH_TYPE_EX, + CSS_LENGTH_TYPE_CH, + CSS_LENGTH_TYPE_REM, + CSS_LENGTH_TYPE_VW, + CSS_LENGTH_TYPE_VH, + CSS_LENGTH_TYPE_VMIN, + CSS_LENGTH_TYPE_VMAX, CSS_LENGTH_TYPE_PERCENTAGE, CSS_LENGTH_TYPE_RELATIVE, /**< This does not exist in CSS but is used in HTML */ @@ -104,6 +110,12 @@ inline CssLength CSS_CREATE_LENGTH (float v, CssLengthType t) { case CSS_LENGTH_TYPE_MM: case CSS_LENGTH_TYPE_EM: case CSS_LENGTH_TYPE_EX: + case CSS_LENGTH_TYPE_CH: + case CSS_LENGTH_TYPE_REM: + case CSS_LENGTH_TYPE_VW: + case CSS_LENGTH_TYPE_VH: + case CSS_LENGTH_TYPE_VMIN: + case CSS_LENGTH_TYPE_VMAX: case CSS_LENGTH_TYPE_PERCENTAGE: case CSS_LENGTH_TYPE_RELATIVE: l.f = v; @@ -131,6 +143,12 @@ inline float CSS_LENGTH_VALUE (CssLength l) { case CSS_LENGTH_TYPE_MM: case CSS_LENGTH_TYPE_EM: case CSS_LENGTH_TYPE_EX: + case CSS_LENGTH_TYPE_CH: + case CSS_LENGTH_TYPE_REM: + case CSS_LENGTH_TYPE_VW: + case CSS_LENGTH_TYPE_VH: + case CSS_LENGTH_TYPE_VMIN: + case CSS_LENGTH_TYPE_VMAX: case CSS_LENGTH_TYPE_PERCENTAGE: case CSS_LENGTH_TYPE_RELATIVE: return l.f; diff --git a/src/cssparser.cc b/src/cssparser.cc index 13b6db200..6e4b76140 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -967,6 +967,24 @@ bool CssParser::parseValue(CssPropertyName prop, } else if (dStrAsciiCasecmp(tval, "ex") == 0) { lentype = CSS_LENGTH_TYPE_EX; nextToken(); + } else if (dStrAsciiCasecmp(tval, "ch") == 0) { + lentype = CSS_LENGTH_TYPE_CH; + nextToken(); + } else if (dStrAsciiCasecmp(tval, "rem") == 0) { + lentype = CSS_LENGTH_TYPE_REM; + nextToken(); + } else if (dStrAsciiCasecmp(tval, "vw") == 0) { + lentype = CSS_LENGTH_TYPE_VW; + nextToken(); + } else if (dStrAsciiCasecmp(tval, "vh") == 0) { + lentype = CSS_LENGTH_TYPE_VH; + nextToken(); + } else if (dStrAsciiCasecmp(tval, "vmin") == 0) { + lentype = CSS_LENGTH_TYPE_VMIN; + nextToken(); + } else if (dStrAsciiCasecmp(tval, "vmax") == 0) { + lentype = CSS_LENGTH_TYPE_VMAX; + nextToken(); } else { ret = false; } diff --git a/src/styleengine.cc b/src/styleengine.cc index ea818f854..14411da85 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -804,6 +804,32 @@ bool StyleEngine::computeValue (int *dest, CssLength value, Font *font) { /* Doesn't need zoom as it is already applied to font->xHeight */ *dest = roundInt (CSS_LENGTH_VALUE(value) * font->xHeight); return true; + case CSS_LENGTH_TYPE_CH: + *dest = roundInt (CSS_LENGTH_VALUE(value) * font->zeroWidth); + return true; + case CSS_LENGTH_TYPE_REM: + if (stack->size() < 2) { + *dest = 0; + } else { + dw::core::style::Style *root_style = stack->getRef (1)->style; + if (root_style) + *dest = roundInt (CSS_LENGTH_VALUE(value) * root_style->font->size); + else + *dest = 0; + } + return true; + case CSS_LENGTH_TYPE_VW: + *dest = roundInt (CSS_LENGTH_VALUE(value) * layout->getWidthViewport() / 100); + return true; + case CSS_LENGTH_TYPE_VH: + *dest = roundInt (CSS_LENGTH_VALUE(value) * layout->getHeightViewport() / 100); + return true; + case CSS_LENGTH_TYPE_VMIN: + *dest = roundInt (CSS_LENGTH_VALUE(value) * MIN(layout->getWidthViewport(), layout->getHeightViewport()) / 100); + return true; + case CSS_LENGTH_TYPE_VMAX: + *dest = roundInt (CSS_LENGTH_VALUE(value) * MAX(layout->getWidthViewport(), layout->getHeightViewport()) / 100); + return true; case CSS_LENGTH_TYPE_NONE: // length values other than 0 without unit are only allowed // in special cases (line-height) and have to be handled