static fz_css_number border_width_from_property(fz_css_match *match, const char *property) { fz_css_value *value = value_from_property(match, property); if (value) { if (!strcmp(value->data, "thin")) return make_number(1, N_LENGTH); if (!strcmp(value->data, "medium")) return make_number(2, N_LENGTH); if (!strcmp(value->data, "thick")) return make_number(4, N_LENGTH); return number_from_value(value, 0, N_LENGTH); } return make_number(2, N_LENGTH); /* initial: 'medium' */ }
static fz_css_number number_from_property(fz_css_match *match, const char *property, float initial, int initial_unit) { return number_from_value(value_from_property(match, property), initial, initial_unit); }
static fz_css_color color_from_value(fz_css_value *value, fz_css_color initial) { if (!value) return initial; if (value->type == CSS_HASH) { int r, g, b; size_t n = strlen(value->data); if (n == 3) { r = tohex(value->data[0]) * 16 + tohex(value->data[0]); g = tohex(value->data[1]) * 16 + tohex(value->data[1]); b = tohex(value->data[2]) * 16 + tohex(value->data[2]); } else if (n == 6) { r = tohex(value->data[0]) * 16 + tohex(value->data[1]); g = tohex(value->data[2]) * 16 + tohex(value->data[3]); b = tohex(value->data[4]) * 16 + tohex(value->data[5]); } else { r = g = b = 0; } return make_color(r, g, b, 255); } if (value->type == '(' && !strcmp(value->data, "rgb")) { fz_css_value *vr, *vg, *vb; int r, g, b; vr = value->args; vg = vr && vr->next ? vr->next->next : NULL; /* skip the ',' nodes */ vb = vg && vg->next ? vg->next->next : NULL; /* skip the ',' nodes */ r = fz_from_css_number(number_from_value(vr, 0, N_NUMBER), 255, 255); g = fz_from_css_number(number_from_value(vg, 0, N_NUMBER), 255, 255); b = fz_from_css_number(number_from_value(vb, 0, N_NUMBER), 255, 255); return make_color(r, g, b, 255); } if (value->type == CSS_KEYWORD) { if (!strcmp(value->data, "transparent")) return make_color(0, 0, 0, 0); if (!strcmp(value->data, "maroon")) return make_color(0x80, 0x00, 0x00, 255); if (!strcmp(value->data, "red")) return make_color(0xFF, 0x00, 0x00, 255); if (!strcmp(value->data, "orange")) return make_color(0xFF, 0xA5, 0x00, 255); if (!strcmp(value->data, "yellow")) return make_color(0xFF, 0xFF, 0x00, 255); if (!strcmp(value->data, "olive")) return make_color(0x80, 0x80, 0x00, 255); if (!strcmp(value->data, "purple")) return make_color(0x80, 0x00, 0x80, 255); if (!strcmp(value->data, "fuchsia")) return make_color(0xFF, 0x00, 0xFF, 255); if (!strcmp(value->data, "white")) return make_color(0xFF, 0xFF, 0xFF, 255); if (!strcmp(value->data, "lime")) return make_color(0x00, 0xFF, 0x00, 255); if (!strcmp(value->data, "green")) return make_color(0x00, 0x80, 0x00, 255); if (!strcmp(value->data, "navy")) return make_color(0x00, 0x00, 0x80, 255); if (!strcmp(value->data, "blue")) return make_color(0x00, 0x00, 0xFF, 255); if (!strcmp(value->data, "aqua")) return make_color(0x00, 0xFF, 0xFF, 255); if (!strcmp(value->data, "teal")) return make_color(0x00, 0x80, 0x80, 255); if (!strcmp(value->data, "black")) return make_color(0x00, 0x00, 0x00, 255); if (!strcmp(value->data, "silver")) return make_color(0xC0, 0xC0, 0xC0, 255); if (!strcmp(value->data, "gray")) return make_color(0x80, 0x80, 0x80, 255); return make_color(0, 0, 0, 255); } return initial; }
void fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, fz_css_match *match) { fz_css_value *value; fz_css_color black = { 0, 0, 0, 255 }; fz_css_color transparent = { 0, 0, 0, 0 }; fz_default_css_style(ctx, style); style->visibility = visibility_from_property(match); style->white_space = white_space_from_property(match); style->page_break_before = page_break_from_property(match, "page-break-before"); style->page_break_after = page_break_from_property(match, "page-break-after"); value = value_from_property(match, "text-align"); if (value) { if (!strcmp(value->data, "left")) style->text_align = TA_LEFT; else if (!strcmp(value->data, "right")) style->text_align = TA_RIGHT; else if (!strcmp(value->data, "center")) style->text_align = TA_CENTER; else if (!strcmp(value->data, "justify")) style->text_align = TA_JUSTIFY; } value = value_from_property(match, "vertical-align"); if (value) { if (!strcmp(value->data, "baseline")) style->vertical_align = VA_BASELINE; else if (!strcmp(value->data, "sub")) style->vertical_align = VA_SUB; else if (!strcmp(value->data, "super")) style->vertical_align = VA_SUPER; else if (!strcmp(value->data, "top")) style->vertical_align = VA_TOP; else if (!strcmp(value->data, "bottom")) style->vertical_align = VA_BOTTOM; else if (!strcmp(value->data, "text-top")) style->vertical_align = VA_TEXT_TOP; else if (!strcmp(value->data, "text-bottom")) style->vertical_align = VA_TEXT_BOTTOM; } value = value_from_property(match, "font-size"); if (value) { if (!strcmp(value->data, "xx-large")) style->font_size = make_number(1.73f, N_SCALE); else if (!strcmp(value->data, "x-large")) style->font_size = make_number(1.44f, N_SCALE); else if (!strcmp(value->data, "large")) style->font_size = make_number(1.2f, N_SCALE); else if (!strcmp(value->data, "medium")) style->font_size = make_number(1.0f, N_SCALE); else if (!strcmp(value->data, "small")) style->font_size = make_number(0.83f, N_SCALE); else if (!strcmp(value->data, "x-small")) style->font_size = make_number(0.69f, N_SCALE); else if (!strcmp(value->data, "xx-small")) style->font_size = make_number(0.69f, N_SCALE); else if (!strcmp(value->data, "larger")) style->font_size = make_number(1.2f, N_SCALE); else if (!strcmp(value->data, "smaller")) style->font_size = make_number(1/1.2f, N_SCALE); else style->font_size = number_from_value(value, 12, N_LENGTH); } else { style->font_size = make_number(1, N_SCALE); } value = value_from_property(match, "list-style-type"); if (value) { if (!strcmp(value->data, "none")) style->list_style_type = LST_NONE; else if (!strcmp(value->data, "disc")) style->list_style_type = LST_DISC; else if (!strcmp(value->data, "circle")) style->list_style_type = LST_CIRCLE; else if (!strcmp(value->data, "square")) style->list_style_type = LST_SQUARE; else if (!strcmp(value->data, "decimal")) style->list_style_type = LST_DECIMAL; else if (!strcmp(value->data, "decimal-leading-zero")) style->list_style_type = LST_DECIMAL_ZERO; else if (!strcmp(value->data, "lower-roman")) style->list_style_type = LST_LC_ROMAN; else if (!strcmp(value->data, "upper-roman")) style->list_style_type = LST_UC_ROMAN; else if (!strcmp(value->data, "lower-greek")) style->list_style_type = LST_LC_GREEK; else if (!strcmp(value->data, "upper-greek")) style->list_style_type = LST_UC_GREEK; else if (!strcmp(value->data, "lower-latin")) style->list_style_type = LST_LC_LATIN; else if (!strcmp(value->data, "upper-latin")) style->list_style_type = LST_UC_LATIN; else if (!strcmp(value->data, "lower-alpha")) style->list_style_type = LST_LC_ALPHA; else if (!strcmp(value->data, "upper-alpha")) style->list_style_type = LST_UC_ALPHA; else if (!strcmp(value->data, "armenian")) style->list_style_type = LST_ARMENIAN; else if (!strcmp(value->data, "georgian")) style->list_style_type = LST_GEORGIAN; } style->line_height = number_from_property(match, "line-height", 1.2f, N_SCALE); style->text_indent = number_from_property(match, "text-indent", 0, N_LENGTH); style->width = number_from_property(match, "width", 0, N_AUTO); style->height = number_from_property(match, "height", 0, N_AUTO); style->margin[0] = number_from_property(match, "margin-top", 0, N_LENGTH); style->margin[1] = number_from_property(match, "margin-right", 0, N_LENGTH); style->margin[2] = number_from_property(match, "margin-bottom", 0, N_LENGTH); style->margin[3] = number_from_property(match, "margin-left", 0, N_LENGTH); style->padding[0] = number_from_property(match, "padding-top", 0, N_LENGTH); style->padding[1] = number_from_property(match, "padding-right", 0, N_LENGTH); style->padding[2] = number_from_property(match, "padding-bottom", 0, N_LENGTH); style->padding[3] = number_from_property(match, "padding-left", 0, N_LENGTH); style->color = color_from_property(match, "color", black); style->background_color = color_from_property(match, "background-color", transparent); style->border_style[0] = border_style_from_property(match, "border-top-style"); style->border_style[1] = border_style_from_property(match, "border-right-style"); style->border_style[2] = border_style_from_property(match, "border-bottom-style"); style->border_style[3] = border_style_from_property(match, "border-left-style"); style->border_color[0] = color_from_property(match, "border-top-color", style->color); style->border_color[1] = color_from_property(match, "border-right-color", style->color); style->border_color[2] = color_from_property(match, "border-bottom-color", style->color); style->border_color[3] = color_from_property(match, "border-left-color", style->color); style->border_width[0] = border_width_from_property(match, "border-top-width"); style->border_width[1] = border_width_from_property(match, "border-right-width"); style->border_width[2] = border_width_from_property(match, "border-bottom-width"); style->border_width[3] = border_width_from_property(match, "border-left-width"); { const char *font_weight = string_from_property(match, "font-weight", "normal"); const char *font_style = string_from_property(match, "font-style", "normal"); int is_bold = is_bold_from_font_weight(font_weight); int is_italic = is_italic_from_font_style(font_style); value = value_from_property(match, "font-family"); while (value) { if (strcmp(value->data, ",") != 0) { style->font = fz_load_html_font(ctx, set, value->data, is_bold, is_italic); if (style->font) break; } value = value->next; } if (!style->font) style->font = fz_load_html_font(ctx, set, "serif", is_bold, is_italic); } }
void fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, fz_css_match *match) { fz_css_value *value; fz_css_color black = { 0, 0, 0, 255 }; fz_css_color transparent = { 0, 0, 0, 0 }; fz_default_css_style(ctx, style); style->white_space = white_space_from_property(match); value = value_from_property(match, "text-align"); if (value) { if (!strcmp(value->data, "left")) style->text_align = TA_LEFT; if (!strcmp(value->data, "right")) style->text_align = TA_RIGHT; if (!strcmp(value->data, "center")) style->text_align = TA_CENTER; if (!strcmp(value->data, "justify")) style->text_align = TA_JUSTIFY; } value = value_from_property(match, "vertical-align"); if (value) { if (!strcmp(value->data, "baseline")) style->vertical_align = VA_BASELINE; if (!strcmp(value->data, "sub")) style->vertical_align = VA_SUB; if (!strcmp(value->data, "super")) style->vertical_align = VA_SUPER; if (!strcmp(value->data, "top")) style->vertical_align = VA_TOP; if (!strcmp(value->data, "bottom")) style->vertical_align = VA_BOTTOM; } value = value_from_property(match, "font-size"); if (value) { if (!strcmp(value->data, "xx-large")) style->font_size = make_number(1.73f, N_SCALE); else if (!strcmp(value->data, "x-large")) style->font_size = make_number(1.44f, N_SCALE); else if (!strcmp(value->data, "large")) style->font_size = make_number(1.2f, N_SCALE); else if (!strcmp(value->data, "medium")) style->font_size = make_number(1.0f, N_SCALE); else if (!strcmp(value->data, "small")) style->font_size = make_number(0.83f, N_SCALE); else if (!strcmp(value->data, "x-small")) style->font_size = make_number(0.69f, N_SCALE); else if (!strcmp(value->data, "xx-small")) style->font_size = make_number(0.69f, N_SCALE); else if (!strcmp(value->data, "larger")) style->font_size = make_number(1.2f, N_SCALE); else if (!strcmp(value->data, "smaller")) style->font_size = make_number(1/1.2f, N_SCALE); else style->font_size = number_from_value(value, 12, N_NUMBER); } else { style->font_size = make_number(1, N_SCALE); } value = value_from_property(match, "border-style"); if (value) { if (!strcmp(value->data, "none")) style->border_style = BS_NONE; if (!strcmp(value->data, "hidden")) style->border_style = BS_NONE; if (!strcmp(value->data, "solid")) style->border_style = BS_SOLID; } style->line_height = number_from_property(match, "line-height", 1.2f, N_SCALE); style->text_indent = number_from_property(match, "text-indent", 0, N_NUMBER); style->margin[0] = number_from_property(match, "margin-top", 0, N_NUMBER); style->margin[1] = number_from_property(match, "margin-right", 0, N_NUMBER); style->margin[2] = number_from_property(match, "margin-bottom", 0, N_NUMBER); style->margin[3] = number_from_property(match, "margin-left", 0, N_NUMBER); style->padding[0] = number_from_property(match, "padding-top", 0, N_NUMBER); style->padding[1] = number_from_property(match, "padding-right", 0, N_NUMBER); style->padding[2] = number_from_property(match, "padding-bottom", 0, N_NUMBER); style->padding[3] = number_from_property(match, "padding-left", 0, N_NUMBER); style->border_width[0] = border_width_from_property(match, "border-width-top"); style->border_width[1] = border_width_from_property(match, "border-width-right"); style->border_width[2] = border_width_from_property(match, "border-width-bottom"); style->border_width[3] = border_width_from_property(match, "border-width-left"); style->color = color_from_property(match, "color", black); style->background_color = color_from_property(match, "background-color", transparent); style->border_color = color_from_property(match, "border-color", style->color); { const char *font_family = string_from_property(match, "font-family", "serif"); const char *font_variant = string_from_property(match, "font-variant", "normal"); const char *font_style = string_from_property(match, "font-style", "normal"); const char *font_weight = string_from_property(match, "font-weight", "normal"); style->font = fz_load_html_font(ctx, set, font_family, font_variant, font_style, font_weight); } }