Example #1
0
static int xml_parse_internal(XMLState *s, const char *buf_start, int buf_len,
                              EditBuffer *b, int offset_start)
{
    int ch, offset, offset0, text_offset_start, ret, offset_end;
    const char *buf_end, *buf;

    buf = buf_start;
    buf_end = buf + buf_len;
    offset = offset_start;
    offset_end = offset_start + buf_len;
    offset0 = 0; /* not used */
    text_offset_start = 0; /* not used */
    for (;;) {
        if (buf) {
            if (buf >= buf_end)
                break;
            ch = charset_decode(&s->charset_state, &buf);
        } else {
            if (offset >= offset_end)
                break;
            offset0 = offset;
            ch = eb_nextc(b, offset, &offset);
        }
        /* increment line number to signal errors */
        if (ch == '\n') {
            /* well, should add counter, but we test abort here */
            if (s->abort_func(s->abort_opaque))
                return -1;
            s->line_num++;
        }

        switch (s->state) {
        case XML_STATE_TAG:
            if (ch == '>') {
                strbuf_addch(&s->str, '\0');
                ret = parse_tag(s, (char *)s->str.buf);
                switch (ret) {
                default:
                case XML_STATE_TEXT:
                xml_text:
                    strbuf_reset(&s->str);
                    s->state = XML_STATE_TEXT;
                    text_offset_start = offset;
                    break;
                case XML_STATE_PRETAG:
                    strbuf_reset(&s->str);
                    s->state = XML_STATE_PRETAG;
                    text_offset_start = offset;
                    break;
                }
            } else {
                strbuf_addch(&s->str, ch);
                /* test comment */
                if (s->str.size == 3 &&
                    s->str.buf[0] == '!' &&
                    s->str.buf[1] == '-' &&
                    s->str.buf[2] == '-') {
                    s->state = XML_STATE_COMMENT;
                }
            }
            break;
        case XML_STATE_TEXT:
            if (ch == '<') {
                /* XXX: not strictly correct with comments : should
                   not flush if comment */
                if (buf) {
                    strbuf_addch(&s->str, '\0');
                    flush_text(s, (char *)s->str.buf);
                    strbuf_reset(&s->str);
                } else {
                    flush_text_buffer(s, text_offset_start, offset0);
                }
                s->state = XML_STATE_TAG;
            } else {
                if (buf) {
                    /* evaluate entities */
                    if (ch == '&') {
                        buf--;
                        ch = parse_entity(&buf);
                    }
                    strbuf_addch(&s->str, ch);
                }
            }
            break;
        case XML_STATE_COMMENT:
            if (ch == '-')
                s->state = XML_STATE_COMMENT1;
            break;
        case XML_STATE_COMMENT1:
            if (ch == '-')
                s->state = XML_STATE_COMMENT2;
            else
                s->state = XML_STATE_COMMENT;
            break;
        case XML_STATE_COMMENT2:
            if (ch == '>') {
                goto xml_text;
            } else if (ch != '-') {
                s->state = XML_STATE_COMMENT;
            }
            break;
        case XML_STATE_PRETAG:
            {
                int len, taglen;

                strbuf_addch(&s->str, ch);
                taglen = s->pretaglen + 2;
                len = s->str.size - taglen;
                if (len >= 0 && 
                    s->str.buf[len] == '<' && 
                    s->str.buf[len + 1] == '/' &&
                    !xml_tagcmp((char *)s->str.buf + len + 2, s->pretag)) {
                    s->str.buf[len] = '\0';
                    
                    if (!xml_tagcmp(s->pretag, "style")) {
                        if (s->style_sheet) {
                            CSSParseState b1, *b = &b1;
                            b->ptr = (char *)s->str.buf;
                            b->line_num = s->line_num; /* XXX: incorrect */
                            b->filename = s->filename;
                            b->ignore_case = s->ignore_case;
                            css_parse_style_sheet(s->style_sheet, b);
                        }
                    } else if (!xml_tagcmp(s->pretag, "script")) {
                        /* XXX: handle script */
                    } else {
                        /* just add the content */
                        if (buf) {
                            flush_text(s, (char *)s->str.buf);
                        } else {
                            /* XXX: would be incorrect if non ascii chars */
                            flush_text_buffer(s, text_offset_start, offset - taglen);
                        }
                        strbuf_reset(&s->str);
                        if (s->box)
                            s->box = s->box->parent;
                    }
                    s->state = XML_STATE_WAIT_EOT;
                }
            }
            break;
        case XML_STATE_WAIT_EOT:
            /* wait end of tag */
            if (ch == '>')
                    goto xml_text;
            break;
        }
    }
    return buf - buf_start;
}
Example #2
0
/*
 * Transition from string context to text context.
 */
static int
sync_text_state(gx_device_pdf *pdev)
{
    pdf_text_state_t *pts = pdev->text->text_state;
    stream *s = pdev->strm;
    int code;

    if (pts->buffer.count_chars == 0)
        return 0;		/* nothing to output */

    if (pts->continue_line)
        return flush_text_buffer(pdev);

    /* Bring text state parameters up to date. */

    if (pts->out.character_spacing != pts->in.character_spacing) {
        pprintg1(s, "%g Tc\n", pts->in.character_spacing);
        pts->out.character_spacing = pts->in.character_spacing;
    }

    if (pts->out.pdfont != pts->in.pdfont || pts->out.size != pts->in.size) {
        pdf_font_resource_t *pdfont = pts->in.pdfont;

        code = pdf_assign_font_object_id(pdev, pdfont);
        if (code < 0)
            return code;
        pprints1(s, "/%s ", pdfont->rname);
        pprintg1(s, "%g Tf\n", pts->in.size);
        pts->out.pdfont = pdfont;
        pts->out.size = pts->in.size;
        /*
         * In PDF, the only place to specify WMode is in the CMap
         * (a.k.a. Encoding) of a Type 0 font.
         */
        pts->wmode =
            (pdfont->FontType == ft_composite ?
             pdfont->u.type0.WMode : 0);
        code = pdf_used_charproc_resources(pdev, pdfont);
        if (code < 0)
            return code;
    }

    if (memcmp(&pts->in.matrix, &pts->out.matrix, sizeof(pts->in.matrix)) ||
         ((pts->start.x != pts->out_pos.x || pts->start.y != pts->out_pos.y) &&
          (pts->buffer.count_chars != 0 || pts->buffer.count_moves != 0))) {
        /* pdf_set_text_matrix sets out.matrix = in.matrix */
        code = pdf_set_text_matrix(pdev);
        if (code < 0)
            return code;
    }

    if (pts->out.render_mode != pts->in.render_mode) {
        pprintg1(s, "%g Tr\n", pts->in.render_mode);
        pts->out.render_mode = pts->in.render_mode;
    }

    if (pts->out.word_spacing != pts->in.word_spacing) {
        if (memchr(pts->buffer.chars, 32, pts->buffer.count_chars)) {
            pprintg1(s, "%g Tw\n", pts->in.word_spacing);
            pts->out.word_spacing = pts->in.word_spacing;
        }
    }

    return flush_text_buffer(pdev);
}