Gitweb links:

...log 
http://git.netsurf-browser.org/libcss.git/shortlog/b26554d3808c5c2736d611d4fb8eff28dc765b72
...commit 
http://git.netsurf-browser.org/libcss.git/commit/b26554d3808c5c2736d611d4fb8eff28dc765b72
...tree 
http://git.netsurf-browser.org/libcss.git/tree/b26554d3808c5c2736d611d4fb8eff28dc765b72

The branch, tlsa/units has been updated
  discards  8d9f75aaf18364175b67c48ad00d78a8ff40bd40 (commit)
       via  b26554d3808c5c2736d611d4fb8eff28dc765b72 (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (8d9f75aaf18364175b67c48ad00d78a8ff40bd40)
            \
             N -- N -- N (b26554d3808c5c2736d611d4fb8eff28dc765b72)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=b26554d3808c5c2736d611d4fb8eff28dc765b72
commit b26554d3808c5c2736d611d4fb8eff28dc765b72
Author: Michael Drake <Michael Drake [email protected]>
Commit: Michael Drake <Michael Drake [email protected]>

    WIP: Add support for length unit conversion to libcss.

diff --git a/src/select/Makefile b/src/select/Makefile
index 8b47673..f5ddb18 100644
--- a/src/select/Makefile
+++ b/src/select/Makefile
@@ -2,6 +2,6 @@
 select_generator:
        python3 src/select/select_generator.py
 
-DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c 
format_list_style.c
+DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c 
format_list_style.c unit.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/src/select/hash.c b/src/select/hash.c
index 4b11702..4dedec9 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -8,6 +8,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <libcss/hint.h>
+
 #include "stylesheet.h"
 #include "select/hash.h"
 #include "select/mq.h"
diff --git a/src/select/mq.h b/src/select/mq.h
index 79303e9..080a6ba 100644
--- a/src/select/mq.h
+++ b/src/select/mq.h
@@ -10,107 +10,7 @@
 #define css_select_mq_h_
 
 #include "select/helpers.h"
-
-static inline css_fixed css_len2px(
-               css_fixed length,
-               css_unit unit,
-               const css_media *media)
-{
-       css_fixed px_per_unit;
-
-       switch (unit) {
-       case CSS_UNIT_VI:
-               /* TODO: Assumes writing mode. */
-               unit = CSS_UNIT_VW;
-               break;
-       case CSS_UNIT_VB:
-               /* TODO: Assumes writing mode. */
-               unit = CSS_UNIT_VH;
-               break;
-       case CSS_UNIT_VMIN:
-               unit = (media->height < media->width) ?
-                               CSS_UNIT_VH : CSS_UNIT_VW;
-               break;
-       case CSS_UNIT_VMAX:
-               unit = (media->width > media->height) ?
-                               CSS_UNIT_VH : CSS_UNIT_VW;
-               break;
-       default:
-               break;
-       }
-
-       switch (unit) {
-       case CSS_UNIT_EM:
-       case CSS_UNIT_EX:
-       case CSS_UNIT_CAP:
-       case CSS_UNIT_CH:
-       case CSS_UNIT_IC:
-       {
-               px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
-
-               /* TODO: Handling these as fixed ratios of CSS_UNIT_EM. */
-               switch (unit) {
-               case CSS_UNIT_EX:
-                       px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
-                       break;
-               case CSS_UNIT_CAP:
-                       px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.9));
-                       break;
-               case CSS_UNIT_CH:
-                       px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.4));
-                       break;
-               case CSS_UNIT_IC:
-                       px_per_unit = FMUL(px_per_unit, FLTTOFIX(1.1));
-                       break;
-               default:
-                       break;
-               }
-       }
-               break;
-       case CSS_UNIT_PX:
-               return length;
-       case CSS_UNIT_IN:
-               px_per_unit = F_96;
-               break;
-       case CSS_UNIT_CM:
-               px_per_unit = FDIV(F_96, FLTTOFIX(2.54));
-               break;
-       case CSS_UNIT_MM:
-               px_per_unit = FDIV(F_96, FLTTOFIX(25.4));
-               break;
-       case CSS_UNIT_Q:
-               px_per_unit = FDIV(F_96, FLTTOFIX(101.6));
-               break;
-       case CSS_UNIT_PT:
-               px_per_unit = FDIV(F_96, F_72);
-               break;
-       case CSS_UNIT_PC:
-               px_per_unit = FDIV(F_96, INTTOFIX(6));
-               break;
-       case CSS_UNIT_REM:
-               px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
-               break;
-       case CSS_UNIT_RLH:
-               px_per_unit = media->client_line_height;
-               break;
-       case CSS_UNIT_VH:
-               px_per_unit = FDIV(media->height, F_100);
-               break;
-       case CSS_UNIT_VW:
-               px_per_unit = FDIV(media->width, F_100);
-               break;
-       default:
-               px_per_unit = 0;
-               break;
-       }
-
-       /* Ensure we round px_per_unit to the nearest whole number of pixels:
-        * the use of FIXTOINT() below will truncate. */
-       px_per_unit += F_0_5;
-
-       /* Calculate total number of pixels */
-       return FMUL(length, TRUNCATEFIX(px_per_unit));
-}
+#include "select/unit.h"
 
 static inline bool mq_match_feature_range_length_op1(
                css_mq_feature_op op,
@@ -125,9 +25,9 @@ static inline bool mq_match_feature_range_length_op1(
        }
 
        if (value->data.dim.unit != UNIT_PX) {
-               v = css_len2px(value->data.dim.len,
-                               css__to_css_unit(value->data.dim.unit),
-                               media);
+               v = css_unit_len2px_mq(media,
+                               value->data.dim.len,
+                               css__to_css_unit(value->data.dim.unit));
        } else {
                v = value->data.dim.len;
        }
@@ -160,9 +60,9 @@ static inline bool mq_match_feature_range_length_op2(
        }
 
        if (value->data.dim.unit != UNIT_PX) {
-               v = css_len2px(value->data.dim.len,
-                               css__to_css_unit(value->data.dim.unit),
-                               media);
+               v = css_unit_len2px_mq(media,
+                               value->data.dim.len,
+                               css__to_css_unit(value->data.dim.unit));
        } else {
                v = value->data.dim.len;
        }
diff --git a/src/select/unit.c b/src/select/unit.c
new file mode 100644
index 0000000..e01c59e
--- /dev/null
+++ b/src/select/unit.c
@@ -0,0 +1,460 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2021 Michael Drake <[email protected]>
+ */
+
+#include <libcss/stylesheet.h>
+
+#include "utils/utils.h"
+
+#include "propget.h"
+#include "unit.h"
+
+/**
+ * Map viewport-relative length units to either vh or vw.
+ *
+ * Non-viewport-relative units are unchanged.
+ *
+ * \param[in] style            Reference style.
+ * \param[in] viewport_height  Viewport height in px.
+ * \param[in] viewport_width   Viewport width in px.
+ * \param[in] unit             Unit to map.
+ * \return the mapped unit.
+ */
+static inline css_unit css_unit__map_viewport_units(
+               const css_computed_style *style,
+               const css_fixed viewport_height,
+               const css_fixed viewport_width,
+               const css_unit unit)
+{
+       switch (unit) {
+       case CSS_UNIT_VI:
+               return (style != NULL && get_writing_mode(style) !=
+                               CSS_WRITING_MODE_HORIZONTAL_TB) ?
+                               CSS_UNIT_VH : CSS_UNIT_VW;
+
+       case CSS_UNIT_VB:
+               return (style != NULL && get_writing_mode(style) !=
+                               CSS_WRITING_MODE_HORIZONTAL_TB) ?
+                               CSS_UNIT_VW : CSS_UNIT_VH;
+
+       case CSS_UNIT_VMIN:
+               return (viewport_height < viewport_width) ?
+                               CSS_UNIT_VH : CSS_UNIT_VW;
+
+       case CSS_UNIT_VMAX:
+               return (viewport_height > viewport_width) ?
+                               CSS_UNIT_VH : CSS_UNIT_VW;
+
+       default:
+               return unit;
+       }
+}
+
+static inline css_fixed css_unit__len2pt(
+               const css_computed_style *style,
+               const css_fixed viewport_height,
+               const css_fixed viewport_width,
+               const css_fixed length,
+               const css_unit unit)
+{
+       /* Length must not be relative */
+       assert(unit != CSS_UNIT_EM &&
+              unit != CSS_UNIT_EX &&
+              unit != CSS_UNIT_CH &&
+              unit != CSS_UNIT_REM);
+
+       switch (css_unit__map_viewport_units(style,
+                       viewport_height,
+                       viewport_width,
+                       unit)) {
+       case CSS_UNIT_PX:
+               return FDIV(FMUL(length, F_72), F_96);
+
+       case CSS_UNIT_IN:
+               return FMUL(length, F_72);
+
+       case CSS_UNIT_CM:
+               return FMUL(length, FDIV(F_72, FLTTOFIX(2.54)));
+
+       case CSS_UNIT_MM:
+               return FMUL(length, FDIV(F_72, FLTTOFIX(25.4)));
+
+       case CSS_UNIT_Q:
+               return FMUL(length, FDIV(F_72, FLTTOFIX(101.6)));
+
+       case CSS_UNIT_PT:
+               return length;
+
+       case CSS_UNIT_PC:
+               return FMUL(length, INTTOFIX(12));
+
+       case CSS_UNIT_VH:
+               return FDIV(FMUL(FDIV(FMUL(length, viewport_height), F_100),
+                               F_72), F_96);
+
+       case CSS_UNIT_VW:
+               return FDIV(FMUL(FDIV(FMUL(length, viewport_width), F_100),
+                               F_72), F_96);
+
+       default:
+               return 0;
+       }
+}
+
+css_fixed css_unit_font_size_len2pt(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit)
+{
+       return css_unit__len2pt(
+                       ctx->ref_style,
+                       ctx->viewport_height,
+                       ctx->viewport_width,
+                       length,
+                       unit);
+}
+
+static inline css_fixed css_unit__font_size_px(
+               const css_computed_style *style,
+               const css_fixed font_size_default,
+               const css_fixed font_size_minimum,
+               const css_fixed viewport_height,
+               const css_fixed viewport_width)
+{
+       css_fixed font_length = 0;
+       css_unit font_unit = CSS_UNIT_PT;
+
+       if (style == NULL) {
+               return font_size_default;
+       }
+
+       get_font_size(style, &font_length, &font_unit);
+
+       font_length = css_unit__len2pt(style,
+                       viewport_height,
+                       viewport_width,
+                       font_length,
+                       font_unit);
+
+       /* Convert from pt to CSS pixels.*/
+       font_length = FDIV(FMUL(font_length, F_96), F_72);
+
+       /* Clamp to configured minimum */
+       if (font_length < font_size_minimum) {
+               font_length = font_size_minimum;
+       }
+
+       return font_length;
+}
+
+/**
+ * Get the number of CSS pixels for a given unit.
+ *
+ * \param[in] measure            Client callback for font measuring.
+ * \param[in] ref_style          Reference style.  (Element or parent, or 
NULL).
+ * \param[in] root_style         Root element style or NULL.
+ * \param[in] font_size_default  Client default font size in CSS pixels.
+ * \param[in] font_size_minimum  Client minimum font size in CSS pixels.  May 
be zero.
+ * \param[in] viewport_height    Viewport height in CSS pixels.
+ * \param[in] viewport_width     Viewport width in CSS pixels.
+ * \param[in] unit               The unit to convert from.
+ * \param[in] pw                 Client private word for measure callback.
+ * \return Number of CSS pixels equivalent to the given unit.
+ */
+static inline css_fixed css_unit__px_per_unit(
+               const css_unit_len_measure measure,
+               const css_computed_style *ref_style,
+               const css_computed_style *root_style,
+               const css_fixed font_size_default,
+               const css_fixed font_size_minimum,
+               const css_fixed viewport_height,
+               const css_fixed viewport_width,
+               const css_unit unit,
+               void *pw)
+{
+       switch (css_unit__map_viewport_units(
+                       ref_style,
+                       viewport_height,
+                       viewport_width,
+                       unit)) {
+       case CSS_UNIT_EM:
+               return css_unit__font_size_px(
+                               ref_style,
+                               font_size_default,
+                               font_size_minimum,
+                               viewport_height,
+                               viewport_width);
+
+       case CSS_UNIT_EX:
+               if (measure != NULL) {
+                       return measure(pw, ref_style, CSS_UNIT_EX);
+               }
+               return FMUL(css_unit__font_size_px(
+                               ref_style,
+                               font_size_default,
+                               font_size_minimum,
+                               viewport_height,
+                               viewport_width), FLTTOFIX(0.6));
+
+       case CSS_UNIT_CH:
+               if (measure != NULL) {
+                       return measure(pw, ref_style, CSS_UNIT_CH);
+               }
+               return FMUL(css_unit__font_size_px(
+                               ref_style,
+                               font_size_default,
+                               font_size_minimum,
+                               viewport_height,
+                               viewport_width), FLTTOFIX(0.4));
+
+       case CSS_UNIT_PX:
+               return F_1;
+
+       case CSS_UNIT_IN:
+               return F_96;
+
+       case CSS_UNIT_CM:
+               return FDIV(F_96, FLTTOFIX(2.54));
+
+       case CSS_UNIT_MM:
+               return FDIV(F_96, FLTTOFIX(25.4));
+
+       case CSS_UNIT_Q:
+               return FDIV(F_96, FLTTOFIX(101.6));
+
+       case CSS_UNIT_PT:
+               return FDIV(F_96, F_72);
+
+       case CSS_UNIT_PC:
+               return FDIV(F_96, INTTOFIX(6));
+
+       case CSS_UNIT_REM:
+               return css_unit__font_size_px(
+                               root_style,
+                               font_size_default,
+                               font_size_minimum,
+                               viewport_height,
+                               viewport_width);
+
+       case CSS_UNIT_VH:
+               return FDIV(viewport_width, F_100);
+
+       case CSS_UNIT_VW:
+               return FDIV(viewport_height, F_100);
+
+       default:
+               return 0;
+       }
+}
+
+css_fixed css_unit_len2px_mq(
+               const css_media *media,
+               const css_fixed length,
+               const css_unit unit)
+{
+       /* In the media query context there is no reference or root element
+        * style, so these are hardcoded to NULL. */
+       css_fixed px_per_unit = css_unit__px_per_unit(
+                       NULL,
+                       NULL,
+                       NULL,
+                       media->client_font_size,
+                       INTTOFIX(0),
+                       media->height,
+                       media->width,
+                       unit,
+                       NULL);
+
+       /* Ensure we round px_per_unit to the nearest whole number of pixels:
+        * the use of FIXTOINT() below will truncate. */
+       px_per_unit += F_0_5;
+
+       /* Calculate total number of pixels */
+       return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+css_fixed css_unit_len2css_px(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit)
+{
+       css_fixed px_per_unit = css_unit__px_per_unit(
+                       ctx->measure,
+                       ctx->ref_style,
+                       ctx->root_style,
+                       ctx->font_size_default,
+                       ctx->font_size_minimum,
+                       ctx->viewport_height,
+                       ctx->viewport_width,
+                       unit,
+                       ctx->pw);
+
+       /* Ensure we round px_per_unit to the nearest whole number of pixels:
+        * the use of FIXTOINT() below will truncate. */
+       px_per_unit += F_0_5;
+
+       /* Calculate total number of pixels */
+       return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+css_fixed css_unit_len2device_px(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit)
+{
+       css_fixed px_per_unit = css_unit__px_per_unit(
+                       ctx->measure,
+                       ctx->ref_style,
+                       ctx->root_style,
+                       ctx->font_size_default,
+                       ctx->font_size_minimum,
+                       ctx->viewport_height,
+                       ctx->viewport_width,
+                       unit,
+                       ctx->pw);
+
+       px_per_unit = css_unit_css2device_px(px_per_unit, ctx->device_dpi);
+
+       /* Ensure we round px_per_unit to the nearest whole number of pixels:
+        * the use of FIXTOINT() below will truncate. */
+       px_per_unit += F_0_5;
+
+       /* Calculate total number of pixels */
+       return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+static inline css_hint_length css_unit__get_font_size(
+               const css_unit_len_ctx *ctx,
+               const css_computed_style *style)
+{
+       css_hint_length size;
+
+       if (style == NULL) {
+               size.value = ctx->font_size_default;
+               size.unit = CSS_UNIT_PX;
+       } else {
+               enum css_font_size_e status = get_font_size(
+                               style, &size.value, &size.unit);
+
+               UNUSED(status);
+
+               assert(status == CSS_FONT_SIZE_DIMENSION);
+               assert(size.unit != CSS_UNIT_EM);
+               assert(size.unit != CSS_UNIT_EX);
+               assert(size.unit != CSS_UNIT_PCT);
+       }
+
+       return size;
+}
+
+/* Exported function, documented in unit.h. */
+css_error css_unit_compute_absolute_font_size(
+               const css_unit_len_ctx *ctx,
+               css_hint *size)
+{
+       css_hint_length ref_len;
+
+       assert(size->status != CSS_FONT_SIZE_INHERIT);
+
+       switch (size->status) {
+       case CSS_FONT_SIZE_XX_SMALL: /* Fall-through. */
+       case CSS_FONT_SIZE_X_SMALL:  /* Fall-through. */
+       case CSS_FONT_SIZE_SMALL:    /* Fall-through. */
+       case CSS_FONT_SIZE_MEDIUM:   /* Fall-through. */
+       case CSS_FONT_SIZE_LARGE:    /* Fall-through. */
+       case CSS_FONT_SIZE_X_LARGE:  /* Fall-through. */
+       case CSS_FONT_SIZE_XX_LARGE:
+       {
+               static const css_fixed factors[CSS_FONT_SIZE_XX_LARGE] = {
+                       [CSS_FONT_SIZE_XX_SMALL - 1] = FLTTOFIX(0.5625),
+                       [CSS_FONT_SIZE_X_SMALL  - 1] = FLTTOFIX(0.6250),
+                       [CSS_FONT_SIZE_SMALL    - 1] = FLTTOFIX(0.8125),
+                       [CSS_FONT_SIZE_MEDIUM   - 1] = FLTTOFIX(1.0000),
+                       [CSS_FONT_SIZE_LARGE    - 1] = FLTTOFIX(1.1250),
+                       [CSS_FONT_SIZE_X_LARGE  - 1] = FLTTOFIX(1.5000),
+                       [CSS_FONT_SIZE_XX_LARGE - 1] = FLTTOFIX(2.0000),
+               };
+               assert(CSS_FONT_SIZE_INHERIT  == 0);
+               assert(CSS_FONT_SIZE_XX_SMALL == 1);
+
+               size->data.length.value = FMUL(factors[size->status - 1],
+                               ctx->font_size_default);
+               size->data.length.unit = CSS_UNIT_PX;
+               size->status = CSS_FONT_SIZE_DIMENSION;
+               break;
+       }
+       case CSS_FONT_SIZE_LARGER:
+               ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+               size->data.length.value = FMUL(ref_len.value, FLTTOFIX(1.2));
+               size->data.length.unit = ref_len.unit;
+               size->status = CSS_FONT_SIZE_DIMENSION;
+               break;
+
+       case CSS_FONT_SIZE_SMALLER:
+               ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+               size->data.length.value = FDIV(ref_len.value, FLTTOFIX(1.2));
+               size->data.length.unit = ref_len.unit;
+               size->status = CSS_FONT_SIZE_DIMENSION;
+               break;
+
+       case CSS_FONT_SIZE_DIMENSION:
+               /* Convert any relative units to absolute. */
+               switch (size->data.length.unit) {
+               case CSS_UNIT_PCT:
+                       ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+                       size->data.length.value = FDIV(
+                                       FMUL(size->data.length.value,
+                                       ref_len.value), INTTOFIX(100));
+                       size->data.length.unit = ref_len.unit;
+                       break;
+
+               case CSS_UNIT_EM: /* Fall-through */
+               case CSS_UNIT_EX: /* Fall-through */
+               case CSS_UNIT_CH:
+                       /* Parent relative units. */
+                       ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+
+                       size->data.length.unit = ref_len.unit;
+                       size->data.length.value = FMUL(size->data.length.value,
+                                               ref_len.value);
+
+                       switch (size->data.length.unit) {
+                       case CSS_UNIT_EX:
+                               size->data.length.value = FMUL(
+                                               size->data.length.value,
+                                               FLTTOFIX(0.6));
+                               break;
+
+                       case CSS_UNIT_CH:
+                               size->data.length.value = FMUL(
+                                               size->data.length.value,
+                                               FLTTOFIX(0.4));
+                               break;
+
+                       default:
+                               break;
+                       }
+                       break;
+
+               case CSS_UNIT_REM:
+                       /* Root element relative units. */
+                       ref_len = css_unit__get_font_size(ctx, ctx->root_style);
+
+                       size->data.length.unit = ref_len.unit;
+                       size->data.length.value = FMUL(size->data.length.value,
+                                               ref_len.value);
+                       break;
+
+               default:
+                       break;
+               }
+       default:
+               break;
+       }
+
+       return CSS_OK;
+}
diff --git a/src/select/unit.h b/src/select/unit.h
new file mode 100644
index 0000000..7ed6458
--- /dev/null
+++ b/src/select/unit.h
@@ -0,0 +1,146 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2021 Michael Drake <[email protected]>
+ */
+
+#ifndef css_select_unit_h_
+#define css_select_unit_h_
+
+/**
+ * Client callback for font measuring.
+ *
+ * \param[in]  pw     Client data.
+ * \param[in]  style  Style to measure font for, or NULL.
+ * \param[in]  unit   Either CSS_UNIT_EX, or CSS_UNIT_CH.
+ * \return length in CSS pixels.
+ */
+typedef css_fixed (*css_unit_len_measure)(
+               void *pw,
+               const css_computed_style *style,
+               const css_unit unit);
+
+/**
+ * LibCSS unit conversion context.
+ *
+ * The client callback is optional.  It is used for measuring "ch"
+ * (glyph '0' advance) and "ex" (height of the letter 'x') units.
+ * If a NULL pointer is given, LibCSS will use a fixed scaling of
+ * the "em" unit.
+ */
+typedef struct css_unit_len_ctx {
+       /**
+        * Viewport width in CSS pixels.
+        * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+        */
+       css_fixed viewport_width;
+       /**
+        * Viewport height in CSS pixels.
+        * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+        */
+       css_fixed viewport_height;
+       /**
+        * Client default font size in CSS pixels.
+        */
+       css_fixed font_size_default;
+       /**
+        * Client minimum font size in CSS pixels.  May be zero.
+        */
+       css_fixed font_size_minimum;
+       /**
+        * DPI of the device the style is selected for.
+        */
+       css_fixed device_dpi;
+       /**
+        * Reference style.  Most of the time, this is the element's style.
+        * When converting a length for a typographical property, such as
+        * font-size, then this should be the parent node.  If the node has
+        * no parent then this may be NULL.
+        */
+       const css_computed_style *ref_style;
+       /**
+        * Computed style for the document root element.
+        * May be NULL if unit is not rem.
+        */
+       const css_computed_style *root_style;
+       /**
+        * Client private word for measure callback.
+        */
+       void *pw;
+       /**
+        * Client callback for font measuring.
+        */
+       const css_unit_len_measure measure;
+} css_unit_len_ctx;
+
+/**
+ * Convert css pixels to physical pixels.
+ *
+ * \param[in] css_pixels  Length in css pixels.
+ * \param[in] device_dpi  Device dots per inch.
+ * \return Length in device pixels.
+ */
+static inline css_fixed css_unit_css2device_px(
+               const css_fixed css_pixels,
+               const css_fixed device_dpi)
+{
+       return FDIV(FMUL(css_pixels, device_dpi), F_96);
+}
+
+/**
+ * Convert device pixels to css pixels.
+ *
+ * \param[in] device_pixels  Length in physical pixels.
+ * \param[in] device_dpi     Device dots per inch.
+ * \return Length in css pixels.
+ */
+static inline css_fixed css_unit_device2css_px(
+               const css_fixed device_pixels,
+               const css_fixed device_dpi)
+{
+       return FDIV(FMUL(device_pixels, F_96), device_dpi);
+}
+
+css_fixed css_unit_font_size_len2pt(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit);
+
+
+css_fixed css_unit_len2css_px(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit);
+
+css_fixed css_unit_len2device_px(
+               const css_unit_len_ctx *ctx,
+               const css_fixed length,
+               const css_unit unit);
+
+/**
+ * Convert a length to CSS pixels for a media query context.
+ *
+ * \param[in]  media   Client media specification.
+ * \param[in]  length  Length to convert.
+ * \param[in]  unit    Current unit of length.
+ * \return A length in CSS pixels.
+ */
+css_fixed css_unit_len2px_mq(
+               const css_media *media,
+               const css_fixed length,
+               const css_unit unit);
+
+/**
+ * Convert relative font size units to absolute units.
+ *
+ * \param[in]     ctx   Length unit conversion context.
+ * \param[in,out] size  The length to convert.
+ * \return CSS_OK on success, or appropriate error otherwise.
+ */
+css_error css_unit_compute_absolute_font_size(
+               const css_unit_len_ctx *ctx,
+               css_hint *size);
+
+#endif


-----------------------------------------------------------------------

Summary of changes:
 src/select/unit.c |  126 +++++++++++++++++++++++++++++++----------------------
 src/select/unit.h |   13 ++++--
 2 files changed, 85 insertions(+), 54 deletions(-)

diff --git a/src/select/unit.c b/src/select/unit.c
index 7559740..e01c59e 100644
--- a/src/select/unit.c
+++ b/src/select/unit.c
@@ -72,31 +72,24 @@ static inline css_fixed css_unit__len2pt(
                        viewport_width,
                        unit)) {
        case CSS_UNIT_PX:
-               /* We assume the screen and any other output has the same dpi */
-               /* 1in = DPIpx => 1px = (72/DPI)pt */
                return FDIV(FMUL(length, F_72), F_96);
 
        case CSS_UNIT_IN:
-               /* 1in = 72pt */
                return FMUL(length, F_72);
 
        case CSS_UNIT_CM:
-               /* 1in = 2.54cm => 1cm = (72/2.54)pt */
                return FMUL(length, FDIV(F_72, FLTTOFIX(2.54)));
 
        case CSS_UNIT_MM:
-               /* 1in = 25.4mm => 1mm = (72/25.4)pt */
                return FMUL(length, FDIV(F_72, FLTTOFIX(25.4)));
 
        case CSS_UNIT_Q:
-               /* 1in = 101.6q => 1mm = (72/101.6)pt */
                return FMUL(length, FDIV(F_72, FLTTOFIX(101.6)));
 
        case CSS_UNIT_PT:
                return length;
 
        case CSS_UNIT_PC:
-               /* 1pc = 12pt */
                return FMUL(length, INTTOFIX(12));
 
        case CSS_UNIT_VH:
@@ -112,7 +105,7 @@ static inline css_fixed css_unit__len2pt(
        }
 }
 
-css_fixed css_unit_len2pt(
+css_fixed css_unit_font_size_len2pt(
                const css_unit_len_ctx *ctx,
                const css_fixed length,
                const css_unit unit)
@@ -125,7 +118,7 @@ css_fixed css_unit_len2pt(
                        unit);
 }
 
-static inline css_fixed css_unit__font_size(
+static inline css_fixed css_unit__font_size_px(
                const css_computed_style *style,
                const css_fixed font_size_default,
                const css_fixed font_size_minimum,
@@ -141,13 +134,15 @@ static inline css_fixed css_unit__font_size(
 
        get_font_size(style, &font_length, &font_unit);
 
-       /* Convert to points */
        font_length = css_unit__len2pt(style,
                        viewport_height,
                        viewport_width,
                        font_length,
                        font_unit);
 
+       /* Convert from pt to CSS pixels.*/
+       font_length = FDIV(FMUL(font_length, F_96), F_72);
+
        /* Clamp to configured minimum */
        if (font_length < font_size_minimum) {
                font_length = font_size_minimum;
@@ -187,7 +182,7 @@ static inline css_fixed css_unit__px_per_unit(
                        viewport_width,
                        unit)) {
        case CSS_UNIT_EM:
-               return css_unit__font_size(
+               return css_unit__font_size_px(
                                ref_style,
                                font_size_default,
                                font_size_minimum,
@@ -198,7 +193,7 @@ static inline css_fixed css_unit__px_per_unit(
                if (measure != NULL) {
                        return measure(pw, ref_style, CSS_UNIT_EX);
                }
-               return FMUL(css_unit__font_size(
+               return FMUL(css_unit__font_size_px(
                                ref_style,
                                font_size_default,
                                font_size_minimum,
@@ -209,7 +204,7 @@ static inline css_fixed css_unit__px_per_unit(
                if (measure != NULL) {
                        return measure(pw, ref_style, CSS_UNIT_CH);
                }
-               return FMUL(css_unit__font_size(
+               return FMUL(css_unit__font_size_px(
                                ref_style,
                                font_size_default,
                                font_size_minimum,
@@ -238,7 +233,7 @@ static inline css_fixed css_unit__px_per_unit(
                return FDIV(F_96, INTTOFIX(6));
 
        case CSS_UNIT_REM:
-               return css_unit__font_size(
+               return css_unit__font_size_px(
                                root_style,
                                font_size_default,
                                font_size_minimum,
@@ -356,17 +351,24 @@ static inline css_hint_length css_unit__get_font_size(
        return size;
 }
 
-/* TODO: Cleanup..... */
+/* Exported function, documented in unit.h. */
 css_error css_unit_compute_absolute_font_size(
                const css_unit_len_ctx *ctx,
                css_hint *size)
 {
-       css_hint_length parent = css_unit__get_font_size(ctx, ctx->ref_style);
+       css_hint_length ref_len;
 
        assert(size->status != CSS_FONT_SIZE_INHERIT);
 
-       if (size->status <= CSS_FONT_SIZE_XX_LARGE) {
-               /* Table of font-size keyword scale factors. */
+       switch (size->status) {
+       case CSS_FONT_SIZE_XX_SMALL: /* Fall-through. */
+       case CSS_FONT_SIZE_X_SMALL:  /* Fall-through. */
+       case CSS_FONT_SIZE_SMALL:    /* Fall-through. */
+       case CSS_FONT_SIZE_MEDIUM:   /* Fall-through. */
+       case CSS_FONT_SIZE_LARGE:    /* Fall-through. */
+       case CSS_FONT_SIZE_X_LARGE:  /* Fall-through. */
+       case CSS_FONT_SIZE_XX_LARGE:
+       {
                static const css_fixed factors[CSS_FONT_SIZE_XX_LARGE] = {
                        [CSS_FONT_SIZE_XX_SMALL - 1] = FLTTOFIX(0.5625),
                        [CSS_FONT_SIZE_X_SMALL  - 1] = FLTTOFIX(0.6250),
@@ -382,55 +384,77 @@ css_error css_unit_compute_absolute_font_size(
                size->data.length.value = FMUL(factors[size->status - 1],
                                ctx->font_size_default);
                size->data.length.unit = CSS_UNIT_PX;
-
-       } else if (size->status == CSS_FONT_SIZE_LARGER) {
-               size->data.length.value = FMUL(parent.value, FLTTOFIX(1.2));
-               size->data.length.unit = parent.unit;
-
-       } else if (size->status == CSS_FONT_SIZE_SMALLER) {
-               size->data.length.value = FDIV(parent.value, FLTTOFIX(1.2));
-               size->data.length.unit = parent.unit;
-
-       } else switch (size->data.length.unit) {
-       case CSS_UNIT_PCT:
-               size->data.length.value = FDIV(FMUL(size->data.length.value,
-                               parent.value), INTTOFIX(100));
-               size->data.length.unit = parent.unit;
+               size->status = CSS_FONT_SIZE_DIMENSION;
+               break;
+       }
+       case CSS_FONT_SIZE_LARGER:
+               ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+               size->data.length.value = FMUL(ref_len.value, FLTTOFIX(1.2));
+               size->data.length.unit = ref_len.unit;
+               size->status = CSS_FONT_SIZE_DIMENSION;
                break;
 
-       case CSS_UNIT_REM:
-               /* Root element relative units. */
-               parent = css_unit__get_font_size(ctx, ctx->root_style);
-               /* Fall-through */
-       case CSS_UNIT_EM: /* Fall-through */
-       case CSS_UNIT_EX: /* Fall-through */
-       case CSS_UNIT_CH:
-               /* Parent relative units. */
-               size->data.length.unit = parent.unit;
-               size->data.length.value =
-                               FMUL(size->data.length.value, parent.value);
+       case CSS_FONT_SIZE_SMALLER:
+               ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+               size->data.length.value = FDIV(ref_len.value, FLTTOFIX(1.2));
+               size->data.length.unit = ref_len.unit;
+               size->status = CSS_FONT_SIZE_DIMENSION;
+               break;
 
+       case CSS_FONT_SIZE_DIMENSION:
+               /* Convert any relative units to absolute. */
                switch (size->data.length.unit) {
-               case CSS_UNIT_EX:
-                       size->data.length.value = FMUL(size->data.length.value,
-                                       FLTTOFIX(0.6));
+               case CSS_UNIT_PCT:
+                       ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+                       size->data.length.value = FDIV(
+                                       FMUL(size->data.length.value,
+                                       ref_len.value), INTTOFIX(100));
+                       size->data.length.unit = ref_len.unit;
                        break;
 
+               case CSS_UNIT_EM: /* Fall-through */
+               case CSS_UNIT_EX: /* Fall-through */
                case CSS_UNIT_CH:
+                       /* Parent relative units. */
+                       ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+
+                       size->data.length.unit = ref_len.unit;
                        size->data.length.value = FMUL(size->data.length.value,
-                                       FLTTOFIX(0.4));
+                                               ref_len.value);
+
+                       switch (size->data.length.unit) {
+                       case CSS_UNIT_EX:
+                               size->data.length.value = FMUL(
+                                               size->data.length.value,
+                                               FLTTOFIX(0.6));
+                               break;
+
+                       case CSS_UNIT_CH:
+                               size->data.length.value = FMUL(
+                                               size->data.length.value,
+                                               FLTTOFIX(0.4));
+                               break;
+
+                       default:
+                               break;
+                       }
+                       break;
+
+               case CSS_UNIT_REM:
+                       /* Root element relative units. */
+                       ref_len = css_unit__get_font_size(ctx, ctx->root_style);
+
+                       size->data.length.unit = ref_len.unit;
+                       size->data.length.value = FMUL(size->data.length.value,
+                                               ref_len.value);
                        break;
 
                default:
                        break;
                }
-               break;
-
        default:
                break;
        }
 
-       size->status = CSS_FONT_SIZE_DIMENSION;
-
        return CSS_OK;
 }
diff --git a/src/select/unit.h b/src/select/unit.h
index 89fe781..7ed6458 100644
--- a/src/select/unit.h
+++ b/src/select/unit.h
@@ -42,7 +42,7 @@ typedef struct css_unit_len_ctx {
         */
        css_fixed viewport_height;
        /**
-        * Default font size in CSS pixels.
+        * Client default font size in CSS pixels.
         */
        css_fixed font_size_default;
        /**
@@ -66,7 +66,7 @@ typedef struct css_unit_len_ctx {
         */
        const css_computed_style *root_style;
        /**
-        * Client private word for callback.
+        * Client private word for measure callback.
         */
        void *pw;
        /**
@@ -103,7 +103,7 @@ static inline css_fixed css_unit_device2css_px(
        return FDIV(FMUL(device_pixels, F_96), device_dpi);
 }
 
-css_fixed css_unit_len2pt(
+css_fixed css_unit_font_size_len2pt(
                const css_unit_len_ctx *ctx,
                const css_fixed length,
                const css_unit unit);
@@ -132,6 +132,13 @@ css_fixed css_unit_len2px_mq(
                const css_fixed length,
                const css_unit unit);
 
+/**
+ * Convert relative font size units to absolute units.
+ *
+ * \param[in]     ctx   Length unit conversion context.
+ * \param[in,out] size  The length to convert.
+ * \return CSS_OK on success, or appropriate error otherwise.
+ */
 css_error css_unit_compute_absolute_font_size(
                const css_unit_len_ctx *ctx,
                css_hint *size);


-- 
Cascading Style Sheets library
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to