<commit_before>/*
 * libcss-handler.c
 * Copyright 2017 <NAME> <<EMAIL>>
 *
 * Handler functions for libcss.
 * Based on the source code of netsurf and libcss.
 * Base files available at http://source.netsurf-browser.org
 *
 * Part of the w3d project.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libcss/libcss.h>

css_error css_resolve_url(void *pw, const char *base,
  lwc_string *rel, lwc_string **abs);
void add_stylesheet (const char* css_string, const char* level,
    const char* charset, const char* url);

static css_error node_name(void *pw, void *node, css_qname *qname);
static css_error node_classes(void *pw, void *node,
		lwc_string ***classes, uint32_t *n_classes);
static css_error node_id(void *pw, void *node, lwc_string **id);
static css_error named_parent_node(void *pw, void *node,
		const css_qname *qname, void **parent);
static css_error named_sibling_node(void *pw, void *node,
		const css_qname *qname, void **sibling);
static css_error named_generic_sibling_node(void *pw, void *node,
		const css_qname *qname, void **sibling);
static css_error parent_node(void *pw, void *node, void **parent);
static css_error sibling_node(void *pw, void *node, void **sibling);
static css_error node_has_name(void *pw, void *node,
		const css_qname *qname, bool *match);
static css_error node_has_class(void *pw, void *node,
		lwc_string *name, bool *match);
static css_error node_has_id(void *pw, void *node,
		lwc_string *name, bool *match);
static css_error node_has_attribute(void *pw, void *node,
		const css_qname *qname, bool *match);
static css_error node_has_attribute_equal(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_dashmatch(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_includes(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_prefix(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_suffix(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_substring(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_is_root(void *pw, void *node, bool *match);
static css_error node_count_siblings(void *pw, void *node,
		bool same_name, bool after, int32_t *count);
static css_error node_is_empty(void *pw, void *node, bool *match);
static css_error node_is_link(void *pw, void *node, bool *match);
static css_error node_is_hover(void *pw, void *node, bool *match);
static css_error node_is_active(void *pw, void *node, bool *match);
static css_error node_is_focus(void *pw, void *node, bool *match);
static css_error node_is_enabled(void *pw, void *node, bool *match);
static css_error node_is_disabled(void *pw, void *node, bool *match);
static css_error node_is_checked(void *pw, void *node, bool *match);
static css_error node_is_target(void *pw, void *node, bool *match);
static css_error node_is_lang(void *pw, void *node,
		lwc_string *lang, bool *match);
static css_error node_presentational_hint(void *pw, void *node,
			uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
		css_hint *hint);
static css_error set_libcss_node_data(void *pw, void *node,
		void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *node,
		void **libcss_node_data);

/**
 * Selection callback table for libcss
 */
static css_select_handler selection_handler = {
	CSS_SELECT_HANDLER_VERSION_1,

	node_name,
	node_classes,
	node_id,
	named_ancestor_node,
	named_parent_node,
	named_sibling_node,
	named_generic_sibling_node,
	parent_node,
	sibling_node,
	node_has_name,
	node_has_class,
	node_has_id,
	node_has_attribute,
	node_has_attribute_equal,
	node_has_attribute_dashmatch,
	node_has_attribute_includes,
	node_has_attribute_prefix,
	node_has_attribute_suffix,
	node_has_attribute_substring,
	node_is_root,
	node_count_siblings,
	node_is_empty,
	node_is_link,
	node_is_visited,
	node_is_hover,
	node_is_active,
	node_is_focus,
	node_is_enabled,
	node_is_disabled,
	node_is_checked,
	node_is_target,
	node_is_lang,
	node_presentational_hint,
	ua_default_for_property,
	compute_font_size,
	set_libcss_node_data,
	get_libcss_node_data,
};

css_select_ctx* select_ctx;
css_select_ctx_create(&select_ctx);

css_error resolve_url(
  void *pw, const char *base, lwc_string *rel, lwc_string **abs
)
{
  const char* base_str = base;
  const size_t base_s = strlen(base);
  const char* rel_str = lwc_string_data(rel_str);
  const size_t rel_s = strlen(rel_str);

  if (base_str[base_s] == "/")
    base_str[base_s] = "\0";

  char abs_str[base_s + rel_s + 2];
  strcpy(abs_str, base_str);
  strcat(abs_str, "/");
  strcat(abs_str, rel_str);

  lwc_intern_string(abs_str, strlen(abs_str), abs);
  return CSS_OK;
}

