home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / calentool / part01 / pcal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-27  |  8.1 KB  |  330 lines

  1. /*
  2.  * $Header: pcal.c,v 2.1 89/05/16 16:30:00 billr Exp $
  3.  */
  4. /*
  5.  * pcal - print pretty PostScript image of a month calendar
  6.  *
  7.  * Pieces extracted from the pcal program by Ken Keirnan and modified
  8.  * slightly by Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>.
  9.  * 
  10.  * "Pcal" is a program to print PostScript calendars for any month and year.
  11.  * Pcal is the combined effort of several people, most notably Patrick Wood
  12.  * of Pipeline Associates, Inc. for the original PostScript code and Bill
  13.  * Vogel of AT&T for the calendar file mechanism.  My part was simple
  14.  * translation to a "C" program, the addition of a couple options and a more
  15.  * generalized date searching routine (oh yes, and a manual page :-).
  16.  * 
  17.  * The original calendar PostScript was Copyright (c) 1987 by Patrick Wood
  18.  * and Pipeline Associates, Inc. with permission to modify and redistribute.
  19.  * 
  20.  * Ken Keirnan
  21.  * Pacific Bell
  22.  * San Ramon, CA.
  23.  *
  24.  * Changes and additions Copyright (C) 1989 Tektronix, Inc.
  25.  *    All Rights Reserved
  26.  * Permission is hereby granted to use and modify the modifications in source
  27.  * or binary form as long as they are not sold for profit and this copyright
  28.  * notice remains intact.
  29.  */
  30. #include "ct.h"        /* for the NO_PRINTER #define */
  31.  
  32. #ifndef NO_PRINTER
  33. #include <stdio.h>
  34. #include <time.h>
  35.  
  36. extern struct tm current, First;
  37. extern struct dayslot slots[];
  38.  
  39. /*
  40.  * pheader - provides the PostScript routines
  41.  */
  42. char *pheader[] = {
  43.   "%!",
  44.   "/titlefont /Times-Bold def",
  45.   "/dayfont /Helvetica-Bold def",
  46.   "/month_names [ (January) (February) (March) (April) (May) (June) (July)",
  47.   "\t\t(August) (September) (October) (November) (December) ] def",
  48.   "/prtnum { 3 string cvs show} def",
  49.   "/drawgrid {\t\t% draw calendar boxes",
  50.   "\tdayfont findfont 10 scalefont setfont",
  51.   "\t0 1 6 {",
  52.   "\t\tdup dup 100 mul 40 moveto",
  53.   "\t\t[ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ] exch get",
  54.   "\t\t100 center",
  55.   "\t\t100 mul 35 moveto",
  56.   "\t\t1.0 setlinewidth",
  57.   "\t\t0 1 5 {",
  58.   "\t\t\tgsave",
  59.   "\t\t\t100 0 rlineto ",
  60.   "\t\t\t0 -80 rlineto",
  61.   "\t\t\t-100 0 rlineto",
  62.   "\t\t\tclosepath stroke",
  63.   "\t\t\tgrestore",
  64.   "\t\t\t0 -80 rmoveto",
  65.   "\t\t} for",
  66.   "\t} for",
  67.   "} def",
  68.   "/drawnums {\t\t% place day numbers on calendar",
  69.   "\tdayfont findfont 30 scalefont setfont",
  70.   "\t/start startday def",
  71.   "\t/days ndays def",
  72.   "\tstart 100 mul 5 add 10 rmoveto",
  73.   "\t1 1 days {",
  74.   "\t\t/day exch def",
  75.   "\t\tgsave",
  76. #ifndef SATBLK
  77.   "\t\tday start add 7 mod 0 eq",
  78.   "\t\t{",
  79.   "\t\t\tsubmonth 0 eq",
  80.   "\t\t\t{",
  81.   "\t\t\t\t.8 setgray",
  82.   "\t\t\t} if",
  83.   "\t\t} if",
  84. #endif
  85.   "\t\tday start add 7 mod 1 eq",
  86.   "\t\t{",
  87.   "\t\t\tsubmonth 0 eq",
  88.   "\t\t\t{",
  89.   "\t\t\t\t.8 setgray",
  90.   "\t\t\t} if",
  91.   "\t\t} if",
  92.   "\t\tday prtnum",
  93.   "\t\tgrestore",
  94.   "\t\tday start add 7 mod 0 eq",
  95.   "\t\t{",
  96.   "\t\t\tcurrentpoint exch pop 80 sub 5 exch moveto",
  97.   "\t\t}",
  98.   "\t\t{",
  99.   "\t\t\t100 0 rmoveto",
  100.   "\t\t} ifelse",
  101.   "\t} for",
  102.   "} def",
  103.   "/drawfill {\t\t% place fill squares on calendar",
  104.   "\t/start startday def",
  105.   "\t/days ndays def",
  106.   "\t0 35 rmoveto",
  107.   "\t1.0 setlinewidth",
  108.   "\t0 1 start 1 sub {",
  109.   "\t\tgsave",
  110.   "\t\t.9 setgray",
  111.   "\t\t100 0 rlineto ",
  112.   "\t\t0 -80 rlineto",
  113.   "\t\t-100 0 rlineto",
  114.   "\t\tclosepath fill",
  115.   "\t\tgrestore",
  116.   "\t\t100 0 rmoveto",
  117.   "\t} for",
  118.   "\tsubmonth 1 eq",
  119.   "\t{",
  120.   "\t\t/lastday 42 def",
  121.   "\t\t600 -365 moveto",
  122.   "\t}",
  123.   "\t{",
  124.   "\t\t/lastday 40 def",
  125.   "\t\t400 -365 moveto",
  126.   "\t} ifelse",
  127.   "\tlastday -1 ndays start 1 add add",
  128.   "\t{",
  129.   "\t\t/day exch def",
  130.   "\t\tgsave",
  131.   "\t\t.9 setgray",
  132.   "\t\t100 0 rlineto ",
  133.   "\t\t0 -80 rlineto",
  134.   "\t\t-100 0 rlineto",
  135.   "\t\tclosepath fill",
  136.   "\t\tgrestore",
  137.   "\t\tday 7 mod 1 eq",
  138.   "\t\t{",
  139.   "\t\t\t600 -365 80 add moveto",
  140.   "\t\t}",
  141.   "\t\t{",
  142.   "\t\t\t-100 0 rmoveto",
  143.   "\t\t} ifelse",
  144.   "\t} for",
  145.   "} def",
  146.   "/isleap {\t\t% is this a leap year?",
  147.   "\tyear 4 mod 0 eq\t\t% multiple of 4",
  148.   "\tyear 100 mod 0 ne \t% not century",
  149.   "\tyear 1000 mod 0 eq or and\t% unless it's a millenia",
  150.   "} def",
  151.   "/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def",
  152.   "/ndays {\t\t% number of days in this month",
  153.   "\tdays_month month 1 sub get",
  154.   "\tmonth 2 eq\t% Feb",
  155.   "\tisleap and",
  156.   "\t{",
  157.   "\t\t1 add",
  158.   "\t} if",
  159.   "} def",
  160.   "/startday {\t\t% starting day-of-week for this month",
  161.   "\t/off year 2000 sub def\t% offset from start of epoch",
  162.   "\toff",
  163.   "\toff 4 idiv add\t\t% number of leap years",
  164.   "\toff 100 idiv sub\t% number of centuries",
  165.   "\toff 1000 idiv add\t% number of millenia",
  166.   "\t6 add 7 mod 7 add \t% offset from Jan 1 2000",
  167.   "\t/off exch def",
  168.   "\t1 1 month 1 sub {",
  169.   "\t\t/idx exch def",
  170.   "\t\tdays_month idx 1 sub get",
  171.   "\t\tidx 2 eq",
  172.   "\t\tisleap and",
  173.   "\t\t{",
  174.   "\t\t\t1 add",
  175.   "\t\t} if",
  176.   "\t\t/off exch off add def",
  177.   "\t} for",
  178.   "\toff 7 mod\t\t% 0--Sunday, 1--monday, etc.",
  179.   "} def",
  180.   "/center {\t\t% center string in given width",
  181.   "\t/width exch def",
  182.   "\t/str exch def width str ",
  183.   "\tstringwidth pop sub 2 div 0 rmoveto str show",
  184.   "} def",
  185.   "/calendar",
  186.   "{",
  187.   "\ttitlefont findfont 48 scalefont setfont",
  188.   "\t0 60 moveto",
  189.   "\t/month_name month_names month 1 sub get def",
  190.   "\tmonth_name show",
  191.   "\t/yearstring year 10 string cvs def",
  192.   "\t700 yearstring stringwidth pop sub 60 moveto",
  193.   "\tyearstring show",
  194.   "\t0 0 moveto",
  195.   "\tdrawnums",
  196.   "\t0 0 moveto",
  197.   "\tdrawfill",
  198.   "\t0 0 moveto",
  199.   "\tdrawgrid",
  200.   "} def",
  201.   "/daytext {",
  202.   "\t/Helvetica-Narrow findfont 6 scalefont setfont",
  203.   "\t/mytext\texch def /myday exch def",
  204.   "\tstartday myday 1 sub add dup 7 mod 100 mul 5 add % gives column",
  205.   "\texch 7 idiv -80 mul % gives row",
  206.   "\tdup /ypos exch def moveto",
  207.   "\t/LM currentpoint pop def /RM LM 95 add def",
  208.   "        mytext { dup (.p) eq { crlf pop} {prstr ( ) show} ifelse } forall",
  209.   "} def",
  210.   "/crlf {",
  211.   "    ypos 8 sub /ypos exch def LM ypos moveto",
  212.   "} def",
  213.   "/prstr {",
  214.   "    dup stringwidth pop currentpoint pop",
  215.   "    add RM gt {crlf} if show",
  216.   "} def",
  217.   "/printmonth {",
  218.   "\t90 rotate",
  219.   "\t50 -120 translate",
  220.   "\t/submonth 0 def",
  221.   "\tcalendar",
  222.   "\tmonth 1 sub 0 eq",
  223.   "\t{",
  224.   "\t\t/lmonth 12 def",
  225.   "\t\t/lyear year 1 sub def",
  226.   "\t}",
  227.   "\t{",
  228.   "\t\t/lmonth month 1 sub def",
  229.   "\t\t/lyear year def",
  230.   "\t} ifelse",
  231.   "\tmonth 1 add 13 eq",
  232.   "\t{",
  233.   "\t\t/nmonth 1 def",
  234.   "\t\t/nyear year 1 add def",
  235.   "\t} ",
  236.   "\t{",
  237.   "\t\t/nmonth month 1 add def",
  238.   "\t\t/nyear year def",
  239.   "\t} ifelse",
  240.   "\t/savemonth month def",
  241.   "\t/saveyear year def",
  242.   "\t/submonth 1 def",
  243.   "\t/year lyear def",
  244.   "\t/month lmonth def",
  245.   "\tgsave",
  246.   "\t500 -365 translate",
  247.   "\tgsave",
  248.   "\t.138 .138 scale",
  249.   "\t10 -120 translate",
  250.   "\tcalendar",
  251.   "\tgrestore",
  252.   "\t/submonth 1 def",
  253.   "\t/year nyear def",
  254.   "\t/month nmonth def",
  255.   "\t100 0 translate",
  256.   "\tgsave",
  257.   "\t.138 .138 scale",
  258.   "\t10 -120 translate",
  259.   "\tcalendar",
  260.   "\tgrestore",
  261.   "\t/month savemonth def",
  262.   "\t/year saveyear def",
  263.   "\t/submonth 0 def",
  264.   "\tgrestore",
  265.   "} def",
  266.   (char *)0,
  267. };
  268.  
  269. print_month(fp)
  270. FILE *fp;
  271. {
  272.     char **ap;
  273.     int i;
  274.  
  275.     /*
  276.      * Write out PostScript prolog
  277.      */
  278.     for (ap = pheader; *ap; ap++)
  279.         fprintf(fp, "%s\n", *ap);
  280.  
  281.     /*
  282.      * Do the calendar
  283.      */
  284.     fprintf(fp, "/year %d def\n", current.tm_year+1900);
  285.     fprintf(fp, "/month %d def\n", current.tm_mon+1);
  286.     fprintf(fp, "printmonth\n");
  287.  
  288.     First = current;
  289.     current.tm_mday = 1;
  290.     for (i=0; i<monthlength(current.tm_mon); i++) {
  291.         fix_current_day();
  292.         get_day_appts();
  293.         print_mday(fp);
  294.         current.tm_mday++;
  295.     }
  296.     current = First;
  297.  
  298.     /*
  299.      * Write out PostScript postlog
  300.      */
  301.     fprintf(fp, "showpage\n");
  302. }
  303.  
  304. print_mday(fp)
  305. FILE *fp;
  306. {
  307.     int slotno, did_one=0;
  308.     struct appt_entry    *aptr, *optr;
  309.  
  310.     fprintf(fp, "%d [ \n", current.tm_mday);
  311.     for (slotno=0; slotno<N_SLOTS; slotno++) {
  312.         /* any appts in this timeslot? */
  313.         if (slots[slotno].first) {
  314.             /* get printable string from each appt */
  315.             for (aptr=slots[slotno].first; aptr;) {
  316.                 if (did_one)
  317.                     fprintf(fp, "(.p)\n");
  318.                 fprintf(fp, "(%s)\n", format_appt_nd(aptr));
  319.                 did_one = 1;
  320.                 /* free up memory used */
  321.                 optr = aptr;
  322.                 aptr = aptr->next;
  323.                 free(optr);
  324.             }
  325.         }
  326.     }
  327.     fprintf(fp, " ] daytext\n");
  328. }
  329. #endif /* NO_PRINTER */
  330.