home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume17
/
calentool
/
part04
/
pcaldw.c
Wrap
C/C++ Source or Header
|
1991-04-06
|
14KB
|
551 lines
/*
* $Header: pcaldw.c,v 1.2 91/03/27 16:46:17 billr Exp $
*/
/*
* pcaldw - print pretty PostScript image of a day or week calendar
*
* Pieces extracted from the pcal program by Ken Keirnan and modified
* heavily by Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>.
* Support for non-English characters by Hakan Kallberg <hk@simulina.se>.
*
* This program is Copyright (C) 1991 Tektronix, Inc.
* All Rights Reserved
* Permission is hereby granted to use and modify the modifications in source
* or binary form as long as they are not sold for profit and this copyright
* notice remains intact.
*
*/
#include "ct.h" /* for NO_PRINTER define */
#ifndef NO_PRINTER
#ifndef RASTER_ONLY
#include <stdio.h>
#include <time.h>
extern struct tm current, First;
extern struct dayslot *slots;
extern struct weekrect week_boxes[];
extern char *daynames[], *monthnames[];
extern int day_first, hour24, n_tslots, nr_weekdays, n_slots;
extern int start_hour;
extern int day_of_year(), days_remaining_in_year();
int weekday;
#define DAY_FORMAT 1
#define WEEK_FORMAT 2
#define MAX_SLOTS 64
/*
* natural language support for non-English characters
*/
#ifdef LANGUAGE
/** Note: Only SWEDISH is currently supported **/
/** send your local encodings to billr@saab.CNA.TEK.COM **/
#define SWEDISH
/* #define ISO_LATIN_1 */
/* #define GERMAN */
/* #define FRENCH */
/*
* p_lang_header - provides national language support
*/
char *p_lang_header[] = {
"/ReEncodeSmall",
" { 0 begin",
" /newcodesandnames exch def",
" /basefontname exch def",
" /basefontdict basefontname findfont def",
" /newfont basefontdict maxlength dict def",
" basefontdict",
" { exch dup /FID ne",
" { dup /Encoding eq",
" { exch dup length array copy",
" newfont 3 1 roll put }",
" { exch newfont 3 1 roll put }",
" ifelse }",
" { pop pop }",
" ifelse",
" } forall",
" newcodesandnames aload pop",
" newcodesandnames length 2 idiv",
" { newfont /Encoding get 3 1 roll put}",
" repeat",
" basefontname newfont definefont pop",
" end",
" } def",
"/ReEncodeSmall load 0 12 dict put",
"/codevec [",
#ifdef SWEDISH
" 8#140 /eacute % `",
" 8#176 /udieresis % ~",
" 8#175 /aring % }",
" 8#173 /adieresis % {",
" 8#174 /odieresis % |",
" 8#100 /Eacute % @",
" 8#136 /Udieresis % ^",
" 8#135 /Aring % ]",
" 8#133 /Adieresis % [",
" 8#134 /Odieresis % \\",
#endif SWEDISH
#ifdef ISO_LATIN_1
#endif ISO_LATIN_1
#ifdef GERMAN
#endif GERMAN
#ifdef FRENCH
#endif FRENCH
" ] def",
"daytextfont dup codevec ReEncodeSmall",
(char *)0
};
#endif
/*
* pheader - provides the PostScript routines
*/
static char *prolog[] = {
"%!",
"%%Creator: Bill Randle, Tektronix, Inc.",
"%%Title: calentool's day-or-week-at-a-glance",
"%%For: calentool",
"%%DocumentFonts: Times-Bold Helvetica Times",
"%%Bounding Box: 0 0 500 700",
"%%Pages: 1",
"%%EndComments",
"/titlefont /Times-Bold def",
"/dayfont /Helvetica def",
"/daytextfont /Times def",
(char *)0
};
static char *pheader[] = {
"/prtnum { 3 string cvs show} def",
/*
* Draw the day name and the grid for the current day
*/
"/drawgrid {",
" 1.0 setlinewidth",
" 0 1 nslots 1 sub {",
" gsave",
" 400 0 rlineto",
" 0 slotHeight neg rlineto",
" -400 0 rlineto",
" closepath stroke",
" grestore",
" 0 slotHeight neg rmoveto",
" } for",
"} def",
"/drawtimes {",
" /timex exch def",
" dayfont findfont 12 scalefont setfont",
" 0 1 nslots 1 sub {",
" /slot exch def",
" slot slotHeight mul slotHeight 0.75 mul add neg timex exch moveto",
" slot ntslots eq {",
" (Notes) show",
" } { slot ntslots lt {",
" hour24 0 eq {",
" shour slot 2 idiv add 12 mod dup 0 eq { pop (12) show",
" } { prtnum } ifelse (:) show slot 2 mod 0 eq {",
" (00) } { (30) } ifelse show",
" shour slot 2 idiv add 12 lt { (am) } { (pm) } ifelse show",
" } {",
" shour slot 2 idiv add prtnum",
" slot 2 mod 0 eq { (00) } { (30) } ifelse show",
" } ifelse",
" } if",
" } ifelse",
" } for",
"} def",
/*
* define clipping region for the text
*/
"/pageclip {",
" newpath",
" 100 0 moveto",
" 400 0 rlineto",
" 0 slotHeight nslots mul neg rlineto",
" -400 0 rlineto",
" closepath",
"} def",
/*
* string width center
* centers <string> in the width given by <width>
*/
"/center {",
" /width exch def",
" /str exch def width str ",
" stringwidth pop sub 2 div 0 rmoveto str show",
"} def",
/*
* print the string for a given slot s
* str x s slotstr
*/
"/slotstr {",
" slotHeight mul slotHeight 0.75 mul add neg moveto show",
"} def",
/*
* draw an arrow shaft from point x1, slot s1 to slot s2.
* x1 s1 s2 arrowshaft
*/
"/arrowshaft {",
" 3 1 roll 3 copy 1.0 setlinewidth",
" dup slotHeight mul neg exch 3 1 roll moveto",
" sub 1 add slotHeight mul neg 0 exch rlineto",
" dup slotHeight mul neg exch 3 1 roll exch 7 add exch moveto",
" sub 1 add slotHeight mul neg 0 exch rlineto",
"} def",
/*
* draw an arrowhead at point x, slot s.
* x s arrowhead
*/
"/arrowhead {",
" 2 copy 2 setlinejoin 1.0 setlinewidth",
" slotHeight mul neg moveto 0 slotHeight neg rlineto",
" -5 slotHeight 0.4 mul rlineto stroke",
" slotHeight mul neg exch 7 add exch moveto 0 slotHeight neg rlineto",
" 5 slotHeight 0.4 mul rlineto stroke",
"} def",
/*
* draw a vertical bar to seperate multiple appts in the same slot
* x s apptbar
*/
"/apptbar {",
" 2.0 setlinewidth\n",
" slotHeight mul neg moveto 0 slotHeight neg rlineto",
"} def",
/*
* do one day page
*/
"/daypage",
"{",
" 100 0 moveto",
" drawgrid",
" gsave",
" pageclip clip",
" daytext",
" grestore",
"} def",
/*
* printweek - Draw an entire week calendar by printing
* scaled versions of individual day pages.
*/
"/printweek",
"{",
" 90 rotate",
" 40 -50 translate",
" /offset -405 def",
" /xscale 8.75 nweekd div 5.625 div def",
" dayfont findfont 10 scalefont setfont",
" gsave",
" 0 1 nweekd 1 sub {",
" /daynum exch def",
" /offset offset 405 add def",
" gsave",
" xscale .73 scale",
" offset 0 translate",
" daytextfont findfont 12 scalefont setfont",
" daytextindex daynum get cvn cvx /daytext exch def",
" daypage",
" grestore",
" gsave",
" offset xscale mul 0 translate",
" 100 xscale mul 20 .73 mul moveto",
" weekday daynum get",
" 400 xscale mul center",
" 100 xscale mul -620 .73 mul moveto",
" weekdate daynum get",
" 400 xscale mul center",
" grestore",
" } for",
" gsave",
" 1 .73 scale",
" -20 drawtimes",
" 405 nweekd mul xscale mul 40 add drawtimes",
" grestore",
" grestore",
" 120 -500 moveto",
" yearweek show",
"} def",
/*
* printday - print a single day page
*/
"/printday {",
" 40 700 translate",
" titlefont findfont 24 scalefont setfont",
" 100 40 moveto",
" title 400 center",
" dayfont findfont 10 scalefont setfont",
" daytextfont findfont 10 scalefont setfont",
" daypage",
" drawtimes",
" dayfont findfont 10 scalefont setfont",
" 100 -660 moveto",
" yearday 400 center",
"} def",
"/daytextindex [ (day0) (day1) (day2) (day3) (day4) (day5) (day6) ] def",
(char *)0,
};
print_psday(fp, noteflag)
FILE *fp;
int noteflag;
{
char daystring[128];
/*
* write out headers and prologs
*/
do_ps_header(fp);
/*
* Do the calendar
*/
First = current;
if (day_first)
sprintf(daystring, "%s %d %s %d",
daynames[current.tm_wday], current.tm_mday,
monthnames[current.tm_mon], 1900 + current.tm_year);
else
sprintf(daystring, "%s %s %d, %d",
daynames[current.tm_wday], monthnames[current.tm_mon],
current.tm_mday, 1900 + current.tm_year);
fprintf(fp, "/title (%s) def\n", daystring);
sprintf(daystring,
"Day of year: %d -- %d days remaining. Week number: %d",
day_of_year((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900),
days_remaining_in_year((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900),
week_number());
fprintf(fp, "/yearday (%s) def\n", daystring);
/*
* printout the text for this day
*/
fprintf(fp, "/daytext {\n");
do_ps_day(fp, noteflag, DAY_FORMAT);
fprintf(fp, "} def\n");
fprintf(fp, "printday\n");
/*
* Write out PostScript postlog
*/
fprintf(fp, "showpage\n");
}
print_psweek(fp, noteflag)
FILE *fp;
int noteflag;
{
/*
* write out headers and prologs
*/
do_ps_header(fp);
/*
* Do the calendar
*/
First = current;
fprintf(fp, "/weekday [ ");
for (weekday=0; weekday<nr_weekdays; weekday++)
fprintf(fp, "(%3.3s) ", daynames[(First.tm_wday+weekday) % 7]);
fprintf(fp, "] def\n");
fprintf(fp, "/weekdate [ ");
for (weekday=0; weekday<nr_weekdays; weekday++) {
if (day_first)
fprintf(fp, "(%d %3.3s) ", current.tm_mday,
monthnames[current.tm_mon]);
else
fprintf(fp, "(%3.3s %d) ", monthnames[current.tm_mon],
current.tm_mday);
current.tm_mday++;
fix_current_day();
}
fprintf(fp, "] def\n");
current = First;
fprintf(fp, "/yearweek (%d Week number: %d) def\n",
current.tm_year+1900, week_number());
/*
* get list of appts for this week
*/
get_week_appts();
/*
* printout the text for each weekday
*/
for (weekday=0; weekday<nr_weekdays; weekday++) {
fprintf(fp, "/day%d\n{\n", weekday);
do_ps_day(fp, noteflag, WEEK_FORMAT);
fprintf(fp, "} def\n");
}
fprintf(fp, "printweek\n");
/*
* Write out PostScript postlog
*/
fprintf(fp, "showpage\n");
/*
* free up memory
*/
free_week_appts();
}
do_ps_header(fp)
FILE *fp;
{
char **ap;
/*
* Write out PostScript header
*/
for (ap = prolog; *ap; ap++)
fprintf(fp, "%s\n", *ap);
#ifdef LANGUAGE
/*
* Write out PS prolog for local languages
*/
for (ap = p_lang_header; *ap; ap++)
fprintf(fp, "%s\n", *ap);
#endif
fprintf(fp, "%%EndProlog\n");
/*
* Write out common PostScript
*/
for (ap = pheader; *ap; ap++)
fprintf(fp, "%s\n", *ap);
fprintf(fp, "/shour %d def\n", start_hour);
fprintf(fp, "/nslots %d def\n", n_slots);
fprintf(fp, "/ntslots %d def\n", n_tslots);
fprintf(fp, "/hour24 %d def\n", hour24);
fprintf(fp, "/nweekd %d def\n", nr_weekdays);
fprintf(fp, "/slotHeight %.2f def\n", (double)600/n_slots);
}
/*
* printout text for appts and the continuation arrows
*/
do_ps_day(fp, noteflag, format)
FILE *fp;
int noteflag;
int format;
{
char *p, *q;
int i, offset, narrows;
int slotno, xpos=105;
struct appt_entry *aptr;
char strbuf[MAX_STRLEN+MAX_STRLEN/4];
int arrow_loc[MAX_SLOTS];
struct dayslot *slptr;
for (slotno=0; slotno<n_slots; slotno++)
arrow_loc[slotno] = 0;
for (slotno=0; slotno<n_slots; slotno++) {
/* any appts in this timeslot? */
slptr = (format==WEEK_FORMAT ? &week_boxes[weekday].weekslots[slotno] :
&slots[slotno]);
if (slptr->active) {
fprintf(fp, " /xpos %d def\n", xpos);
if (slptr->count > slptr->active) {
/*
* there are arrows here from above. offset our start
* of text so they won't be on top of each other.
*/
offset = 0;
while (arrow_loc[slotno] & 1<<offset)
offset++;
fprintf(fp, " xpos 30 %d mul add /xpos exch def\n",
offset+1);
}
i = 0;
for (aptr=slptr->first; aptr; aptr=aptr->next) {
/* get printable string from each appt */
if (!deleted(aptr, slptr) &&
(!noteflag || ((aptr->flags & MARKED_NOTE) != MARKED_NOTE))) {
if (i) {
/* not the first time thru the loop */
/* move over, print a bar then next appt */
fprintf(fp, " xpos %d apptbar\n", slotno);
fprintf(fp, " xpos 5 add /xpos exch def\n");
}
/* cleanup the strings */
p = aptr->str;
q = strbuf;
while (*p) {
switch (*p) {
/* ignore these */
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
break;
/* escape these for PostScript */
case '\\':
case '(':
case ')':
*q++ = '\\';
break;
}
*q++ = *p++;
}
*q = '\0';
/* print the string and any arrows */
fprintf(fp, " (%s) xpos %d slotstr\n", strbuf, slotno);
if ((narrows = aptr->arrows) > 0) {
while (narrows)
arrow_loc[slotno+narrows--] |= 1<<offset;
if (aptr->arrows > 1)
fprintf(fp, " xpos 20 add %d %d arrowshaft\n",
slotno+1, slotno+aptr->arrows-1);
fprintf(fp, " xpos 20 add %d arrowhead\n",
slotno+aptr->arrows);
}
fprintf(fp, " (%s) stringwidth pop xpos add 5 add /xpos exch def\n", strbuf);
i++;
}
}
}
}
}
/* check to see if appt pointed to by ap has been deleted */
int
deleted(ap, slptr)
struct appt_entry *ap;
struct dayslot *slptr;
{
struct appt_entry *a;
if (ap->flags & DELETED)
return(1);
if (Repeating(ap->flags))
/* run through the list to see if there are any deleted */
for (a=slptr->first; a; a=a->next)
if (a->flags & DELETED) {
/* now see if the current one matches */
if (!strcmp(a->str, ap->str))
return(1);
}
return(0);
}
#endif /* RASTER_ONLY */
#endif /* NO_PRINTER */