void add_stylesheet (
  const char* css_string,
  const char* level,
  const char* charset,
  const char* url
)
{
  css_language_level css_level;
  if (strcmp(level, "1") == 0)
    css_level = CSS_LEVEL_1;
  else if (strcmp(level, "2") == 0)
    css_level = CSS_LEVEL_2;
  else if (strcmp(level, "2.1") == 0)
    css_level = CSS_LEVEL_21;
  else
    css_level = CSS_LEVEL_3; /* Default */

  css_stylesheet_params params;
  params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
  params.level = css_level;
  params.charset = charset;
  params.url = url;
  params.title = NULL;
  params.allow_quirks = false;
  params.inline_style = false;
  params.resolve = resolve_url;
  params.resolve_pw = NULL;
  params.import = NULL;
  params.import_pw = NULL;
  params.color = NULL;
  params.color_pw = NULL;
  params.font = NULL;
  params.font_pw = NULL;

  css_stylesheet *sheet;
  css_stylesheet_create(&params, &sheet);

  css_stylesheet_append_data(
    sheet,
    (const uint8_t *) data,
    sizeof data
  );
  css_stylesheet_data_done(sheet);

  css_select_ctx_append_sheet(
    select_ctx,
    sheet,
    CSS_ORIGIN_AUTHOR,
    CSS_MEDIA_ALL
  );
}

/*
 * Warning: if inline_style is set, the resulting stylesheet will not
 * be destroyed! This implementation leaks memory.
 */
css_select_results* buildStyle(
  lwc_string* node,
  const char* inline_style
)
{
  const css_stylesheet* in_style;
  if (inline_style == NULL || *inline_style == "\0")
    in_style = NULL;
  else
  {
    css_stylesheet_params params;
    params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
    params.level = css_level;
    params.charset = "UTF-8";
    params.url = NULL;
    params.title = NULL;
    params.allow_quirks = false;
    params.inline_style = true;
    params.resolve = NULL;
    params.resolve_pw = NULL;
    params.import = NULL;
    params.import_pw = NULL;
    params.color = NULL;
    params.color_pw = NULL;
    params.font = NULL;
    params.font_pw = NULL;

    css_stylesheet* sheet;
    css_stylesheet_create(&params, &sheet);

    css_stylesheet_append_data(
      sheet,
      (const uint8_t *) inline_style,
      sizeof inline_style
    );
    css_stylesheet_data_done(sheet);
    in_style = sheet;
  }

  css_select_results* results;
  css_select_style(
    select_ctx,
    node,
    CSS_MEDIA_SCREEN,
    in_style,
		selection_handler,
    NULL,
		&results
  );

  return results;
}

uint64_t make_results_for_js (
    uint8_t type,
    uint8_t var1,
    uint8_t var2,
    uint8_t var3
)
{
  uint64_t results = (uint64_t) type;
  results += ((uint64_t) var1) * 0x100;
  results += ((uint64_t) var2) * 0x10000;
  results += ((uint64_t) var3) * 0x1000000;
  return results;
}

