#include "mupdf/fitz.h" #include "mupdf/pdf.h" #include #include const char snark[] = "" "" "" "
" "A" "
" "
" "
" "C" "
" "
" "
" "

The hunting of the Snark

" "
" "

\"Just the place for a Snark!\" the Bellman cried,
" "As he landed his crew with care;
" "Supporting each man on the top of the tide
" "By a finger entwined in his hair.

" "

Just the place for a Snark! I have said it twice:
" "That alone should encourage the crew.
" "Just the place for a Snark! I have said it thrice:
" "What I tell you three times is true.

" "

The crew was complete: it included a Boots-
" "A maker of Bonnets and Hoods-
" "A Barrister, brought to arrange their disputes-
" "And a Broker, to value their goods.

" "

A Billiard-marker, whose skill was immense,
" "Might perhaps have won more than his share-
" "But a Banker, engaged at enormous expense,
" "Had the whole of their cash in his care.

" "

There was also a Beaver, that paced on the deck,
" "Or would sit making lace in the bow:
" "And had often (the Bellman said) saved them from wreck,
" "Though none of the sailors knew how.

" "

There was one who was famed for the number of things
" "He forgot when he entered the ship:
" "His umbrella, his watch, all his jewels and rings,
" "And the clothes he had bought for the trip.

" "
" "

He had forty-two boxes, all carefully packed,
" "With his name painted clearly on each:
" "But, since he omitted to mention the fact,
" "They were all left behind on the beach.

" "
" "

The loss of his clothes hardly mattered, because
" "He had seven coats on when he came,
" "With three pair of boots-but the worst of it was,
" "He had wholly forgotten his name.

" "

He would answer to \"Hi!\" or to any loud cry,
" "Such as \"Fry me!\" or \"Fritter my wig!\"
" "To \"What-you-may-call-um!\" or \"What-was-his-name!\"
" "But especially \"Thing-um-a-jig!\"

" "

While, for those who preferred a more forcible word,
" "He had different names from these:
" "His intimate friends called him \"Candle-ends,\"
" "And his enemies \"Toasted-cheese.\"

" "

\"His form is ungainly-his intellect small-\"
" "(So the Bellman would often remark)
" "\"But his courage is perfect! And that, after all,
" "Is the thing that one needs with a Snark.\"

" "

He would joke with hyenas, returning their stare
" "With an impudent wag of the head:
" "And he once went a walk, paw-in-paw, with a bear,
" "\"Just to keep up its spirits,\" he said.

" "

He came as a Baker: but owned, when too late-
" "And it drove the poor Bellman half-mad-
" "He could only bake Bride-cake-for which, I may state,
" "No materials were to be had.

" "

The last of the crew needs especial remark,
" "Though he looked an incredible dunce:
" "He had just one idea-but, that one being \"Snark,\"
" "The good Bellman engaged him at once.

" "

He came as a Butcher: but gravely declared,
" "When the ship had been sailing a week,
" "He could only kill Beavers. The Bellman looked scared,
" "And was almost too frightened to speak:

" "

But at length he explained, in a tremulous tone,
" "There was only one Beaver on board;
" "And that was a tame one he had of his own,
" "Whose death would be deeply deplored.

" "
" "

The Beaver, who happened to hear the remark,
" "Protested, with tears in its eyes,
" "That not even the rapture of hunting the Snark
" "Could atone for that dismal surprise!

" "
" "

It strongly advised that the Butcher should be
" "Conveyed in a separate ship:
" "But the Bellman declared that would never agree
" "With the plans he had made for the trip:

" "

Navigation was always a difficult art,
" "Though with only one ship and one bell:
" "And he feared he must really decline, for his part,
" "Undertaking another as well.

" "

The Beaver's best course was, no doubt, to procure
" "A second-hand dagger-proof coat-
" "So the Baker advised it-and next, to insure
" "Its life in some Office of note:

" "

This the Banker suggested, and offered for hire
" "(On moderate terms), or for sale,
" "Two excellent Policies, one Against Fire,
" "And one Against Damage From Hail.

" "

Yet still, ever after that sorrowful day,
" "Whenever the Butcher was by,
" "The Beaver kept looking the opposite way,
" "And appeared unaccountably shy.

" ; #define MAX_CAST_MEMBERS 32 typedef struct { const char *title; const char *director; const char *year; const char *cast[MAX_CAST_MEMBERS]; } film_t; static const film_t films[] = { { "Pulp Fiction", "Quentin Tarantino", "1994", { "John Travolta", "Samuel L Jackson", "Uma Thurman", "Bruce Willis", "Ving Rhames", "Harvey Keitel", "Tim Roth", "Bridget Fonda" } }, { "The Usual Suspects", "Bryan Singer", "1995", { "Kevin Spacey", "Gabriel Byrne", "Chazz Palminteri", "Benicio Del Toro", "Kevin Pollak", "Pete Postlethwaite", "Steven Baldwin" } }, { "Fight Club", "David Fincher", "1999", { "Brad Pitt", "Edward Norton", "Helena Bonham Carter" } } }; const char *festival_template = "Why do we have a title? Why not?" "

