コード例 #1
0
ファイル: html-layout.c プロジェクト: songtzu/mupdf-4
static void measure_word(fz_context *ctx, fz_html_flow *node, float em)
{
	const char *s;
	int c, g;
	float w;

	em = fz_from_css_number(node->style->font_size, em, em);
	node->x = 0;
	node->y = 0;
	node->h = fz_from_css_number_scale(node->style->line_height, em, em, em);

	w = 0;
	s = node->text;
	while (*s)
	{
		s += fz_chartorune(&c, s);
		g = fz_encode_character(ctx, node->style->font, c);
		if (g)
		{
			w += fz_advance_glyph(ctx, node->style->font, g) * em;
		}
		else
		{
			g = fz_encode_character(ctx, node->style->fallback, c);
			w += fz_advance_glyph(ctx, node->style->fallback, g) * em;
		}
	}
	node->w = w;
	node->em = em;
}
コード例 #2
0
ファイル: html-layout.c プロジェクト: paragasu/mupdf
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;
}
コード例 #3
0
ファイル: html-layout.c プロジェクト: paragasu/mupdf
static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm, int n)
{
    fz_font *font;
    fz_text *text;
    fz_matrix trm;
    fz_html_flow *line;
    float y, w;
    float color[3];
    const char *s;
    char buf[40];
    int c, g;

    fz_scale(&trm, box->em, -box->em);

    text = fz_new_text(ctx);

    line = find_list_mark_anchor(ctx, box);
    if (line)
    {
        y = line->y;
    }
    else
    {
        float h = fz_from_css_number_scale(box->style.line_height, box->em, box->em, box->em);
        float a = box->em * 0.8;
        float d = box->em * 0.2;
        if (a + d > h)
            h = a + d;
        y = box->y + a + (h - a - d) / 2;
    }

    if (y > page_bot || y < page_top)
        return;

    format_list_number(ctx, box->style.list_style_type, n, buf, sizeof buf);

    s = buf;
    w = 0;
    while (*s)
    {
        s += fz_chartorune(&c, s);
        g = fz_encode_character_with_fallback(ctx, box->style.font, c, UCDN_SCRIPT_LATIN, &font);
        w += fz_advance_glyph(ctx, font, g) * box->em;
    }

    s = buf;
    trm.e = box->x - w;
    trm.f = y;
    while (*s)
    {
        s += fz_chartorune(&c, s);
        g = fz_encode_character_with_fallback(ctx, box->style.font, c, UCDN_SCRIPT_LATIN, &font);
        fz_add_text(ctx, text, font, 0, &trm, g, c);
        trm.e += fz_advance_glyph(ctx, font, g) * box->em;
    }

    color[0] = box->style.color.r / 255.0f;
    color[1] = box->style.color.g / 255.0f;
    color[2] = box->style.color.b / 255.0f;

    fz_fill_text(ctx, dev, text, ctm, fz_device_rgb(ctx), color, 1);

    fz_drop_text(ctx, text);
}
コード例 #4
0
ファイル: html-layout.c プロジェクト: Crayonic/muPDFC
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;
		}
	}
}