uint64_t get_property (css_stylesheet* sheet, const char* prop)
{
case CSS_PROP_AZIMUTH:
break;
case CSS_PROP_BACKGROUND_ATTACHMENT:
break;
case CSS_PROP_BACKGROUND_COLOR:
break;
case CSS_PROP_BACKGROUND_IMAGE:
break;
case CSS_PROP_BACKGROUND_POSITION:
break;
case CSS_PROP_BACKGROUND_REPEAT:
break;
case CSS_PROP_BORDER_COLLAPSE:
break;
case CSS_PROP_BORDER_SPACING:
break;
case CSS_PROP_BORDER_TOP_COLOR:
break;
case CSS_PROP_BORDER_RIGHT_COLOR:
break;
case CSS_PROP_BORDER_BOTTOM_COLOR:
break;
case CSS_PROP_BORDER_LEFT_COLOR:
break;
case CSS_PROP_BORDER_TOP_STYLE:
break;
case CSS_PROP_BORDER_RIGHT_STYLE:
break;
case CSS_PROP_BORDER_BOTTOM_STYLE:
break;
case CSS_PROP_BORDER_LEFT_STYLE:
break;
case CSS_PROP_BORDER_TOP_WIDTH:
break;
case CSS_PROP_BORDER_RIGHT_WIDTH:
break;
case CSS_PROP_BORDER_BOTTOM_WIDTH:
break;
case CSS_PROP_BORDER_LEFT_WIDTH:
break;
case CSS_PROP_BOTTOM:
break;
case CSS_PROP_CAPTION_SIDE:
break;
case CSS_PROP_CLEAR:
break;
case CSS_PROP_CLIP:
break;
case CSS_PROP_COLOR:
break;
case CSS_PROP_CONTENT:
break;
case CSS_PROP_COUNTER_INCREMENT:
break;
case CSS_PROP_COUNTER_RESET:
break;
case CSS_PROP_CUE_AFTER:
break;
case CSS_PROP_CUE_BEFORE:
break;
case CSS_PROP_CURSOR:
break;
case CSS_PROP_DIRECTION:
break;
case CSS_PROP_DISPLAY:
break;
case CSS_PROP_ELEVATION:
break;
case CSS_PROP_EMPTY_CELLS:
break;
case CSS_PROP_FLOAT:
break;
case CSS_PROP_FONT_FAMILY:
break;
case CSS_PROP_FONT_SIZE:
break;
case CSS_PROP_FONT_STYLE:
break;
case CSS_PROP_FONT_VARIANT:
break;
case CSS_PROP_FONT_WEIGHT:
break;
case CSS_PROP_HEIGHT:
break;
case CSS_PROP_LEFT:
break;
case CSS_PROP_LETTER_SPACING:
break;
case CSS_PROP_LINE_HEIGHT:
break;
case CSS_PROP_LIST_STYLE_IMAGE:
break;
case CSS_PROP_LIST_STYLE_POSITION:
break;
case CSS_PROP_LIST_STYLE_TYPE:
break;
case CSS_PROP_MARGIN_TOP:
break;
case CSS_PROP_MARGIN_RIGHT:
break;
case CSS_PROP_MARGIN_BOTTOM:
break;
case CSS_PROP_MARGIN_LEFT:
break;
case CSS_PROP_MAX_HEIGHT:
break;
case CSS_PROP_MAX_WIDTH:
break;
case CSS_PROP_MIN_HEIGHT:
break;
case CSS_PROP_MIN_WIDTH:
break;
case CSS_PROP_ORPHANS:
break;
case CSS_PROP_OUTLINE_COLOR:
break;
case CSS_PROP_OUTLINE_STYLE:
break;
case CSS_PROP_OUTLINE_WIDTH:
break;
case CSS_PROP_OVERFLOW_X:
break;
case CSS_PROP_PADDING_TOP:
break;
case CSS_PROP_PADDING_RIGHT:
break;
case CSS_PROP_PADDING_BOTTOM:
break;
case CSS_PROP_PADDING_LEFT:
break;
case CSS_PROP_PAGE_BREAK_AFTER:
break;
case CSS_PROP_PAGE_BREAK_BEFORE:
break;
case CSS_PROP_PAGE_BREAK_INSIDE:
break;
case CSS_PROP_PAUSE_AFTER:
break;
case CSS_PROP_PAUSE_BEFORE:
break;
case CSS_PROP_PITCH_RANGE:
break;
case CSS_PROP_PITCH:
break;
case CSS_PROP_PLAY_DURING:
break;
case CSS_PROP_POSITION:
break;
case CSS_PROP_QUOTES:
break;
case CSS_PROP_RICHNESS:
break;
case CSS_PROP_RIGHT:
break;
case CSS_PROP_SPEAK_HEADER:
break;
case CSS_PROP_SPEAK_NUMERAL:
break;
case CSS_PROP_SPEAK_PUNCTUATION:
break;
case CSS_PROP_SPEAK:
break;
case CSS_PROP_SPEECH_RATE:
break;
case CSS_PROP_STRESS:
break;
case CSS_PROP_TABLE_LAYOUT:
break;
case CSS_PROP_TEXT_ALIGN:
break;
case CSS_PROP_TEXT_DECORATION:
break;
case CSS_PROP_TEXT_INDENT:
break;
case CSS_PROP_TEXT_TRANSFORM:
break;
case CSS_PROP_TOP:
break;
case CSS_PROP_UNICODE_BIDI:
break;
case CSS_PROP_VERTICAL_ALIGN:
break;
case CSS_PROP_VISIBILITY:
break;
case CSS_PROP_VOICE_FAMILY:
break;
case CSS_PROP_VOLUME:
break;
case CSS_PROP_WHITE_SPACE:
break;
case CSS_PROP_WIDOWS:
break;
case CSS_PROP_WIDTH:
break;
case CSS_PROP_WORD_SPACING:
break;
case CSS_PROP_Z_INDEX:
break;
case CSS_PROP_OPACITY:
break;
case CSS_PROP_BREAK_AFTER:
break;
case CSS_PROP_BREAK_BEFORE:
break;
case CSS_PROP_BREAK_INSIDE:
break;
case CSS_PROP_COLUMN_COUNT:
break;
case CSS_PROP_COLUMN_FILL:
break;
case CSS_PROP_COLUMN_GAP:
break;
case CSS_PROP_COLUMN_RULE_COLOR:
break;
case CSS_PROP_COLUMN_RULE_STYLE:
break;
case CSS_PROP_COLUMN_RULE_WIDTH:
break;
case CSS_PROP_COLUMN_SPAN:
break;
case CSS_PROP_COLUMN_WIDTH:
break;
case CSS_PROP_WRITING_MODE:
break;
case CSS_PROP_OVERFLOW_Y:
break;
case CSS_PROP_BOX_SIZING:
break;
}

