home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / test / pdftest.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  25.7 KB  |  1,021 lines  |  [TEXT/CWIE]

  1. /*---------------------------------------------------------------------------*
  2.  |              PDFlib - A library for generating PDF on the fly             |
  3.  +---------------------------------------------------------------------------+
  4.  | Copyright (c) 1997-2001 PDFlib GmbH and Thomas Merz. All rights reserved. |
  5.  +---------------------------------------------------------------------------+
  6.  |    This software is NOT in the public domain.  It can be used under two   |
  7.  |    substantially different licensing terms:                               |
  8.  |                                                                           |
  9.  |    The commercial license is available for a fee, and allows you to       |
  10.  |    - ship a commercial product based on PDFlib                            |
  11.  |    - implement commercial Web services with PDFlib                        |
  12.  |    - distribute (free or commercial) software when the source code is     |
  13.  |      not made available                                                   |
  14.  |    Details can be found in the file PDFlib-license.pdf.                   |
  15.  |                                                                           |
  16.  |    The "Aladdin Free Public License" doesn't require any license fee,     |
  17.  |    and allows you to                                                      |
  18.  |    - develop and distribute PDFlib-based software for which the complete  |
  19.  |      source code is made available                                        |
  20.  |    - redistribute PDFlib non-commercially under certain conditions        |
  21.  |    - redistribute PDFlib on digital media for a fee if the complete       |
  22.  |      contents of the media are freely redistributable                     |
  23.  |    Details can be found in the file aladdin-license.pdf.                  |
  24.  |                                                                           |
  25.  |    These conditions extend to ports to other programming languages.       |
  26.  |    PDFlib is distributed with no warranty of any kind. Commercial users,  |
  27.  |    however, will receive warranty and support statements in writing.      |
  28.  *---------------------------------------------------------------------------*/
  29.  
  30. /* $Id: pdftest.c,v 1.16 2001/04/02 14:14:40 rjs Exp $
  31.  *
  32.  * Test bed and sample application for PDFlib
  33.  */
  34.  
  35. /*
  36.  * We would prefer to receive this from a central config file but
  37.  * alas, CodeWarrior's support for predefined symbols is so clumsy...
  38.  */
  39.  
  40. #if __POWERPC__ || __CFM68K__ || __MC68K__
  41. #define MAC
  42. #endif
  43.  
  44. #if defined(__INTEL__) && defined(__MWERKS__)
  45. #define WIN32
  46. #endif
  47.  
  48. #if defined(WIN32) || defined(OS2)
  49. #include <fcntl.h>
  50. #include <io.h>
  51. #endif
  52.  
  53. #include <stdio.h>
  54. #include <string.h>
  55. #include <stdlib.h>
  56. #include <math.h>
  57.  
  58. #include "pdflib.h"
  59.  
  60. #ifdef MVS
  61. #define PDF_SHORTNAMES
  62. #endif
  63.  
  64. /* #define this to create a multi-threaded test program (compile with _MT) */
  65. #undef PDF_WINTHREADS
  66.  
  67. /* Don't clutter output from many threads with messages */
  68. #ifdef PDF_WINTHREADS
  69.  
  70. #define WIN32_LEAN_AND_MEAN
  71.     #include <windows.h>
  72.     #include <process.h>
  73. #undef WIN32_LEAN_AND_MEAN
  74.  
  75. #define MESSAGE(m)        /* */
  76. #define PDF_ENDTHREAD(val)    _endthreadex(val);
  77.  
  78. #else
  79.  
  80. #define MESSAGE(m)        fprintf(stderr, m)
  81. #define PDF_ENDTHREAD(val)    /* */
  82.  
  83. #endif /* PDF_WINTHREADS */
  84.  
  85. /* figure out whether or not we're running on an EBCDIC-based machine */
  86. #define    ASCII_A            0x41
  87. #define PLATFORM_A        'A'
  88. #define EBCDIC_A        0xC1
  89.  
  90. #if (ASCII_A != PLATFORM_A && EBCDIC_A == PLATFORM_A)
  91. #define PDFLIB_EBCDIC
  92. #endif
  93.  
  94. /* build a 4-digit ASCII hex representation of an int,
  95. ** even on EBCDIC platforms.
  96. */
  97. static void bin2ascii_hex(char *buf, int n)
  98. {
  99.     int i;
  100.     static const char digits[] =
  101.     "\060\061\062\063\064\065\066\067\070\071\101\102\103\104\105\106";
  102.  
  103.     for (i = 3; 0 <= i; --i)
  104.     {
  105.     buf[i] = digits[n & 0x0F];
  106.     n >>= 4;
  107.     }
  108.  
  109.     buf[4] = 0;
  110. }
  111.  
  112. /* ------------------------------------------------------------- */
  113. static void
  114. bookmarks(PDF *p)
  115. {
  116. #define UNICODEINFO    "\376\377\000\061\000\056\000\101\0\0"
  117. #define LEFT 50
  118. #define FONTSIZE 24
  119. #define LEAD ((int) (FONTSIZE * 1.5))
  120.  
  121.     unsigned char buf[64], tmp[64];
  122.     int c, i, pos;
  123.     float y=700;
  124.     int level1, level2=0, level3=0, font;
  125.  
  126.     MESSAGE("Bookmark test...");
  127.  
  128.     font = PDF_findfont(p, "Helvetica", "host", 0);
  129.  
  130.     PDF_begin_page(p, a4_width, a4_height);
  131.  
  132.     PDF_setfont(p, font, FONTSIZE);
  133.  
  134.     PDF_show_xy(p, "The bookmarks for this page contain all", LEFT, y-=LEAD);
  135.     PDF_show_xy(p, "Unicode characters.", LEFT, y-=LEAD);
  136.     PDF_show_xy(p, "Depending on the available fonts,", LEFT, y-=LEAD);
  137.     PDF_show_xy(p, "only a certain subset will be visible on", LEFT, y-=LEAD);
  138.     PDF_show_xy(p, "your system.", LEFT, y-=LEAD);
  139.     
  140.     /* private Unicode info entry */
  141.     PDF_set_info(p, "Revision", UNICODEINFO);
  142.  
  143.     /* Generate Unicode bookmarks */
  144.     level1 = PDF_add_bookmark(p, "Unicode bookmarks", 0, 0);
  145.  
  146.  
  147.     for (c = 0; c < 65535; c += 16) {
  148.     if (c % 4096 == 0) {
  149.         sprintf((char *) tmp, "U+%04X", c);
  150.         level2 = PDF_add_bookmark(p, (char *) tmp, level1, 0);
  151.     }
  152.     if (c % 256 == 0) {
  153.         sprintf((char *) tmp, "U+%04X", c);
  154.         level3 = PDF_add_bookmark(p, (char *) tmp, level2, 0);
  155.     }
  156.  
  157.     tmp[0] = '\125';    /* ASCII 'U' */
  158.     tmp[1] = '\053';    /* ASCII '+' */
  159.     bin2ascii_hex((char *) tmp+2, c);
  160.     tmp[6] = '\072';    /* ASCII ':' */
  161.     tmp[7] = '\040';    /* ASCII ' ' */
  162.     tmp[8] = 0;
  163.  
  164.     /* write the Unicode byte order mark */
  165.     strcpy((char *) buf, "\376\377");
  166.  
  167.     for (pos = 0; tmp[pos/2]; /* */ ) {
  168.         buf[2 + pos] = 0;
  169.         pos++;
  170.         buf[2 + pos] = tmp[pos/2];    /* construct Unicode string */
  171.         pos++;
  172.     }
  173.  
  174.     pos += 2;     /* account for the BOM */
  175.     for (i = 0; i < 16; i++) {    /* continue filling buf with chars */
  176.         buf[pos++] = (unsigned char) ((((c+i)) & 0xFF00) >> 8);
  177.         buf[pos++] = (unsigned char) (((c+i)) & 0x00FF);
  178.     }
  179.  
  180.     /* signal end of string with two null bytes */
  181.     buf[pos++] = (unsigned char) 0;
  182.     buf[pos] = (unsigned char) 0;
  183.  
  184.     (void) PDF_add_bookmark(p, (char *) buf, level3, 1);
  185.     }
  186.  
  187.     PDF_end_page(p);
  188.  
  189.     MESSAGE("done\n");
  190.  
  191. #undef FONTSIZE
  192. #undef LEFT
  193. #undef UNICODEINFO
  194. #undef LEAD
  195. }
  196.  
  197. /* ------------------------------------------------------------- */
  198. static void
  199. gif_image(PDF *p)
  200. {
  201.     int    image;
  202.  
  203. #ifndef PDF_SHORTNAMES
  204. #define GIFFILE        "machine.gif"
  205. #else
  206. #define GIFFILE        "machine"
  207. #endif
  208.  
  209.     MESSAGE("GIF test...");
  210.  
  211.     if ((image = PDF_open_image_file(p, "gif", GIFFILE, "", 0)) == -1) {
  212.     fprintf(stderr, "Error: Couldn't analyze GIF image '%s'.\n", GIFFILE);
  213.     return;
  214.     }
  215.  
  216.     PDF_begin_page(p, PDF_get_value(p, "imagewidth", (float) image),
  217.             PDF_get_value(p, "imageheight", (float) image));
  218.  
  219.     (void) PDF_add_bookmark(p, "GIF image", 0, 1);
  220.  
  221.     PDF_place_image(p, image, (float) 0.0, (float) 0.0, (float) 1.0);
  222.     PDF_close_image(p, image);
  223.  
  224.     PDF_end_page(p);
  225.  
  226.     MESSAGE("done\n");
  227.  
  228. #undef GIFFILE
  229. }
  230.  
  231. /* ------------------------------------------------------------- */
  232. static void
  233. png_image(PDF *p)
  234. {
  235.     int    image;
  236.  
  237. #ifndef PDF_SHORTNAMES
  238. #define PNGFILE        "pdflib.png"
  239. #else
  240. #define PNGFILE        "pdflib"
  241. #endif
  242.  
  243.     MESSAGE("PNG test...");
  244.  
  245.     if ((image = PDF_open_image_file(p, "png", PNGFILE, "", 0)) == -1) {
  246.     fprintf(stderr, "Error: Couldn't analyze PNG image '%s'.\n", PNGFILE);
  247.     return;
  248.     }
  249.  
  250.     PDF_begin_page(p, PDF_get_value(p, "imagewidth", (float) image),
  251.             PDF_get_value(p, "imageheight", (float) image));
  252.     (void) PDF_add_bookmark(p, "PNG image", 0, 1);
  253.  
  254.     PDF_place_image(p, image, (float) 0.0, (float) 0.0, (float) 1.0);
  255.     PDF_close_image(p, image);
  256.  
  257.     PDF_end_page(p);
  258.  
  259.     MESSAGE("done\n");
  260.  
  261. #undef PNGFILE
  262. }
  263.  
  264. /* ------------------------------------------------------------- */
  265. static void
  266. tiff_image(PDF *p)
  267. {
  268.     int    image;
  269.  
  270. #ifndef PDF_SHORTNAMES
  271. #define TIFFFILE    "acroweb.tif"
  272. #else
  273. #define TIFFFILE    "acroweb"
  274. #endif
  275.  
  276.     MESSAGE("TIFF test...");
  277.  
  278.     if ((image = PDF_open_image_file(p, "tiff", TIFFFILE, "", 0)) == -1) {
  279.     fprintf(stderr, "Error: Couldn't analyze TIFF image '%s'.\n", TIFFFILE);
  280.     return;
  281.     }
  282.  
  283.     PDF_begin_page(p, PDF_get_value(p, "imagewidth", (float) image),
  284.             PDF_get_value(p, "imageheight", (float) image));
  285.     (void) PDF_add_bookmark(p, "TIFF image", 0, 1);
  286.  
  287.     PDF_place_image(p, image, (float) 0.0, (float) 0.0, (float) 1.0);
  288.     PDF_close_image(p, image);
  289.  
  290.     PDF_end_page(p);
  291.  
  292.     MESSAGE("done\n");
  293.  
  294. #undef TIFFFILE
  295. }
  296.  
  297. /* ------------------------------------------------------------- */
  298. static void
  299. jpeg_image(PDF *p)
  300. {
  301.     int    image;
  302.     float    scale;
  303.  
  304. #ifndef PDF_SHORTNAMES
  305. #define JPEGFILE    "nesrin.jpg"
  306. #else
  307. #define JPEGFILE    "nesrin"
  308. #endif
  309.  
  310.     MESSAGE("JPEG test...");
  311.  
  312.     if ((image = PDF_open_image_file(p, "jpeg", JPEGFILE, "", 0)) == -1) {
  313.     fprintf(stderr, "Error: Couldn't analyze JPEG image '%s'.\n", JPEGFILE);
  314.     return;
  315.     }
  316.  
  317.     PDF_begin_page(p, a4_width, a4_height);
  318.     (void) PDF_add_bookmark(p, "JPEG image", 0, 1);
  319.  
  320.     /* ----------------- first image ------------------- */
  321.     /* fit image to page width */
  322.     scale = (float) a4_width/PDF_get_value(p, "imagewidth", (float) image);
  323.     PDF_place_image(p, image, (float) 0.0, 
  324.         a4_height - PDF_get_value(p, "imageheight", (float) image) * scale,
  325.     scale);
  326.  
  327.     /* ----------------- second image ------------------- */
  328.     scale = (float) 0.5;
  329.     PDF_save(p);
  330.     PDF_rotate(p, (float) 90.0);
  331.     PDF_place_image(p, image, (float) 0.0, (float) (-1 * a4_width), scale);
  332.     PDF_restore(p);
  333.  
  334.     /* ----------------- third image ------------------- */
  335.     scale = (float) 0.25;
  336.     PDF_save(p);
  337.     PDF_rotate(p, (float) 45.0);
  338.     PDF_place_image(p, image, (float) 200.0, (float) 0.0, scale);
  339.     PDF_restore(p);
  340.  
  341.     PDF_close_image(p, image);
  342.  
  343.     PDF_end_page(p);
  344.  
  345.     MESSAGE("done\n");
  346.  
  347. #undef JPEGFILE
  348. }
  349.  
  350. /* ------------------------------------------------------------- */
  351. static void
  352. character_table(PDF *p)
  353. {
  354.     char    text[50];
  355.     int        i, j, font;
  356.     float    x, y;
  357.  
  358. #define LEFT        50
  359. #define TOP        700
  360. #define FONTSIZE    16
  361. #define FONTNAME    "Times-Roman"
  362.  
  363. #define ENCODING    "host"
  364.  
  365.     MESSAGE("Character encoding test...");
  366.  
  367.     font = PDF_findfont(p, FONTNAME, ENCODING, 0);
  368.  
  369.     PDF_begin_page(p, a4_width, a4_height);
  370.  
  371.     (void) PDF_add_bookmark(p, "Host Encoding", 0, 1);
  372.  
  373.     PDF_setfont(p, font, 2*FONTSIZE);
  374.     PDF_show_xy(p, "Host Encoding", LEFT, TOP+2*FONTSIZE);
  375.     PDF_show(p, " (");
  376.     PDF_show(p, PDF_get_parameter(p, "fontencoding", (float) 0));
  377.     PDF_show(p, " )");
  378.  
  379.     PDF_setfont(p, font, FONTSIZE);
  380.     text[1] = 0;
  381.  
  382.     y = TOP;
  383.     for (i = 2; i < 16; i++) {
  384.     y -=  2*FONTSIZE;
  385.     x = LEFT;
  386.     for (j = 0; j < 16; j++) {
  387.         text[0] = (char) (i*16 + j);
  388.         PDF_show_xy(p, text, x, y);
  389.         x += 2*FONTSIZE;
  390.     }
  391.     }
  392.  
  393.     PDF_end_page(p);
  394.  
  395.     MESSAGE("done\n");
  396.  
  397. #undef LEFT
  398. #undef TOP
  399. #undef FONTSIZE
  400. #undef FONTNAME
  401. }
  402.  
  403. /* ------------------------------------------------------------- */
  404. static void
  405. grid(PDF *p)
  406. {
  407. #define STEP        10
  408. #define FONTSIZE    ((float) 10.0)
  409. #define THICK        ((float) 1.0)
  410. #define THIN        ((float) 0.01)
  411.  
  412.     char buf[10];
  413.     float i;
  414.     float width = a4_width, height = a4_height;
  415.     int font;
  416.  
  417.     MESSAGE("Grid test...");
  418.  
  419.     PDF_begin_page(p, width, height);
  420.     (void) PDF_add_bookmark(p, "Grid", 0, 1);
  421.  
  422.     PDF_setlinewidth(p, THIN);
  423.     PDF_setdash(p, (float) 1.0, (float) 2.0);
  424.  
  425.     /* draw vertical lines */
  426.     for (i = 0; i < width; i += STEP) {
  427.     PDF_save(p);
  428.     if ((int) i % 100 == 0)
  429.         PDF_setlinewidth(p, THICK);
  430.     if ((int) i % 50 == 0)
  431.         PDF_setdash(p, (float) 0.0, (float) 0.0);
  432.     PDF_moveto(p, i, 0);
  433.     PDF_lineto(p, i, (float) height);
  434.     PDF_stroke(p);
  435.     PDF_restore(p);
  436.     }
  437.  
  438.     /* draw horizontal lines */
  439.     for (i = 0; i < height; i += STEP) {
  440.     PDF_save(p);
  441.     if ((int) i % 50 == 0)
  442.         PDF_setdash(p, (float) 0.0, (float) 0.0);
  443.     if ((int) i % 100 == 0)
  444.         PDF_setlinewidth(p, THICK);
  445.     PDF_moveto(p, 0, i);
  446.     PDF_lineto(p, (float) width, i);
  447.     PDF_stroke(p);
  448.     PDF_restore(p);
  449.     }
  450.  
  451. #define FONTNAME    "Helvetica-Bold"
  452. #define DELTA    ((float) 9)
  453. #define RADIUS    ((float) 12.0)
  454.  
  455.     font = PDF_findfont(p, FONTNAME, "host", 0);
  456.  
  457.     PDF_setfont(p, font, FONTSIZE);
  458.  
  459.     /* print captions */
  460.     for (i = 100; i < width; i+= 100) {
  461.     PDF_save(p);
  462.     PDF_setcolor(p, "fill", "gray", (float) 1.0, 0, 0, 0);
  463.     PDF_circle(p, i, (float) 20.0, RADIUS);
  464.     PDF_fill(p);
  465.     PDF_restore(p);
  466.     sprintf(buf, "%d", (int) i);
  467.     PDF_show_xy(p, buf, i - DELTA, (float) 20.0 - FONTSIZE/3);
  468.     }
  469.  
  470.     for (i = 100; i < height; i+= 100) {
  471.     PDF_save(p);
  472.     PDF_setcolor(p, "fill", "gray", (float) 1.0, 0, 0, 0);
  473.     PDF_circle(p, (float) 40.0, i, RADIUS);
  474.     PDF_fill(p);
  475.     PDF_restore(p);
  476.     sprintf(buf, "%d", (int) i);
  477.     PDF_show_xy(p, buf, (float) 40.0 - DELTA, i - FONTSIZE/3);
  478.     }
  479.  
  480.     PDF_end_page(p);
  481.  
  482.     MESSAGE("done\n");
  483.  
  484. #undef STEP
  485. #undef FONTSIZE
  486. #undef DELTA
  487. #undef RADIUS
  488. #undef FONTNAME
  489. }
  490.  
  491.  
  492. /* ------------------------------------------------------------- */
  493. static void
  494. shaded_circle(PDF *p)
  495. {
  496.     int i;
  497.     float gray = (float) 0.1, r;
  498.  
  499.     MESSAGE("Shaded circle test...");
  500.  
  501.     /* generate perceptual linear color blend */
  502.     r = (float) pow(1.0/gray, 1.0/255.0);
  503.  
  504.     PDF_begin_page(p, a4_width, a4_height);
  505.     (void) PDF_add_bookmark(p, "Shaded circle", 0, 1);
  506.  
  507.     for (i = 255; i >= 0; i--) {
  508.     PDF_setcolor(p, "fill", "rgb", gray, gray, (float) 1, (float) 0);
  509.     PDF_circle(p, (float) 300.0, (float) 400.0, (float) i);
  510.     PDF_fill(p);
  511.     gray *= r;
  512.     }
  513.     PDF_end_page(p);
  514.  
  515.     MESSAGE("done\n");
  516. }
  517.  
  518.  
  519. /* ------------------------------------------------------------- */
  520. static void
  521. annotations(PDF *p)
  522. {
  523. #define FILENAME    "pdftest.c"
  524. #define MIMETYPE    "text/plain"
  525. #define NOTETEXT    "Hi! I'm a text annotation!"
  526.  
  527. /* Some greek and russian words for the unicode annotation test */
  528. #define GREEKTEXT    \
  529.     "\376\377\003\233\003\237\003\223\003\237\003\243\0\0"
  530. #define RUSSIANTEXT    \
  531.     "\376\377\004\037\004\036\004\024\004\040\004\043\004\023\004\020\0\0"
  532.  
  533.     MESSAGE("Annotation test...");
  534.  
  535.     PDF_begin_page(p, a4_width, a4_height);
  536.  
  537.     (void) PDF_add_bookmark(p, "Annotations", 0, 1);
  538.  
  539.     (void) PDF_attach_file(p, 100, 200, 150, 250, FILENAME,
  540.             "C source file", "Thomas Merz", MIMETYPE, "graph");
  541.  
  542.     PDF_set_border_style(p, "dashed", (float) 3.0);
  543.     PDF_set_border_color(p, (float) 0.0, (float) 0.0, (float) 1.0);
  544.     PDF_set_border_dash(p, (float) 5.0, (float) 1.0);
  545.  
  546.     PDF_add_note(p, 200, 400, 300, 450, NOTETEXT, "Thomas Merz", "comment", 0);
  547.  
  548.     PDF_set_border_style(p, "dashed", (float) 4.0);
  549.     PDF_set_border_color(p, (float) 1.0, (float) 0.0, (float) 0.0);
  550.     PDF_set_border_dash(p, (float) 1.0, (float) 4.0);
  551.  
  552.     PDF_add_note(p, 200, 600, 550, 750, GREEKTEXT, "Greek annotation",
  553.             "insert",1);
  554.  
  555.     PDF_add_note(p, 100, 500, 400, 650, RUSSIANTEXT,
  556.             "Russian annotation", "paragraph", 1);
  557.  
  558.     PDF_add_launchlink(p, 300, 300, 400, 350, "../readme.txt");
  559.  
  560.     PDF_set_border_color(p, (float) 0.0, (float) 1.0, (float) 0.0);
  561.     PDF_set_border_dash(p, (float) 3.0, (float) 2.0);
  562.  
  563.     PDF_add_pdflink(p, 400, 200, 500, 250, "../doc/PDFlib-manual.pdf", 2,
  564.     "fitpage");
  565.  
  566.     PDF_set_border_color(p, (float) 1.0, (float) 1.0, (float) 0.0);
  567.     PDF_set_border_dash(p, (float) 3.0, (float) 2.0);
  568.  
  569.     PDF_add_locallink(p, 500, 100, 550, 150, 8, "fitwidth");
  570.  
  571.     PDF_set_border_style(p, "solid", (float) 7.0);
  572.     PDF_set_border_color(p, (float) 0.0, (float) 1.0, (float) 1.0);
  573.     PDF_set_border_dash(p, (float) 0.0, (float) 0.0);
  574.  
  575.     PDF_add_weblink(p, 100, 150, 300, 250, "http://www.pdflib.com");
  576.  
  577.     PDF_end_page(p);
  578.  
  579.     MESSAGE("done\n");
  580.  
  581. #undef NOTETEXT
  582. #undef FILENAME
  583. #undef MIMETYPE
  584. #undef RUSSIANTEXT
  585. #undef GREEKTEXT
  586. }
  587.  
  588. /* ------------------------------------------------------------- */
  589. static void
  590. centered_text(PDF *p)
  591. {
  592.     float    y;
  593.     char    **cp;
  594.     int        textfont, titlefont;
  595.     char    *title = "Der Zauberlehrling";
  596.     char    *subtitle ="Johann Wolfgang von Goethe";
  597. /* We don't want to use metrics files for the sample, and therefore
  598.  * stick to host encoding. For this reason the sample text (which
  599.  * uses German special characters) must be platform-specific.
  600.  * The three flavors only differ in the special characters.
  601.  */
  602. #ifdef MAC
  603.     char    *poem[] = {
  604.             "Hat der alte Hexenmeister",
  605.             "Sich doch einmal wegbegeben!",
  606.             "Und nun sollen seine Geister",
  607.             "Auch nach meinem Willen leben.",
  608.             "Seine Wort\325 und Werke",
  609.             "Merkt ich und den Brauch,",
  610.             "Und mit Geistesst\212rke",
  611.             "Tu ich Wunder auch.",
  612.             "Walle! walle",
  613.             "Manche Strecke,",
  614.             "Da\247, zum Zwecke,",
  615.             "Wasser flie\247e",
  616.             "Und mit reichem, vollem Schwalle",
  617.             "Zu dem Bade sich ergie\247e.",
  618.             NULL };
  619. #elif defined(PDFLIB_EBCDIC)
  620.     char    *poem[] = {
  621.             "Hat der alte Hexenmeister",
  622.             "Sich doch einmal wegbegeben!",
  623.             "Und nun sollen seine Geister",
  624.             "Auch nach meinem Willen leben.",
  625.             "Seine Wort\175 und Werke",
  626.             "Merkt ich und den Brauch,",
  627.             "Und mit Geistesst\103rke",
  628.             "Tu ich Wunder auch.",
  629.             "Walle! walle",
  630.             "Manche Strecke,",
  631.             "Da\131, zum Zwecke,",
  632.             "Wasser flie\131e",
  633.             "Und mit reichem, vollem Schwalle",
  634.             "Zu dem Bade sich ergie\131e.",
  635.             NULL };
  636. #else    /* all other platforms */
  637.     char    *poem[] = {
  638.             "Hat der alte Hexenmeister",
  639.             "Sich doch einmal wegbegeben!",
  640.             "Und nun sollen seine Geister",
  641.             "Auch nach meinem Willen leben.",
  642.             "Seine Wort\222 und Werke",
  643.             "Merkt ich und den Brauch,",
  644.             "Und mit Geistesst\344rke",
  645.             "Tu ich Wunder auch.",
  646.             "Walle! walle",
  647.             "Manche Strecke,",
  648.             "Da\337, zum Zwecke,",
  649.             "Wasser flie\337e",
  650.             "Und mit reichem, vollem Schwalle",
  651.             "Zu dem Bade sich ergie\337e.",
  652.             NULL };
  653. #endif
  654.  
  655. #define FONTSIZE    24
  656. #define CENTER        290
  657. #define TOP        750
  658.  
  659.     MESSAGE("Centered text test...");
  660.  
  661.     PDF_begin_page(p, a4_width, a4_height);
  662.     (void) PDF_add_bookmark(p, "Centered text", 0, 1);
  663.  
  664.     textfont = PDF_findfont(p, "Times-Roman", ENCODING, 0);
  665.  
  666.     y = TOP;
  667.  
  668.     titlefont = PDF_findfont(p, "Helvetica-Bold", ENCODING, 0);
  669.     PDF_setfont(p, titlefont, (float) (1.5 * FONTSIZE));
  670.     PDF_show_boxed(p, title, CENTER, y, 0, 0, "center", "");
  671.     y -= (float) (1.5 * FONTSIZE);
  672.  
  673.     PDF_setfont(p, titlefont, FONTSIZE/2);
  674.     PDF_show_boxed(p, subtitle, CENTER, y, 0, 0, "center", "");
  675.     y -= (float) (3.0 * FONTSIZE);
  676.  
  677.     PDF_setfont(p, textfont, FONTSIZE);
  678.  
  679.     for (cp = poem; *cp; cp++) {
  680.     PDF_show_boxed(p, *cp, CENTER, y, 0, 0, "center", "");
  681.     y -= (float) (1.5 * FONTSIZE);
  682.     }
  683.  
  684.     PDF_end_page(p);
  685.  
  686.     MESSAGE("done\n");
  687.  
  688. #undef FONTSIZE
  689. #undef RIGHT
  690. #undef TOP
  691. }
  692.  
  693. /* ------------------------------------------------------------- */
  694. static void
  695. memory_image(PDF *p)
  696. {
  697.     char     *buf, *bp;
  698.     int        width, height, components;
  699.     int        bpc;
  700.     int        image;
  701.     int        i, j;
  702.     float    y, sx, sy;
  703.  
  704. #define LEFT        ((float) 50.0)
  705.  
  706.     width    = 256;
  707.     height    = 1;
  708.     bpc        = 8;
  709.     components    = 3;
  710.  
  711.     MESSAGE("Memory image test...");
  712.  
  713.     sx = (float) 3.0;        /* desired horizontal scaling factor */
  714.     sy = (float) 128.0;        /* desired height of one color band */
  715.  
  716.     buf = (char *) calloc((size_t) (width * height * components), 1);
  717.  
  718.     if (buf == NULL) {
  719.     fprintf(stderr, "Not enough memory for memory image!\n");
  720.     return;
  721.     }
  722.  
  723.     /* now fill the buffer with fake image data (simple color ramp) */
  724.     for (bp = buf, i=0; i<height; i++) {
  725.     for (j=0; j<width; j++) {
  726.         *bp++ = (char) (j % 256);    /* red blend */
  727.         *bp++ = 0;
  728.         *bp++ = 0;
  729.     }
  730.     }
  731.  
  732.     /* 
  733.      * In positioning the images below, we will have to compensate 
  734.      * for the scaling.
  735.      */
  736.     y = LEFT;
  737.  
  738.     image = PDF_open_image(p, "raw", "memory", buf, width*height*components,
  739.         width, height, components, bpc, "");
  740.     if (image == -1) {
  741.     fprintf(stderr, "Not enough memory for memory image!\n");
  742.     free(buf);
  743.     return;
  744.     }
  745.  
  746.     PDF_begin_page(p, 900, 600);
  747.     (void) PDF_add_bookmark(p, "Memory image", 0, 1);
  748.  
  749.     /* 
  750.      * Since the image interface doesn't support non-proportional
  751.      * scaling, we will use PDF_scale() instead to stretch the image.
  752.      */
  753.     PDF_scale(p, sx, sy);        /* stretch image */
  754.  
  755.     PDF_place_image(p, image, LEFT/sx, y/sy, (float) 1.0);
  756.     PDF_close_image(p, image);
  757.  
  758.     for (bp = buf, i=0; i<height; i++) {
  759.     for (j=0; j<width; j++) {
  760.         *bp++ = 0;
  761.         *bp++ = (char) (j % 256);    /* green blend */
  762.         *bp++ = 0;
  763.     }
  764.     }
  765.  
  766.     y += height * sy;        /* position the image */
  767.  
  768.     image = PDF_open_image(p, "raw", "memory", buf, width*height*components,
  769.         width, height, components, bpc, "");
  770.     if (image == -1) {
  771.     fprintf(stderr, "Not enough memory for memory image!\n");
  772.     free(buf);
  773.     PDF_end_page(p);
  774.     return;
  775.     }
  776.  
  777.     PDF_place_image(p, image, LEFT/sx, y/sy, (float) 1.0);
  778.     PDF_close_image(p, image);
  779.  
  780.     for (bp = buf, i=0; i<height; i++) {
  781.     for (j=0; j<width; j++) {
  782.         *bp++ = 0;
  783.         *bp++ = 0;
  784.         *bp++ = (char) (j % 256);    /* blue blend */
  785.     }
  786.     }
  787.  
  788.     y += height * sy;        /* position the image */
  789.  
  790.     image = PDF_open_image(p, "raw", "memory", buf, width*height*components,
  791.         width, height, components, bpc, "");
  792.     if (image == -1) {
  793.     fprintf(stderr, "Not enough memory for memory image!\n");
  794.     free(buf);
  795.     PDF_end_page(p);
  796.     return;
  797.     }
  798.  
  799.     PDF_place_image(p, image, LEFT/sx, y/sy, (float) 1.0);
  800.     PDF_close_image(p, image);
  801.  
  802.     for (bp = buf, i=0; i<height; i++) {
  803.     for (j=0; j<width; j++) {
  804.         *bp++ = (char) (j % 256);    /* gray blend */
  805.     }
  806.     }
  807.  
  808.     y += height * sy;        /* position the image */
  809.  
  810.     components    = 1;        /* now a single component image */
  811.     image = PDF_open_image(p, "raw", "memory", buf, width*height*components,
  812.         width, height, components, bpc, "");
  813.     if (image == -1) {
  814.     fprintf(stderr, "Not enough memory for memory image!\n");
  815.     free(buf);
  816.     PDF_end_page(p);
  817.     return;
  818.     }
  819.  
  820.     PDF_place_image(p, image, LEFT/sx, y/sy, (float) 1.0);
  821.     PDF_close_image(p, image);
  822.  
  823.     free(buf);
  824.     PDF_end_page(p);
  825.  
  826.     MESSAGE("done\n");
  827.  
  828. #undef LEFT
  829. }
  830.  
  831. /* ------------------------------------------------------------- */
  832. static void
  833. radial_structure(PDF *p)
  834. {
  835.     float alpha;
  836.  
  837.     MESSAGE("Radial structure test...");
  838.  
  839.     PDF_begin_page(p, a4_width, a4_height);
  840.     (void) PDF_add_bookmark(p, "Radial structure", 0, 1);
  841.  
  842.     PDF_translate(p, (float) 300.0, (float) 400.0);
  843.     PDF_setlinewidth(p, (float) 0.1);
  844.  
  845.     /* better solution: don't accumulate rounding errors */
  846.     for (alpha = 0; alpha < 360; alpha++) {
  847.     PDF_save(p);
  848.     PDF_rotate(p, alpha);
  849.     PDF_moveto(p, (float) 0.0, (float) 0.0);
  850.     PDF_lineto(p, (float) 250.0, (float) 0.0);
  851.     PDF_stroke(p);
  852.     PDF_restore(p);
  853.     }
  854.  
  855.     PDF_end_page(p);
  856.  
  857.     MESSAGE("done\n");
  858. }
  859.  
  860. /* ------------------------------------------------------------- */
  861. static void
  862. random_data_graph(PDF *p)
  863. {
  864.     float x;
  865.  
  866.     MESSAGE("Random graph test...");
  867.  
  868.     PDF_begin_page(p, a4_width, a4_height);
  869.     (void) PDF_add_bookmark(p, "Random graph", 0, 1);
  870.  
  871. #define STEP    ((float) 10.0)
  872. #define MARGIN    ((float) 50.0)
  873. #define RIGHT    ((float) 500.0)
  874. #define TOP    ((float) 800.0)
  875.     PDF_setlinewidth(p, 2);
  876.     PDF_setcolor(p, "stroke", "gray", 0, 0, 0, 0);    /* black */
  877.     PDF_moveto(p, RIGHT, MARGIN);
  878.     PDF_lineto(p, MARGIN, MARGIN);
  879.     PDF_lineto(p, MARGIN, TOP);
  880.     PDF_stroke(p);
  881.  
  882.     PDF_setlinewidth(p, 1);
  883.  
  884.     /* construct some random graph data */
  885.     /* red */
  886.     PDF_setcolor(p, "stroke", "rgb", (float)1, (float)0, (float) 0, (float) 0);
  887.     PDF_moveto(p, MARGIN, MARGIN);
  888.     for (x=MARGIN; x<RIGHT; x+=STEP)
  889.     PDF_lineto(p, x,
  890.         x + (TOP-MARGIN)/(float)2.0*rand()/(RAND_MAX+(float)1.0));
  891.  
  892.     PDF_stroke(p);
  893.  
  894.     /* green */
  895.     PDF_setcolor(p, "stroke", "rgb", (float)0, (float)1, (float)0, (float) 0);
  896.     PDF_moveto(p, MARGIN, MARGIN);
  897.     for (x=MARGIN; x<RIGHT; x+=STEP)
  898.     PDF_lineto(p, x, 
  899.         MARGIN + TOP*(x-MARGIN)*(x-MARGIN)/((RIGHT-MARGIN)*(RIGHT-MARGIN)));
  900.  
  901.     PDF_stroke(p);
  902.  
  903.     /* blue */
  904.     PDF_setcolor(p, "stroke", "rgb", (float) 0, (float) 0, (float)1, (float) 0);
  905.     PDF_moveto(p, MARGIN, MARGIN);
  906.     for (x=MARGIN; x<RIGHT; x+=STEP)
  907.     PDF_lineto(p, x, MARGIN + x + MARGIN*rand()/(RAND_MAX+(float)1.0));
  908.  
  909.     PDF_stroke(p);
  910.  
  911.     PDF_end_page(p);
  912.  
  913.     MESSAGE("done\n");
  914.  
  915. #undef STEP
  916. #undef MARGIN
  917. #undef RIGHT
  918. #undef TOP
  919. }
  920.  
  921. static unsigned
  922. #ifdef PDF_WINTHREADS
  923. __stdcall        /* needed for threads */
  924. #endif
  925. Do_PDFlib_tests(void *arg)
  926. {
  927.     char    filename[50];
  928.     PDF        *p;
  929.  
  930. #ifdef PDF_WINTHREADS
  931.     sprintf(filename, "pdftest%03ld.pdf", (long) arg);
  932. #else
  933.     (void) arg;    /* avoid compiler warning "unreferenced parameter" */
  934.     strcpy(filename, "pdftest.pdf");
  935. #endif
  936.  
  937.     fprintf(stderr, "Creating PDFlib test file '%s'!\n", filename);
  938.  
  939.     PDF_boot();
  940.  
  941.     p = PDF_new();
  942.  
  943.     if (PDF_open_file(p, filename) == -1) {
  944.         printf("Couldn't open PDF file '%s'!\n", filename);
  945.     PDF_ENDTHREAD(1);
  946.     return 1;
  947.     }
  948.  
  949.     PDF_set_info(p, "Keywords", "image graphics text hypertext");
  950.     PDF_set_info(p, "Subject", "Check many PDFlib function calls");
  951.     PDF_set_info(p, "Title", "PDFlib test program");
  952.     PDF_set_info(p, "Creator", "PDFtest");
  953.     PDF_set_info(p, "Author", "Thomas Merz");
  954.  
  955.     PDF_set_value(p, "compress", 0);
  956.  
  957.     png_image(p);
  958.     gif_image(p);
  959.     jpeg_image(p);
  960.     tiff_image(p);
  961.     centered_text(p);
  962.     character_table(p);
  963.     annotations(p);
  964.     bookmarks(p);
  965.     grid(p);
  966.     shaded_circle(p);
  967.     memory_image(p);
  968.     radial_structure(p);
  969.     random_data_graph(p);
  970.  
  971.     PDF_close(p);
  972.     PDF_delete(p);
  973.  
  974.     PDF_shutdown();
  975.  
  976.     fprintf(stderr, "\nPDFlib test file '%s' finished!\n", filename);
  977.  
  978.     PDF_ENDTHREAD(0);
  979.  
  980.     return 0;
  981. }
  982.  
  983. #define PDF_MAXTHREADS 4
  984.  
  985. int
  986. main(int argc, char *argv[])
  987. {
  988. #ifdef PDF_WINTHREADS
  989.     unsigned t, w, thread_id;
  990.     HANDLE hThread[PDF_MAXTHREADS];
  991.  
  992.     /* do a multi-threaded test */
  993.     for (t=0; t < PDF_MAXTHREADS; t++) {
  994.     hThread[t] =(HANDLE) _beginthreadex(NULL, 0, &Do_PDFlib_tests,
  995.                     (void *)t, 0, &thread_id );
  996.     if (hThread[t] == 0) {
  997.         printf("Couldn't create thread %ud\n", t);
  998.         break;
  999.     }
  1000.     }
  1001.  
  1002.     for (w=0; w < t; w++) {
  1003.     WaitForSingleObject(hThread[w], INFINITE);
  1004.     CloseHandle(hThread[w]);
  1005.     }
  1006. #else /* !PDF_WINTHREADS */
  1007.  
  1008.     /* do a single test */
  1009.     Do_PDFlib_tests((void *) 0L);
  1010.  
  1011. #endif /* !PDF_WINTHREADS */
  1012.  
  1013.     (void) argc;    /* avoid compiler warning "unreferenced parameter" */
  1014.     (void) argv;    /* avoid compiler warning "unreferenced parameter" */
  1015.  
  1016.     exit(0);
  1017.  
  1018.     return 0;    /* shut up compiler warnings */
  1019. }
  1020.  
  1021.