diff options
-rw-r--r-- | include/mupdf/html.h | 4 | ||||
-rw-r--r-- | source/html/css-apply.c | 87 | ||||
-rw-r--r-- | source/html/layout.c | 38 |
3 files changed, 112 insertions, 17 deletions
diff --git a/include/mupdf/html.h b/include/mupdf/html.h index 9e48b47d..57249c03 100644 --- a/include/mupdf/html.h +++ b/include/mupdf/html.h @@ -114,7 +114,7 @@ struct number struct color { - unsigned char r, g, b; + unsigned char r, g, b, a; }; struct computed_style @@ -127,6 +127,8 @@ struct computed_style int text_align; int vertical_align; struct number line_height; + struct color background_color; + struct color color; fz_font *font; }; diff --git a/source/html/css-apply.c b/source/html/css-apply.c index 8284c5ac..351f05e6 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -751,7 +751,8 @@ number_from_value(struct value *value, float initial, int initial_unit) return make_number(initial, initial_unit); } -static struct number number_from_property(struct style *node, const char *property, float initial, int initial_unit) +static struct number +number_from_property(struct style *node, const char *property, float initial, int initial_unit) { return number_from_value(get_style_property(node, property), initial, initial_unit); } @@ -778,6 +779,85 @@ from_number_scale(struct number number, float scale, float em, float width) } } +static struct color +make_color(int r, int g, int b, int a) +{ + struct color c; + c.r = r; + c.g = g; + c.b = b; + c.a = a; + return c; +} + +static int tohex(int c) +{ + if (c - '0' < 10) + return c - '0'; + return (c | 32) - 'a' + 10; +} + +static struct color +color_from_value(struct value *value) +{ + if (!value) + return make_color(0, 0, 0, 0); + if (value->type == CSS_COLOR) + { + int r = tohex(value->data[0]) * 16 + tohex(value->data[1]); + int g = tohex(value->data[2]) * 16 + tohex(value->data[3]); + int b = tohex(value->data[4]) * 16 + tohex(value->data[5]); + 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 make_color(0, 0, 0, 0); +} + +static struct color +color_from_property(struct style *node, const char *property) +{ + return color_from_value(get_style_property(node, property)); +} + int get_style_property_display(struct style *node) { @@ -819,6 +899,8 @@ default_computed_style(struct computed_style *style) style->vertical_align = 0; style->white_space = WS_NORMAL; style->font_size = make_number(1, N_SCALE); + style->background_color = make_color(0, 0, 0, 0); + style->color = make_color(0, 0, 0, 255); } void @@ -885,6 +967,9 @@ compute_style(html_document *doc, struct computed_style *style, struct style *no style->padding[2] = number_from_property(node, "padding-bottom", 0, N_NUMBER); style->padding[3] = number_from_property(node, "padding-left", 0, N_NUMBER); + style->color = color_from_property(node, "color"); + style->background_color = color_from_property(node, "background-color"); + { const char *font_family = get_style_property_string(node, "font-family", "serif"); const char *font_variant = get_style_property_string(node, "font-variant", "normal"); diff --git a/source/html/layout.c b/source/html/layout.c index 3439ccdb..f5436b10 100644 --- a/source/html/layout.c +++ b/source/html/layout.c @@ -571,12 +571,10 @@ draw_flow_box(fz_context *ctx, struct box *box, float page_top, float page_bot, fz_text *text; fz_matrix trm; const char *s; - float black[1]; + float color[3]; float x, y; int c, g; - black[0] = 0; - for (node = box->flow_head; node; node = node->next) { if (node->y > page_bot || node->y + node->h < page_top) @@ -598,7 +596,11 @@ draw_flow_box(fz_context *ctx, struct box *box, float page_top, float page_bot, x += fz_advance_glyph(ctx, node->style->font, g) * node->em; } - fz_fill_text(dev, text, ctm, fz_device_gray(ctx), black, 1); + color[0] = node->style->color.r / 255.0f; + color[1] = node->style->color.g / 255.0f; + color[2] = node->style->color.b / 255.0f; + + fz_fill_text(dev, text, ctm, fz_device_rgb(ctx), color, 1); fz_free_text(ctx, text); } @@ -609,14 +611,11 @@ static void draw_block_box(fz_context *ctx, struct box *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm) { fz_path *path; - float black[1]; float x0, y0, x1, y1; // TODO: background fill // TODO: border stroke - black[0] = 0; - x0 = box->x - box->padding[LEFT]; y0 = box->y - box->padding[TOP]; x1 = box->x + box->w + box->padding[RIGHT]; @@ -625,16 +624,25 @@ draw_block_box(fz_context *ctx, struct box *box, float page_top, float page_bot, if (y0 > page_bot || y1 < page_top) return; - 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); + if (box->style.background_color.a > 0) + { + float color[3]; - fz_fill_path(dev, path, 0, ctm, fz_device_gray(ctx), black, 0.1); + 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; - fz_free_path(ctx, 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_fill_path(dev, path, 0, ctm, fz_device_rgb(ctx), color, box->style.background_color.a / 255.0f); + + fz_free_path(ctx, path); + } for (box = box->down; box; box = box->next) { |