const int UA_FONT_SIZE = js_ua_font_size();

/**
 * Font size computation callback for libcss
 *
 * \param pw      Computation context
 * \param parent  Parent font size (absolute)
 * \param size    Font size to compute
 * \return CSS_OK on success
 *
 * \post \a size will be an absolute font size
 *
 * Slightly adapted from NetSurf's original implementation.
 */
css_error compute_font_size(void *pw, const css_hint *parent,
		css_hint *size)
{
	/**
	 * Table of font-size keyword scale factors
	 *
	 * These are multiplied by the configured default font size
	 * to produce an absolute size for the relevant keyword
	 */
	static const css_fixed factors[] = {
		FLTTOFIX(0.5625), /* xx-small */
		FLTTOFIX(0.6250), /* x-small */<commit_msg>Still worling on the libcss handler<commit_after>/*
 * libcss-handler.c
 * Copyright 2017 <NAME> <<EMAIL>>
 *
 * Handler functions for libcss.
 * Based on the source code of netsurf and libcss.
 * Base files available at http://source.netsurf-browser.org
 *
 * Part of the w3d project.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libcss/libcss.h>

css_error css_resolve_url(void *pw, const char *base,
  lwc_string *rel, lwc_string **abs);
void add_stylesheet (const char* css_string, const char* level,
    const char* charset, const char* url);

static css_error node_name(void *pw, void *node, css_qname *qname);
static css_error node_classes(void *pw, void *node,
		lwc_string ***classes, uint32_t *n_classes);
static css_error node_id(void *pw, void *node, lwc_string **id);
static css_error named_parent_node(void *pw, void *node,
		const css_qname *qname, void **parent);
static css_error named_sibling_node(void *pw, void *node,
		const css_qname *qname, void **sibling);
static css_error named_generic_sibling_node(void *pw, void *node,
		const css_qname *qname, void **sibling);
static css_error parent_node(void *pw, void *node, void **parent);
static css_error sibling_node(void *pw, void *node, void **sibling);
static css_error node_has_name(void *pw, void *node,
		const css_qname *qname, bool *match);
static css_error node_has_class(void *pw, void *node,
		lwc_string *name, bool *match);
static css_error node_has_id(void *pw, void *node,
		lwc_string *name, bool *match);
static css_error node_has_attribute(void *pw, void *node,
		const css_qname *qname, bool *match);
static css_error node_has_attribute_equal(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_dashmatch(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_includes(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_prefix(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_suffix(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_has_attribute_substring(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match);
static css_error node_is_root(void *pw, void *node, bool *match);
static css_error node_count_siblings(void *pw, void *node,
		bool same_name, bool after, int32_t *count);
static css_error node_is_empty(void *pw, void *node, bool *match);
static css_error node_is_link(void *pw, void *node, bool *match);
static css_error node_is_hover(void *pw, void *node, bool *match);
static css_error node_is_active(void *pw, void *node, bool *match);
static css_error node_is_focus(void *pw, void *node, bool *match);
static css_error node_is_enabled(void *pw, void *node, bool *match);
static css_error node_is_disabled(void *pw, void *node, bool *match);
static css_error node_is_checked(void *pw, void *node, bool *match);
static css_error node_is_target(void *pw, void *node, bool *match);
static css_error node_is_lang(void *pw, void *node,
		lwc_string *lang, bool *match);
static css_error node_presentational_hint(void *pw, void *node,
			uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
		css_hint *hint);
static css_error set_libcss_node_data(void *pw, void *node,
		void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *node,
		void **libcss_node_data);

/**
 * Selection callback table for libcss
 */
static css_select_handler selection_handler = {
	CSS_SELECT_HANDLER_VERSION_1,

	node_name,
	node_classes,
	node_id,
	named_ancestor_node,
	named_parent_node,
	named_sibling_node,
	named_generic_sibling_node,
	parent_node,
	sibling_node,
	node_has_name,
	node_has_class,
	node_has_id,
	node_has_attribute,
	node_has_attribute_equal,
	node_has_attribute_dashmatch,
	node_has_attribute_includes,
	node_has_attribute_prefix,
	node_has_attribute_suffix,
	node_has_attribute_substring,
	node_is_root,
	node_count_siblings,
	node_is_empty,
	node_is_link,
	node_is_visited,
	node_is_hover,
	node_is_active,
	node_is_focus,
	node_is_enabled,
	node_is_disabled,
	node_is_checked,
	node_is_target,
	node_is_lang,
	node_presentational_hint,
	ua_default_for_property,
	compute_font_size,
	set_libcss_node_data,
	get_libcss_node_data,
};

css_select_ctx* select_ctx;
css_select_ctx_create(&select_ctx);

css_error resolve_url(
  void *pw, const char *base, lwc_string *rel, lwc_string **abs
)
{
  const char* base_str = base;
  const size_t base_s = strlen(base);
  const char* rel_str = lwc_string_data(rel_str);
  const size_t rel_s = strlen(rel_str);

  if (base_str[base_s] == "/")
    base_str[base_s] = "\0";

  char abs_str[base_s + rel_s + 2];
  strcpy(abs_str, base_str);
  strcat(abs_str, "/");
  strcat(abs_str, rel_str);

  lwc_intern_string(abs_str, strlen(abs_str), abs);
  return CSS_OK;
}

void add_stylesheet (
  const char* css_string,
  const char* level,
  const char* charset,
  const char* url
)
{
  css_language_level css_level;
  if (strcmp(level, "1") == 0)
    css_level = CSS_LEVEL_1;
  else if (strcmp(level, "2") == 0)
    css_level = CSS_LEVEL_2;
  else if (strcmp(level, "2.1") == 0)
    css_level = CSS_LEVEL_21;
  else
    css_level = CSS_LEVEL_3; /* Default */

  css_stylesheet_params params;
  params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
  params.level = css_level;
  params.charset = charset;
  params.url = url;
  params.title = NULL;
  params.allow_quirks = false;
  params.inline_style = false;
  params.resolve = resolve_url;
  params.resolve_pw = NULL;
  params.import = NULL;
  params.import_pw = NULL;
  params.color = NULL;
  params.color_pw = NULL;
  params.font = NULL;
  params.font_pw = NULL;

  css_stylesheet *sheet;
  css_stylesheet_create(&params, &sheet);

  css_stylesheet_append_data(
    sheet,
    (const uint8_t *) data,
    sizeof data
  );
  css_stylesheet_data_done(sheet);

  css_select_ctx_append_sheet(
    select_ctx,
    sheet,
    CSS_ORIGIN_AUTHOR,
    CSS_MEDIA_ALL
  );
}

/*
 * Warning: if inline_style is set, the resulting stylesheet will not
 * be destroyed! This implementation leaks memory.
 */
css_select_results* buildStyle(
  lwc_string* node,
  const char* inline_style
)
{
  const css_stylesheet* in_style;
  if (inline_style == NULL || *inline_style == "\0")
    in_style = NULL;
  else
  {
    css_stylesheet_params params;
    params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
    params.level = css_level;
    params.charset = "UTF-8";
    params.url = NULL;
    params.title = NULL;
    params.allow_quirks = false;
    params.inline_style = true;
    params.resolve = NULL;
    params.resolve_pw = NULL;
    params.import = NULL;
    params.import_pw = NULL;
    params.color = NULL;
    params.color_pw = NULL;
    params.font = NULL;
    params.font_pw = NULL;

    css_stylesheet* sheet;
    css_stylesheet_create(&params, &sheet);

    css_stylesheet_append_data(
      sheet,
      (const uint8_t *) inline_style,
      sizeof inline_style
    );
    css_stylesheet_data_done(sheet);
    in_style = sheet;
  }

  css_select_results* results;
  css_select_style(
    select_ctx,
    node,
    CSS_MEDIA_SCREEN,
    in_style,
		selection_handler,
    NULL,
		&results
  );

  return results;
}

uint64_t make_results_for_js (
    uint8_t type,
    uint8_t var1,
    uint8_t var2,
    uint8_t var3
)
{
  uint64_t results = (uint64_t) type;
  results += ((uint64_t) var1) * 0x100;
  results += ((uint64_t) var2) * 0x10000;
  results += ((uint64_t) var3) * 0x1000000;
  return results;
}

uint64_t get_style (const css_computed_style* s, uint8_t prop)
{
  uint64_t style;
  const uint64_t NOT_IMPLEMENTED = 0xffffffffffffffff;

  switch (prop)
  {
    case CSS_PROP_AZIMUTH:
      style = NOT_IMPLEMENTED;
      break;
    case CSS_PROP_BACKGROUND_ATTACHMENT:
      style = css_computed_background_attachment(s);
      break;
    case CSS_PROP_BACKGROUND_COLOR:
      css_color* color;
      style = css_computed_background_color(s, color);
      style += ((uint64_t) (*color)) * 0x100;
      break;
    case CSS_PROP_BACKGROUND_IMAGE:
      lwc_string* url;
      css_computed_background_image(s, &url);
      style = (uint64_t) url;
      break;
    case CSS_PROP_BACKGROUND_POSITION:
      /*
       * TODO: Need to find a way to fit two uint32_t and one uint8_t in our
       * uint64_t. Might need a breakthrough in quantum computers for this.
       */
      style = NOT_IMPLEMENTED;
      break;
    case CSS_PROP_BACKGROUND_REPEAT:
      style = css_computed_background_repeat(s);
      break;
    case CSS_PROP_BORDER_COLLAPSE:
      style = css_computed_border_collapse(s);
      break;
    case CSS_PROP_BORDER_SPACING:
      style = NOT_IMPLEMENTED;
      break;
    case CSS_PROP_BORDER_TOP_COLOR:
      css_color* color;
      style = css_computed_border_top_color(s, color);
      style += ((uint64_t) (*color)) * 0x100;
      break;
    case CSS_PROP_BORDER_RIGHT_COLOR:
      css_color* color;
      style = css_computed_border_right_color(s, color);
      style += ((uint64_t) (*color)) * 0x100;
      break;
    case CSS_PROP_BORDER_BOTTOM_COLOR:
      css_color* color;
      style = css_computed_border_bottom_color(s, color);
      style += ((uint64_t) (*color)) * 0x100;
      break;
    case CSS_PROP_BORDER_LEFT_COLOR:
      css_color* color;
      style = css_computed_border_left_color(s, color);
      style += ((uint64_t) (*color)) * 0x100;
      break;
    case CSS_PROP_BORDER_TOP_STYLE:
      style = css_computed_border_top_style(s);
      break;
    case CSS_PROP_BORDER_RIGHT_STYLE:
      style = css_computed_border_right_style(s);
      break;
    case CSS_PROP_BORDER_BOTTOM_STYLE:
      style = css_computed_border_bottom_style(s);
      break;
    case CSS_PROP_BORDER_LEFT_STYLE:
      style = css_computed_border_left_style(s);
      break;
    case CSS_PROP_BORDER_TOP_WIDTH:
      css_fixed* width; /* = int32_t */
      css_unit* unit; /* A number literal */
      style = css_computed_border_top_width(s, width, unit);
      style += ((uint64_t) (*width)) * 0x100;
      style += ((uint64_t) (*unit)) * 0x10000000000;
      break;
    case CSS_PROP_BORDER_RIGHT_WIDTH:
      css_fixed* width;
      css_unit* unit;
      style = css_computed_border_right_width(s, width, unit);
      style += ((uint64_t) (*width)) * 0x100;
      style += ((uint64_t) (*unit)) * 0x10000000000;
      break;
    case CSS_PROP_BORDER_BOTTOM_WIDTH:
      css_fixed* width;
      css_unit* unit;
      style = css_computed_border_bottom_width(s, width, unit);
      style += ((uint64_t) (*width)) * 0x100;
      style += ((uint64_t) (*unit)) * 0x10000000000;
      break;
    case CSS_PROP_BORDER_LEFT_WIDTH:
      css_fixed* width;
      css_unit* unit;
      style = css_computed_border_left_width(s, width, unit);
      style += ((uint64_t) (*width)) * 0x100;
      style += ((uint64_t) (*unit)) * 0x10000000000;
      break;
    case CSS_PROP_BOTTOM:
      css_fixed* length;
      css_unit* unit;
      style = css_computed_bottom(s, length, unit);
      style += ((uint64_t) (*length)) * 0x100;
      style += ((uint64_t) (*unit)) * 0x10000000000;
      break;
    case CSS_PROP_CAPTION_SIDE:
      style = css_computed_caption_side(s);
      break;
    case CSS_PROP_CLEAR:
      style = css_computed_clear(s);
      break;
    case CSS_PROP_CLIP:
      break;
    case CSS_PROP_COLOR:
      break;
    case CSS_PROP_CONTENT:
      break;
    case CSS_PROP_COUNTER_INCREMENT:
      break;
    case CSS_PROP_COUNTER_RESET:
      break;
    case CSS_PROP_CUE_AFTER:
      break;
    case CSS_PROP_CUE_BEFORE:
      break;
    case CSS_PROP_CURSOR:
      break;
    case CSS_PROP_DIRECTION:
      break;
    case CSS_PROP_DISPLAY:
      break;
    case CSS_PROP_ELEVATION:
      break;
    case CSS_PROP_EMPTY_CELLS:
      break;
    case CSS_PROP_FLOAT:
      break;
    case CSS_PROP_FONT_FAMILY:
      break;
    case CSS_PROP_FONT_SIZE:
      break;
    case CSS_PROP_FONT_STYLE:
      break;
    case CSS_PROP_FONT_VARIANT:
      break;
    case CSS_PROP_FONT_WEIGHT:
      break;
    case CSS_PROP_HEIGHT:
      break;
    case CSS_PROP_LEFT:
      break;
    case CSS_PROP_LETTER_SPACING:
      break;
    case CSS_PROP_LINE_HEIGHT:
      break;
    case CSS_PROP_LIST_STYLE_IMAGE:
      break;
    case CSS_PROP_LIST_STYLE_POSITION:
      break;
    case CSS_PROP_LIST_STYLE_TYPE:
      break;
    case CSS_PROP_MARGIN_TOP:
      break;
    case CSS_PROP_MARGIN_RIGHT:
      break;
    case CSS_PROP_MARGIN_BOTTOM:
      break;
    case CSS_PROP_MARGIN_LEFT:
      break;
    case CSS_PROP_MAX_HEIGHT:
      break;
    case CSS_PROP_MAX_WIDTH:
      break;
    case CSS_PROP_MIN_HEIGHT:
      break;
    case CSS_PROP_MIN_WIDTH:
      break;
    case CSS_PROP_ORPHANS:
      break;
    case CSS_PROP_OUTLINE_COLOR:
      break;
    case CSS_PROP_OUTLINE_STYLE:
      break;
    case CSS_PROP_OUTLINE_WIDTH:
      break;
    case CSS_PROP_OVERFLOW_X:
      break;
    case CSS_PROP_PADDING_TOP:
      break;
    case CSS_PROP_PADDING_RIGHT:
      break;
    case CSS_PROP_PADDING_BOTTOM:
      break;
    case CSS_PROP_PADDING_LEFT:
      break;
    case CSS_PROP_PAGE_BREAK_AFTER:
      break;
    case CSS_PROP_PAGE_BREAK_BEFORE:
      break;
    case CSS_PROP_PAGE_BREAK_INSIDE:
      break;
    case CSS_PROP_PAUSE_AFTER:
      break;
    case CSS_PROP_PAUSE_BEFORE:
      break;
    case CSS_PROP_PITCH_RANGE:
      break;
    case CSS_PROP_PITCH:
      break;
    case CSS_PROP_PLAY_DURING:
      break;
    case CSS_PROP_POSITION:
      break;
    case CSS_PROP_QUOTES:
      break;
    case CSS_PROP_RICHNESS:
      break;
    case CSS_PROP_RIGHT:
      break;
    case CSS_PROP_SPEAK_HEADER:
      break;
    case CSS_PROP_SPEAK_NUMERAL:
      break;
    case CSS_PROP_SPEAK_PUNCTUATION:
      break;
    case CSS_PROP_SPEAK:
      break;
    case CSS_PROP_SPEECH_RATE:
      break;
    case CSS_PROP_STRESS:
      break;
    case CSS_PROP_TABLE_LAYOUT:
      break;
    case CSS_PROP_TEXT_ALIGN:
      break;
    case CSS_PROP_TEXT_DECORATION:
      break;
    case CSS_PROP_TEXT_INDENT:
      break;
    case CSS_PROP_TEXT_TRANSFORM:
      break;
    case CSS_PROP_TOP:
      break;
    case CSS_PROP_UNICODE_BIDI:
      break;
    case CSS_PROP_VERTICAL_ALIGN:
      break;
    case CSS_PROP_VISIBILITY:
      break;
    case CSS_PROP_VOICE_FAMILY:
      break;
    case CSS_PROP_VOLUME:
      break;
    case CSS_PROP_WHITE_SPACE:
      break;
    case CSS_PROP_WIDOWS:
      break;
    case CSS_PROP_WIDTH:
      break;
    case CSS_PROP_WORD_SPACING:
      break;
    case CSS_PROP_Z_INDEX:
      break;
    case CSS_PROP_OPACITY:
      break;
    case CSS_PROP_BREAK_AFTER:
      break;
    case CSS_PROP_BREAK_BEFORE:
      break;
    case CSS_PROP_BREAK_INSIDE:
      break;
    case CSS_PROP_COLUMN_COUNT:
      break;
    case CSS_PROP_COLUMN_FILL:
      break;
    case CSS_PROP_COLUMN_GAP:
      break;
    case CSS_PROP_COLUMN_RULE_COLOR:
      break;
    case CSS_PROP_COLUMN_RULE_STYLE:
      break;
    case CSS_PROP_COLUMN_RULE_WIDTH:
      break;
    case CSS_PROP_COLUMN_SPAN:
      break;
    case CSS_PROP_COLUMN_WIDTH:
      break;
    case CSS_PROP_WRITING_MODE:
      break;
    case CSS_PROP_OVERFLOW_Y:
      break;
    case CSS_PROP_BOX_SIZING:
      break;
    default:
      style = NOT_IMPLEMENTED;
      break;
  }

  return style;
}

const int UA_FONT_SIZE = js_ua_font_size();

/**
 * Font size computation callback for libcss
 *
 * \param pw      Computation context
 * \param parent  Parent font size (absolute)
 * \param size    Font size to compute
 * \return CSS_OK on success
 *
 * \post \a size will be an absolute font size
 *
 * Slightly adapted from NetSurf's original implementation.
 */
css_error compute_font_size(void *pw, const css_hint *parent,
		css_hint *size)
{
	/**
	 * Table of font-size keyword scale factors
	 *
	 * These are multiplied by the configured default font size
	 * to produce an absolute size for the relevant keyword
	 */
	static const css_fixed factors[] = {
		FLTTOFIX(0.5625), /* xx-small */
		FLTTOFIX(0.6250), /* x-small */
{'fraction_non_alphanumeric': 0.08830068083923857, 'fraction_numerical': 0.011011532583020704, 'mean_word_length': 4.266922795462861, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5064040', 'n_tokens_mistral': 11034, 'n_tokens_neox': 10692, 'n_words': 2462}