4 * Author: Teemu Rantanen <tvr@cs.hut.fi> Copyright (c) 1992 Teemu Rantanen All
7 * Created: Sun Apr 26 21:30:47 1992 tvr Last modified: Mon May 11 22:56:41 1992
16 int PrintTopMargin = 0;
17 int PrintBottomMargin = 0;
18 int PrintLeftMargin = 0;
22 char PrintCommand[1024] = "lpr";
23 char PrintFileName[1024] = "foobar.www";
27 * One object on a line
29 typedef struct PrintObject_s {
31 HTextObject_t *HtObject;
33 struct PrintObject_s *Next;
38 * All line objects and info on line
40 typedef struct PrintLine_s {
44 PrintObject_t *Objects;
46 struct PrintLine_s *Next;
53 * Allocate new PrintObject.
60 p = (PrintObject_t *) malloc(sizeof(*p));
65 memset(p, 0, sizeof(*p));
72 * Allocate new PrintLine.
79 p = (PrintLine_t *) malloc(sizeof(*p));
84 memset(p, 0, sizeof(*p));
91 * Append object to a line. Sort objects according to x position
93 int printobject_append(line, htobject)
95 HTextObject_t *htobject;
97 PrintObject_t *object = line->Objects;
98 PrintObject_t *prev = 0;
101 * First object on a line
104 if (!(line->Objects = new_print_object()))
107 line->Objects->HtObject = htobject;
112 * Check on which place do we put this ?
114 while (object && (htobject->x > object->HtObject->x)) {
118 object = object->Next;
122 * Set object to line-list
126 PrintObject_t *new_object = new_print_object();
131 new_object->Next = object;
133 new_object->HtObject = htobject;
137 prev->Next = new_object;
141 line->Objects = new_object;
149 * Check on which line object should be appended
152 print_check_line_append(first, object)
154 HTextObject_t *object;
157 PrintLine_t *new_line;
161 * If this is first line, no problemo ...
165 p = new_print_line();
170 p->LineY = object->y;
172 if (!printobject_append(p, object))
183 while (p && (p->LineY < object->y)) {
191 * Line already exists ?
193 if (p && (p->LineY == object->y)) {
195 if (!printobject_append(p, object))
201 * Line does not exist ... make one
204 new_line = new_print_line();
209 new_line->LineY = object->y;
213 * Append to middle of the list
215 prev->Next = new_line;
219 if (!printobject_append(new_line, object))
229 if (!printobject_append(new_line, object))
236 * Should not get here
243 * Print using this command
245 int erwise_popen(command)
254 printf("erwise_popen: cannot make pipe\n");
258 switch (ppid = fork()) {
276 printf("cannot fork\n");
290 * should not get here ...
298 * Open files, handle commands, call DoPrint
305 if ((PrintWidth <= 0) || (PrintTopMargin < 0) || (PrintBottomMargin < 0) ||
306 (PrintLeftMargin < 0)) {
308 printf("Print: parameters insane\n");
314 fd = open(PrintFileName, O_WRONLY | O_CREAT, 0666);
318 printf("Print: cannot create file %s\n", PrintFileName);
322 DoPrint(htext, fd, PrintWidth, PrintLeftMargin, PrintTopMargin,
329 fd = erwise_popen(PrintCommand);
333 printf("Print: failed printing to command %s\n", PrintCommand);
337 DoPrint(htext, fd, PrintWidth, PrintLeftMargin, PrintTopMargin,
348 * Handle printing. Format text (ascii) and put it to wanted fd
350 int DoPrint(old_htext, fd, width, lmargin, top, bottom)
358 PrintLine_t *first_line = 0;
362 htext = (HText_t *) HtDuplicate(old_htext);
368 * Format text using fixed width. After this call every object is
369 * positioned correctly.
371 XlFormatTextForPrinting(htext, lmargin, lmargin + width);
374 * Because some objects may not be in x,y order, contruct list of lines
375 * so that lines are in order 0->j and for every line objects are in
378 * Because of allmost all objects are in order by default, contruct lists
379 * from last to first. Now most objects can be inserted as the first
380 * object of the first line.
390 * XXXXX free allocated on error
392 first_line = print_check_line_append(first_line, p);
399 * Now, print line by line
403 PrintLine_t *line = first_line;
415 for (; top > 0; top--)
416 write(fd, newline, 1);
423 while (y < line->LineY) {
426 write(fd, newline, 1);
430 * Get maximum x on a line
441 if (max_x < (p->HtObject->x + p->HtObject->width))
442 max_x = p->HtObject->x + p->HtObject->width;
449 * Collect data on a line and print it
454 char *d = malloc(max_x + 1);
464 memset(d, ' ', max_x + 1);
467 if (p->HtObject->data) {
469 memcpy(d + p->HtObject->x, p->HtObject->data,
470 p->HtObject->length);
475 write(fd, d, max_x + 1);
484 write(fd, newline, 1);
487 * Write bottom margin
489 for (; bottom > 0; bottom--)
490 write(fd, newline, 1);
495 * Free objects allocated here