home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / TEXT / UTILITY / PIL50KIT.ZIP / CFILES / PILGEN.C < prev    next >
Encoding:
Text File  |  1992-04-09  |  60.6 KB  |  2,157 lines

  1. /* ----------------------------------------------------------------------------    */
  2. /*    Originators:                                                                */
  3. /*      Tom Arnold,    Quark, Inc.,    300 S. Jackson,     Denver,     CO 80209    */
  4. /*        Ron Perry,     Atex, Inc.,        165 Lexington Road,    Billerica,     MA 01821    */
  5. /* ----------------------------------------------------------------------------    */
  6. /*    The source code in this file is provided by Quark and Atex for use in the    */
  7. /*    development of a Publishing Interchange Language. The code provided herein    */
  8. /*    is non-proprietary, non-copyrighted, and is for use in the public domain.    */
  9. /*    The source code contained herein is provided "as is".                        */
  10. /* ----------------------------------------------------------------------------    */
  11. /*    QUARK AND ATEX DISCLAIM ALL WARRANTIES, EXPRESSED OR IMPLIED, WITH REGARD    */ 
  12. /*    TO THE ENCLOSED SOURCE CODE. QUARK AND ATEX DISCLAIM ANY IMPLIED WARRANTY,    */
  13. /*    INCLUDING, BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF FITNESS FOR A            */
  14. /*    PARTICULAR PURPOSE OR MERCHANTABILITY.                                        */
  15. /* ----------------------------------------------------------------------------    */
  16.  
  17.  
  18. /*$ab ----------------------------- abstract ----------------------------------
  19.   pilgen.c       Contains routines to generate the Publisher's Interchange
  20.                   Language from the data structures defined in pilstruc.h.
  21.                   
  22.                   NO MEMORY IS ALLOCATED OR FREED BY THE FUNCTIONS IN THIS MODULE!
  23.                   
  24.                   NO I/O (FILE OPENS, CLOSES, READS, OR WRITES, ERROR PRINTING)
  25.                   IS DONE DIRECTLY BY THE FUNCTIONS IN THIS MODULE.
  26.  
  27.                   ERRORS ARE COMMUNICATED TO THE APPLICATION BY RETURNING AN
  28.                   ERROR CODE AND SETTING A GLOBAL ERROR WORD WITH THAT ERROR CODE. 
  29.                   
  30.                   The functions in this module are called by pil_put_component
  31.                   to generate pil "code" from the pil data structures. The
  32.                   functions here call pil_put_string, in pilapi.c, to write to
  33.                   a file opened by the application that called pil_put_component.
  34.                   
  35.                   
  36.     Contains:
  37.         pil_nextline                    End the current line and indent the next        
  38.         pil_put_asa                        Write an application specific attribute
  39.         pil_put_asi                        Write an application specific item
  40.         pil_put_canvas                    Write a canvas
  41.         pil_put_clipper                    Write a clipping shape for canvas, object
  42.         pil_put_content_data            Write content for a pil-content entity
  43.         pil_put_content_end                End a pil-content entity
  44.         pil_put_content_hdr                Write the header for a pil-content entity
  45.         pil_put_content_start            Write the start of a pil-content entity
  46.         pil_put_data_code                Write data type codes for app. spec. items
  47.         pil_put_group                    Write a group
  48.         pil_put_kw                        Translate a token to a keyword & write it
  49.         pil_put_layout_end                End a layout entity, write it
  50.         pil_put_layout_start            Write the start of a layout entity
  51.         pil_put_nametbleentry            Write a single entry for a nametable
  52.         pil_put_name_table                Write the whole nametable
  53.         pil_put_nested_begblk            Write a begin block & adjust indents
  54.         pil_put_nested_endblk            Write an end block & adjust indents
  55.         pil_put_object                    Write a pil object
  56.         pil_put_objid                    Write the object id
  57.         pil_put_pathpt                    Write a single point for a path
  58.         pil_put_point                    Write a single pil_point, e.g. origin
  59.         pil_put_polydata                Write all points for polygon or polyline
  60.         pil_put_polypt                    Write single point for polygon or polyline
  61.         pil_put_pvalue                    Write a single value for app. spec. items
  62.         pil_put_rectdata                Write the origin, width, height for rectangle
  63.         pil_put_string                    Write a string to the open pil file
  64.         pil_put_text_flow                Write a text flow component
  65.         pil_set_dflt_hdr                Set up the default header for pil content
  66.  
  67.     Calls:        pil_set_error            in pilapi.c
  68.  
  69.  
  70.  
  71. ---------------------------------------------------------------------------- */
  72.  
  73.  
  74. /*$au ------------------------------ audits -----------------------------------
  75.     Author: Tom Arnold
  76.             Quark, Inc.
  77.             300 South Jackson
  78.             Denver, Colorado 80209
  79.             (303) 934-2211
  80.  
  81.     Ver     Date       Who  Etc
  82.     v01.02  24-apr-91  tla    Updated for PIL 5.0
  83.     v01.01  03-apr-91  tla    Fixed prototype for pil_put_color, and minor bug.
  84.         Fixed bug in pil_put_pathdata that treated arc radius as unsigned int.
  85.     v01.00  12-feb-91  tla    Initial version
  86. ---------------------------------------------------------------------------- */
  87.  
  88. /*$ep --------------------------- header files ----------------------------- */
  89.  
  90. #include "pildefs.h"    /* everything */
  91. #ifdef THINK_DA
  92. #include <SANE.h>        /* num2str (Apple's SANE floating point to ascii) */
  93. #else
  94. #include <stdio.h>        /* for sprintf() */
  95. #endif
  96.  
  97. /*$ed ------------------------ public global data -------------------------- */
  98.  
  99. #ifdef PIL_ANSI_PROTOTYPES
  100. extern int (FPTRTYPE *pil_putchar)(PIL_UINT8);    /* pointer to Appl PutChar function */
  101. #else
  102. extern int (FPTRTYPE *pil_putchar)();    /* pointer to Appl PutChar function */
  103. #endif
  104. extern char PTRTYPE *pil_kws[];            /* Keyword pointer array            */
  105.  
  106. /*$ld --------------------------- static  data ----------------------------- */
  107.  
  108. static char hex[16] = {'0','1','2','3','4','5','6','7',
  109.                        '8','9','A','B','C','D','E','F'};
  110.                        
  111. static char outbuf[80];                /* used by pil_put_ui32, etc */
  112. static int indentlev = 0;            /* current level of indentation */
  113.  
  114. static     pil_content_hdr currenthdr = {
  115.      (PIL_INT32)PIL_CONTENT_HDR_C,    /* component type */
  116.      (PIL_INT8)PIL_ASCII_CONTENT,    /* encoding */
  117.      (PIL_INT8)PIL_BIG_ENDIAN,        /* byte order(big-endian is like Motorola)*/
  118.      (PIL_UINT8)PIL_DFT_CNT_ESC,    /* escape character */
  119.      (PIL_UINT8)PIL_DFT_CNT_BEG,    /* begin block character */
  120.      (PIL_UINT8)PIL_DFT_CNT_END        /* end block character */
  121. };
  122.  
  123.  
  124. /*$co ---------------------------- code start ------------------------------ */
  125.         
  126. /*=======================================================================*\
  127.   pil_put_component
  128.  
  129.     Writes a pil component to the open pil file.
  130.     APPLICATION MUST OPEN THE FILE FIRST, AND CALL pil_set_putchar
  131.  
  132.     Entry:    Pointer to the pil component
  133.  
  134.     Exit:    Error code
  135.  
  136. \*-----------------------------------------------------------------------*/
  137. PIL_ERROR pil_put_component(ptr)
  138. FAST    pil_component PTRTYPE *ptr;
  139. {
  140.     /* make sure there is a putchar function to call ! */
  141.     if (pil_putchar == NULL) {
  142.         return(pil_set_error(PIL_NO_W_FUNC));
  143.     }
  144.     if (ptr->type == PIL_CANVAS_C) {
  145.         return (pil_put_canvas((pil_canvas PTRTYPE *)ptr));
  146.     }
  147.     if (ptr->type == PIL_NAME_TABLE_C) {
  148.         return (pil_put_name_table((pil_name_table PTRTYPE *)ptr));
  149.     }
  150.     if (ptr->type == PIL_OBJECT_C) {
  151.         return (pil_put_object((pil_object PTRTYPE *)ptr));
  152.     }
  153.     if (ptr->type == PIL_TEXT_FLOW_C) {
  154.         return (pil_put_text_flow((pil_text_flow PTRTYPE *)ptr));
  155.     }
  156.     if (ptr->type == PIL_GROUP_C) {
  157.         return (pil_put_group((pil_group PTRTYPE *)ptr));
  158.     }
  159.     if (ptr->type == PIL_LAYOUT_START_C) {
  160.         return (pil_put_layout_start((pil_layout_start PTRTYPE *)ptr));
  161.     }
  162.     if (ptr->type == PIL_LAYOUT_END_C) {
  163.         return (pil_put_layout_end((pil_layout_end PTRTYPE *)ptr));
  164.     }
  165.     if (ptr->type == PIL_CONTENT_START_C) {
  166.         return (pil_put_content_start((pil_content_start PTRTYPE *)ptr));
  167.     }
  168.     if (ptr->type == PIL_CONTENT_HDR_C) {
  169.         return (pil_put_content_hdr((pil_content_hdr PTRTYPE *)ptr));
  170.     }
  171.     if (ptr->type == PIL_CONTENT_DATA_C) {
  172.         return (pil_put_content_data((pil_content_data PTRTYPE *)ptr));
  173.     }
  174.     if (ptr->type == PIL_CONTENT_END_C) {
  175.         return (pil_put_content_end((pil_content_end PTRTYPE *)ptr));
  176.     }
  177.     return (PIL_OK);
  178. }
  179.  
  180. /*=======================================================================*\
  181.   pil_put_comment
  182.  
  183.     Writes a comment string to the open pil file.
  184.     APPLICATION MUST OPEN THE FILE FIRST.
  185.     This function does not break the comment into lines, it just writes
  186.     out whatever it is passed.
  187.     To select C or C++ commenting conventions, choos the appropriate
  188.     definitions of PIL_BEGIN_COMMENT and PIL_END_COMMENT in pil_struct.h
  189.     
  190.     CAUTION! A legal PIL file must start with an entity, not a comment!
  191.     Therefore do not call pil_put_comment until after you've written a 
  192.     pil_layout_start or a pil_content_start to the file.
  193.  
  194.     Entry:    Pointer to the string.
  195.  
  196.     Exit:    No return value. Writes comment via pil_put_string
  197.  
  198. \*-----------------------------------------------------------------------*/
  199. PIL_VOID pil_put_comment(ptr)
  200. char PTRTYPE *ptr;
  201. {
  202.     pil_put_string(PIL_BEGIN_COMMENT);
  203.     pil_put_string(ptr);
  204.     pil_put_string(PIL_END_COMMENT);
  205.     pil_nextline();
  206. }
  207.  
  208. /*=======================================================================*\
  209.   pil_put_string
  210.  
  211.     Writes a c string to the open pil file.
  212.     APPLICATION MUST OPEN THE FILE FIRST, AND CALL pil_set_putchar, or 
  213.     provide a putchar function by calling pil_pg_init.
  214.     
  215.     NOTE: This function, and all functions that call pil_putchar, assume
  216.     that all writes succeed. Therefore the write function itself must have
  217.     some capability of detecting and correcting errors.
  218.     
  219.     Entry:    Pointer to the string
  220.  
  221.     Exit:    None.
  222.  
  223. \*-----------------------------------------------------------------------*/
  224.  
  225. PIL_VOID pil_put_string(str)
  226. char PTRTYPE *str;
  227. {
  228.     while (*str) {
  229.         (pil_putchar)(*str++);
  230.     }
  231. }
  232.  
  233. /*=======================================================================*\
  234.   pil_put_layout_start
  235.  
  236.     Subroutine for pil_put_component.
  237.     Writes a pil_layout_start to the open pil file.
  238.  
  239.     Entry:    Pointer to a pil_layout_start  
  240.  
  241.     Exit:    Error code is returned
  242.  
  243. \*-----------------------------------------------------------------------*/
  244.  
  245. PIL_ERROR pil_put_layout_start(lsptr)
  246. pil_layout_start PTRTYPE *lsptr;
  247. {
  248.     if (!PIL_RIGHT_CMPNT(lsptr,PIL_LAYOUT_START_C))
  249.         return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  250.     pil_put_kw_no_sep(PIL_KW_LAYOUT);
  251.     pil_put_literal(lsptr->version);
  252.     pil_put_quoted_str(lsptr->name);
  253.     pil_put_nested_begblk();
  254.     pil_nextline();
  255.     return (PIL_OK);
  256. }
  257.  
  258. /*=======================================================================*\
  259.   pil_put_name_table
  260.  
  261.     Subroutine for pil_put_component.
  262.     Writes a pil_name_table to the open pil file.
  263.  
  264.     Entry:    Pointer to a pil_name_table
  265.  
  266.     Exit:    Error code is returned.
  267.  
  268. \*-----------------------------------------------------------------------*/
  269.  
  270. PIL_ERROR pil_put_name_table(nptr)
  271. pil_name_table PTRTYPE *nptr;
  272. {
  273.     FAST pil_name_table_entry PTRTYPE *nte;
  274.     
  275.     pil_put_named_begblk(PIL_KW_NAME_TABLE);
  276.     if ((nte = nptr->entries) != NULL) {
  277.         pil_nextline();
  278.         do {
  279.             if (pil_put_nametbleentry(nte) != PIL_OK)
  280.                 return (pil_last_error());
  281.             if ((nte = nte->next)!= NULL)
  282.                 pil_nextline();
  283.         } while (nte != NULL);
  284.     }
  285.     pil_put_nested_endblk();
  286.     pil_nextline();
  287.     return (PIL_OK);
  288. }
  289.  
  290. /*=======================================================================*\
  291.   pil_put_canvas
  292.  
  293.     Subroutine for pil_put_component.
  294.     Writes a pil_canvas to the open pil file.
  295.  
  296.     Entry:    Pointer to a pil_canvas
  297.  
  298.     Exit:    Error code is returned.
  299.  
  300. \*-----------------------------------------------------------------------*/
  301.  
  302. PIL_ERROR pil_put_canvas(cptr)
  303. pil_canvas PTRTYPE *cptr;
  304. {
  305.     pil_put_named_begblk(PIL_KW_CANVAS);
  306.     if (cptr->username) {
  307.         pil_nextline();
  308.         pil_put_named_str(PIL_KW_USER_NAME,cptr->username);
  309.     }
  310.     if (cptr->cantype) {
  311.         pil_nextline();
  312.         pil_put_named_str(PIL_KW_TYPE,cptr->cantype);
  313.     }
  314.     if (cptr->units <= 0) return (pil_set_error(PIL_BAD_UNITS));
  315.     pil_nextline();
  316.     pil_put_named_dbl(PIL_KW_UNITS,cptr->units);
  317.     pil_nextline();
  318.     if (pil_put_dimensions(cptr->width,cptr->height) != PIL_OK)
  319.         return (pil_last_error());
  320.     if (cptr->clipshape.type != PIL_NO_SHAPE) {
  321.         pil_nextline();
  322.         if (pil_put_clipper(&cptr->clipshape) != PIL_OK) 
  323.             return (pil_last_error());
  324.     }
  325.     if (cptr->asi != NULL) {
  326.         pil_nextline();
  327.         if (pil_put_asi(cptr->asi) != PIL_OK) return (pil_last_error());
  328.     }
  329.     pil_put_nested_endblk();
  330.     pil_nextline();
  331.     return (PIL_OK);
  332. }
  333. /*=======================================================================*\
  334.   pil_put_object
  335.  
  336.     Subroutine for pil_put_component.
  337.     Writes a pil_object to the open pil file.
  338.  
  339.     Entry:    Pointer to a pil_object
  340.  
  341.     Exit:    Error code is returned.
  342.  
  343. \*-----------------------------------------------------------------------*/
  344.  
  345. PIL_ERROR pil_put_object(optr)
  346. pil_object PTRTYPE *optr;
  347. {    
  348.     PIL_RC_TYPE rctype;
  349.     
  350.     pil_put_named_begblk(PIL_KW_OBJECT);
  351.     pil_nextline();
  352.     pil_put_kw(PIL_KW_ORIGIN);
  353.     pil_put_point(&optr->dest_rect.ul);
  354.     pil_nextline();
  355.     if (pil_put_dimensions(optr->dest_rect.width, 
  356.         optr->dest_rect.height) != PIL_OK)
  357.         return (pil_last_error());
  358.     if (optr->id) {
  359.         pil_nextline();
  360.         pil_put_named_str(PIL_KW_ID,optr->id);
  361.     }
  362.     if (optr->units > 0.0) {
  363.         pil_nextline();
  364.         pil_put_named_dbl(PIL_KW_UNITS,optr->units);
  365.     }
  366.     if (optr->username) {
  367.         pil_nextline();
  368.         pil_put_named_str(PIL_KW_USER_NAME,optr->username);
  369.     }
  370.     if (optr->objtype != PIL_OBJ_UNKNOWN) {
  371.         pil_nextline();
  372.         pil_put_kw(PIL_KW_TYPE);
  373.         switch (optr->objtype) {
  374.             case PIL_OBJ_TEXT:
  375.                 pil_put_kw(PIL_KW_OBJ_TEXT);
  376.                 break;
  377.             case PIL_OBJ_PRIMITIVE:
  378.                 pil_put_kw(PIL_KW_OBJ_PRIMITIVE);
  379.                 break;
  380.             case PIL_OBJ_PICTURE:
  381.                 pil_put_kw(PIL_KW_OBJ_PICTURE);
  382.         }
  383.     }
  384.     if (optr->rotation_angle != 0.0) {
  385.         pil_nextline();
  386.         pil_put_named_dbl(PIL_KW_ROT_ANGLE,optr->rotation_angle);
  387.         if (optr->rotation_point.x != 0 && optr->rotation_point.y != 0) {
  388.             pil_nextline();
  389.             pil_put_kw(PIL_KW_ROT_POINT);
  390.             pil_put_point(&optr->rotation_point);
  391.         }
  392.     }
  393.     if (optr->clipshape.type != PIL_NO_SHAPE) {
  394.         pil_nextline();
  395.         if (pil_put_clipper(&optr->clipshape) != PIL_OK)
  396.             return (pil_last_error());
  397.     }
  398.     if (optr->container.type != PIL_NO_SHAPE) {
  399.         pil_nextline();
  400.         if (pil_put_container(&optr->container) != PIL_OK)
  401.             return (pil_last_error());
  402.     }
  403.     if (optr->graphic.shape.type != PIL_NO_SHAPE) {
  404.         pil_nextline();
  405.         if (pil_put_graphic(&optr->graphic) != PIL_OK)
  406.             return (pil_last_error());
  407.     }
  408.     if (optr->rctype != PIL_RC_UNKNOWN){
  409.         pil_nextline();
  410.         rctype = optr->rctype;
  411.         /* PLEASE MAKE ME A SUBROUTINE!  */
  412.         pil_put_kw(PIL_KW_RC_TYPE);
  413.         pil_put_string(BEGINLIST);
  414.         if (rctype & PIL_RC_TEXT) {
  415.             pil_put_kw(PIL_KW_RC_TYPE_TEXT); 
  416.         }
  417.         if (rctype & PIL_RC_GEOMETRY) {
  418.             pil_put_kw(PIL_KW_RC_TYPE_GEOMETRY); 
  419.         }
  420.         if (rctype & PIL_RC_LINEART) {
  421.             pil_put_kw(PIL_KW_RC_TYPE_LINEART); 
  422.         }
  423.         if (rctype & PIL_RC_IMAGE) {
  424.             pil_put_kw(PIL_KW_RC_TYPE_IMAGE); 
  425.         }
  426.         pil_put_string(ENDBLOCK);
  427.     }
  428.     if (optr->rcname) {
  429.         pil_nextline();
  430.         pil_put_named_str(PIL_KW_RC_NAME,optr->rcname);
  431.     }
  432.  
  433.     if (optr->src_rect.width != 0 && optr->src_rect.height != 0) {
  434.         pil_nextline();
  435.         pil_put_kw(PIL_KW_BBOX);
  436.         pil_put_string(BEGINLIST);
  437.         pil_put_dbl(optr->src_rect.ul.x);
  438.         pil_put_dbl(optr->src_rect.ul.y);
  439.         pil_put_dbl(optr->src_rect.width);
  440.         pil_put_dbl(optr->src_rect.height);
  441.         pil_put_string(ENDBLOCK);
  442.         pil_nextline();
  443.     }
  444.     if (optr->asi != NULL) {
  445.         pil_nextline();
  446.         pil_put_asi(optr->asi);
  447.     }
  448.     pil_put_nested_endblk();
  449.     pil_nextline();
  450.     return (PIL_OK);
  451. }
  452.  
  453. /*=======================================================================*\
  454.   pil_put_text_flow
  455.  
  456.     Subroutine for pil_put_component.
  457.     Writes a pil_text_flow to the open pil file.
  458.  
  459.     Entry:    Pointer to a pil_text_flow
  460.  
  461.     Exit:    Error code is returned.
  462.  
  463. \*-----------------------------------------------------------------------*/
  464.  
  465. PIL_ERROR pil_put_text_flow(tfptr)
  466. pil_text_flow PTRTYPE *tfptr;
  467. {
  468.     pil_put_named_begblk(PIL_KW_TEXT_FLOW);
  469.     if (tfptr->label) {
  470.         pil_nextline();
  471.         pil_put_named_str(PIL_KW_FLOW_LABEL,tfptr->label);
  472.     }
  473.     if (tfptr->from_layout) {
  474.         pil_nextline();
  475.         pil_put_kw(PIL_KW_FLOW_FROM);
  476.         pil_put_string(BEGINLIST);
  477.         pil_put_quoted_str(tfptr->from_layout);
  478.         if (tfptr->from_label) pil_put_quoted_str(tfptr->from_label);
  479.         pil_put_string(ENDBLOCK);        
  480.     }
  481.     if (tfptr->to_layout) {
  482.         pil_nextline();
  483.         pil_put_kw(PIL_KW_FLOW_TO);
  484.         pil_put_string(BEGINLIST);
  485.         pil_put_quoted_str(tfptr->to_layout);
  486.         if (tfptr->to_label) pil_put_quoted_str(tfptr->to_label);
  487.         pil_put_string(ENDBLOCK);
  488.     }
  489.     if (tfptr->objects) {
  490.         pil_nextline();
  491.         pil_put_kw(PIL_KW_FLOW_OBJECTS);
  492.         if (pil_put_objid(tfptr->objects) != PIL_OK)
  493.             return (pil_last_error());
  494.     }
  495.     if (tfptr->content) {
  496.         pil_nextline();
  497.         pil_put_kw(PIL_KW_FLOW_CONTENT);
  498.         if (pil_put_objid(tfptr->content) != PIL_OK)
  499.             return (pil_last_error());
  500.     }
  501.     pil_put_nested_endblk();
  502.     pil_nextline();
  503.     return (PIL_OK);
  504. }
  505. /*=======================================================================*\
  506.   pil_put_group
  507.  
  508.     Subroutine for pil_put_component.
  509.     Writes a pil_group to the open pil file.
  510.  
  511.     Entry:    Pointer to a pil_group
  512.  
  513.     Exit:    Error code is returned.
  514.  
  515. \*-----------------------------------------------------------------------*/
  516.  
  517. PIL_ERROR pil_put_group(gptr)
  518. pil_group PTRTYPE *gptr;
  519. {
  520.     pil_put_named_begblk(PIL_KW_GROUP);
  521.     pil_nextline();
  522.     if (gptr->name) {
  523.         pil_put_kw(PIL_KW_ID);
  524.         pil_put_quoted_str(gptr->name);
  525.         pil_nextline();
  526.     }
  527.     if (gptr->objects) {
  528.         pil_put_kw(PIL_KW_GROUP_OBJECTS);
  529.         if (pil_put_objid(gptr->objects) != PIL_OK)
  530.             return (pil_last_error());
  531.     }
  532.     pil_put_nested_endblk();
  533.     pil_nextline();
  534.     return (PIL_OK);
  535. }
  536.  
  537. /*=======================================================================*\
  538.   pil_put_layout_end
  539.  
  540.     Subroutine for pil_put_component.
  541.     Writes a pil_layout_end to the open pil file.
  542.  
  543.     Entry:    Pointer to a pil_layout_end
  544.  
  545.     Exit:    Error code is returned.
  546.  
  547. \*-----------------------------------------------------------------------*/
  548.  
  549. PIL_ERROR pil_put_layout_end(leptr)
  550. pil_layout_end PTRTYPE *leptr;
  551. {
  552.     if (!PIL_RIGHT_CMPNT(leptr,PIL_LAYOUT_END_C))
  553.         return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  554.     pil_put_nested_endblk();
  555.     pil_nextline();
  556.     return (PIL_OK);
  557. }
  558.  
  559. /*=======================================================================*\
  560.   pil_put_content_start
  561.  
  562.     Subroutine for pil_put_component.
  563.     Writes a pil_content_start to the open pil file.
  564.  
  565.     Entry:    Pointer to a pil_content_start
  566.  
  567.     Exit:    Err code returned.
  568.  
  569. \*-----------------------------------------------------------------------*/
  570.  
  571. PIL_ERROR pil_put_content_start(csptr)
  572. pil_content_start PTRTYPE *csptr;
  573. {
  574.     /* set up the content header defaults for this entity */
  575.     if (!PIL_RIGHT_CMPNT(csptr,PIL_CONTENT_START_C))
  576.         return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  577.     pil_set_dflt_hdr();
  578.     pil_put_kw_no_sep(PIL_KW_CONTENT);
  579.     pil_put_literal(csptr->version);
  580.     pil_put_quoted_str(csptr->name);
  581.     pil_put_nested_begblk();
  582.     pil_nextline();
  583.     return (PIL_OK);
  584. }
  585.  
  586. /*=======================================================================*\
  587.   pil_put_content_hdr
  588.  
  589.     Subroutine for pil_put_component.
  590.     Writes a header for content data to the open pil file.
  591.     If called with a pointer to a content header, it writes that header.
  592.     Can also be called with a null pointer, in which case it writes out
  593.     the current (last used) content header (but does not reset it to
  594.     the defaults).
  595.  
  596.     Entry:    Pointer to a pil_content_hdr
  597.  
  598.     Exit:    Err code returned.
  599.  
  600. \*-----------------------------------------------------------------------*/
  601.  
  602. PIL_ERROR pil_put_content_hdr(chptr)
  603. FAST pil_content_hdr PTRTYPE *chptr;
  604. {
  605.     /* Set up new header data, if we were passed a valid header */
  606.     if (chptr != NULL) {
  607.         if (!PIL_RIGHT_CMPNT(chptr,PIL_CONTENT_HDR_C))
  608.             return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  609.         if (chptr->encoding != PIL_ASCII_CONTENT &&
  610.             chptr->encoding != PIL_BINARY_CONTENT) {
  611.             return (pil_set_error(PIL_UNKN_HDR_ENC));
  612.         }
  613.         if (chptr->byteorder != PIL_LITTLE_ENDIAN &&
  614.             chptr->byteorder != PIL_BIG_ENDIAN) {
  615.             return (pil_set_error(PIL_UNKN_HDR_BORD));
  616.         }
  617.         if (chptr->endblkchar == chptr->escapechar) {
  618.             return (pil_set_error(PIL_BAD_HEADER));
  619.         }
  620.         /* NOTE: for binary data, the escape, begin block and end block */
  621.         /*    characters can be ignored. Therefore, we check here and set */
  622.         /*    them to the language "defaults" if we have binary data */
  623.         currenthdr.encoding = chptr->encoding;
  624.         currenthdr.byteorder = chptr->byteorder;
  625.         if (chptr->encoding == PIL_BINARY_CONTENT) {
  626.             currenthdr.escapechar = PIL_DFT_CNT_ESC;
  627.             currenthdr.begblkchar = PIL_DFT_CNT_BEG;
  628.             currenthdr.endblkchar = PIL_DFT_CNT_END;
  629.         }
  630.         else {
  631.             currenthdr.escapechar = chptr->escapechar;
  632.             currenthdr.begblkchar = chptr->begblkchar;
  633.             currenthdr.endblkchar = chptr->endblkchar;
  634.         }
  635.     }
  636.     pil_put_kw(PIL_KW_HEADER);
  637.     pil_put_string(BEGINLIST);
  638.     if (currenthdr.byteorder == PIL_LITTLE_ENDIAN) {
  639.         pil_put_kw(PIL_KW_LITTLE_ENDIAN);
  640.     }
  641.     else {
  642.         pil_put_kw(PIL_KW_BIG_ENDIAN);
  643.     }
  644.     if (currenthdr.encoding == PIL_ASCII_CONTENT) {
  645.         pil_put_kw(PIL_KW_ASCII);
  646.     }
  647.     else {
  648.         pil_put_kw(PIL_KW_BINARY);
  649.     }
  650.     pil_put_ui32((PIL_UINT32)currenthdr.escapechar);
  651.     pil_put_ui32((PIL_UINT32)currenthdr.begblkchar);
  652.     pil_put_ui32((PIL_UINT32)currenthdr.endblkchar);
  653.     pil_put_string(ENDBLOCK);
  654.     pil_nextline();
  655.     return (PIL_OK);
  656. }
  657. /*=======================================================================*\
  658.   pil_put_content_data
  659.  
  660.     Subroutine for pil_put_component.
  661.     Writes a pil_content_start to the open pil file.
  662.  
  663.     Entry:    Pointer to a pil_content_start 
  664.  
  665.     Exit:    Err code returned.
  666.  
  667. \*-----------------------------------------------------------------------*/
  668.  
  669. PIL_ERROR pil_put_content_data(cdptr)
  670. pil_content_data PTRTYPE *cdptr;
  671. {
  672. FAST PIL_UINT8    end,esc,c;
  673. char lilbuf[4];
  674. static char linebuf[60];
  675. static int    bufpos = 0;
  676. FAST char PTRTYPE *p;
  677. PIL_UINT32    l;
  678.     if (!PIL_RIGHT_CMPNT(cdptr,PIL_CONTENT_DATA_C))
  679.         return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  680.     pil_put_kw(PIL_KW_DATA);
  681.     (pil_putchar)(currenthdr.begblkchar);
  682.     p = cdptr->data;
  683.     if ((l = cdptr->length) > 0) {
  684.         if (currenthdr.encoding == PIL_ASCII_CONTENT) {
  685.             end = currenthdr.endblkchar;
  686.             esc = currenthdr.escapechar;
  687.             while (l--) {
  688.             /* if an endblock character or non-printing character occurs in */
  689.             /* the data, escape it */
  690.                 c = *p++;
  691.                 if (c == esc || c == end || c < ' ' || c > '~')
  692.                 {
  693.                     lilbuf[0] = esc;
  694.                     lilbuf[1] = hex[c >> 4];
  695.                     lilbuf[2] = hex[c & 0x0F];
  696.                     lilbuf[3] = '\0';
  697.                     pil_put_string(lilbuf);
  698.                 }
  699.                 else {
  700.                     (pil_putchar)(c);
  701.                 }
  702.             }
  703.         }
  704.         else {                /* binary data, just pump it out neatly */
  705.             pil_nextline();    /* whitespace is tolerated */
  706.             while (l--) {
  707.                 c = *p++;
  708.                 if (bufpos > sizeof(linebuf) - 4) {
  709.                     linebuf[bufpos] = '\0';
  710.                     pil_put_string(linebuf);
  711.                     pil_nextline();
  712.                     bufpos = 0;
  713.                     linebuf[0] = '\0';
  714.                 }
  715.                 linebuf[bufpos++] = hex[c >> 4];
  716.                 linebuf[bufpos++] = hex[c & 0x0F];
  717.                 linebuf[bufpos++] = ' ';
  718.             }
  719.             if (bufpos > 0) {
  720.                 linebuf[bufpos] = '\0';
  721.                 pil_put_string(linebuf);
  722.                 pil_nextline();
  723.                 bufpos = 0;
  724.                 linebuf[0] = '\0';
  725.             }
  726.         }
  727.     }
  728.     (pil_putchar)(currenthdr.endblkchar);
  729.     pil_nextline();
  730.     return (PIL_OK);
  731. }
  732.  
  733. /*=======================================================================*\
  734.   pil_put_content_end
  735.  
  736.     Subroutine for pil_put_component.
  737.     Writes a pil_content_end to the open pil file.
  738.  
  739.     Entry:    Pointer to a pil_content_end
  740.  
  741.     Exit:    Error code is returned.
  742.  
  743. \*-----------------------------------------------------------------------*/
  744.  
  745. PIL_ERROR pil_put_content_end(ceptr)
  746. pil_content_end PTRTYPE *ceptr;
  747. {
  748.     if (!PIL_RIGHT_CMPNT(ceptr,PIL_CONTENT_END_C))
  749.         return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  750.     pil_put_nested_endblk();
  751.     pil_nextline();
  752.     return (PIL_OK);
  753. }
  754.  
  755. /*=======================================================================*\
  756.   pil_put_dimensions
  757.  
  758.     Subroutine for pil_put_canvas, pil_put_object.
  759.     Writes a dimensions to the open pil file.
  760.  
  761.     Entry:    width, height (UIN32)
  762.  
  763.     Exit:    Error code is returned.
  764.  
  765. \*-----------------------------------------------------------------------*/
  766. PIL_ERROR pil_put_dimensions(width, height)
  767. PIL_UINT32 width,height;
  768. {
  769.     if (width == 0 || height == 0) return (pil_set_error(PIL_ZERO_DIMENSION));
  770.     pil_put_kw(PIL_KW_DIMENSIONS);
  771.     pil_put_string(BEGINBLOCK);
  772.     pil_put_ui32(width);
  773.     pil_put_ui32(height);
  774.     pil_put_string(ENDBLOCK);
  775.     return (PIL_OK);
  776. }
  777.     
  778. /*=======================================================================*\
  779.   pil_put_clipper
  780.  
  781.     Subroutine for pil_put_canvas, pil_put_object.
  782.     Writes a pil_clipshape to the open pil file.
  783.  
  784.     Entry:    Pointer to a pil_clipper
  785.  
  786.     Exit:    Error code is returned.
  787.  
  788. \*-----------------------------------------------------------------------*/
  789. PIL_ERROR pil_put_clipper(cptr)
  790. pil_clipper PTRTYPE *cptr;
  791. {
  792.     pil_put_named_begblk(PIL_KW_CLIPPER);
  793.     pil_nextline();
  794.     if (IS_OPEN_SHAPE(cptr->type)) return (pil_set_error(PIL_OPEN_CLIPPER));
  795.     if (pil_put_closed_shape(cptr) != PIL_OK) return (pil_last_error());
  796.     pil_put_nested_endblk();
  797.     return (PIL_OK);
  798. }
  799.  
  800. /*=======================================================================*\
  801.   pil_put_container
  802.  
  803.     Subroutine for pil_put_object.
  804.     Writes a pil_container to the open pil file.
  805.  
  806.     Entry:    Pointer to a pil_clipper
  807.  
  808.     Exit:    Error code is returned.
  809.  
  810. \*-----------------------------------------------------------------------*/
  811. PIL_ERROR pil_put_container(cptr)
  812. pil_container PTRTYPE *cptr;
  813. {
  814.     pil_put_named_begblk(PIL_KW_CONTAINER);
  815.     pil_nextline();
  816.     if (IS_OPEN_SHAPE(cptr->type)) return (pil_set_error(PIL_OPEN_CONTAINER));
  817.     if (pil_put_closed_shape(cptr) != PIL_OK) return (pil_last_error());
  818.     pil_put_nested_endblk();
  819.     return (PIL_OK);
  820. }
  821.  
  822. /*=======================================================================*\
  823.   pil_put_graphic
  824.  
  825.     Subroutine for pil_put_object.
  826.     Writes a pil_graphic to the open pil file.
  827.  
  828.     Entry:    Pointer to a pil_graphic
  829.  
  830.     Exit:    Error code is returned.
  831.  
  832. \*-----------------------------------------------------------------------*/
  833. PIL_ERROR pil_put_graphic(gptr)
  834. pil_graphic PTRTYPE *gptr;
  835. {
  836.     static int colortokens[] = {
  837.         PIL_KW_DEV_GRAY,            /*    PIL_DEV_GRAY_CM        0x0000 */
  838.         PIL_KW_CAL_GRAY,            /*    PIL_CAL_GRAY_CM        0x0001 */
  839.         PIL_KW_DEV_RGB,                /*    PIL_DEV_RGB_CM        0x0002 */
  840.         PIL_KW_CAL_RGB,                /*    PIL_CAL_RGB_CM        0x0003 */
  841.         PIL_KW_DEV_CMYK,            /*    PIL_DEV_CMYK_CM        0x0004 */
  842.         PIL_KW_PANTONE,                /*    PIL_PANTONE_CM        0x0005 */
  843.         PIL_KW_SPOT                    /*    PIL_SPOT_CM            0x0006 */
  844.     };
  845.     static int renderops[] = {
  846.         0,
  847.         PIL_KW_FILL,                /* PIL_FILL_RENDER_OP            0x0001 */
  848.         PIL_KW_STROKE,                /* PIL_STROKE_RENDER_OP            0x0002 */
  849.         PIL_KW_FILL_STROKE            /* PIL_FILL_STROKE_RENDER_OP    0x0003 */
  850.     };
  851.     
  852.     pil_put_named_begblk(PIL_KW_GRAPHIC);
  853.     /* put the color model */
  854.     if (gptr->color_model > PIL_SPOT_CM) {
  855.         return (pil_set_error(PIL_UNKN_CM));
  856.     }
  857.     else {
  858.         pil_nextline();
  859.         pil_put_kw(PIL_KW_COLOR_MODEL); 
  860.         pil_put_kw(colortokens[gptr->color_model]); 
  861.     }
  862.     
  863.     /* put the renderop */
  864.     if (gptr->renderop < PIL_FILL_RENDER_OP || 
  865.         gptr->renderop > PIL_FILL_STROKE_RENDER_OP) 
  866.         return (pil_set_error(PIL_UNKN_RENDEROP));
  867.     pil_nextline();
  868.     pil_put_kw(PIL_KW_RENDER_OP);
  869.     pil_put_kw(renderops[gptr->renderop]);
  870.     pil_nextline();
  871.     
  872.     /* then the render attributes */
  873.     pil_put_named_begblk(PIL_KW_RENDER_ATTR); 
  874.     if (PIL_IS_STROKE_OP(gptr->renderop)) {        /* the stroke attributes */
  875.         /* Write out the stroke color */
  876.         pil_nextline();
  877.         pil_put_kw(PIL_KW_STROKE_COLOR);
  878.         if (pil_put_color(gptr->color_model,&gptr->stroke_color) != PIL_OK)
  879.             return (pil_last_error());
  880.  
  881.         /* Write out the line position, if not the default */
  882.         if (gptr->lineposition != PIL_CENTERED) {
  883.             pil_nextline();
  884.             pil_put_kw(PIL_KW_POSITION); 
  885.             if (gptr->lineposition == PIL_INSIDE) {
  886.                 pil_put_kw(PIL_KW_INSIDE); 
  887.             }
  888.             else if (gptr->lineposition == PIL_OUTSIDE){
  889.                 pil_put_kw(PIL_KW_OUTSIDE); 
  890.             }
  891.             else {
  892.                 return (pil_set_error(PIL_UNKN_RENDEROP));
  893.             }
  894.         }
  895.         
  896.         /* Write out the line width, if not the default */
  897.         if (gptr->linewidth != 10) {
  898.             pil_nextline();
  899.             pil_put_kw(PIL_KW_WIDTH); 
  900.             pil_put_ui32(gptr->linewidth);
  901.         }
  902.         
  903.         /* Write out the line cap, if not the default */
  904.         if (gptr->linecap != PIL_BUTT_CAP) {
  905.             pil_nextline();
  906.             pil_put_kw(PIL_KW_CAP); 
  907.             if (gptr->linecap == PIL_ROUND_CAP) {
  908.                 pil_put_kw(PIL_KW_ROUND_CAP); 
  909.             }
  910.             else if (gptr->linecap == PIL_PROJECTING_CAP){
  911.                 pil_put_kw(PIL_KW_PROJECTING_CAP); 
  912.             }
  913.             else {
  914.                 return (pil_set_error(PIL_UNKN_RENDEROP));
  915.             }
  916.         }
  917.         
  918.         /* Write out the line join, if not the default */
  919.         if (gptr->linejoin != PIL_MITER_JOIN) {
  920.             pil_nextline();
  921.             pil_put_kw(PIL_KW_JOIN); 
  922.             if (gptr->linejoin == PIL_BEVEL_JOIN) {
  923.                 pil_put_kw(PIL_KW_BEVEL_JOIN); 
  924.             }
  925.             else if (gptr->linejoin == PIL_ROUND_JOIN){
  926.                 pil_put_kw(PIL_KW_ROUND_JOIN); 
  927.             }
  928.             else {
  929.                 return (pil_set_error(PIL_UNKN_RENDEROP));
  930.             }
  931.         }
  932.         
  933.         /* Write out the miter limit, if not the default */
  934.         if (gptr->miter_limit != 10.0) {
  935.             if (gptr->miter_limit < 1.0) return (pil_set_error(PIL_BAD_MITERLIM));
  936.             pil_nextline();
  937.             pil_put_kw(PIL_KW_MITER_LIMIT); 
  938.             pil_put_dbl(gptr->miter_limit);
  939.         }
  940.         
  941.     }
  942.     if (PIL_IS_FILL_OP(gptr->renderop)) {                /* do the fill attributes */
  943.         /* Write out the fill color */
  944.         pil_nextline();
  945.         pil_put_kw(PIL_KW_FILL_COLOR);
  946.         if (pil_put_color(gptr->color_model,&gptr->fill_color) != PIL_OK)
  947.             return (pil_last_error());
  948.         if (gptr->fill_rule != PIL_EVEN_ODD) {
  949.             pil_nextline();
  950.             pil_put_kw(PIL_KW_FILL_RULE); 
  951.             if (gptr->fill_rule == PIL_NON_ZERO_WINDING){
  952.                 pil_put_kw(PIL_KW_NZ_WINDING); 
  953.             }
  954.             else {
  955.                 return (pil_set_error(PIL_UNKN_FILLRULE));
  956.             }
  957.         }
  958.     }
  959.     pil_put_nested_endblk();
  960.     pil_nextline();
  961.     /*    Check for 2 special "pseudoshapes" which are only used for the 
  962.         object graphic shape, and hence are not included directly in 
  963.         pil_put_shape: PIL_KW_CLIPPER_SHAPE and PIL_KW_CONTAINER_SHAPE */
  964.     if (gptr->shape.type == PIL_CLIPPER_SHAPE) {
  965.         pil_put_kw(PIL_KW_CLIPPER_SHAPE);
  966.     }
  967.     else if (gptr->shape.type == PIL_CONTAINER_SHAPE) {
  968.         pil_put_kw(PIL_KW_CONTAINER_SHAPE);
  969.     }
  970.     else {
  971.         if (pil_put_shape(&gptr->shape) != PIL_OK) return (pil_last_error());
  972.     }
  973.     pil_put_nested_endblk();
  974.     return (PIL_OK);
  975. }
  976. /*=======================================================================*\
  977.   pil_put_color
  978.  
  979.     Subroutine for pil_put_clipper, pil_put_object.
  980.     Writes a pil_primitive to the open pil file.
  981.  
  982.     Entry:    Pointer to a pil_primitive
  983.  
  984.     Exit:    Error code is returned.
  985.  
  986. \*-----------------------------------------------------------------------*/
  987. PIL_ERROR pil_put_color(model,color)
  988. PIL_UINT16    model;
  989. pil_color    PTRTYPE *color;
  990. {
  991.     switch (model) {
  992.         case PIL_DEV_GRAY_CM:
  993.         case PIL_CAL_GRAY_CM:
  994.             if (color->devgray.value < 0.0 || color->devgray.value > 1.0)
  995.                 return (PIL_BAD_COLOR);
  996.             pil_put_dbl(color->devgray.value);
  997.             break;
  998.         case PIL_DEV_RGB_CM:
  999.         case PIL_CAL_RGB_CM:
  1000.             if (color->devrgb.r < 0.0 || color->devrgb.r > 1.0  ||
  1001.                 color->devrgb.g < 0.0 || color->devrgb.g > 1.0  ||
  1002.                 color->devrgb.b < 0.0 || color->devrgb.b > 1.0)
  1003.                 return (PIL_BAD_COLOR);
  1004.             pil_put_string(BEGINLIST);
  1005.             pil_put_dbl(color->devrgb.r);
  1006.             pil_put_dbl(color->devrgb.g);
  1007.             pil_put_dbl(color->devrgb.b);
  1008.             pil_put_string(ENDBLOCK);
  1009.              break;
  1010.          case PIL_DEV_CMYK_CM:
  1011.             if (color->devcmyk.c < 0.0 || color->devcmyk.c > 1.0 ||
  1012.                 color->devcmyk.m < 0.0 || color->devcmyk.m > 1.0 ||
  1013.                 color->devcmyk.y < 0.0 || color->devcmyk.y > 1.0 ||
  1014.                 color->devcmyk.k < 0.0 || color->devcmyk.k > 1.0)
  1015.                 return (PIL_BAD_COLOR);
  1016.             pil_put_string(BEGINLIST);
  1017.             pil_put_dbl(color->devcmyk.c);
  1018.             pil_put_dbl(color->devcmyk.m);
  1019.             pil_put_dbl(color->devcmyk.y);
  1020.             pil_put_dbl(color->devcmyk.k);
  1021.             pil_put_string(ENDBLOCK);
  1022.              break;
  1023.         case PIL_PANTONE_CM:
  1024.         case PIL_SPOT_CM:
  1025.             pil_put_quoted_str(color->pantone.name);
  1026.             break;
  1027.         default:
  1028.             return (pil_set_error(PIL_UNKN_CM));    
  1029.     }
  1030.     pil_nextline();
  1031.     return (PIL_OK);
  1032. }
  1033.  
  1034. /*=======================================================================*\
  1035.   pil_put_closed_shape
  1036.  
  1037.     Subroutine for pil_put_clipper, pil_put_object.
  1038.     Writes a pil_primitive to the open pil file.
  1039.  
  1040.     Entry:    Pointer to a pil_primitive
  1041.  
  1042.     Exit:    Error code is returned.
  1043.  
  1044. \*-----------------------------------------------------------------------*/
  1045. PIL_ERROR pil_put_closed_shape(cptr)
  1046. pil_closed_primitive PTRTYPE *cptr;
  1047. {
  1048.     PIL_ERROR rc;
  1049.  
  1050.     if (pil_put_shape_code(cptr->type) != PIL_OK) return (pil_last_error());
  1051.     switch (cptr->type) {
  1052.         case    PIL_RECTANGLE_SHAPE:
  1053.             rc = pil_put_rectdata(&cptr->shape.rect);
  1054.             break;
  1055.         case    PIL_CIRCLE_SHAPE:
  1056.             rc = pil_put_circledata(&cptr->shape.circle);
  1057.             break;
  1058.         case    PIL_ELLIPSE_SHAPE:
  1059.             rc = pil_put_rectdata((pil_rectangle PTRTYPE *)&cptr->shape.ellipse);
  1060.             break;
  1061.         case    PIL_POLYGON_SHAPE:
  1062.             rc = pil_put_polydata(&cptr->shape.polygon);
  1063.             break;
  1064.         case    PIL_CLOSEDPATH_SHAPE:
  1065.             rc = pil_put_pathdata(&cptr->shape.closedpath);
  1066.             break;
  1067.         default:
  1068.             rc = pil_set_error(PIL_UNKN_SHAPE);
  1069.             break;
  1070.     }
  1071.     return(rc);
  1072. }
  1073. /*=======================================================================*\
  1074.   pil_put_shape
  1075.  
  1076.     Subroutine for pil_put_clipper, pil_put_object, pil_put_graphic.
  1077.     Writes a pil_primitive to the open pil file.
  1078.  
  1079.     Entry:    Pointer to a pil_primitive
  1080.  
  1081.     Exit:    Error code is returned.
  1082.  
  1083. \*-----------------------------------------------------------------------*/
  1084. PIL_ERROR pil_put_shape(cptr)
  1085. pil_primitive PTRTYPE *cptr;
  1086. {
  1087.     PIL_ERROR rc;
  1088.  
  1089.     if (pil_put_shape_code(cptr->type) != PIL_OK) 
  1090.         return (pil_last_error());
  1091.     switch (cptr->type) {
  1092.         case    PIL_LINE_SHAPE:
  1093.             rc = pil_put_line(&cptr->shape.line);
  1094.             break;
  1095.         case    PIL_ARC_SHAPE:
  1096.             rc = pil_put_arc(&cptr->shape.arc);
  1097.             break;
  1098.         case    PIL_BEZIER_SHAPE:
  1099.             rc = pil_put_bezier(&cptr->shape.bezier);
  1100.             break;
  1101.         case    PIL_RECTANGLE_SHAPE:
  1102.             rc = pil_put_rectdata(&cptr->shape.rect);
  1103.             break;
  1104.         case    PIL_CIRCLE_SHAPE:
  1105.             rc = pil_put_circledata(&cptr->shape.circle);
  1106.             break;
  1107.         case    PIL_ELLIPSE_SHAPE:
  1108.             rc = pil_put_rectdata((pil_rectangle PTRTYPE *)&cptr->shape.ellipse);
  1109.             break;
  1110.         case    PIL_POLYGON_SHAPE:
  1111.         case    PIL_POLYLINE_SHAPE:
  1112.             rc = pil_put_polydata(&cptr->shape.polygon);
  1113.             break;
  1114.         case    PIL_CLOSEDPATH_SHAPE:
  1115.         case    PIL_OPENPATH_SHAPE:
  1116.             rc = pil_put_pathdata(&cptr->shape.closedpath);
  1117.             break;
  1118.         default:
  1119.             rc = pil_set_error(PIL_UNKN_SHAPE);
  1120.             break;
  1121.     }
  1122.     return (rc);
  1123. }
  1124. /*=======================================================================*\
  1125.   pil_put_line
  1126.  
  1127.     Subroutine for pil_put_shape.
  1128.     Writes a pil_line to the open pil file.
  1129.  
  1130.     Entry:    Pointer to a pil_primitive
  1131.  
  1132.     Exit:    Error code is returned.
  1133.  
  1134. \*-----------------------------------------------------------------------*/
  1135. PIL_ERROR pil_put_line(ptr)
  1136. pil_line PTRTYPE *ptr;
  1137. {
  1138.     if (SAMEPOINT(ptr->start,ptr->end)) 
  1139.         return (pil_set_error(PIL_ZERO_LENGTH));
  1140.     pil_put_string(BEGINBLOCK);
  1141.     pil_put_point_data(&ptr->start);
  1142.     pil_put_point_data(&ptr->end);
  1143.     pil_put_string(ENDBLOCK);
  1144.     return (PIL_OK);
  1145. }
  1146. /*=======================================================================*\
  1147.   pil_put_arc
  1148.  
  1149.     Subroutine for pil_put_shape.
  1150.     Writes a pil_arc to the open pil file.
  1151.  
  1152.     Entry:    Pointer to a pil_arc
  1153.  
  1154.     Exit:    Error code is returned.
  1155.  
  1156. \*-----------------------------------------------------------------------*/
  1157. PIL_ERROR pil_put_arc(ptr)
  1158. pil_arc PTRTYPE *ptr;
  1159. {
  1160.     if (ptr->arc_square.length == 0 ||
  1161.         (ptr->start_angle == ptr->end_angle)) {
  1162.         return (pil_set_error(PIL_ZERO_SHAPE));
  1163.     }
  1164.     pil_put_string(BEGINBLOCK);
  1165.     pil_put_point_data(&ptr->arc_square.ul);
  1166.     pil_put_ui32(ptr->arc_square.length);
  1167.     pil_put_dbl(ptr->start_angle);
  1168.     pil_put_dbl(ptr->end_angle);
  1169.     pil_put_string(ENDBLOCK);
  1170.     return (PIL_OK);
  1171. }
  1172. /*=======================================================================*\
  1173.   pil_put_bezier
  1174.  
  1175.     Subroutine for pil_put_shape.
  1176.     Writes a pil_bezier to the open pil file.
  1177.  
  1178.     Entry:    Pointer to a pil_bezier
  1179.  
  1180.     Exit:    Error code is returned.
  1181.  
  1182. \*-----------------------------------------------------------------------*/
  1183. PIL_ERROR pil_put_bezier(ptr)
  1184. pil_bezier PTRTYPE *ptr;
  1185. {
  1186.     pil_put_string(BEGINBLOCK);
  1187.     pil_put_point(&ptr->start);
  1188.     pil_put_point(&ptr->start_ctrl_pt);
  1189.     pil_put_point(&ptr->end_ctrl_pt);
  1190.     pil_put_point(&ptr->end);
  1191.     pil_put_string(ENDBLOCK);
  1192.     return (PIL_OK);
  1193. }
  1194.  
  1195. /*=======================================================================*\
  1196.   pil_put_rectdata
  1197.  
  1198.     Subroutine for pil_put_shape
  1199.     Writes a pil_rectangle to the open pil file.
  1200.  
  1201.     Entry:    Pointer to a pil_rectangle
  1202.  
  1203.     Exit:    Error code is returned.
  1204.  
  1205. \*-----------------------------------------------------------------------*/
  1206. PIL_ERROR pil_put_rectdata(ptr)
  1207. pil_rectangle PTRTYPE *ptr;
  1208. {
  1209.     if (ptr->height == 0 || ptr->width == 0) 
  1210.         return (pil_set_error(PIL_ZERO_SHAPE));
  1211.     pil_put_string(BEGINBLOCK);
  1212.     pil_put_point_data(&ptr->ul);
  1213.     pil_put_ui32(ptr->width);
  1214.     pil_put_ui32(ptr->height);
  1215.     pil_put_string(ENDBLOCK);
  1216.     return (PIL_OK);
  1217. }
  1218. /*=======================================================================*\
  1219.   pil_circledata
  1220.  
  1221.     Subroutine for pil_put_shape.
  1222.     Writes a pil_circle to the open pil file.
  1223.  
  1224.     Entry:    Pointer to a pil_circle
  1225.  
  1226.     Exit:    Error code is returned.
  1227.  
  1228. \*-----------------------------------------------------------------------*/
  1229. PIL_ERROR pil_put_circledata(ptr)
  1230. pil_circle PTRTYPE *ptr;
  1231. {
  1232.     if (ptr->length == 0) return (pil_set_error(PIL_ZERO_SHAPE));
  1233.     pil_put_string(BEGINBLOCK);
  1234.     pil_put_i32(ptr->ul.x);
  1235.     pil_put_i32(ptr->ul.y);
  1236.     pil_put_ui32(ptr->length);
  1237.     pil_put_string(ENDBLOCK);
  1238.     return (PIL_OK);
  1239. }
  1240. /*=======================================================================*\
  1241.   pil_put_pathdata
  1242.  
  1243.     Subroutine for pil_put_shape.
  1244.     Writes the points of a pil_path to the open pil file.
  1245.  
  1246.     Entry:    Pointer to a pil_polygon
  1247.  
  1248.     Exit:    Error code is returned.
  1249.  
  1250. \*-----------------------------------------------------------------------*/
  1251. PIL_ERROR pil_put_pathdata(ptr)
  1252. pil_path_pt PTRTYPE *ptr;
  1253. {
  1254.     pil_put_nested_begblk();
  1255.     pil_nextline();
  1256.     if (ptr->type != PIL_MOVE_TO) return (pil_set_error(PIL_NEED_MOVE_TO));
  1257.     while (ptr != NULL) {
  1258.         switch(ptr->type) {
  1259.             case PIL_MOVE_TO:
  1260.                 pil_put_kw(PIL_KW_MOVE_TO); 
  1261.                 pil_put_point(&ptr->p.mt.pt);
  1262.                 break;
  1263.             case PIL_LINE_TO:
  1264.                 pil_put_kw(PIL_KW_LINE_TO); 
  1265.                 pil_put_point(&ptr->p.lt.pt);
  1266.                 break;
  1267.             case PIL_CURVE_TO:
  1268.                 pil_put_kw(PIL_KW_CURVE_TO); 
  1269.                 pil_put_string(BEGINBLOCK);
  1270.                 pil_put_point(&ptr->p.ct.ctrl_pt_1);
  1271.                 pil_put_point(&ptr->p.ct.ctrl_pt_2);
  1272.                 pil_put_point(&ptr->p.ct.end_pt);
  1273.                 pil_put_string(ENDBLOCK);
  1274.                 break;
  1275.             case PIL_ARC_TO:
  1276.                 pil_put_kw(PIL_KW_ARC_TO); 
  1277.                 pil_put_string(BEGINBLOCK);
  1278.                 pil_put_point(&ptr->p.at.ctrl_pt_1);
  1279.                 pil_put_point(&ptr->p.at.ctrl_pt_2);
  1280.                 pil_put_i32(ptr->p.at.radius);
  1281.                 pil_put_string(ENDBLOCK);
  1282.                 break;
  1283.             default:
  1284.                 return (pil_set_error(PIL_UNKN_PATHPT));
  1285.         }
  1286.         if ((ptr = ptr->next) != NULL) {
  1287.             pil_nextline();
  1288.         }
  1289.         else {
  1290.             break;
  1291.         }
  1292.     }
  1293.     pil_put_nested_endblk();
  1294.     return (PIL_OK);
  1295. }
  1296.  
  1297. /*=======================================================================*\
  1298.   pil_put_polydata
  1299.  
  1300.     Subroutine for pil_put_shape.
  1301.     Writes the points of a pil_polygon or pil_polyline to the open pil file.
  1302.  
  1303.     Entry:    Pointer to a pil_polygon
  1304.  
  1305.     Exit:    Error code is returned.
  1306.  
  1307. \*-----------------------------------------------------------------------*/
  1308. PIL_ERROR pil_put_polydata(ptr)
  1309. pil_poly_pt PTRTYPE *ptr;
  1310. {
  1311.     pil_put_nested_begblk();
  1312.     pil_nextline();
  1313.     for (;;) {
  1314.         pil_put_point(&ptr->p);
  1315.         if ((ptr = ptr->next) == NULL)
  1316.             break;
  1317.         else 
  1318.             pil_nextline();
  1319.     }
  1320.     pil_put_nested_endblk();
  1321.     return (PIL_OK);
  1322. }
  1323. /*=======================================================================*\
  1324.   pil_put_point
  1325.  
  1326.     Subroutine to write a pil_point to the open pil file.
  1327.  
  1328.     Entry:    Pointer to a pil_point
  1329.  
  1330.     Exit:    Error code is returned.
  1331.  
  1332. \*-----------------------------------------------------------------------*/
  1333. PIL_VOID pil_put_point(ptr)
  1334. pil_point PTRTYPE *ptr;
  1335. {
  1336.     pil_put_string(BEGINBLOCK);
  1337.     pil_put_point_data(ptr);
  1338.     pil_put_string(ENDBLOCK);
  1339. }
  1340. /*=======================================================================*\
  1341.   pil_put_point_data
  1342.  
  1343.     Subroutine to write coordinates of a pil_point to the open pil file.
  1344.  
  1345.     Entry:    Pointer to a pil_point
  1346.  
  1347.     Exit:    Error code is returned.
  1348.  
  1349. \*-----------------------------------------------------------------------*/
  1350. PIL_VOID pil_put_point_data(ptr)
  1351. pil_point PTRTYPE *ptr;
  1352. {
  1353.     pil_put_i32(ptr->x);
  1354.     pil_put_i32(ptr->y);
  1355. }
  1356.  
  1357. /*=======================================================================*\
  1358.   pil_put_nametblentry
  1359.  
  1360.     Writes a pil_name_table_entry to the open pil file.
  1361.  
  1362.     Entry:    Pointer to a pil_name_table *
  1363.  
  1364.     Exit:    Error code is returned.
  1365.  
  1366. \*-----------------------------------------------------------------------*/
  1367. PIL_ERROR pil_put_nametbleentry(ptr)
  1368. FAST pil_name_table_entry PTRTYPE *ptr;
  1369. {
  1370.     if (ptr->name == NULL) return (pil_set_error(PIL_BAD_NTE));
  1371.     pil_put_quoted_str(ptr->name);
  1372.     if (pil_put_ctype_code(ptr->content_type_code, ptr->content_type_string) 
  1373.         != PIL_OK) return (pil_last_error());
  1374.     if (pil_put_domain_code(ptr->domain_type_code, ptr->domain_type_string) 
  1375.         != PIL_OK) return (pil_last_error());
  1376.     switch (ptr->value_type_code) {
  1377.         case    PIL_VAL_INLINE:
  1378.             pil_put_kw(PIL_KW_INLINE);
  1379.             break;
  1380.         case    PIL_VAL_UNKNOWN:
  1381.             pil_put_kw(PIL_KW_UNKNOWN);
  1382.             break;
  1383.         case    PIL_VAL_OTHER:
  1384.             if (ptr->value_type_string == NULL)
  1385.                 return  (pil_set_error(PIL_BAD_NTE));
  1386.             else
  1387.                 pil_put_quoted_str(ptr->value_type_string);
  1388.             break;
  1389.         default:
  1390.             return (pil_set_error(PIL_BAD_NTE));
  1391.     }
  1392.     return (PIL_OK);
  1393. }
  1394.  
  1395. /*=======================================================================*\
  1396.   pil_put_ctype_code
  1397.  
  1398.     Writes a content type code to the open pil file. This routine depends
  1399.     on the fact that the content type codes as defined in pildefs.h are
  1400.     sequential integers which can be used as an array index. The array
  1401.     declared below puts the appropriate keyword value for each content
  1402.     type at the appropriate place in the array.
  1403.  
  1404.     Entry:    UINT16 that is a pil content type code
  1405.  
  1406.     Exit:    Error code is returned.
  1407.  
  1408. \*-----------------------------------------------------------------------*/
  1409.  
  1410. PIL_ERROR pil_put_ctype_code(code,string)
  1411. PIL_NT_TYPE code;
  1412. char PTRTYPE *string;
  1413. {
  1414.     static int ctypetokens[] = {/* This column has the content type code */
  1415.         0,                        /* PIL_CNT_OTHER                0 */
  1416.         PIL_KW_UNKNOWN ,        /* PIL_CNT_UNKNOWN                1 */
  1417.         PIL_KW_ASCII_TEXT ,        /* PIL_CNT_ASCII_TEXT            2 */
  1418.         PIL_KW_ATEX_ARIS ,        /* PIL_CNT_ATEX_ARIS            3 */
  1419.         PIL_KW_ATEX_ITF ,        /* PIL_CNT_ATEX_ITF                4 */
  1420.         PIL_KW_EPS ,            /* PIL_CNT_EPS                    5 */
  1421.         PIL_KW_ICL ,            /* PIL_CNT_ICL                    6 */
  1422.         PIL_KW_IT8_1 ,            /* PIL_CNT_IT8_1                7 */
  1423.         PIL_KW_IT8_2 ,            /* PIL_CNT_IT8_2                8 */
  1424.         PIL_KW_MS_RTF ,            /* PIL_CNT_MS_RTF                9 */
  1425.         PIL_KW_MS_WORD_3 ,        /* PIL_CNT_MS_WORD_3_0            10 */
  1426.         PIL_KW_MS_WORD_4 ,        /* PIL_CNT_MS_WORD_4_0            11 */
  1427.         PIL_KW_MIF ,            /* PIL_CNT_MIF                    12 */
  1428.         PIL_KW_PICT ,            /* PIL_CNT_PICT                    13 */
  1429.         PIL_KW_PIL_LAYOUT_NTET,    /* PIL_CNT_PIL_LAYOUT            14 */
  1430.         PIL_KW_POSTSCRIPT ,        /* PIL_CNT_POSTSCRIPT            15 */
  1431.         PIL_KW_QUARK_XPRESSTAGS,/* PIL_CNT_QUARK_XP_TAGS        16 */
  1432.         PIL_KW_SCITEX_CT ,        /* PIL_CNT_SCITEX_CT            17 */
  1433.         PIL_KW_SCITEX_HANDSHAKE,/* PIL_CNT_SCITEX_HS            18 */
  1434.         PIL_KW_SCITEX_LW ,        /* PIL_CNT_SCITEX_LW            19 */
  1435.         PIL_KW_SGML ,            /* PIL_CNT_SGML                    20 */
  1436.         PIL_KW_TIFF ,            /* PIL_CNT_TIFF                    21 */
  1437.         PIL_KW_WP_100 ,            /* PIL_CNT_WP_1_00                22 */
  1438.         PIL_KW_WP_102 ,            /* PIL_CNT_WP_1_02                23 */
  1439.         PIL_KW_XYQUEST_XYWRITE    /* PIL_CNT_XYQUEST_XYWRITE        24 */
  1440.     };
  1441.     /* check for out of range content type code */
  1442.     if (code > PIL_CNT_XYQUEST_XYWRITE)
  1443.         return (pil_set_error(PIL_BAD_NTE));
  1444.     /* check for no content type */
  1445.     if (code == PIL_CNT_OTHER) {
  1446.         if (string == NULL) 
  1447.             return (pil_set_error(PIL_BAD_NTE));
  1448.         else
  1449.             pil_put_quoted_str(string);
  1450.     }
  1451.     else {
  1452.         pil_put_kw(ctypetokens[code]);
  1453.     }
  1454.     return (PIL_OK);
  1455. }
  1456.  
  1457. /*=======================================================================*\
  1458.   pil_put_domain_code
  1459.  
  1460.     Writes a domain type code to the open pil file. This routine depends
  1461.     on the fact that the domain type codes as defined in pildefs.h are
  1462.     sequential integers which can be used as an array index. The array
  1463.     declared below puts the appropriate keyword value for each content
  1464.     type at the appropriate place in the array.
  1465.  
  1466.     Entry:    UINT16 that is a pil domain type code
  1467.  
  1468.     Exit:    Error code is returned.
  1469.  
  1470. \*-----------------------------------------------------------------------*/
  1471.  
  1472. PIL_ERROR pil_put_domain_code(code,string)
  1473. PIL_NT_DMN code;
  1474. char PTRTYPE *string;
  1475. {
  1476.     static int dtypetokens[] = {
  1477.         0,                                /* PIL_DMN_OTHER            0 */
  1478.         PIL_KW_MAC_FILENAME,            /* PIL_DMN_MAC_FILE            1 */
  1479.         PIL_KW_UNIX_FILENAME,            /* PIL_DMN_UNIX_FILE        2 */
  1480.         PIL_KW_MSDOS_FILENAME,            /* PIL_DMN_MSDOS_FILE        3 */
  1481.         PIL_KW_OS2_FILENAME,            /* PIL_DMN_OS2_FILE            4 */
  1482.         PIL_KW_VMS_FILENAME,            /* PIL_DMN_VMS_FILE            5 */
  1483.         PIL_KW_VM_FILENAME,                /* PIL_DMN_VM_FILE            6 */
  1484.         PIL_KW_LCD_FILENAME,            /* PIL_DMN_LCD_FILE            7 */
  1485.         PIL_KW_INLINE,                    /* PIL_DMN_INLINE            8 */
  1486.         PIL_KW_UNKNOWN,                    /* PIL_DMN_UNKNOWN            9 */
  1487.     };
  1488.     /* check for out of range domain type code */
  1489.     if (code > PIL_DMN_UNKNOWN)
  1490.         return (pil_set_error(PIL_BAD_NTE));
  1491.     /* check for no content type */
  1492.     if (code == PIL_DMN_OTHER) {
  1493.         if (string == NULL)
  1494.             return (pil_set_error(PIL_BAD_NTE));
  1495.         else
  1496.             pil_put_quoted_str(string);
  1497.     }
  1498.     else {
  1499.         pil_put_kw(dtypetokens[code]);
  1500.     }
  1501.     return (PIL_OK);
  1502. }
  1503.  
  1504. /*=======================================================================*\
  1505.   pil_put_shape_code
  1506.  
  1507.     Writes the name of a shape to the open pil file.
  1508.  
  1509.     Entry:    UINT16 that is a pil shape type
  1510.  
  1511.     Exit:    Error code is returned.
  1512.  
  1513. \*-----------------------------------------------------------------------*/
  1514.  
  1515. PIL_ERROR pil_put_shape_code(code)
  1516. PIL_UINT16 code;
  1517. {
  1518.     static int openshapes[] = {
  1519.         0,                            /*  */
  1520.         PIL_KW_LINE,                /* PIL_LINE_SHAPE         0x0001 */
  1521.         PIL_KW_ARC,                    /* PIL_ARC_SHAPE        0x0002 */
  1522.         PIL_KW_BEZIER,                /* PIL_BEZIER_SHAPE        0x0003  */
  1523.         PIL_KW_POLY_LINE,            /* PIL_POLYLINE_SHAPE    0x0004  */
  1524.         PIL_KW_OPEN_PATH            /* PIL_OPENPATH_SHAPE    0x0005  */
  1525.     };
  1526.     static int closedshapes[] = {
  1527.         0,                            /*  */
  1528.         PIL_KW_RECTANGLE,            /* PIL_RECTANGLE_SHAPE    0x0100 */
  1529.         PIL_KW_CIRCLE,                /* PIL_CIRCLE_SHAPE        0x0200 */
  1530.         PIL_KW_ELLIPSE,                /* PIL_ELLIPSE_SHAPE    0x0300 */
  1531.         PIL_KW_POLYGON,                /* PIL_POLYGON_SHAPE    0x0400 */
  1532.         PIL_KW_CLOSED_PATH            /* PIL_CLOSEDPATH_SHAPE    0x0500 */
  1533.     };
  1534.     if (IS_CLOSED_SHAPE(code)) {
  1535.         if (code < PIL_RECTANGLE_SHAPE || code > PIL_CLOSEDPATH_SHAPE)
  1536.             return (pil_set_error(PIL_UNKN_SHAPE));
  1537.         pil_put_kw(closedshapes[code>>8]);
  1538.     }
  1539.     else {
  1540.         if (code < PIL_LINE_SHAPE || code > PIL_OPENPATH_SHAPE)
  1541.             return (pil_set_error(PIL_UNKN_SHAPE));
  1542.         pil_put_kw(openshapes[code]);
  1543.     }
  1544.     return (PIL_OK);
  1545. }
  1546.  
  1547. /*=======================================================================*\
  1548.   pil_put_asi
  1549.  
  1550.     Writes a pil_APPL_SPECIFIC_ITEM to the open pil file. 
  1551.  
  1552.     Entry:    Pointer to a pil_asi *
  1553.  
  1554.     Exit:    Error code is returned.
  1555.  
  1556. \*-----------------------------------------------------------------------*/
  1557.  
  1558.  
  1559. PIL_ERROR pil_put_asi(ptr)
  1560. pil_asi PTRTYPE *ptr;
  1561. {
  1562.     while (ptr != NULL) {
  1563.         pil_put_named_begblk(PIL_KW_APPLICATION);
  1564.         pil_nextline();
  1565.         pil_put_named_str(PIL_KW_APP_NAME,ptr->asi_name);
  1566.         pil_nextline();
  1567.         if (pil_put_asa(ptr->asa) != PIL_OK)
  1568.             return (pil_last_error());
  1569.         pil_put_nested_endblk();
  1570.         if ((ptr = ptr->next) != NULL) pil_nextline();
  1571.     }
  1572.     return (PIL_OK);
  1573. }
  1574.  
  1575. /*=======================================================================*\
  1576.   pil_put_asa
  1577.  
  1578.     Writes a pil_asa list to the open pil file.
  1579.     The pil_asa is put in the buffer at the next 
  1580.     available location. It is given a name a list of values as passed
  1581.     to this function.
  1582.  
  1583.     Entry:    Pointer to a pil_asa *
  1584.  
  1585.     Exit:    Error code is returned.
  1586.  
  1587. \*-----------------------------------------------------------------------*/
  1588.  
  1589. PIL_ERROR pil_put_asa(ptr)
  1590. pil_asa PTRTYPE *ptr;
  1591. {
  1592.     while (ptr != NULL) {
  1593.         if (pil_put_data_code(ptr->type & 0x0FFF) != PIL_OK)
  1594.             return (pil_last_error());
  1595.         pil_put_string(BEGINLIST);
  1596.         pil_put_string(ptr->attr_name);
  1597.         pil_put_string(SEPARATOR);
  1598.         if (pil_put_pvalue(ptr->value,ptr->type) != PIL_OK)
  1599.             return (pil_last_error());
  1600.         pil_put_string(ENDBLOCK);
  1601.         if ((ptr = ptr->next) != NULL) pil_nextline();
  1602.     }
  1603.     return (PIL_OK);
  1604. }
  1605.  
  1606. /*=======================================================================*\
  1607.   pil_put_data_code
  1608.  
  1609.     Writes the token for a data type to the open pil file. NOTE: the
  1610.     array of tokens stored here corresponds to the definition of the 
  1611.     pil data type codes in pildefs.h, so don't change one without changing
  1612.     the other!
  1613.  
  1614.     Entry:    type code
  1615.  
  1616.     Exit:    Error code is returned.
  1617.  
  1618. \*-----------------------------------------------------------------------*/
  1619. PIL_ERROR pil_put_data_code(type)
  1620. PIL_ASA_VAL_TYPE  type;
  1621. {
  1622.     static int datatokens[] = {
  1623.         PIL_KW_APP_INT8 ,
  1624.         PIL_KW_APP_INT16 ,
  1625.         PIL_KW_APP_INT32 ,
  1626.         PIL_KW_APP_UINT8 ,
  1627.         PIL_KW_APP_UINT16 ,
  1628.         PIL_KW_APP_UINT32 ,
  1629.         PIL_KW_APP_DOUBLE ,
  1630.         PIL_KW_APP_STRING
  1631.     };
  1632.     if (type > PIL_STRING_CODE)
  1633.         return (pil_set_error(PIL_BAD_VALUE_TYPE));
  1634.     pil_put_kw(datatokens[type]);
  1635.     return (PIL_OK);
  1636. }
  1637.  
  1638. /*=======================================================================*\
  1639.   pil_put_pvalue
  1640.  
  1641.     Writes a pil_value to the open pil file.
  1642.  
  1643.     Entry:    Pointer to a pil_value, data type of the value
  1644.  
  1645.     Exit:    Error code is returned.
  1646.  
  1647. \*-----------------------------------------------------------------------*/
  1648. PIL_ERROR pil_put_pvalue(ptr,type)
  1649. pil_value PTRTYPE *ptr;
  1650. PIL_ASA_VAL_TYPE type;
  1651. {
  1652.     if (IS_PIL_VALUE_LIST(type)) {
  1653.         pil_put_string(BEGINLIST);
  1654.     }
  1655.     while (ptr != NULL) {
  1656.         switch (type) {
  1657.             case     PIL_DOUBLE_CODE:
  1658.             case     PIL_DOUBLE_LIST_CODE:
  1659.                 pil_put_dbl((PIL_DOUBLE)ptr->data.dbl);
  1660.                 break;
  1661.             case     PIL_INT8_CODE:
  1662.             case     PIL_INT8_LIST_CODE:
  1663.                 pil_put_i32((PIL_INT32)((PIL_INT8)ptr->data.int8));
  1664.                 break;
  1665.             case     PIL_INT16_CODE:
  1666.             case     PIL_INT16_LIST_CODE:
  1667.                 pil_put_i32((PIL_INT32)((PIL_INT16)ptr->data.int16));
  1668.                 break;
  1669.             case     PIL_INT32_CODE:
  1670.             case     PIL_INT32_LIST_CODE:
  1671.                 pil_put_i32((PIL_INT32)ptr->data.int32);
  1672.                 break;
  1673.             case     PIL_UINT8_CODE:
  1674.             case     PIL_UINT8_LIST_CODE:
  1675.                 pil_put_ui32((PIL_UINT32)((PIL_UINT8)ptr->data.uint8));
  1676.                 break;
  1677.             case     PIL_UINT16_CODE:
  1678.             case     PIL_UINT16_LIST_CODE:
  1679.                 pil_put_ui32((PIL_UINT32)((PIL_UINT16)ptr->data.uint16));
  1680.                 break;
  1681.             case     PIL_UINT32_CODE:
  1682.             case     PIL_UINT32_LIST_CODE:
  1683.                 pil_put_ui32((PIL_UINT32)ptr->data.int32);
  1684.                 break;
  1685.             case     PIL_STRING_CODE:
  1686.             case     PIL_STRING_LIST_CODE:
  1687.                 pil_put_quoted_str((char PTRTYPE *)ptr->data.string);
  1688.                 break;
  1689.             default:
  1690.                 return (pil_set_error(PIL_BAD_VALUE_TYPE));
  1691.         }
  1692.         ptr = ptr->next;
  1693.     }
  1694.     if (IS_PIL_VALUE_LIST(type)) {
  1695.         pil_put_string(ENDBLOCK);
  1696.         pil_put_string(" ");
  1697.     }
  1698.     return (PIL_OK);
  1699. }
  1700.  
  1701. /*=======================================================================*\
  1702.   pil_put_objid
  1703.  
  1704.     Writes a pil_object_id_list to the open pil file.
  1705.  
  1706.     Entry:    Pointer to a pil_object_id_list *
  1707.  
  1708.     Exit:    Error code is returned.
  1709.  
  1710. \*-----------------------------------------------------------------------*/
  1711.  
  1712. PIL_ERROR pil_put_objid(ptr)
  1713. pil_object_id_list PTRTYPE *ptr;
  1714. {
  1715.     pil_put_string(BEGINLIST);
  1716.     while (ptr != NULL) {
  1717.         if (ptr->id == NULL) return (pil_set_error(PIL_BAD_OBJID));
  1718.         pil_put_quoted_str(ptr->id);
  1719.         ptr = ptr->next;
  1720.     }
  1721.     pil_put_string(ENDBLOCK);
  1722.     return (PIL_OK);
  1723. }
  1724.  
  1725. /*=======================================================================*\
  1726.   pil_set_dflt_hdr
  1727.  
  1728.     Subroutine for pil_put_content_start
  1729.     Resets the content header defaults for the start of a new content
  1730.     entity. If the application does not call pil_put_content_hdr, then
  1731.     the defaults set here will be used when writing the pil_content_data.
  1732.  
  1733.     Entry:    None
  1734.  
  1735.     Exit:    None
  1736.  
  1737. \*-----------------------------------------------------------------------*/
  1738.  
  1739. PIL_VOID pil_set_dflt_hdr()
  1740. {
  1741.     currenthdr.encoding = (PIL_INT8)PIL_ASCII_CONTENT;
  1742.     currenthdr.byteorder = (PIL_INT8)PIL_LITTLE_ENDIAN;
  1743.     currenthdr.escapechar = (PIL_UINT8)'\\';
  1744.     currenthdr.begblkchar = (PIL_UINT8)'{';
  1745.     currenthdr.endblkchar = (PIL_UINT8)'}';
  1746. }
  1747. /*=======================================================================*\
  1748.   pil_put_nested_begblk
  1749.  
  1750.     Subroutine for pil_put_component. Starts a nested block, set indent
  1751.     level.
  1752.  
  1753.     Entry:    none 
  1754.  
  1755.     Exit:    none
  1756.  
  1757. \*-----------------------------------------------------------------------*/
  1758.  
  1759. PIL_VOID pil_put_nested_begblk()
  1760. {
  1761.     indentlev++;
  1762.     pil_put_string(BEGINBLOCK);
  1763. }
  1764. /*=======================================================================*\
  1765.   pil_put_nested_endblk
  1766.  
  1767.     Subroutine for pil_put_component. Ends a nested block, sets indent
  1768.     level and indents the next line.
  1769.  
  1770.     Entry:    none 
  1771.  
  1772.     Exit:    none
  1773.  
  1774. \*-----------------------------------------------------------------------*/
  1775.  
  1776. PIL_VOID pil_put_nested_endblk()
  1777. {
  1778.     pil_put_string(NEWLINE);
  1779.     if (indentlev > 0) indentlev--;
  1780.     pil_put_string(pil_gen_indents((int) indentlev));
  1781.     pil_put_string(ENDBLOCK);
  1782. }
  1783.  
  1784. /*=======================================================================*\
  1785.   pil_put_literal
  1786.   
  1787.     Writes a string and a separator.
  1788.  
  1789.     Entry:    pointer to string 
  1790.  
  1791.     Exit:    none
  1792.  
  1793. \*-----------------------------------------------------------------------*/
  1794. PIL_VOID pil_put_literal(str)
  1795. char PTRTYPE *str;
  1796. {
  1797.     pil_put_string(str); 
  1798.     pil_put_string(SEPARATOR);
  1799. }
  1800. /*=======================================================================*\
  1801.   pil_put_named_str
  1802.   
  1803.     Writes a token, a separator, and a string in quotes, for exmaple,
  1804.         user-name "Page 1"
  1805.  
  1806.     Entry:    token, and string pointer 
  1807.  
  1808.     Exit:    none
  1809.  
  1810. \*-----------------------------------------------------------------------*/
  1811. PIL_VOID pil_put_named_str(token, str)
  1812. int token;
  1813. char PTRTYPE *str;
  1814. {
  1815.     pil_put_kw(token); 
  1816.     pil_put_quoted_str(str); 
  1817. }
  1818.  
  1819. /*=======================================================================*\
  1820.   pil_put_named_begblk
  1821.   
  1822.     Writes a token, a separator,nested begin block (indents line and 
  1823.     puts a newline)
  1824.  
  1825.     Entry:    token
  1826.  
  1827.     Exit:    none
  1828.  
  1829. \*-----------------------------------------------------------------------*/
  1830. PIL_VOID pil_put_named_begblk(token)
  1831. int token;
  1832. {
  1833.     pil_put_kw(token); 
  1834.     pil_put_nested_begblk(); 
  1835. }
  1836.  
  1837.  
  1838. /*=======================================================================*\
  1839.   pil_put_named_i32
  1840.   
  1841.     Writes a token, a separator, and an integer, for example,
  1842.         width 500
  1843.  
  1844.     Entry:    token, and a PIL_INT32
  1845.  
  1846.     Exit:    none
  1847.  
  1848. \*-----------------------------------------------------------------------*/
  1849. PIL_VOID pil_put_named_i32(token, n)
  1850. int token;
  1851. PIL_INT32 n;
  1852. {
  1853.     pil_put_kw(token); 
  1854.     pil_put_i32(n); 
  1855. }
  1856.  
  1857. /*=======================================================================*\
  1858.   pil_put_named_ui32
  1859.   
  1860.     Writes a token, a separator, and an integer, for example,
  1861.         width 500
  1862.  
  1863.     Entry:    token, and a PIL_UINT32
  1864.  
  1865.     Exit:    none
  1866.  
  1867. \*-----------------------------------------------------------------------*/
  1868. PIL_VOID pil_put_named_ui32(token, n)
  1869. int token;
  1870. PIL_UINT32 n;
  1871. {
  1872.     pil_put_kw(token); 
  1873.     pil_put_ui32(n); 
  1874. }
  1875.  
  1876. /*=======================================================================*\
  1877.   pil_put_named_dbl
  1878.   
  1879.     Writes a token, a separator, and an integer, for example,
  1880.         rot-angle -354.2
  1881.  
  1882.     Entry:    token, and a PIL_INT32
  1883.  
  1884.     Exit:    none
  1885.  
  1886. \*-----------------------------------------------------------------------*/
  1887. PIL_VOID pil_put_named_dbl(token, n)
  1888. int token;
  1889. PIL_DOUBLE n;
  1890. {
  1891.     pil_put_kw(token); 
  1892.     pil_put_dbl(n); 
  1893. }
  1894.  
  1895.  
  1896. /*=======================================================================*\
  1897.   pil_put_quoted_str
  1898.   
  1899.     Writes a string in quotes, followed by a separator.
  1900.  
  1901.     Entry:    string pointer 
  1902.  
  1903.     Exit:    none
  1904.  
  1905. \*-----------------------------------------------------------------------*/
  1906. PIL_VOID pil_put_quoted_str(str)
  1907. char PTRTYPE *str;
  1908. {
  1909.     pil_put_string("\""); 
  1910.     pil_put_string(str); 
  1911.     pil_put_string("\"");
  1912.     pil_put_string(SEPARATOR);
  1913. }
  1914.  
  1915. /*=======================================================================*\
  1916.   pil_nextline
  1917.   
  1918.     Subroutine for pil_put_component. Ends a line and indents the next one.
  1919.  
  1920.     Entry:    none 
  1921.  
  1922.     Exit:    none
  1923.  
  1924. \*-----------------------------------------------------------------------*/
  1925.  
  1926. PIL_VOID pil_nextline()
  1927. {
  1928.     pil_put_string(NEWLINE);
  1929.     pil_put_string(pil_gen_indents ((int) indentlev));
  1930. }
  1931.  
  1932. /*=======================================================================*\
  1933.   pil_put_kw
  1934.   
  1935.     Subroutine for pil_put_xxxxxx.
  1936.     Calls pil_put_string to write the keyword corresponding to the integer
  1937.     token, to the open pil file.
  1938.  
  1939.     Entry:    integer token 
  1940.  
  1941.     Exit:    none
  1942.     
  1943. \*-----------------------------------------------------------------------*/
  1944. PIL_VOID pil_put_kw(token)
  1945. int token;
  1946. {
  1947.     pil_put_string(pil_token_to_str(token));
  1948.     pil_put_string(SEPARATOR);
  1949. }
  1950. /*=======================================================================*\
  1951.   pil_put_kw_no_sep
  1952.   
  1953.     Subroutine for pil_put_xxxxxx.
  1954.     Calls pil_put_string to write the keyword corresponding to the integer
  1955.     token, to the open pil file.
  1956.  
  1957.     Entry:    integer token 
  1958.  
  1959.     Exit:    none
  1960.  
  1961. \*-----------------------------------------------------------------------*/
  1962. PIL_VOID pil_put_kw_no_sep(token)
  1963. int token;
  1964. {
  1965.     pil_put_string(pil_token_to_str(token));
  1966. }
  1967.  
  1968.  
  1969. /*=======================================================================*\
  1970.   pil_token_to_str
  1971.   
  1972.     Subroutine for pil_put_kw.Converts an integer token to string.
  1973.  
  1974.     Entry:    integer token 
  1975.  
  1976.     Exit:    pointer to a string
  1977.  
  1978. \*-----------------------------------------------------------------------*/
  1979. char PTRTYPE *pil_token_to_str(token)
  1980. FAST int token; 
  1981. {
  1982.     if (token < PIL_MIN_KW || token > PIL_SIZE_KW_ARRAY-1) return ("");
  1983.     return (pil_kws[token]);     
  1984. }
  1985.  
  1986.  
  1987. /*=======================================================================*\
  1988.   pil_i32toa
  1989.   
  1990.     Convert a signed 32 bit int to a string.
  1991.  
  1992.     Entry:    number, string buffer pointer
  1993.  
  1994.     Exit:    no return value,
  1995.             ascii representation of the number is in the buffer.
  1996.  
  1997. \*-----------------------------------------------------------------------*/
  1998. PIL_VOID pil_i32toa(n,s)
  1999. FAST PIL_INT32 n;
  2000. FAST char PTRTYPE *s;
  2001. {
  2002.     PIL_INT32 i, j, sign;
  2003.     char c;
  2004.     
  2005.     if ((sign=n) < 0)
  2006.         n = -n;
  2007.     i = 0;
  2008.     do {
  2009.         s[i++] = (char)(n % 10 + '0');
  2010.     } while ((n /= 10) > 0);
  2011.  
  2012.     if (sign < 0)
  2013.         s[i++] = '-';
  2014.  
  2015.     s[i] = '\0';
  2016.     /* reverse the string in place */
  2017.     for (j=0,i--; j<i; j++,i--) {
  2018.         c = s[j];
  2019.         s[j] = s[i];
  2020.         s[i] = c;
  2021.     }
  2022. }
  2023. /*=======================================================================*\
  2024.   pil_iu32toa
  2025.   
  2026.     Convert an unsigned 32 bit int to a string.
  2027.  
  2028.     Entry:    number, string buffer pointer
  2029.  
  2030.     Exit:    no return value,
  2031.             ascii representation of the number is in the buffer.
  2032.  
  2033. \*-----------------------------------------------------------------------*/
  2034.  
  2035. PIL_VOID pil_ui32toa(n,s)
  2036. PIL_UINT32 n;
  2037. FAST char PTRTYPE *s;
  2038. {
  2039.     int i,j;
  2040.     char c;
  2041.     i = 0;
  2042.     do {
  2043.         s[i++] = (char)(n % 10 + '0');
  2044.     } while ((n /= 10) > 0);
  2045.     s[i] = '\0';
  2046.     /* reverse the string in place */
  2047.     for (j=0,i--; j<i; j++,i--) {
  2048.         c = s[j];
  2049.         s[j] = s[i];
  2050.         s[i] = c;
  2051.     }
  2052. }
  2053. /*=======================================================================*\
  2054.   pil_ftoa
  2055.   
  2056.     Convert a PIL_DOUBLE (IEEE-754 floating point number) to ascii.
  2057.  
  2058.     Entry:    number, string buffer pointer
  2059.  
  2060.     Exit:    no return value,
  2061.             ascii representation of the number is in the buffer.
  2062.  
  2063. \*-----------------------------------------------------------------------*/
  2064.  
  2065. PIL_VOID pil_ftoa(n,s)
  2066. PIL_DOUBLE    n;
  2067. FAST char PTRTYPE *s;
  2068. {
  2069. #ifdef THINK_DA
  2070.     FAST int    i;
  2071.     decform    dform;                /* need to do %f or %g */
  2072.     /* convert floating point value to string */
  2073.     if (n > -1.0e9 && n < 1.0e9) dform.style = FIXEDDECIMAL;
  2074.     else dform.style = FLOATDECIMAL;
  2075.     dform.digits = 17;    /* 17 digits after the decimal point  */
  2076.     num2str(&dform,n,s);
  2077.     for (i = (int)*s; i > 0 ; i--, s++)
  2078.         *s = *(s+1);
  2079.     *s = '\0';
  2080.     /* PtoCstr(s); */
  2081. #else
  2082. #ifdef WINDOWS3
  2083.     /* stdlib routines require near pointers, so put string in a local buf */
  2084.     char localbuf[32];
  2085.     sprintf(localbuf,"%g",n);
  2086.     pil_strcpy(s,(char PTRTYPE *)localbuf);
  2087. #else
  2088.     sprintf(s,"%g",n);
  2089. #endif
  2090. #endif
  2091. }
  2092.  
  2093. /*=======================================================================*\
  2094.   pil_put_xxxxx 
  2095.   
  2096.     Various routines to print out numbers
  2097.      
  2098.     Entry:    number
  2099.  
  2100.     Exit:    no return value
  2101.  
  2102. \*-----------------------------------------------------------------------*/
  2103.  
  2104. PIL_VOID pil_put_i32(n)
  2105. PIL_INT32 n;
  2106. {
  2107.     pil_i32toa(n,outbuf);
  2108.     pil_put_string(outbuf);
  2109.     pil_put_string(SEPARATOR);
  2110. }
  2111. PIL_VOID pil_put_ui32(n)
  2112. PIL_UINT32 n;
  2113. {
  2114.     pil_ui32toa(n,outbuf);
  2115.     pil_put_string(outbuf);
  2116.     pil_put_string(SEPARATOR);
  2117. }
  2118.  
  2119. PIL_VOID pil_put_dbl(n)
  2120. PIL_DOUBLE n;
  2121. {
  2122.     pil_ftoa(n,outbuf);
  2123.     pil_put_string(outbuf);
  2124.     pil_put_string(SEPARATOR);
  2125. }
  2126.  
  2127. /*=======================================================================*\
  2128.   pil_gen_indents 
  2129.      
  2130.     Entry:    indent level
  2131.  
  2132.     Exit:    char pointer to your desired indenting string
  2133.  
  2134. \*-----------------------------------------------------------------------*/
  2135.  
  2136. char PTRTYPE *pil_gen_indents (level)
  2137. int level;
  2138. {
  2139.     switch (level)
  2140.     {
  2141.         case 0:        return ("");
  2142.         case 1:        return ("\t");
  2143.         case 2:        return ("\t\t");
  2144.         case 3:        return ("\t\t\t");
  2145.         case 4:        return ("\t\t\t\t");
  2146.         case 5:        return ("\t\t\t\t\t");
  2147.         case 6:        return ("\t\t\t\t\t\t");
  2148.         case 7:        return ("\t\t\t\t\t\t\t");
  2149.         case 8:        return ("\t\t\t\t\t\t\t\t");
  2150.         case 9:        return ("\t\t\t\t\t\t\t\t\t");
  2151.         case 10:    return ("\t\t\t\t\t\t\t\t\t\t");
  2152.         default:    return ("\t\t\t\t\t\t\t\t\t\t\t");
  2153.     }
  2154. }
  2155.  
  2156. /****************************End of pilgen.c******************************/
  2157.