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; }
/* * 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); }