From e2b0aed8d52d8a011d8bf4cc6c501057dfa05f0d Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 27 Apr 2015 15:27:22 +0200 Subject: epub: Support individual T,B,L,R border styles and colors. --- source/html/css-apply.c | 117 ++++++++++++++++++++++++++++++++++++---------- source/html/html-layout.c | 63 +++++++++++-------------- 2 files changed, 119 insertions(+), 61 deletions(-) (limited to 'source/html') diff --git a/source/html/css-apply.c b/source/html/css-apply.c index 40cae696..052888db 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -404,38 +404,61 @@ add_shorthand_border_width(fz_css_match *match, fz_css_value *value, int spec) } static void -add_shorthand_border(fz_css_match *match, fz_css_value *value, int spec) +add_shorthand_border_color(fz_css_match *match, fz_css_value *value, int spec) +{ + add_shorthand_trbl(match, value, spec, + "border-color-top", "border-color-right", "border-color-bottom", "border-color-left"); +} + +static void +add_shorthand_border_style(fz_css_match *match, fz_css_value *value, int spec) +{ + add_shorthand_trbl(match, value, spec, + "border-style-top", "border-style-right", "border-style-bottom", "border-style-left"); +} + +static void +add_shorthand_border(fz_css_match *match, fz_css_value *value, int spec, int T, int R, int B, int L) { while (value) { if (value->type == CSS_COLOR) { - add_property(match, "border-color", value, spec); + if (T) add_property(match, "border-color-top", value, spec); + if (R) add_property(match, "border-color-right", value, spec); + if (B) add_property(match, "border-color-bottom", value, spec); + if (L) add_property(match, "border-color-left", value, spec); } else if (value->type == CSS_KEYWORD) { if (keyword_in_list(value->data, border_width_kw, nelem(border_width_kw))) { - add_property(match, "border-width-top", value, spec); - add_property(match, "border-width-right", value, spec); - add_property(match, "border-width-bottom", value, spec); - add_property(match, "border-width-left", value, spec); + if (T) add_property(match, "border-width-top", value, spec); + if (R) add_property(match, "border-width-right", value, spec); + if (B) add_property(match, "border-width-bottom", value, spec); + if (L) add_property(match, "border-width-left", value, spec); } else if (keyword_in_list(value->data, border_style_kw, nelem(border_style_kw))) { - add_property(match, "border-style", value, spec); + if (T) add_property(match, "border-style-top", value, spec); + if (R) add_property(match, "border-style-right", value, spec); + if (B) add_property(match, "border-style-bottom", value, spec); + if (L) add_property(match, "border-style-left", value, spec); } else if (keyword_in_list(value->data, color_kw, nelem(color_kw))) { - add_property(match, "border-color", value, spec); + if (T) add_property(match, "border-color-top", value, spec); + if (R) add_property(match, "border-color-right", value, spec); + if (B) add_property(match, "border-color-bottom", value, spec); + if (L) add_property(match, "border-color-left", value, spec); } } else { - add_property(match, "border-width-top", value, spec); - add_property(match, "border-width-right", value, spec); - add_property(match, "border-width-bottom", value, spec); - add_property(match, "border-width-left", value, spec); + if (T) add_property(match, "border-width-top", value, spec); + if (R) add_property(match, "border-width-right", value, spec); + if (B) add_property(match, "border-width-bottom", value, spec); + if (L) add_property(match, "border-width-left", value, spec); } value = value->next; } @@ -481,9 +504,39 @@ add_property(fz_css_match *match, const char *name, fz_css_value *value, int spe add_shorthand_border_width(match, value, spec); return; } + if (!strcmp(name, "border-color")) + { + add_shorthand_border_color(match, value, spec); + return; + } + if (!strcmp(name, "border-style")) + { + add_shorthand_border_style(match, value, spec); + return; + } if (!strcmp(name, "border")) { - add_shorthand_border(match, value, spec); + add_shorthand_border(match, value, spec, 1, 1, 1, 1); + return; + } + if (!strcmp(name, "border-top")) + { + add_shorthand_border(match, value, spec, 1, 0, 0, 0); + return; + } + if (!strcmp(name, "border-right")) + { + add_shorthand_border(match, value, spec, 0, 1, 0, 0); + return; + } + if (!strcmp(name, "border-bottom")) + { + add_shorthand_border(match, value, spec, 0, 0, 1, 0); + return; + } + if (!strcmp(name, "border-left")) + { + add_shorthand_border(match, value, spec, 0, 0, 0, 1); return; } if (!strcmp(name, "list-style")) @@ -674,6 +727,19 @@ border_width_from_property(fz_css_match *match, const char *property) return make_number(2, N_NUMBER); /* initial: 'medium' */ } +static int +border_style_from_property(fz_css_match *match, const char *property) +{ + fz_css_value *value = value_from_property(match, property); + if (value) + { + if (!strcmp(value->data, "none")) return BS_NONE; + else if (!strcmp(value->data, "hidden")) return BS_NONE; + else if (!strcmp(value->data, "solid")) return BS_SOLID; + } + return BS_NONE; +} + float fz_from_css_number(fz_css_number number, float em, float width) { @@ -869,14 +935,6 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, 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; - else if (!strcmp(value->data, "hidden")) style->border_style = BS_NONE; - else if (!strcmp(value->data, "solid")) style->border_style = BS_SOLID; - } - value = value_from_property(match, "list-style-type"); if (value) { @@ -912,15 +970,24 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, 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->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-style-top"); + style->border_style[1] = border_style_from_property(match, "border-style-right"); + style->border_style[2] = border_style_from_property(match, "border-style-bottom"); + style->border_style[3] = border_style_from_property(match, "border-style-left"); + + style->border_color[0] = color_from_property(match, "border-color-top", transparent); + style->border_color[1] = color_from_property(match, "border-color-right", transparent); + style->border_color[2] = color_from_property(match, "border-color-bottom", transparent); + style->border_color[3] = color_from_property(match, "border-color-left", transparent); + 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"); diff --git a/source/html/html-layout.c b/source/html/html-layout.c index f0d523a2..cc510a22 100644 --- a/source/html/html-layout.c +++ b/source/html/html-layout.c @@ -749,19 +749,28 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p } } -static void draw_rect(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, float *rgba, float x0, float y0, float x1, float y1) +static void draw_rect(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, fz_css_color color, float x0, float y0, float x1, float y1) { - fz_path *path = fz_new_path(ctx); + if (color.a > 0) + { + float rgb[3]; + + fz_path *path = fz_new_path(ctx); + + fz_moveto(ctx, path, x0, y0); + fz_lineto(ctx, path, x1, y0); + fz_lineto(ctx, path, x1, y1); + fz_lineto(ctx, path, x0, y1); + fz_closepath(ctx, path); - fz_moveto(ctx, path, x0, y0); - fz_lineto(ctx, path, x1, y0); - fz_lineto(ctx, path, x1, y1); - fz_lineto(ctx, path, x0, y1); - fz_closepath(ctx, path); + rgb[0] = color.r / 255.0f; + rgb[1] = color.g / 255.0f; + rgb[2] = color.b / 255.0f; - fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgba, rgba[3]); + fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgb, color.a / 255.0f); - fz_drop_path(ctx, path); + fz_drop_path(ctx, path); + } } static const char *roman_uc[3][10] = { @@ -893,10 +902,6 @@ static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float static void draw_block_box(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm) { float x0, y0, x1, y1; - float color[4]; - - // TODO: background fill - // TODO: border stroke float *border = box->border; float *padding = box->padding; @@ -909,30 +914,16 @@ static void draw_block_box(fz_context *ctx, fz_html *box, float page_top, float if (y0 > page_bot || y1 < page_top) return; - if (box->style.background_color.a > 0) - { - color[0] = box->style.background_color.r / 255.0f; - color[1] = box->style.background_color.g / 255.0f; - color[2] = box->style.background_color.b / 255.0f; - color[3] = box->style.background_color.a / 255.0f; - draw_rect(ctx, dev, ctm, color, x0, y0, x1, y1); - } + draw_rect(ctx, dev, ctm, box->style.background_color, x0, y0, x1, y1); - if (box->style.border_color.a > 0) - { - color[0] = box->style.border_color.r / 255.0f; - color[1] = box->style.border_color.g / 255.0f; - color[2] = box->style.border_color.b / 255.0f; - color[3] = box->style.border_color.a / 255.0f; - if (border[T] > 0) - draw_rect(ctx, dev, ctm, color, x0 - border[L], y0 - border[T], x1 + border[R], y0); - if (border[B] > 0) - draw_rect(ctx, dev, ctm, color, x0 - border[L], y1, x1 + border[R], y1 + border[B]); - if (border[L] > 0) - draw_rect(ctx, dev, ctm, color, x0 - border[L], y0 - border[T], x0, y1 + border[B]); - if (border[R] > 0) - draw_rect(ctx, dev, ctm, color, x1, y0 - border[T], x1 + border[R], y1 + border[B]); - } + if (border[T] > 0) + draw_rect(ctx, dev, ctm, box->style.border_color[T], x0 - border[L], y0 - border[T], x1 + border[R], y0); + if (border[B] > 0) + draw_rect(ctx, dev, ctm, box->style.border_color[B], x0 - border[L], y1, x1 + border[R], y1 + border[B]); + if (border[L] > 0) + draw_rect(ctx, dev, ctm, box->style.border_color[L], x0 - border[L], y0 - border[T], x0, y1 + border[B]); + if (border[R] > 0) + draw_rect(ctx, dev, ctm, box->style.border_color[R], x1, y0 - border[T], x1 + border[R], y1 + border[B]); if (box->list_item) { -- cgit v1.2.3