summaryrefslogtreecommitdiff
path: root/source/html
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-04-27 15:27:22 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-04-27 15:27:22 +0200
commite2b0aed8d52d8a011d8bf4cc6c501057dfa05f0d (patch)
treec7d8bb489df030d8fb3927cc1a5097c57afee019 /source/html
parent317a3d0271b21813e50d7c9e8288e26d21c62d4f (diff)
downloadmupdf-e2b0aed8d52d8a011d8bf4cc6c501057dfa05f0d.tar.xz
epub: Support individual T,B,L,R border styles and colors.
Diffstat (limited to 'source/html')
-rw-r--r--source/html/css-apply.c117
-rw-r--r--source/html/html-layout.c63
2 files changed, 119 insertions, 61 deletions
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)
{