From 409aa04d9de6bc570db3f4125405be6c44988700 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 9 Jun 2021 17:52:59 +0100 Subject: [PATCH] [Rework] Html/Css: Start rework of the html blocks --- src/libserver/css/css_value.hxx | 17 ++-- src/libserver/html/html.cxx | 1 + src/libserver/html/html.h | 29 ------- src/libserver/html/html.hxx | 10 +-- src/libserver/html/html_block.hxx | 136 ++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 41 deletions(-) create mode 100644 src/libserver/html/html_block.hxx diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx index 82f65e3e9..a7b9a9b47 100644 --- a/src/libserver/css/css_value.hxx +++ b/src/libserver/css/css_value.hxx @@ -49,6 +49,13 @@ struct alignas(int) css_color { friend bool operator==(const css_color& l, const css_color& r) { return (memcmp(&l, &r, sizeof(css_color)) == 0); } + + static auto white() -> css_color { + return css_color{255, 255, 255}; + } + static auto black() -> css_color { + return css_color{0, 0, 0}; + } }; struct css_dimension { @@ -59,7 +66,7 @@ struct css_dimension { /* * Simple enum class for display stuff */ -enum class css_display_value { +enum class css_display_value : std::uint8_t { DISPLAY_NORMAL, DISPLAY_HIDDEN }; @@ -70,7 +77,7 @@ enum class css_display_value { */ struct css_value { std::variant value; @@ -78,7 +85,7 @@ struct css_value { css_value() {} css_value(const css_color &color) : value(color) {} - css_value(double num) : + css_value(float num) : value(num) {} css_value(css_dimension dim) : value(dim) {} @@ -89,8 +96,8 @@ struct css_value { return extract_value_maybe(); } - auto to_number(void) const -> std::optional { - return extract_value_maybe(); + auto to_number(void) const -> std::optional { + return extract_value_maybe(); } auto to_dimension(void) const -> std::optional { diff --git a/src/libserver/html/html.cxx b/src/libserver/html/html.cxx index 62f2a8c7d..e867cce6d 100644 --- a/src/libserver/html/html.cxx +++ b/src/libserver/html/html.cxx @@ -18,6 +18,7 @@ #include "message.h" #include "html.h" #include "html_tags.h" +#include "html_block.hxx" #include "html.hxx" #include "libserver/css/css_value.hxx" diff --git a/src/libserver/html/html.h b/src/libserver/html/html.h index 3b6592402..291e0cfda 100644 --- a/src/libserver/html/html.h +++ b/src/libserver/html/html.h @@ -57,35 +57,6 @@ struct html_image { void *tag; }; -struct html_color { - union { - struct { -#if !defined(BYTE_ORDER) || BYTE_ORDER == LITTLE_ENDIAN - guint8 b; - guint8 g; - guint8 r; - guint8 alpha; -#else - guint8 alpha; - guint8 r; - guint8 g; - guint8 b; -#endif - } comp; - guint32 val; - } d; - gboolean valid; -}; - -struct html_block { - void *tag; - struct html_color font_color; - struct html_color background_color; - rspamd_ftok_t style; - guint font_size; - gboolean visible; - gchar *html_class; -}; /* Public tags flags */ /* XML tag */ diff --git a/src/libserver/html/html.hxx b/src/libserver/html/html.hxx index 99948ebbd..fc1dda141 100644 --- a/src/libserver/html/html.hxx +++ b/src/libserver/html/html.hxx @@ -24,18 +24,20 @@ #include "libserver/html/html.h" #include "libserver/html/html_tags.h" + #include #include #include "function2/function2.hpp" namespace rspamd::html { +struct html_block; + struct html_content { struct rspamd_url *base_url = nullptr; struct html_tag *root_tag = nullptr; gint flags = 0; guint total_tags = 0; - struct html_color bgcolor; std::vector tags_seen; std::vector images; std::vector blocks; @@ -49,12 +51,6 @@ struct html_content { blocks.reserve(128); all_tags.reserve(128); parsed.reserve(256); - /* Set white background color by default */ - bgcolor.d.comp.alpha = 0; - bgcolor.d.comp.r = 255; - bgcolor.d.comp.g = 255; - bgcolor.d.comp.b = 255; - bgcolor.valid = TRUE; } static void html_content_dtor(void *ptr) { diff --git a/src/libserver/html/html_block.hxx b/src/libserver/html/html_block.hxx new file mode 100644 index 000000000..276b77dec --- /dev/null +++ b/src/libserver/html/html_block.hxx @@ -0,0 +1,136 @@ +/*- + * Copyright 2021 Vsevolod Stakhov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RSPAMD_HTML_BLOCK_HXX +#define RSPAMD_HTML_BLOCK_HXX +#pragma once + +#include "libserver/css/css_value.hxx" + +namespace rspamd::html { + +/* + * Block tag definition + */ +struct html_block { + rspamd::css::css_color fg_color; + rspamd::css::css_color bg_color; + std::uint16_t height; + std::uint16_t width; + std::uint16_t mask; + rspamd::css::css_display_value display; + std::uint8_t font_size; + + constexpr static const auto fg_color_mask = 0x1 << 0; + constexpr static const auto bg_color_mask = 0x1 << 1; + constexpr static const auto height_mask = 0x1 << 2; + constexpr static const auto width_mask = 0x1 << 3; + constexpr static const auto display_mask = 0x1 << 4; + constexpr static const auto font_size_mask = 0x1 << 5; + + /* Helpers to set mask when setting the elements */ + auto set_fgcolor(const rspamd::css::css_color &c) -> void { + fg_color = c; + mask |= fg_color_mask; + } + auto set_bgcolor(const rspamd::css::css_color &c) -> void { + bg_color = c; + mask |= bg_color_mask; + } + auto set_height(double h) -> void { + if (h < 0) { + height = 0; + } + else if (h > UINT16_MAX) { + height = UINT16_MAX; + } + else { + height = h; + } + mask |= height_mask; + } + auto set_width(double w) -> void { + if (w < 0) { + width = 0; + } + else if (w > UINT16_MAX) { + width = UINT16_MAX; + } + else { + width = w; + } + mask |= width_mask; + } + auto set_display(bool v) -> void { + if (v) { + display = rspamd::css::css_display_value::DISPLAY_NORMAL; + } + else { + display = rspamd::css::css_display_value::DISPLAY_HIDDEN; + } + mask |= display_mask; + } + auto set_display(rspamd::css::css_display_value v) -> void { + display = v; + mask |= display_mask; + } + auto set_font_size(float fs) -> void { + if (fs < 0) { + font_size = 0; + } + else if (fs > UINT8_MAX) { + font_size = UINT8_MAX; + } + else { + font_size = fs; + } + mask |= font_size_mask; + } + + /** + * Propagate values from the block if they are not defined by the current block + * @param other + * @return + */ + auto propagate_block(const html_block &other) -> void { +#define PROPAGATE_ELT(elt) \ + do { if (!(mask & elt##_mask) && (other.mask & elt##_mask)) (elt) = other.elt; } while(0) + + PROPAGATE_ELT(fg_color); + PROPAGATE_ELT(bg_color); + PROPAGATE_ELT(height); + PROPAGATE_ELT(width); + PROPAGATE_ELT(display); + PROPAGATE_ELT(font_size); +#undef PROPAGATE_ELT + } + + /** + * Returns a default html block for root HTML element + * @return + */ + static auto default_html_block(void) -> html_block { + return html_block{rspamd::css::css_color::black(), + rspamd::css::css_color::white(), + 0, 0, + (fg_color_mask|bg_color_mask|display_mask|font_size_mask), + rspamd::css::css_display_value::DISPLAY_NORMAL, + 12}; + } +}; + +} + +#endif //RSPAMD_HTML_BLOCK_HXX -- 2.39.5