Example #1
0
static void generate_boxes(fz_context *ctx, fz_pool *pool,
                           fz_html_font_set *set, fz_archive *zip, const char *base_uri,
                           fz_xml *node, fz_html *top, fz_css_rule *rule, fz_css_match *up_match, int list_counter)
{
    fz_css_match match;
    fz_html *box;
    const char *tag;
    int display;

    while (node)
    {
        match.up = up_match;
        match.count = 0;

        tag = fz_xml_tag(node);
        if (tag)
        {
            fz_match_css(ctx, &match, rule, node);

            display = fz_get_css_match_display(&match);

            if (!strcmp(tag, "br"))
            {
                if (top->type == BOX_INLINE)
                {
                    fz_html *flow = top;
                    while (flow->type != BOX_FLOW)
                        flow = flow->up;
                    add_flow_break(ctx, pool, flow, &top->style);
                }
                else
                {
                    box = new_box(ctx, pool);
                    fz_apply_css_style(ctx, set, &box->style, &match);
                    top = insert_break_box(ctx, box, top);
                }
            }

            else if (!strcmp(tag, "img"))
            {
                const char *src = fz_xml_att(node, "src");
                if (src)
                {
                    box = new_box(ctx, pool);
                    fz_apply_css_style(ctx, set, &box->style, &match);
                    insert_inline_box(ctx, pool, box, top);
                    generate_image(ctx, pool, zip, base_uri, box, src);
                }
            }

            else if (display != DIS_NONE)
            {
                box = new_box(ctx, pool);
                fz_apply_css_style(ctx, set, &box->style, &match);

                if (display == DIS_BLOCK || display == DIS_INLINE_BLOCK)
                {
                    top = insert_block_box(ctx, box, top);
                }
                else if (display == DIS_LIST_ITEM)
                {
                    top = insert_block_box(ctx, box, top);
                    box->list_item = ++list_counter;
                }
                else if (display == DIS_INLINE)
                {
                    insert_inline_box(ctx, pool, box, top);
                }
                else
                {
                    fz_warn(ctx, "unknown box display type");
                    insert_box(ctx, box, BOX_BLOCK, top);
                }

                if (fz_xml_down(node))
                {
                    int child_counter = list_counter;
                    if (!strcmp(tag, "ul") || !strcmp(tag, "ol"))
                        child_counter = 0;
                    generate_boxes(ctx, pool, set, zip, base_uri, fz_xml_down(node), box, rule, &match, child_counter);
                }

                // TODO: remove empty flow boxes
            }
        }
        else
        {
            if (top->type != BOX_INLINE)
            {
                /* Create anonymous inline box, with the same style as the top block box. */
                box = new_box(ctx, pool);
                insert_inline_box(ctx, pool, box, top);
                box->style = top->style;
                /* Make sure not to recursively multiply font sizes. */
                box->style.font_size.value = 1;
                box->style.font_size.unit = N_SCALE;
                generate_text(ctx, pool, box, fz_xml_text(node));
            }
            else
            {
                generate_text(ctx, pool, top, fz_xml_text(node));
            }
        }

        node = fz_xml_next(node);
    }
}
Example #2
0
static void generate_boxes(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const char *base_uri,
	fz_xml *node, fz_html *top, fz_css_rule *rule, fz_css_match *up_match)
{
	fz_css_match match;
	fz_html *box;
	const char *tag;
	int display;

	while (node)
	{
		match.up = up_match;
		match.count = 0;

		tag = fz_xml_tag(node);
		if (tag)
		{
			fz_match_css(ctx, &match, rule, node);

			display = fz_get_css_match_display(&match);

			if (!strcmp(tag, "br"))
			{
				box = new_box(ctx);
				fz_apply_css_style(ctx, set, &box->style, &match);
				top = insert_break_box(ctx, box, top);
			}

			else if (!strcmp(tag, "img"))
			{
				const char *src = fz_xml_att(node, "src");
				if (src)
				{
					box = new_box(ctx);
					fz_apply_css_style(ctx, set, &box->style, &match);
					insert_inline_box(ctx, box, top);
					generate_image(ctx, zip, base_uri, box, src);
				}
			}

			else if (display != DIS_NONE)
			{
				box = new_box(ctx);
				fz_apply_css_style(ctx, set, &box->style, &match);

				if (display == DIS_BLOCK)
				{
					top = insert_block_box(ctx, box, top);
				}
				else if (display == DIS_LIST_ITEM)
				{
					top = insert_block_box(ctx, box, top);
				}
				else if (display == DIS_INLINE)
				{
					insert_inline_box(ctx, box, top);
				}
				else
				{
					fz_warn(ctx, "unknown box display type");
					insert_box(ctx, box, BOX_BLOCK, top);
				}

				if (fz_xml_down(node))
					generate_boxes(ctx, set, zip, base_uri, fz_xml_down(node), box, rule, &match);

				// TODO: remove empty flow boxes
			}
		}
		else
		{
			if (top->type != BOX_INLINE)
			{
				box = new_box(ctx);
				insert_inline_box(ctx, box, top);
				box->style = top->style;
				generate_text(ctx, box, fz_xml_text(node));
			}
			else
			{
				generate_text(ctx, top, fz_xml_text(node));
			}
		}

		node = fz_xml_next(node);
	}
}