diff options
-rw-r--r-- | android/jni/Core.mk | 1 | ||||
-rw-r--r-- | apps/mudraw.c | 77 | ||||
-rw-r--r-- | fitz/dev_text.c | 96 | ||||
-rw-r--r-- | fitz/doc_outline.c | 20 | ||||
-rw-r--r-- | fitz/fitz-internal.h | 8 | ||||
-rw-r--r-- | fitz/fitz.h | 37 | ||||
-rw-r--r-- | fitz/stm_buffer.c | 34 | ||||
-rw-r--r-- | fitz/stm_output.c | 65 | ||||
-rw-r--r-- | win32/libmupdf.vcproj | 5 |
9 files changed, 242 insertions, 101 deletions
diff --git a/android/jni/Core.mk b/android/jni/Core.mk index c3f12155..c280b4b7 100644 --- a/android/jni/Core.mk +++ b/android/jni/Core.mk @@ -77,6 +77,7 @@ LOCAL_SRC_FILES := \ $(MY_ROOT)/fitz/stm_buffer.c \ $(MY_ROOT)/fitz/stm_comp_buf.c \ $(MY_ROOT)/fitz/stm_open.c \ + $(MY_ROOT)/fitz/stm_output.c \ $(MY_ROOT)/fitz/stm_read.c \ $(MY_ROOT)/draw/draw_affine.c \ $(MY_ROOT)/draw/draw_blend.c \ diff --git a/apps/mudraw.c b/apps/mudraw.c index e36b1570..e3d4590b 100644 --- a/apps/mudraw.c +++ b/apps/mudraw.c @@ -87,6 +87,7 @@ static fz_text_sheet *sheet = NULL; static fz_colorspace *colorspace; static char *filename; static int files = 0; +fz_output *out = NULL; static char *mujstest_filename = NULL; static FILE *mujstest_file = NULL; @@ -331,12 +332,12 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_try(ctx) { dev = fz_new_trace_device(ctx); - printf("<page number=\"%d\">\n", pagenum); + fz_printf(out, "<page number=\"%d\">\n", pagenum); if (list) fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie); else fz_run_page(doc, page, dev, fz_identity, &cookie); - printf("</page>\n"); + fz_printf(out, "</page>\n"); } fz_always(ctx) { @@ -369,16 +370,16 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) dev = NULL; if (showtext == TEXT_XML) { - fz_print_text_page_xml(ctx, stdout, text); + fz_print_text_page_xml(ctx, out, text); } else if (showtext == TEXT_HTML) { - fz_print_text_page_html(ctx, stdout, text); + fz_print_text_page_html(ctx, out, text); } else if (showtext == TEXT_PLAIN) { - fz_print_text_page(ctx, stdout, text); - printf("\f\n"); + fz_print_text_page(ctx, out, text); + fz_printf(out, "\f\n"); } } fz_always(ctx) @@ -617,11 +618,26 @@ static void drawrange(fz_context *ctx, fz_document *doc, char *range) static void drawoutline(fz_context *ctx, fz_document *doc) { fz_outline *outline = fz_load_outline(doc); - if (showoutline > 1) - fz_print_outline_xml(ctx, stdout, outline); - else - fz_print_outline(ctx, stdout, outline); - fz_free_outline(ctx, outline); + fz_output *out = NULL; + + fz_var(out); + fz_try(ctx) + { + out = fz_new_output_file(ctx, stdout); + if (showoutline > 1) + fz_print_outline_xml(ctx, out, outline); + else + fz_print_outline(ctx, out, outline); + } + fz_always(ctx) + { + fz_close_output(out); + fz_free_outline(ctx, outline); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } } #ifdef MUPDF_COMBINED_EXE @@ -711,21 +727,24 @@ int main(int argc, char **argv) timing.minfilename = ""; timing.maxfilename = ""; - if (showxml || showtext == TEXT_XML) - printf("<?xml version=\"1.0\"?>\n"); - if (showtext) + { + out = fz_new_output_file(ctx, stdout); sheet = fz_new_text_sheet(ctx); + } + + if (showxml || showtext == TEXT_XML) + fz_printf(out, "<?xml version=\"1.0\"?>\n"); if (showtext == TEXT_HTML) { - printf("<style>\n"); - printf("body{background-color:gray;margin:12tp;}\n"); - printf("div.page{background-color:white;margin:6pt;padding:6pt;}\n"); - printf("div.block{border:1px solid gray;margin:6pt;padding:6pt;}\n"); - printf("p{margin:0;padding:0;}\n"); - printf("</style>\n"); - printf("<body>\n"); + fz_printf(out, "<style>\n"); + fz_printf(out, "body{background-color:gray;margin:12tp;}\n"); + fz_printf(out, "div.page{background-color:white;margin:6pt;padding:6pt;}\n"); + fz_printf(out, "div.block{border:1px solid gray;margin:6pt;padding:6pt;}\n"); + fz_printf(out, "p{margin:0;padding:0;}\n"); + fz_printf(out, "</style>\n"); + fz_printf(out, "<body>\n"); } fz_try(ctx) @@ -760,7 +779,7 @@ int main(int argc, char **argv) } if (showxml || showtext == TEXT_XML) - printf("<document name=\"%s\">\n", filename); + fz_printf(out, "<document name=\"%s\">\n", filename); if (showoutline) drawoutline(ctx, doc); @@ -774,7 +793,7 @@ int main(int argc, char **argv) } if (showxml || showtext == TEXT_XML) - printf("</document>\n"); + fz_printf(out, "</document>\n"); fz_close_document(doc); doc = NULL; @@ -799,14 +818,18 @@ int main(int argc, char **argv) if (showtext == TEXT_HTML) { - printf("</body>\n"); - printf("<style>\n"); - fz_print_text_sheet(ctx, stdout, sheet); - printf("</style>\n"); + fz_printf(out, "</body>\n"); + fz_printf(out, "<style>\n"); + fz_print_text_sheet(ctx, out, sheet); + fz_printf(out, "</style>\n"); } if (showtext) + { fz_free_text_sheet(ctx, sheet); + fz_close_output(out); + out = NULL; + } if (showtime && timing.count > 0) { diff --git a/fitz/dev_text.c b/fitz/dev_text.c index a5d765eb..e5b2c927 100644 --- a/fitz/dev_text.c +++ b/fitz/dev_text.c @@ -569,43 +569,43 @@ static int font_is_italic(fz_font *font) } static void -fz_print_style_begin(FILE *out, fz_text_style *style) +fz_print_style_begin(fz_output *out, fz_text_style *style) { int script = style->script; - fprintf(out, "<span class=\"s%d\">", style->id); + fz_printf(out, "<span class=\"s%d\">", style->id); while (script-- > 0) - fprintf(out, "<sup>"); + fz_printf(out, "<sup>"); while (++script < 0) - fprintf(out, "<sub>"); + fz_printf(out, "<sub>"); } static void -fz_print_style_end(FILE *out, fz_text_style *style) +fz_print_style_end(fz_output *out, fz_text_style *style) { int script = style->script; while (script-- > 0) - fprintf(out, "</sup>"); + fz_printf(out, "</sup>"); while (++script < 0) - fprintf(out, "</sub>"); - fprintf(out, "</span>"); + fz_printf(out, "</sub>"); + fz_printf(out, "</span>"); } static void -fz_print_style(FILE *out, fz_text_style *style) +fz_print_style(fz_output *out, fz_text_style *style) { char *s = strchr(style->font->name, '+'); s = s ? s + 1 : style->font->name; - fprintf(out, "span.s%d{font-family:\"%s\";font-size:%gpt;", + fz_printf(out, "span.s%d{font-family:\"%s\";font-size:%gpt;", style->id, s, style->size); if (font_is_italic(style->font)) - fprintf(out, "font-style:italic;"); + fz_printf(out, "font-style:italic;"); if (font_is_bold(style->font)) - fprintf(out, "font-weight:bold;"); - fprintf(out, "}\n"); + fz_printf(out, "font-weight:bold;"); + fz_printf(out, "}\n"); } void -fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet) +fz_print_text_sheet(fz_context *ctx, fz_output *out, fz_text_sheet *sheet) { fz_text_style *style; for (style = sheet->style; style; style = style->next) @@ -613,7 +613,7 @@ fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet) } void -fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page) +fz_print_text_page_html(fz_context *ctx, fz_output *out, fz_text_page *page) { int block_n, line_n, span_n, ch_n; fz_text_style *style = NULL; @@ -621,16 +621,16 @@ fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page) fz_text_line *line; fz_text_span *span; - fprintf(out, "<div class=\"page\">\n"); + fz_printf(out, "<div class=\"page\">\n"); for (block_n = 0; block_n < page->len; block_n++) { block = &page->blocks[block_n]; - fprintf(out, "<div class=\"block\">\n"); + fz_printf(out, "<div class=\"block\">\n"); for (line_n = 0; line_n < block->len; line_n++) { line = &block->lines[line_n]; - fprintf(out, "<p>"); + fz_printf(out, "<p>"); style = NULL; for (span_n = 0; span_n < line->len; span_n++) @@ -648,29 +648,29 @@ fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page) { fz_text_char *ch = &span->text[ch_n]; if (ch->c == '<') - fprintf(out, "<"); + fz_printf(out, "<"); else if (ch->c == '>') - fprintf(out, ">"); + fz_printf(out, ">"); else if (ch->c == '&') - fprintf(out, "&"); + fz_printf(out, "&"); else if (ch->c >= 32 && ch->c <= 127) - fprintf(out, "%c", ch->c); + fz_printf(out, "%c", ch->c); else - fprintf(out, "&#x%x;", ch->c); + fz_printf(out, "&#x%x;", ch->c); } } if (style) fz_print_style_end(out, style); - fprintf(out, "</p>\n"); + fz_printf(out, "</p>\n"); } - fprintf(out, "</div>\n"); + fz_printf(out, "</div>\n"); } - fprintf(out, "</div>\n"); + fz_printf(out, "</div>\n"); } void -fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page) +fz_print_text_page_xml(fz_context *ctx, fz_output *out, fz_text_page *page) { fz_text_block *block; fz_text_line *line; @@ -678,54 +678,54 @@ fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page) fz_text_char *ch; char *s; - fprintf(out, "<page>\n"); + fz_printf(out, "<page>\n"); for (block = page->blocks; block < page->blocks + page->len; block++) { - fprintf(out, "<block bbox=\"%g %g %g %g\">\n", + fz_printf(out, "<block bbox=\"%g %g %g %g\">\n", block->bbox.x0, block->bbox.y0, block->bbox.x1, block->bbox.y1); for (line = block->lines; line < block->lines + block->len; line++) { - fprintf(out, "<line bbox=\"%g %g %g %g\">\n", + fz_printf(out, "<line bbox=\"%g %g %g %g\">\n", line->bbox.x0, line->bbox.y0, line->bbox.x1, line->bbox.y1); for (span = line->spans; span < line->spans + line->len; span++) { fz_text_style *style = span->style; s = strchr(style->font->name, '+'); s = s ? s + 1 : style->font->name; - fprintf(out, "<span bbox=\"%g %g %g %g\" font=\"%s\" size=\"%g\">\n", + fz_printf(out, "<span bbox=\"%g %g %g %g\" font=\"%s\" size=\"%g\">\n", span->bbox.x0, span->bbox.y0, span->bbox.x1, span->bbox.y1, s, style->size); for (ch = span->text; ch < span->text + span->len; ch++) { - fprintf(out, "<char bbox=\"%g %g %g %g\" c=\"", + fz_printf(out, "<char bbox=\"%g %g %g %g\" c=\"", ch->bbox.x0, ch->bbox.y0, ch->bbox.x1, ch->bbox.y1); switch (ch->c) { - case '<': fprintf(out, "<"); break; - case '>': fprintf(out, ">"); break; - case '&': fprintf(out, "&"); break; - case '"': fprintf(out, """); break; - case '\'': fprintf(out, "'"); break; + case '<': fz_printf(out, "<"); break; + case '>': fz_printf(out, ">"); break; + case '&': fz_printf(out, "&"); break; + case '"': fz_printf(out, """); break; + case '\'': fz_printf(out, "'"); break; default: if (ch->c >= 32 && ch->c <= 127) - fprintf(out, "%c", ch->c); + fz_printf(out, "%c", ch->c); else - fprintf(out, "&#x%x;", ch->c); + fz_printf(out, "&#x%x;", ch->c); break; } - fprintf(out, "\"/>\n"); + fz_printf(out, "\"/>\n"); } - fprintf(out, "</span>\n"); + fz_printf(out, "</span>\n"); } - fprintf(out, "</line>\n"); + fz_printf(out, "</line>\n"); } - fprintf(out, "</block>\n"); + fz_printf(out, "</block>\n"); } - fprintf(out, "</page>\n"); + fz_printf(out, "</page>\n"); } void -fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page) +fz_print_text_page(fz_context *ctx, fz_output *out, fz_text_page *page) { fz_text_block *block; fz_text_line *line; @@ -744,11 +744,11 @@ fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page) { n = fz_runetochar(utf, ch->c); for (i = 0; i < n; i++) - putc(utf[i], out); + fz_printf(out, "%c", utf[i]); } } - fprintf(out, "\n"); + fz_printf(out, "\n"); } - fprintf(out, "\n"); + fz_printf(out, "\n"); } } diff --git a/fitz/doc_outline.c b/fitz/doc_outline.c index 71694851..2f23573e 100644 --- a/fitz/doc_outline.c +++ b/fitz/doc_outline.c @@ -15,40 +15,40 @@ fz_free_outline(fz_context *ctx, fz_outline *outline) } static void -do_debug_outline_xml(FILE *out, fz_outline *outline, int level) +do_debug_outline_xml(fz_output *out, fz_outline *outline, int level) { while (outline) { - fprintf(out, "<outline title=\"%s\" page=\"%d\"", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); + fz_printf(out, "<outline title=\"%s\" page=\"%d\"", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); if (outline->down) { - fprintf(out, ">\n"); + fz_printf(out, ">\n"); do_debug_outline_xml(out, outline->down, level + 1); - fprintf(out, "</outline>\n"); + fz_printf(out, "</outline>\n"); } else { - fprintf(out, " />\n"); + fz_printf(out, " />\n"); } outline = outline->next; } } void -fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline) +fz_print_outline_xml(fz_context *ctx, fz_output *out, fz_outline *outline) { do_debug_outline_xml(out, outline, 0); } static void -do_debug_outline(FILE *out, fz_outline *outline, int level) +do_debug_outline(fz_output *out, fz_outline *outline, int level) { int i; while (outline) { for (i = 0; i < level; i++) - fputc('\t', out); - fprintf(out, "%s\t%d\n", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); + fz_printf(out, "\t"); + fz_printf(out, "%s\t%d\n", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); if (outline->down) do_debug_outline(out, outline->down, level + 1); outline = outline->next; @@ -56,7 +56,7 @@ do_debug_outline(FILE *out, fz_outline *outline, int level) } void -fz_print_outline(fz_context *ctx, FILE *out, fz_outline *outline) +fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline) { do_debug_outline(out, outline, 0); } diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index 4839af7d..7e817190 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -651,11 +651,11 @@ void fz_write_buffer_bits(fz_context *ctx, fz_buffer *buf, int val, int bits); void fz_write_buffer_pad(fz_context *ctx, fz_buffer *buf); /* - fz_buffer_printf: print formatted to a buffer. The buffer will - grow, but the caller must ensure that no more than 256 bytes are - added to the buffer per call. + fz_buffer_printf: print formatted to a buffer. The buffer will grow + as required. */ -void fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...); +int fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...); +int fz_buffer_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args); /* fz_buffer_printf: print a string formatted as a pdf string to a buffer. diff --git a/fitz/fitz.h b/fitz/fitz.h index 43634dd9..b606491a 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1784,25 +1784,50 @@ void fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet); fz_text_page *fz_new_text_page(fz_context *ctx, fz_rect mediabox); void fz_free_text_page(fz_context *ctx, fz_text_page *page); +typedef struct fz_output_s fz_output; + +struct fz_output_s +{ + fz_context *ctx; + void *opaque; + int (*printf)(fz_output *, const char *, va_list ap); + void (*close)(fz_output *); +}; + +fz_output *fz_new_output_file(fz_context *, FILE *); + +fz_output *fz_new_output_buffer(fz_context *, fz_buffer *); + +int fz_printf(fz_output *, const char *, ...); + +/* + fz_close_output: Close a previously opened fz_output stream. + + Note: whether or not this closes the underlying output method is + method dependent. FILE * streams created by fz_new_output_file are + NOT closed. +*/ +void fz_close_output(fz_output *); + /* fz_print_text_sheet: Output a text sheet to a file as CSS. */ -void fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet); +void fz_print_text_sheet(fz_context *ctx, fz_output *out, fz_text_sheet *sheet); /* fz_print_text_page_html: Output a page to a file in HTML format. */ -void fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page); +void fz_print_text_page_html(fz_context *ctx, fz_output *out, fz_text_page *page); /* fz_print_text_page_xml: Output a page to a file in XML format. */ -void fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page); +void fz_print_text_page_xml(fz_context *ctx, fz_output *out, fz_text_page *page); /* fz_print_text_page: Output a page to a file in UTF-8 format. */ -void fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page); +void fz_print_text_page(fz_context *ctx, fz_output *out, fz_text_page *page); /* fz_search_text_page: Search for occurrence of 'needle' in text page. @@ -2149,7 +2174,7 @@ struct fz_outline_s outline: The outlines to output. */ -void fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline); +void fz_print_outline_xml(fz_context *ctx, fz_output *out, fz_outline *outline); /* fz_print_outline: Dump the given outlines to as text. @@ -2158,7 +2183,7 @@ void fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline); outline: The outlines to output. */ -void fz_print_outline(fz_context *ctx, FILE *out, fz_outline *outline); +void fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline); /* fz_free_outline: Free hierarchical outline. diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c index 42a40584..a29f92de 100644 --- a/fitz/stm_buffer.c +++ b/fitz/stm_buffer.c @@ -201,19 +201,43 @@ void fz_write_buffer_pad(fz_context *ctx, fz_buffer *buf) buf->unused_bits = 0; } -void +int fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...) { + int ret; va_list args; va_start(args, fmt); - /* Caller guarantees not to generate more than 256 bytes per call */ - while(buffer->cap - buffer->len < 256) + ret = fz_buffer_vprintf(ctx, buffer, fmt, args); + + va_end(args); + + return ret; +} + +int +fz_buffer_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args) +{ + int len; + + do + { + int slack = buffer->cap - buffer->len; + + len = vsnprintf((char *)buffer->data + buffer->len, slack, fmt, args); + /* len = number of chars written, not including the terminating + * NULL, so len+1 > slack means "truncated". MSVC differs here + * and returns -1 for truncated. */ + if (len > 0 && len+1 <= slack) + break; + /* Grow the buffer and retry */ fz_grow_buffer(ctx, buffer); + } + while (1); - buffer->len += vsprintf((char *)buffer->data + buffer->len, fmt, args); + buffer->len += len; - va_end(args); + return len; } void diff --git a/fitz/stm_output.c b/fitz/stm_output.c new file mode 100644 index 00000000..de3d185e --- /dev/null +++ b/fitz/stm_output.c @@ -0,0 +1,65 @@ +#include "fitz-internal.h" + +static int +file_printf(fz_output *out, const char *fmt, va_list ap) +{ + FILE *file = (FILE *)out->opaque; + + return vfprintf(file, fmt, ap); +} + +fz_output * +fz_new_output_file(fz_context *ctx, FILE *file) +{ + fz_output *out = fz_malloc_struct(ctx, fz_output); + out->ctx = ctx; + out->opaque = file; + out->printf = file_printf; + out->close = NULL; + return out; +} + +void +fz_close_output(fz_output *out) +{ + if (!out) + return; + if (out->close) + out->close(out); + fz_free(out->ctx, out); +} + +int +fz_printf(fz_output *out, const char *fmt, ...) +{ + int ret; + va_list ap; + + if (!out) + return 0; + + va_start(ap, fmt); + ret = out->printf(out, fmt, ap); + va_end(ap); + + return ret; +} + +static int +buffer_printf(fz_output *out, const char *fmt, va_list list) +{ + fz_buffer *buffer = (fz_buffer *)out->opaque; + + return fz_buffer_vprintf(out->ctx, buffer, fmt, list); +} + +fz_output * +fz_new_output_buffer(fz_context *ctx, fz_buffer *buf) +{ + fz_output *out = fz_malloc_struct(ctx, fz_output); + out->ctx = ctx; + out->opaque = buf; + out->printf = buffer_printf; + out->close = NULL; + return out; +}
\ No newline at end of file diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index 438865bf..cee47cb5 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -23,7 +23,6 @@ > <Tool Name="VCPreBuildEventTool" - Description="" CommandLine="" /> <Tool @@ -578,6 +577,10 @@ > </File> <File + RelativePath="..\fitz\stm_output.c" + > + </File> + <File RelativePath="..\fitz\stm_read.c" > </File> |