Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/docs/examples/storytest.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 #include "mupdf/fitz.h" | |
| 2 #include "mupdf/pdf.h" | |
| 3 | |
| 4 #include <string.h> | |
| 5 #include <memory.h> | |
| 6 | |
| 7 const char snark[] = | |
| 8 "<!DOCTYPE html>" | |
| 9 "<style>" | |
| 10 "#a { margin: 30px; }" | |
| 11 "#b { margin: 20px; }" | |
| 12 "#c { margin: 5px; }" | |
| 13 "#a { border: 1px solid red; }" | |
| 14 "#b { border: 1px solid green; }" | |
| 15 "#c { border: 1px solid blue; }" | |
| 16 "</style>" | |
| 17 "<body>" | |
| 18 "<div id=\"a\">" | |
| 19 "A" | |
| 20 "</div>" | |
| 21 "<div id=\"b\">" | |
| 22 "<div id=\"c\">" | |
| 23 "C" | |
| 24 "</div>" | |
| 25 "</div>" | |
| 26 "<div style=\"text-align:center;\"><IMG width=\"300\" src=\"docs/examples/SnarkFront.svg\"></div>" | |
| 27 "<H1>The hunting of the Snark</H1>" | |
| 28 "<div style=\"text-align:center\"><IMG width=\"30\" src=\"docs/examples/huntingofthesnark.png\"></div>" | |
| 29 "<p>\"Just the place for a Snark!\" the Bellman cried,<br>" | |
| 30 "As he landed his crew with care;<br>" | |
| 31 "Supporting each man on the top of the tide<br>" | |
| 32 "By a finger entwined in his hair.</p>" | |
| 33 | |
| 34 "<P>Just the place for a Snark! I have said it twice:<br>" | |
| 35 "That alone should encourage the crew.<br>" | |
| 36 "Just the place for a Snark! I have said it thrice:<br>" | |
| 37 "What I tell you three times is true.</p>" | |
| 38 | |
| 39 "<p>The crew was complete: it included a Boots-<br>" | |
| 40 "A maker of Bonnets and Hoods-<br>" | |
| 41 "A Barrister, brought to arrange their disputes-<br>" | |
| 42 "And a Broker, to value their goods.</p>" | |
| 43 | |
| 44 "<p>A Billiard-marker, whose skill was immense,<br>" | |
| 45 "Might perhaps have won more than his share-<br>" | |
| 46 "But a Banker, engaged at enormous expense,<br>" | |
| 47 "Had the whole of their cash in his care.</p>" | |
| 48 | |
| 49 "<p>There was also a Beaver, that paced on the deck,<br>" | |
| 50 "Or would sit making lace in the bow:<br>" | |
| 51 "And had often (the Bellman said) saved them from wreck,<br>" | |
| 52 "Though none of the sailors knew how.</p>" | |
| 53 | |
| 54 "<p>There was one who was famed for the number of things<br>" | |
| 55 "He forgot when he entered the ship:<br>" | |
| 56 "His umbrella, his watch, all his jewels and rings,<br>" | |
| 57 "And the clothes he had bought for the trip.</p>" | |
| 58 "<div id=\"a\">" | |
| 59 "<p>He had forty-two boxes, all carefully packed,<br>" | |
| 60 "With his name painted clearly on each:<br>" | |
| 61 "But, since he omitted to mention the fact,<br>" | |
| 62 "They were all left behind on the beach.</p>" | |
| 63 "</div>" | |
| 64 | |
| 65 "<p>The loss of his clothes hardly mattered, because<br>" | |
| 66 "He had seven coats on when he came,<br>" | |
| 67 "With three pair of boots-but the worst of it was,<br>" | |
| 68 "He had wholly forgotten his name.</p>" | |
| 69 | |
| 70 "<p>He would answer to \"Hi!\" or to any loud cry,<br>" | |
| 71 "Such as \"Fry me!\" or \"Fritter my wig!\"<br>" | |
| 72 "To \"What-you-may-call-um!\" or \"What-was-his-name!\"<br>" | |
| 73 "But especially \"Thing-um-a-jig!\"</p>" | |
| 74 | |
| 75 "<p>While, for those who preferred a more forcible word,<br>" | |
| 76 "He had different names from these:<br>" | |
| 77 "His intimate friends called him \"Candle-ends,\"<br>" | |
| 78 "And his enemies \"Toasted-cheese.\"</p>" | |
| 79 | |
| 80 "<p>\"His form is ungainly-his intellect small-\"<br>" | |
| 81 "(So the Bellman would often remark)<br>" | |
| 82 "\"But his courage is perfect! And that, after all,<br>" | |
| 83 "Is the thing that one needs with a Snark.\"</p>" | |
| 84 | |
| 85 "<p>He would joke with hyenas, returning their stare<br>" | |
| 86 "With an impudent wag of the head:<br>" | |
| 87 "And he once went a walk, paw-in-paw, with a bear,<br>" | |
| 88 "\"Just to keep up its spirits,\" he said.</p>" | |
| 89 | |
| 90 "<p>He came as a Baker: but owned, when too late-<br>" | |
| 91 "And it drove the poor Bellman half-mad-<br>" | |
| 92 "He could only bake Bride-cake-for which, I may state,<br>" | |
| 93 "No materials were to be had.</p>" | |
| 94 | |
| 95 "<p>The last of the crew needs especial remark,<br>" | |
| 96 "Though he looked an incredible dunce:<br>" | |
| 97 "He had just one idea-but, that one being \"Snark,\"<br>" | |
| 98 "The good Bellman engaged him at once.</p>" | |
| 99 | |
| 100 "<p>He came as a Butcher: but gravely declared,<br>" | |
| 101 "When the ship had been sailing a week,<br>" | |
| 102 "He could only kill Beavers. The Bellman looked scared,<br>" | |
| 103 "And was almost too frightened to speak:</p>" | |
| 104 | |
| 105 "<p>But at length he explained, in a tremulous tone,<br>" | |
| 106 "There was only one Beaver on board;<br>" | |
| 107 "And that was a tame one he had of his own,<br>" | |
| 108 "Whose death would be deeply deplored.</p>" | |
| 109 | |
| 110 "<div id=\"b\">" | |
| 111 "<p>The Beaver, who happened to hear the remark,<br>" | |
| 112 "Protested, with tears in its eyes,<br>" | |
| 113 "That not even the rapture of hunting the Snark<br>" | |
| 114 "Could atone for that dismal surprise!</p>" | |
| 115 "</div>" | |
| 116 | |
| 117 "<p style=\"-mupdf-leading:7pt;\">It strongly advised that the Butcher should be<br>" | |
| 118 "Conveyed in a separate ship:<br>" | |
| 119 "But the Bellman declared that would never agree<br>" | |
| 120 "With the plans he had made for the trip:</p>" | |
| 121 | |
| 122 "<p style=\"-mupdf-leading:11pt;\">Navigation was always a difficult art,<br>" | |
| 123 "Though with only one ship and one bell:<br>" | |
| 124 "And he feared he must really decline, for his part,<br>" | |
| 125 "Undertaking another as well.</p>" | |
| 126 | |
| 127 "<p style=\"-mupdf-leading:15pt;\">The Beaver's best course was, no doubt, to procure<br>" | |
| 128 "A second-hand dagger-proof coat-<br>" | |
| 129 "So the Baker advised it-and next, to insure<br>" | |
| 130 "Its life in some Office of note:</p>" | |
| 131 | |
| 132 "<p style=\"-mupdf-leading:20pt;\">This the Banker suggested, and offered for hire<br>" | |
| 133 "(On moderate terms), or for sale,<br>" | |
| 134 "Two excellent Policies, one Against Fire,<br>" | |
| 135 "And one Against Damage From Hail.</p>" | |
| 136 | |
| 137 "<p style=\"-mupdf-leading:30pt;\">Yet still, ever after that sorrowful day,<br>" | |
| 138 "Whenever the Butcher was by,<br>" | |
| 139 "The Beaver kept looking the opposite way,<br>" | |
| 140 "And appeared unaccountably shy.</p>" | |
| 141 ; | |
| 142 | |
| 143 #define MAX_CAST_MEMBERS 32 | |
| 144 | |
| 145 typedef struct { | |
| 146 const char *title; | |
| 147 const char *director; | |
| 148 const char *year; | |
| 149 const char *cast[MAX_CAST_MEMBERS]; | |
| 150 } film_t; | |
| 151 | |
| 152 static const film_t films[] = | |
| 153 { | |
| 154 { | |
| 155 "Pulp Fiction", | |
| 156 "Quentin Tarantino", | |
| 157 "1994", | |
| 158 { | |
| 159 "John Travolta", | |
| 160 "Samuel L Jackson", | |
| 161 "Uma Thurman", | |
| 162 "Bruce Willis", | |
| 163 "Ving Rhames", | |
| 164 "Harvey Keitel", | |
| 165 "Tim Roth", | |
| 166 "Bridget Fonda" | |
| 167 } | |
| 168 }, | |
| 169 | |
| 170 { | |
| 171 "The Usual Suspects", | |
| 172 "Bryan Singer", | |
| 173 "1995", | |
| 174 { | |
| 175 "Kevin Spacey", | |
| 176 "Gabriel Byrne", | |
| 177 "Chazz Palminteri", | |
| 178 "Benicio Del Toro", | |
| 179 "Kevin Pollak", | |
| 180 "Pete Postlethwaite", | |
| 181 "Steven Baldwin" | |
| 182 } | |
| 183 | |
| 184 }, | |
| 185 | |
| 186 { | |
| 187 "Fight Club", | |
| 188 "David Fincher", | |
| 189 "1999", | |
| 190 { | |
| 191 "Brad Pitt", | |
| 192 "Edward Norton", | |
| 193 "Helena Bonham Carter" | |
| 194 } | |
| 195 } | |
| 196 }; | |
| 197 | |
| 198 const char *festival_template = | |
| 199 "<html><head><title>Why do we have a title? Why not?</title></head>" | |
| 200 "<body><h1 style=\"text-align:center\">Hook Norton Film Festival</h1>" | |
| 201 "<ol>" | |
| 202 "<li id=\"filmtemplate\">" | |
| 203 "<b id=\"filmtitle\"></b>" | |
| 204 "<dl>" | |
| 205 "<dt>Director<dd id=\"director\">" | |
| 206 "<dt>Release Year<dd id=\"filmyear\">" | |
| 207 "<dt>Cast<dd id=\"cast\">" | |
| 208 "</dl>" | |
| 209 "</li>" | |
| 210 "<ul>" | |
| 211 "</body></html"; | |
| 212 | |
| 213 | |
| 214 static int toc_rectfn(fz_context *ctx, void *ref, int num, fz_rect filled, fz_rect *rect, fz_matrix *ctm, fz_rect *mediabox) | |
| 215 { | |
| 216 if (num == 0) | |
| 217 { | |
| 218 rect->x0 = 100; | |
| 219 rect->y0 = 200; | |
| 220 rect->x1 = 175; | |
| 221 rect->y1 = 300; | |
| 222 } | |
| 223 else | |
| 224 { | |
| 225 rect->x0 = 10; | |
| 226 rect->y0 = 50; | |
| 227 rect->x1 = 290; | |
| 228 rect->y1 = 350; | |
| 229 } | |
| 230 mediabox->x0 = 0; | |
| 231 mediabox->y0 = 0; | |
| 232 mediabox->x1 = 300; | |
| 233 mediabox->y1 = 400; | |
| 234 return 1; | |
| 235 } | |
| 236 | |
| 237 static void toc_contentfn(fz_context *ctx, void *ref, const fz_write_story_positions *positions, fz_buffer *buffer) | |
| 238 { | |
| 239 int i; | |
| 240 fz_append_string(ctx, buffer, | |
| 241 "<!DOCTYPE html>\n" | |
| 242 "<style>\n" | |
| 243 "#a { margin: 30px; }\n" | |
| 244 "#b { margin: 20px; }\n" | |
| 245 "#c { margin: 5px; }\n" | |
| 246 "#a { border: 1px solid red; }\n" | |
| 247 "#b { border: 1px solid green; }\n" | |
| 248 "#c { border: 1px solid blue; }\n" | |
| 249 "</style>\n" | |
| 250 "<body>\n" | |
| 251 "<h2>Contents</h2>\n" | |
| 252 "<ol>\n" | |
| 253 ); | |
| 254 for (i=0; i<positions->num; ++i) | |
| 255 { | |
| 256 fz_write_story_position *position = &positions->positions[i]; | |
| 257 | |
| 258 fz_append_printf(ctx, buffer, | |
| 259 " <li>page=%i depth=%i heading=%i id='%s' rect=(%f %f %f %f) text='<b>%s</b>' open_close=%i\n", | |
| 260 position->page_num, | |
| 261 position->element.depth, | |
| 262 position->element.heading, | |
| 263 (position->element.id) ? position->element.id : "", | |
| 264 position->element.rect.x0, | |
| 265 position->element.rect.y0, | |
| 266 position->element.rect.x1, | |
| 267 position->element.rect.y1, | |
| 268 (position->element.text) ? position->element.text : "", | |
| 269 position->element.open_close | |
| 270 ); | |
| 271 } | |
| 272 fz_append_string(ctx, buffer, "</ol>\n"); | |
| 273 fz_append_string(ctx, buffer, | |
| 274 "<h1>Section the first</h1>\n" | |
| 275 "<p>Blah.\n" | |
| 276 "<h1>Section the second</h1>\n" | |
| 277 "<p>Blah blah.\n" | |
| 278 "<h2>Subsection</h2>\n" | |
| 279 "<p>Blah blah blah.\n" | |
| 280 "<p>Blah blah blah.\n" | |
| 281 "<p>Blah blah blah.\n" | |
| 282 "<h1>Section the third</h1>\n" | |
| 283 "<p>Blah blah.\n" | |
| 284 "</body>\n" | |
| 285 ); | |
| 286 { | |
| 287 const char *data = fz_string_from_buffer(ctx, buffer); | |
| 288 printf( "======== Html content: ========\n"); | |
| 289 printf( "%s", data); | |
| 290 printf( "========\n"); | |
| 291 } | |
| 292 } | |
| 293 | |
| 294 static void toc_pagefn(fz_context *ctx, void *ref, int page_num, fz_rect mediabox, fz_device *dev, int after) | |
| 295 { | |
| 296 fz_path *path = fz_new_path(ctx); | |
| 297 fz_matrix ctm = fz_identity; | |
| 298 printf("toc_pagefn(): ref=%p page_num=%i dev=%p after=%i\n", ref, page_num, dev, after); | |
| 299 if (after) | |
| 300 { | |
| 301 float rgb[3] = { 0.75, 0.25, 0.125}; | |
| 302 fz_moveto(ctx, path, 50, 50); | |
| 303 fz_lineto(ctx, path, 100, 200); | |
| 304 fz_lineto(ctx, path, 50, 200); | |
| 305 fz_closepath(ctx, path); | |
| 306 fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgb, 0.9f /*alpha*/, fz_default_color_params); | |
| 307 fz_drop_path(ctx, path); | |
| 308 } | |
| 309 else | |
| 310 { | |
| 311 float rgb[3] = { 0.125, 0.25, 0.75}; | |
| 312 fz_moveto(ctx, path, 50, 50); | |
| 313 fz_lineto(ctx, path, 50, 200); | |
| 314 fz_lineto(ctx, path, 100, 50); | |
| 315 fz_closepath(ctx, path); | |
| 316 fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgb, 0.9f /*alpha*/, fz_default_color_params); | |
| 317 fz_drop_path(ctx, path); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 static void test_write_stabilized_story(fz_context *ctx) | |
| 322 { | |
| 323 fz_document_writer *writer = fz_new_pdf_writer(ctx, "out_toc.pdf", ""); | |
| 324 fz_write_stabilized_story( | |
| 325 ctx, | |
| 326 writer, | |
| 327 "" /*user_css*/, | |
| 328 11 /*em*/, | |
| 329 toc_contentfn, | |
| 330 NULL /*contentfn_ref*/, | |
| 331 toc_rectfn, | |
| 332 NULL /*rectfn_ref*/, | |
| 333 toc_pagefn /*pagefn*/, | |
| 334 NULL /*pagefn_ref*/, | |
| 335 NULL /* archive */ | |
| 336 ); | |
| 337 fz_close_document_writer(ctx, writer); | |
| 338 fz_drop_document_writer(ctx, writer); | |
| 339 } | |
| 340 | |
| 341 int main(int argc, const char *argv[]) | |
| 342 { | |
| 343 fz_context *ctx; | |
| 344 fz_document_writer *writer = NULL; | |
| 345 fz_story *story = NULL; | |
| 346 fz_buffer *buf = NULL; | |
| 347 fz_device *dev = NULL; | |
| 348 fz_archive *archive = NULL; | |
| 349 fz_rect mediabox = { 0, 0, 512, 640 }; | |
| 350 float margin = 10; | |
| 351 int more; | |
| 352 | |
| 353 ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); | |
| 354 if (ctx == NULL) | |
| 355 { | |
| 356 fprintf(stderr, "Failed to create context"); | |
| 357 return 1; | |
| 358 } | |
| 359 | |
| 360 fz_var(writer); | |
| 361 fz_var(story); | |
| 362 fz_var(buf); | |
| 363 fz_var(dev); | |
| 364 fz_var(archive); | |
| 365 | |
| 366 /* First one made with precooked content. */ | |
| 367 fz_try(ctx) | |
| 368 { | |
| 369 writer = fz_new_pdf_writer(ctx, "out.pdf", ""); | |
| 370 | |
| 371 buf = fz_new_buffer_from_copied_data(ctx, (unsigned char *)snark, strlen(snark)+1); | |
| 372 | |
| 373 archive = fz_open_directory(ctx, "."); | |
| 374 | |
| 375 story = fz_new_story(ctx, buf, "", 11, archive); | |
| 376 | |
| 377 do | |
| 378 { | |
| 379 fz_rect where; | |
| 380 fz_rect filled; | |
| 381 | |
| 382 where.x0 = mediabox.x0 + margin; | |
| 383 where.y0 = mediabox.y0 + margin; | |
| 384 where.x1 = mediabox.x1 - margin; | |
| 385 where.y1 = mediabox.y1 - margin; | |
| 386 | |
| 387 dev = fz_begin_page(ctx, writer, mediabox); | |
| 388 | |
| 389 more = fz_place_story(ctx, story, where, &filled); | |
| 390 | |
| 391 fz_draw_story(ctx, story, dev, fz_identity); | |
| 392 | |
| 393 fz_end_page(ctx, writer); | |
| 394 } | |
| 395 while (more); | |
| 396 | |
| 397 fz_close_document_writer(ctx, writer); | |
| 398 } | |
| 399 fz_always(ctx) | |
| 400 { | |
| 401 fz_drop_story(ctx, story); | |
| 402 fz_drop_buffer(ctx, buf); | |
| 403 fz_drop_document_writer(ctx, writer); | |
| 404 fz_drop_archive(ctx, archive); | |
| 405 } | |
| 406 fz_catch(ctx) | |
| 407 { | |
| 408 fz_report_error(ctx); | |
| 409 } | |
| 410 | |
| 411 /* Now one made with programmatic content. */ | |
| 412 writer = NULL; | |
| 413 buf = NULL; | |
| 414 story = NULL; | |
| 415 dev = NULL; | |
| 416 | |
| 417 fz_try(ctx) | |
| 418 { | |
| 419 fz_xml *dom, *body, *tmp; | |
| 420 | |
| 421 writer = fz_new_pdf_writer(ctx, "out2.pdf", ""); | |
| 422 | |
| 423 story = fz_new_story(ctx, NULL, "", 11, NULL); | |
| 424 | |
| 425 dom = fz_story_document(ctx, story); | |
| 426 | |
| 427 body = fz_dom_body(ctx, dom); | |
| 428 | |
| 429 fz_dom_append_child(ctx, body, fz_dom_create_text_node(ctx, dom, "This is some text.")); | |
| 430 tmp = fz_dom_create_element(ctx, dom, "b"); | |
| 431 fz_dom_append_child(ctx, body, tmp); | |
| 432 fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, "This is some bold text.")); | |
| 433 fz_dom_append_child(ctx, body, fz_dom_create_text_node(ctx, dom, "This is some normal text.")); | |
| 434 | |
| 435 do | |
| 436 { | |
| 437 fz_rect where; | |
| 438 fz_rect filled; | |
| 439 | |
| 440 where.x0 = mediabox.x0 + margin; | |
| 441 where.y0 = mediabox.y0 + margin; | |
| 442 where.x1 = mediabox.x1 - margin; | |
| 443 where.y1 = mediabox.y1 - margin; | |
| 444 | |
| 445 dev = fz_begin_page(ctx, writer, mediabox); | |
| 446 | |
| 447 more = fz_place_story(ctx, story, where, &filled); | |
| 448 | |
| 449 fz_draw_story(ctx, story, dev, fz_identity); | |
| 450 | |
| 451 fz_end_page(ctx, writer); | |
| 452 } | |
| 453 while (more); | |
| 454 | |
| 455 fz_close_document_writer(ctx, writer); | |
| 456 } | |
| 457 fz_always(ctx) | |
| 458 { | |
| 459 fz_drop_story(ctx, story); | |
| 460 fz_drop_buffer(ctx, buf); | |
| 461 fz_drop_document_writer(ctx, writer); | |
| 462 } | |
| 463 fz_catch(ctx) | |
| 464 { | |
| 465 fz_report_error(ctx); | |
| 466 } | |
| 467 | |
| 468 /* Now a combination of the two. */ | |
| 469 writer = NULL; | |
| 470 buf = NULL; | |
| 471 story = NULL; | |
| 472 dev = NULL; | |
| 473 | |
| 474 fz_try(ctx) | |
| 475 { | |
| 476 fz_xml *dom, *body, *tmp, *templat; | |
| 477 int i, j; | |
| 478 | |
| 479 writer = fz_new_pdf_writer(ctx, "out3.pdf", ""); | |
| 480 | |
| 481 buf = fz_new_buffer_from_copied_data(ctx, (unsigned char *)festival_template, strlen(festival_template)+1); | |
| 482 story = fz_new_story(ctx, buf, "", 11, NULL); | |
| 483 | |
| 484 dom = fz_story_document(ctx, story); | |
| 485 | |
| 486 body = fz_dom_body(ctx, dom); | |
| 487 | |
| 488 templat = fz_dom_find(ctx, body, NULL, "id", "filmtemplate"); | |
| 489 | |
| 490 for (i = 0; i < nelem(films); i++) | |
| 491 { | |
| 492 fz_xml *film = fz_dom_clone(ctx, templat); | |
| 493 | |
| 494 /* Now fill in some of the template. */ | |
| 495 tmp = fz_dom_find(ctx, film, NULL, "id", "filmtitle"); | |
| 496 fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].title)); | |
| 497 | |
| 498 tmp = fz_dom_find(ctx, film, NULL, "id", "director"); | |
| 499 fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].director)); | |
| 500 | |
| 501 tmp = fz_dom_find(ctx, film, NULL, "id", "filmyear"); | |
| 502 fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].year)); | |
| 503 | |
| 504 tmp = fz_dom_find(ctx, film, NULL, "id", "cast"); | |
| 505 for (j = 0; j < MAX_CAST_MEMBERS; j++) | |
| 506 { | |
| 507 if (films[i].cast[j] == NULL) | |
| 508 break; | |
| 509 fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].cast[j])); | |
| 510 fz_dom_append_child(ctx, tmp, fz_dom_create_element(ctx, dom, "br")); | |
| 511 } | |
| 512 | |
| 513 fz_dom_append_child(ctx, fz_dom_parent(ctx, templat), film); | |
| 514 } | |
| 515 | |
| 516 /* Remove the template. */ | |
| 517 fz_dom_remove(ctx, templat); | |
| 518 | |
| 519 do | |
| 520 { | |
| 521 fz_rect where; | |
| 522 fz_rect filled; | |
| 523 | |
| 524 where.x0 = mediabox.x0 + margin; | |
| 525 where.y0 = mediabox.y0 + margin; | |
| 526 where.x1 = mediabox.x1 - margin; | |
| 527 where.y1 = mediabox.y1 - margin; | |
| 528 | |
| 529 dev = fz_begin_page(ctx, writer, mediabox); | |
| 530 | |
| 531 more = fz_place_story(ctx, story, where, &filled); | |
| 532 | |
| 533 fz_draw_story(ctx, story, dev, fz_identity); | |
| 534 | |
| 535 fz_end_page(ctx, writer); | |
| 536 } | |
| 537 while (more); | |
| 538 | |
| 539 fz_close_document_writer(ctx, writer); | |
| 540 } | |
| 541 fz_always(ctx) | |
| 542 { | |
| 543 fz_drop_story(ctx, story); | |
| 544 fz_drop_buffer(ctx, buf); | |
| 545 fz_drop_document_writer(ctx, writer); | |
| 546 } | |
| 547 fz_catch(ctx) | |
| 548 { | |
| 549 fz_report_error(ctx); | |
| 550 } | |
| 551 | |
| 552 test_write_stabilized_story(ctx); | |
| 553 | |
| 554 fz_drop_context(ctx); | |
| 555 | |
| 556 return 0; | |
| 557 } |
