示例#1
0
static float layout_block(fz_context *ctx, fz_html *box, fz_html *top, float em, float page_h, float vertical)
{
    fz_html *child;
    int first;

    fz_css_style *style = &box->style;
    float *margin = box->margin;
    float *border = box->border;
    float *padding = box->padding;

    em = box->em = fz_from_css_number(style->font_size, em, em);

    margin[0] = fz_from_css_number(style->margin[0], em, top->w);
    margin[1] = fz_from_css_number(style->margin[1], em, top->w);
    margin[2] = fz_from_css_number(style->margin[2], em, top->w);
    margin[3] = fz_from_css_number(style->margin[3], em, top->w);

    padding[0] = fz_from_css_number(style->padding[0], em, top->w);
    padding[1] = fz_from_css_number(style->padding[1], em, top->w);
    padding[2] = fz_from_css_number(style->padding[2], em, top->w);
    padding[3] = fz_from_css_number(style->padding[3], em, top->w);

    border[0] = style->border_style[0] ? fz_from_css_number(style->border_width[0], em, top->w) : 0;
    border[1] = style->border_style[1] ? fz_from_css_number(style->border_width[1], em, top->w) : 0;
    border[2] = style->border_style[2] ? fz_from_css_number(style->border_width[2], em, top->w) : 0;
    border[3] = style->border_style[3] ? fz_from_css_number(style->border_width[3], em, top->w) : 0;

    box->x = top->x + margin[L] + border[L] + padding[L];
    box->w = top->w - (margin[L] + margin[R] + border[L] + border[R] + padding[L] + padding[R]);

    if (margin[T] > vertical)
        margin[T] -= vertical;
    else
        margin[T] = 0;

    if (padding[T] == 0 && border[T] == 0)
        vertical += margin[T];
    else
        vertical = 0;

    box->y = top->y + top->h + margin[T] + border[T] + padding[T];
    box->h = 0;

    first = 1;
    for (child = box->down; child; child = child->next)
    {
        if (child->type == BOX_BLOCK)
        {
            vertical = layout_block(ctx, child, box, em, page_h, vertical);
            if (first)
            {
                /* move collapsed parent/child top margins to parent */
                margin[T] += child->margin[T];
                box->y += child->margin[T];
                child->margin[T] = 0;
                first = 0;
            }
            box->h += child->h +
                      child->padding[T] + child->padding[B] +
                      child->border[T] + child->border[B] +
                      child->margin[T] + child->margin[B];
        }
        else if (child->type == BOX_BREAK)
        {
            box->h += fz_from_css_number_scale(style->line_height, em, em, em);
            vertical = 0;
            first = 0;
        }
        else if (child->type == BOX_FLOW)
        {
            layout_flow(ctx, child, box, em, page_h);
            if (child->h > 0)
            {
                box->h += child->h;
                vertical = 0;
                first = 0;
            }
        }
    }

    /* reserve space for the list mark */
    if (box->list_item && box->h == 0)
    {
        box->h += fz_from_css_number_scale(style->line_height, em, em, em);
        vertical = 0;
    }

    if (box->h == 0)
    {
        if (margin[B] > vertical)
            margin[B] -= vertical;
        else
            margin[B] = 0;
    }
    else
    {
        box->h -= vertical;
        vertical = fz_max(margin[B], vertical);
        margin[B] = vertical;
    }

    return vertical;
}
示例#2
0
static void layout_block(fz_context *ctx, fz_html *box, fz_html *top, float em, float top_collapse_margin, float page_h)
{
	fz_html *child;
	float box_collapse_margin;
	int prev_br;

	float *margin = box->margin;
	float *border = box->border;
	float *padding = box->padding;

	em = fz_from_css_number(box->style.font_size, em, em);

	margin[0] = fz_from_css_number(box->style.margin[0], em, top->w);
	margin[1] = fz_from_css_number(box->style.margin[1], em, top->w);
	margin[2] = fz_from_css_number(box->style.margin[2], em, top->w);
	margin[3] = fz_from_css_number(box->style.margin[3], em, top->w);

	padding[0] = fz_from_css_number(box->style.padding[0], em, top->w);
	padding[1] = fz_from_css_number(box->style.padding[1], em, top->w);
	padding[2] = fz_from_css_number(box->style.padding[2], em, top->w);
	padding[3] = fz_from_css_number(box->style.padding[3], em, top->w);

	if (box->style.border_style)
	{
		border[0] = fz_from_css_number(box->style.border_width[0], em, top->w);
		border[1] = fz_from_css_number(box->style.border_width[1], em, top->w);
		border[2] = fz_from_css_number(box->style.border_width[2], em, top->w);
		border[3] = fz_from_css_number(box->style.border_width[3], em, top->w);
	}
	else
		border[0] = border[1] = border[2] = border[3] = 0;

	if (padding[T] == 0 && border[T] == 0)
		box_collapse_margin = margin[T];
	else
		box_collapse_margin = 0;

	if (margin[T] > top_collapse_margin)
		margin[T] -= top_collapse_margin;
	else
		margin[T] = 0;

	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;
	for (child = box->down; child; child = child->next)
	{
		if (child->type == BOX_BLOCK)
		{
			layout_block(ctx, child, box, em, box_collapse_margin, page_h);
			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)
		{
			/* TODO: interaction with page breaks */
			if (prev_br)
				box->h += fz_from_css_number_scale(box->style.line_height, em, em, em);
			prev_br = 1;
		}
		else if (child->type == BOX_FLOW)
		{
			layout_flow(ctx, child, box, em, page_h);
			if (child->h > 0)
			{
				box->h += child->h;
				box_collapse_margin = 0;
				prev_br = 0;
			}
		}
	}

	if (padding[B] == 0 && border[B] == 0)
	{
		if (margin[B] > 0)
		{
			box->h -= box_collapse_margin;
			if (margin[B] < box_collapse_margin)
				margin[B] = box_collapse_margin;
		}
	}
}