diff options
Diffstat (limited to 'source/html/layout.c')
-rw-r--r-- | source/html/layout.c | 126 |
1 files changed, 86 insertions, 40 deletions
diff --git a/source/html/layout.c b/source/html/layout.c index f5436b10..b5a22557 100644 --- a/source/html/layout.c +++ b/source/html/layout.c @@ -1,5 +1,10 @@ #include "mupdf/html.h" +#define L LEFT +#define R RIGHT +#define T TOP +#define B BOTTOM + static const char *default_css = "html,address,blockquote,body,dd,div,dl,dt,h1,h2,h3,h4,h5,h6,ol,p,ul,center,hr,pre{display:block}" "span{display:inline}" @@ -22,7 +27,7 @@ static const char *default_css = "sub{vertical-align:sub}" "sup{vertical-align:super}" "s,strike,del{text-decoration:line-through}" -"hr{border-width:1px;border-color:black}" +"hr{border-width:thin;border-color:black;border-style:solid;margin:.5em 0}" "ol,ul,dir,menu,dd{margin-left:40px}" "ol{list-style-type:decimal}" "ol ul,ul ol,ul ul,ol ol{margin-top:0;margin-bottom:0}" @@ -448,31 +453,45 @@ static void layout_block(fz_context *ctx, struct box *box, struct box *top, floa float box_collapse_margin; int prev_br; + float *margin = box->margin; + float *border = box->border; + float *padding = box->padding; + em = from_number(box->style.font_size, em, em); - box->margin[0] = from_number(box->style.margin[0], em, top->w); - box->margin[1] = from_number(box->style.margin[1], em, top->w); - box->margin[2] = from_number(box->style.margin[2], em, top->w); - box->margin[3] = from_number(box->style.margin[3], em, top->w); + margin[0] = from_number(box->style.margin[0], em, top->w); + margin[1] = from_number(box->style.margin[1], em, top->w); + margin[2] = from_number(box->style.margin[2], em, top->w); + margin[3] = from_number(box->style.margin[3], em, top->w); + + padding[0] = from_number(box->style.padding[0], em, top->w); + padding[1] = from_number(box->style.padding[1], em, top->w); + padding[2] = from_number(box->style.padding[2], em, top->w); + padding[3] = from_number(box->style.padding[3], em, top->w); - box->padding[0] = from_number(box->style.padding[0], em, top->w); - box->padding[1] = from_number(box->style.padding[1], em, top->w); - box->padding[2] = from_number(box->style.padding[2], em, top->w); - box->padding[3] = from_number(box->style.padding[3], em, top->w); + if (box->style.border_style) + { + border[0] = from_number(box->style.border_width[0], em, top->w); + border[1] = from_number(box->style.border_width[1], em, top->w); + border[2] = from_number(box->style.border_width[2], em, top->w); + border[3] = from_number(box->style.border_width[3], em, top->w); + } + else + border[0] = border[1] = border[2] = border[3] = 0; - if (box->padding[TOP] == 0) - box_collapse_margin = box->margin[TOP]; + if (padding[T] == 0 && border[T] == 0) + box_collapse_margin = margin[T]; else box_collapse_margin = 0; - if (box->margin[TOP] > top_collapse_margin) - box->margin[TOP] -= top_collapse_margin; + if (margin[T] > top_collapse_margin) + margin[T] -= top_collapse_margin; else - box->margin[TOP] = 0; + margin[T] = 0; - box->x = top->x + box->margin[LEFT] + box->padding[LEFT]; - box->y = top->y + top->h + box->margin[TOP] + box->padding[TOP]; - box->w = top->w - (box->margin[LEFT] + box->margin[RIGHT] + box->padding[LEFT] + box->padding[RIGHT]); + box->x = top->x + margin[L] + border[L] + padding[L]; + box->y = top->y + top->h + margin[T] + border[T] + padding[T]; + box->w = top->w - (margin[L] + margin[R] + border[L] + border[R] + padding[L] + padding[R]); box->h = 0; prev_br = 0; @@ -481,8 +500,11 @@ static void layout_block(fz_context *ctx, struct box *box, struct box *top, floa if (child->type == BOX_BLOCK) { layout_block(ctx, child, box, em, box_collapse_margin, page_h); - box->h += child->h + child->padding[TOP] + child->padding[BOTTOM] + child->margin[TOP] + child->margin[BOTTOM]; - box_collapse_margin = child->margin[BOTTOM]; + box->h += child->h + + child->padding[T] + child->padding[B] + + child->border[T] + child->border[B] + + child->margin[T] + child->margin[B]; + box_collapse_margin = child->margin[B]; prev_br = 0; } else if (child->type == BOX_BREAK) @@ -504,13 +526,13 @@ static void layout_block(fz_context *ctx, struct box *box, struct box *top, floa } } - if (box->padding[BOTTOM] == 0) + if (padding[B] == 0 && border[B] == 0) { - if (box->margin[BOTTOM] > 0) + if (margin[B] > 0) { box->h -= box_collapse_margin; - if (box->margin[BOTTOM] < box_collapse_margin) - box->margin[BOTTOM] = box_collapse_margin; + if (margin[B] < box_collapse_margin) + margin[B] = box_collapse_margin; } } } @@ -608,40 +630,64 @@ draw_flow_box(fz_context *ctx, struct box *box, float page_top, float page_bot, } static void +draw_rect(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, float *rgba, float x0, float y0, float x1, float y1) +{ + 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_fill_path(dev, path, 0, ctm, fz_device_rgb(ctx), rgba, rgba[3]); + + fz_free_path(ctx, path); +} + +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 x0, y0, x1, y1; + float color[4]; // TODO: background fill // TODO: border stroke - x0 = box->x - box->padding[LEFT]; - y0 = box->y - box->padding[TOP]; - x1 = box->x + box->w + box->padding[RIGHT]; - y1 = box->y + box->h + box->padding[BOTTOM]; + float *border = box->border; + float *padding = box->padding; + + x0 = box->x - padding[L]; + y0 = box->y - padding[T]; + x1 = box->x + box->w + padding[R]; + y1 = box->y + box->h + padding[B]; if (y0 > page_bot || y1 < page_top) return; if (box->style.background_color.a > 0) { - float color[3]; - 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); + } - 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); + 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]); } for (box = box->down; box; box = box->next) |