diff options
Diffstat (limited to 'include/netsurf/plot_style.h')
-rw-r--r-- | include/netsurf/plot_style.h | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/include/netsurf/plot_style.h b/include/netsurf/plot_style.h index 30db3663e..875020cd8 100644 --- a/include/netsurf/plot_style.h +++ b/include/netsurf/plot_style.h @@ -25,6 +25,8 @@ #define NETSURF_PLOT_STYLE_H #include <stdint.h> +#include <stdint.h> +#include <libwapcaplet/libwapcaplet.h> #include "netsurf/types.h" /** light grey widget base colour */ @@ -36,8 +38,26 @@ /** Transparent colour value. */ #define NS_TRANSPARENT 0x01000000 -/** Scaling factor for font sizes */ -#define FONT_SIZE_SCALE 1024 +/** 22:10 fixed point */ +#define PLOT_STYLE_RADIX (10) + +/** Scaling factor for plot styles */ +#define PLOT_STYLE_SCALE (1 << PLOT_STYLE_RADIX) + +/* type for fixed point numbers */ +typedef int32_t plot_style_fixed; + +/* Convert an int to fixed point */ +#define plot_style_int_to_fixed(v) ((v) << PLOT_STYLE_RADIX) + +/* Convert fixed point to int */ +#define plot_style_fixed_to_int(v) ((v) >> PLOT_STYLE_RADIX) + +/* Convert fixed point to float */ +#define plot_style_fixed_to_float(v) (((float)v) / PLOT_STYLE_SCALE) + +/* Convert fixed point to double */ +#define plot_style_fixed_to_double(v) (((double)v) / PLOT_STYLE_SCALE) /** * Type of plot operation @@ -55,7 +75,7 @@ typedef enum { */ typedef struct plot_style_s { plot_operation_type_t stroke_type; /**< Stroke plot type */ - int stroke_width; /**< Width of stroke, in pixels */ + plot_style_fixed stroke_width; /**< Width of stroke, in pixels */ colour stroke_colour; /**< Colour of stroke */ plot_operation_type_t fill_type; /**< Fill plot type */ colour fill_colour; /**< Colour of fill */ @@ -89,8 +109,14 @@ typedef enum { * Font style for plotting */ typedef struct plot_font_style { + /** + * Array of pointers to font families. + * + * May be NULL. Array is NULL terminated. + */ + lwc_string * const * families; plot_font_generic_family_t family; /**< Generic family to plot with */ - int size; /**< Font size, in points * FONT_SIZE_SCALE */ + plot_style_fixed size; /**< Font size, in pt */ int weight; /**< Font weight: value in range [100,900] as per CSS */ plot_font_flags_t flags; /**< Font flags */ colour background; /**< Background colour to blend to, if appropriate */ @@ -98,8 +124,13 @@ typedef struct plot_font_style { } plot_font_style_t; +/* Darken a colour by taking seven eighths of each channel's intensity */ +#define half_darken_colour(c1) \ + ((((7 * (c1 & 0xff00ff)) >> 3) & 0xff00ff) | \ + (((7 * (c1 & 0x00ff00)) >> 3) & 0x00ff00)) + /* Darken a colour by taking three quarters of each channel's intensity */ -#define darken_colour(c1) \ +#define darken_colour(c1) \ ((((3 * (c1 & 0xff00ff)) >> 2) & 0xff00ff) | \ (((3 * (c1 & 0x00ff00)) >> 2) & 0x00ff00)) @@ -108,6 +139,12 @@ typedef struct plot_font_style { ((((9 * (c1 & 0xff00ff)) >> 4) & 0xff00ff) | \ (((9 * (c1 & 0x00ff00)) >> 4) & 0x00ff00)) +/* Lighten a colour by taking seven eighths of each channel's intensity + * and adding a full one eighth intensity */ +#define half_lighten_colour(c1) \ + (((((7 * (c1 & 0xff00ff)) >> 3) + 0x200020) & 0xff00ff) | \ + ((((7 * (c1 & 0x00ff00)) >> 3) + 0x002000) & 0x00ff00)) + /* Lighten a colour by taking 12/16ths of each channel's intensity * and adding a full 4/16ths intensity */ #define lighten_colour(c1) \ @@ -127,13 +164,34 @@ typedef struct plot_font_style { (((((c0 & 0xff00ff) + (c1 & 0xff00ff)) >> 1) & 0xff00ff) | \ ((((c0 & 0x00ff00) + (c1 & 0x00ff00)) >> 1) & 0x00ff00)) +/** + * Obtain the luminance of a colour according to ITU BT.601 + * + * ITU BT.601 formula is + * Y = 0.299 R + 0.587 G + 0.114 B + * actual values are + * Y = 76/255 R + 150/255 G + 29/255 B + * Y = 0.298 R + 0.588 G + 0.113 B + * + * @note if additional performance is required this could be altered to + * Y = 0.375 R + 0.5 G + 0.125 B + * with + * Y = (R << 1 + R + G << 2 + B) >> 3 + */ +#define colour_lightness(c0) \ + ((((c0 & 0x0000ff) * 77) >> 8) + \ + (((c0 & 0x00ff00) * 151) >> 16) + \ + (((c0 & 0xff0000) * 30) >> 24)) + +/* Choose either black or white, depending on which is nearest to the + * percieved lightness of the supplied colour, c0. */ +#define colour_to_bw_nearest(c0) \ + ((colour_lightness(c0) > (0xff / 2)) ? 0xffffff : 0x000000) + /* Choose either black or white, depending on which is furthest from the * percieved lightness of the supplied colour, c0. */ #define colour_to_bw_furthest(c0) \ - ((((((c0 & 0x0000ff) * 77) >> 8) + \ - (((c0 & 0x00ff00) * 151) >> 16) + \ - (((c0 & 0xff0000) * 28) >> 24)) > \ - (0xff / 2)) ? 0x000000 : 0xffffff) + ((colour_lightness(c0) > (0xff / 2)) ? 0x000000 : 0xffffff) /* Mix two colours according to the proportion given by p, where 0 <= p <= 255 * p = 0 gives result ==> c1, p = 255 gives result ==> c0 */ @@ -143,10 +201,6 @@ typedef struct plot_font_style { (((((c1 & 0x00ff00) * (255 - p)) + \ ((c0 & 0x00ff00) * ( p)) ) >> 8) & 0x00ff00)) -/* get a bitmap pixel (image/bitmap.h) into a plot colour */ -#define pixel_to_colour(b) \ - b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24) - /* Get the red channel from a colour */ #define red_from_colour(c) \ ((c ) & 0xff) @@ -159,6 +213,45 @@ typedef struct plot_font_style { #define blue_from_colour(c) \ ((c >> 16) & 0xff) +/* Swap red and blue channels in a colour */ +#define colour_rb_swap(c) \ + (((0x000000ff & c) << 16) | \ + ((0x0000ff00 & c) ) | \ + ((0x00ff0000 & c) >> 16)) + +/** Colour components */ +enum plot_colour_component { + PLOT_COLOUR_COMPONENT_RED, + PLOT_COLOUR_COMPONENT_GREEN, + PLOT_COLOUR_COMPONENT_BLUE, + PLOT_COLOUR_COMPONENT_ALPHA, +}; + +/** + * Engorge a particular colour channel. + * + * \param[in] col The colour to engorge a component of. + * \param[in] dark Whether col is a dark colour. + * \param[in] comp Colour component to engorge. + */ +static inline colour colour_engorge_component( + colour col, + bool dark, + enum plot_colour_component comp) +{ + static const colour msk[PLOT_COLOUR_COMPONENT_ALPHA] = { + [PLOT_COLOUR_COMPONENT_RED] = 0x0000ff, + [PLOT_COLOUR_COMPONENT_GREEN] = 0x00ff00, + [PLOT_COLOUR_COMPONENT_BLUE] = 0xff0000, + }; + colour d = dark ? darken_colour(col) : double_darken_colour(col); + colour l = dark ? double_lighten_colour(col) : lighten_colour(col); + + assert(comp < PLOT_COLOUR_COMPONENT_ALPHA); + + return (msk[comp] & l) | (~msk[comp] & d); +} + /* global fill styles */ extern plot_style_t *plot_style_fill_white; |