mutrace.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. static int usage(void)
  27. {
  28. fprintf(stderr,
  29. "Usage: mutool trace [options] file [pages]\n"
  30. "\t-p -\tpassword\n"
  31. "\n"
  32. "\t-W -\tpage width for EPUB layout\n"
  33. "\t-H -\tpage height for EPUB layout\n"
  34. "\t-S -\tfont size for EPUB layout\n"
  35. "\t-U -\tfile name of user stylesheet for EPUB layout\n"
  36. "\t-X\tdisable document styles for EPUB layout\n"
  37. "\n"
  38. "\t-d\tuse display list\n"
  39. "\n"
  40. "\tpages\tcomma separated list of page numbers and ranges\n"
  41. );
  42. return 1;
  43. }
  44. static float layout_w = FZ_DEFAULT_LAYOUT_W;
  45. static float layout_h = FZ_DEFAULT_LAYOUT_H;
  46. static float layout_em = FZ_DEFAULT_LAYOUT_EM;
  47. static char *layout_css = NULL;
  48. static int layout_use_doc_css = 1;
  49. static int use_display_list = 0;
  50. static void runpage(fz_context *ctx, fz_document *doc, int number)
  51. {
  52. fz_page *page = NULL;
  53. fz_display_list *list = NULL;
  54. fz_device *dev = NULL;
  55. fz_rect mediabox;
  56. fz_var(page);
  57. fz_var(list);
  58. fz_var(dev);
  59. fz_try(ctx)
  60. {
  61. page = fz_load_page(ctx, doc, number - 1);
  62. mediabox = fz_bound_page(ctx, page);
  63. printf("<page number=\"%d\" mediabox=\"%g %g %g %g\">\n",
  64. number, mediabox.x0, mediabox.y0, mediabox.x1, mediabox.y1);
  65. dev = fz_new_trace_device(ctx, fz_stdout(ctx));
  66. if (use_display_list)
  67. {
  68. list = fz_new_display_list_from_page(ctx, page);
  69. fz_run_display_list(ctx, list, dev, fz_identity, fz_infinite_rect, NULL);
  70. }
  71. else
  72. {
  73. fz_run_page(ctx, page, dev, fz_identity, NULL);
  74. }
  75. printf("</page>\n");
  76. }
  77. fz_always(ctx)
  78. {
  79. fz_drop_display_list(ctx, list);
  80. fz_drop_page(ctx, page);
  81. fz_drop_device(ctx, dev);
  82. }
  83. fz_catch(ctx)
  84. fz_rethrow(ctx);
  85. }
  86. static void runrange(fz_context *ctx, fz_document *doc, int count, const char *range)
  87. {
  88. int start, end, i;
  89. while ((range = fz_parse_page_range(ctx, range, &start, &end, count)))
  90. {
  91. if (start < end)
  92. for (i = start; i <= end; ++i)
  93. runpage(ctx, doc, i);
  94. else
  95. for (i = start; i >= end; --i)
  96. runpage(ctx, doc, i);
  97. }
  98. }
  99. int mutrace_main(int argc, char **argv)
  100. {
  101. fz_context *ctx;
  102. fz_document *doc = NULL;
  103. char *password = "";
  104. int i, c, count;
  105. while ((c = fz_getopt(argc, argv, "p:W:H:S:U:Xd")) != -1)
  106. {
  107. switch (c)
  108. {
  109. default: return usage();
  110. case 'p': password = fz_optarg; break;
  111. case 'W': layout_w = fz_atof(fz_optarg); break;
  112. case 'H': layout_h = fz_atof(fz_optarg); break;
  113. case 'S': layout_em = fz_atof(fz_optarg); break;
  114. case 'U': layout_css = fz_optarg; break;
  115. case 'X': layout_use_doc_css = 0; break;
  116. case 'd': use_display_list = 1; break;
  117. }
  118. }
  119. if (fz_optind == argc)
  120. return usage();
  121. ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
  122. if (!ctx)
  123. {
  124. fprintf(stderr, "cannot create mupdf context\n");
  125. return EXIT_FAILURE;
  126. }
  127. fz_try(ctx)
  128. {
  129. fz_register_document_handlers(ctx);
  130. if (layout_css)
  131. fz_load_user_css(ctx, layout_css);
  132. fz_set_use_document_css(ctx, layout_use_doc_css);
  133. }
  134. fz_catch(ctx)
  135. {
  136. fz_report_error(ctx);
  137. fprintf(stderr, "cannot initialize mupdf\n");
  138. fz_drop_context(ctx);
  139. return EXIT_FAILURE;
  140. }
  141. fz_var(doc);
  142. fz_try(ctx)
  143. {
  144. for (i = fz_optind; i < argc; ++i)
  145. {
  146. doc = fz_open_document(ctx, argv[i]);
  147. if (fz_needs_password(ctx, doc))
  148. if (!fz_authenticate_password(ctx, doc, password))
  149. fz_throw(ctx, FZ_ERROR_ARGUMENT, "cannot authenticate password: %s", argv[i]);
  150. fz_layout_document(ctx, doc, layout_w, layout_h, layout_em);
  151. printf("<document filename=\"%s\">\n", argv[i]);
  152. count = fz_count_pages(ctx, doc);
  153. if (i+1 < argc && fz_is_page_range(ctx, argv[i+1]))
  154. runrange(ctx, doc, count, argv[++i]);
  155. else
  156. runrange(ctx, doc, count, "1-N");
  157. printf("</document>\n");
  158. fz_drop_document(ctx, doc);
  159. doc = NULL;
  160. }
  161. }
  162. fz_catch(ctx)
  163. {
  164. fz_report_error(ctx);
  165. fprintf(stderr, "cannot run document\n");
  166. fz_drop_document(ctx, doc);
  167. fz_drop_context(ctx);
  168. return EXIT_FAILURE;
  169. }
  170. fz_drop_context(ctx);
  171. return EXIT_SUCCESS;
  172. }