Hook Norton Film Festival

" "
    " "
  1. " "" "
    " "
    Director
    " "
    Release Year
    " "
    Cast
    " "
    " "
  2. " "
      " "x0 = 100; rect->y0 = 200; rect->x1 = 175; rect->y1 = 300; } else { rect->x0 = 10; rect->y0 = 50; rect->x1 = 290; rect->y1 = 350; } mediabox->x0 = 0; mediabox->y0 = 0; mediabox->x1 = 300; mediabox->y1 = 400; return 1; } static void toc_contentfn(fz_context *ctx, void *ref, const fz_write_story_positions *positions, fz_buffer *buffer) { int i; fz_append_string(ctx, buffer, "\n" "\n" "\n" "

      Contents

      \n" "
        \n" ); for (i=0; inum; ++i) { fz_write_story_position *position = &positions->positions[i]; fz_append_printf(ctx, buffer, "
      1. page=%i depth=%i heading=%i id='%s' rect=(%f %f %f %f) text='%s' open_close=%i\n", position->page_num, position->element.depth, position->element.heading, (position->element.id) ? position->element.id : "", position->element.rect.x0, position->element.rect.y0, position->element.rect.x1, position->element.rect.y1, (position->element.text) ? position->element.text : "", position->element.open_close ); } fz_append_string(ctx, buffer, "
      \n"); fz_append_string(ctx, buffer, "

      Section the first

      \n" "

      Blah.\n" "

      Section the second

      \n" "

      Blah blah.\n" "

      Subsection

      \n" "

      Blah blah blah.\n" "

      Blah blah blah.\n" "

      Blah blah blah.\n" "

      Section the third

      \n" "

      Blah blah.\n" "\n" ); { const char *data = fz_string_from_buffer(ctx, buffer); printf( "======== Html content: ========\n"); printf( "%s", data); printf( "========\n"); } } static void toc_pagefn(fz_context *ctx, void *ref, int page_num, fz_rect mediabox, fz_device *dev, int after) { fz_path *path = fz_new_path(ctx); fz_matrix ctm = fz_identity; printf("toc_pagefn(): ref=%p page_num=%i dev=%p after=%i\n", ref, page_num, dev, after); if (after) { float rgb[3] = { 0.75, 0.25, 0.125}; fz_moveto(ctx, path, 50, 50); fz_lineto(ctx, path, 100, 200); fz_lineto(ctx, path, 50, 200); fz_closepath(ctx, path); fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgb, 0.9 /*alpha*/, fz_default_color_params); fz_drop_path(ctx, path); } else { float rgb[3] = { 0.125, 0.25, 0.75}; fz_moveto(ctx, path, 50, 50); fz_lineto(ctx, path, 50, 200); fz_lineto(ctx, path, 100, 50); fz_closepath(ctx, path); fz_fill_path(ctx, dev, path, 0, ctm, fz_device_rgb(ctx), rgb, 0.9 /*alpha*/, fz_default_color_params); fz_drop_path(ctx, path); } } static void test_write_stabilized_story(fz_context *ctx) { fz_document_writer *writer = fz_new_pdf_writer(ctx, "out_toc.pdf", ""); fz_write_stabilized_story( ctx, writer, "" /*user_css*/, 11 /*em*/, toc_contentfn, NULL /*contentfn_ref*/, toc_rectfn, NULL /*rectfn_ref*/, toc_pagefn /*pagefn*/, NULL /*pagefn_ref*/, NULL /* archive */ ); fz_close_document_writer(ctx, writer); fz_drop_document_writer(ctx, writer); } int main(int argc, const char *argv[]) { fz_context *ctx; fz_document_writer *writer = NULL; fz_story *story = NULL; fz_buffer *buf = NULL; fz_device *dev = NULL; fz_archive *archive = NULL; fz_rect mediabox = { 0, 0, 512, 640 }; float margin = 10; int more; ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); if (ctx == NULL) { fprintf(stderr, "Failed to create context"); return 1; } fz_var(writer); fz_var(story); fz_var(buf); fz_var(dev); fz_var(archive); /* First one made with precooked content. */ fz_try(ctx) { writer = fz_new_pdf_writer(ctx, "out.pdf", ""); buf = fz_new_buffer_from_copied_data(ctx, snark, strlen(snark)+1); archive = fz_open_directory(ctx, "."); story = fz_new_story(ctx, buf, "", 11, archive); do { fz_rect where; fz_rect filled; where.x0 = mediabox.x0 + margin; where.y0 = mediabox.y0 + margin; where.x1 = mediabox.x1 - margin; where.y1 = mediabox.y1 - margin; dev = fz_begin_page(ctx, writer, mediabox); more = fz_place_story(ctx, story, where, &filled); fz_draw_story(ctx, story, dev, fz_identity); fz_end_page(ctx, writer); } while (more); fz_close_document_writer(ctx, writer); } fz_always(ctx) { fz_drop_story(ctx, story); fz_drop_buffer(ctx, buf); fz_drop_document_writer(ctx, writer); fz_drop_archive(ctx, archive); } fz_catch(ctx) { fprintf(stderr, "Failed with %s", fz_caught_message(ctx)); } /* Now one made with programmatic content. */ writer = NULL; buf = NULL; story = NULL; dev = NULL; fz_try(ctx) { fz_xml *dom, *body, *tmp; writer = fz_new_pdf_writer(ctx, "out2.pdf", ""); story = fz_new_story(ctx, NULL, "", 11, NULL); dom = fz_story_document(ctx, story); body = fz_dom_body(ctx, dom); fz_dom_append_child(ctx, body, fz_dom_create_text_node(ctx, dom, "This is some text.")); tmp = fz_dom_create_element(ctx, dom, "b"); fz_dom_append_child(ctx, body, tmp); fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, "This is some bold text.")); fz_dom_append_child(ctx, body, fz_dom_create_text_node(ctx, dom, "This is some normal text.")); do { fz_rect where; fz_rect filled; where.x0 = mediabox.x0 + margin; where.y0 = mediabox.y0 + margin; where.x1 = mediabox.x1 - margin; where.y1 = mediabox.y1 - margin; dev = fz_begin_page(ctx, writer, mediabox); more = fz_place_story(ctx, story, where, &filled); fz_draw_story(ctx, story, dev, fz_identity); fz_end_page(ctx, writer); } while (more); fz_close_document_writer(ctx, writer); } fz_always(ctx) { fz_drop_story(ctx, story); fz_drop_buffer(ctx, buf); fz_drop_document_writer(ctx, writer); } fz_catch(ctx) { fprintf(stderr, "Failed with %s", fz_caught_message(ctx)); } /* Now a combination of the two. */ writer = NULL; buf = NULL; story = NULL; dev = NULL; fz_try(ctx) { fz_xml *dom, *body, *tmp, *templat; int i, j; writer = fz_new_pdf_writer(ctx, "out3.pdf", ""); buf = fz_new_buffer_from_copied_data(ctx, festival_template, strlen(festival_template)+1); story = fz_new_story(ctx, buf, "", 11, NULL); dom = fz_story_document(ctx, story); body = fz_dom_body(ctx, dom); templat = fz_dom_find(ctx, body, NULL, "id", "filmtemplate"); for (i = 0; i < nelem(films); i++) { fz_xml *film = fz_dom_clone(ctx, templat); /* Now fill in some of the template. */ tmp = fz_dom_find(ctx, film, NULL, "id", "filmtitle"); fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].title)); tmp = fz_dom_find(ctx, film, NULL, "id", "director"); fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].director)); tmp = fz_dom_find(ctx, film, NULL, "id", "filmyear"); fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].year)); tmp = fz_dom_find(ctx, film, NULL, "id", "cast"); for (j = 0; j < MAX_CAST_MEMBERS; j++) { if (films[i].cast[j] == NULL) break; fz_dom_append_child(ctx, tmp, fz_dom_create_text_node(ctx, dom, films[i].cast[j])); fz_dom_append_child(ctx, tmp, fz_dom_create_element(ctx, dom, "br")); } fz_dom_append_child(ctx, fz_dom_parent(ctx, templat), film); } /* Remove the template. */ fz_dom_remove(ctx, templat); do { fz_rect where; fz_rect filled; where.x0 = mediabox.x0 + margin; where.y0 = mediabox.y0 + margin; where.x1 = mediabox.x1 - margin; where.y1 = mediabox.y1 - margin; dev = fz_begin_page(ctx, writer, mediabox); more = fz_place_story(ctx, story, where, &filled); fz_draw_story(ctx, story, dev, fz_identity); fz_end_page(ctx, writer); } while (more); fz_close_document_writer(ctx, writer); } fz_always(ctx) { fz_drop_story(ctx, story); fz_drop_buffer(ctx, buf); fz_drop_document_writer(ctx, writer); } fz_catch(ctx) { fprintf(stderr, "Failed with %s", fz_caught_message(ctx)); } test_write_stabilized_story(ctx); fz_drop_context(ctx); return 0; }