~sarahstrong/ubuntu/lucid/gedit/mypatch

« back to all changes in this revision

Viewing changes to src/print-doc.c

  • Committer: Bazaar Package Importer
  • Author(s): Joe Drew
  • Date: 2002-01-13 02:13:27 UTC
  • Revision ID: james.westby@ubuntu.com-20020113021327-dukaa4n50oykvrjg
Tags: upstream-0.9.6
ImportĀ upstreamĀ versionĀ 0.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * gedit
 
4
 *
 
5
 * Copyright (C) 2000 Jose Maria Celorio
 
6
 
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
20
 *
 
21
 * Authors:
 
22
 *   Chema Celorio <chema@celorio.com>
 
23
 */ 
 
24
 
 
25
 
 
26
#include <config.h>
 
27
#include <gnome.h>
 
28
 
 
29
#include <libgnomeprint/gnome-print.h>
 
30
 
 
31
#include "print.h"
 
32
#include "print-doc.h"
 
33
#include "print-util.h"
 
34
 
 
35
 
 
36
static  void print_line (PrintJobInfo *pji, int line);
 
37
static  void print_ps_line(PrintJobInfo * pji, gint line, gint first_line);
 
38
static  void print_header (PrintJobInfo *pji, unsigned int page);
 
39
static  void print_start_job (PrintJobInfo *pji);
 
40
static  void print_set_orientation (PrintJobInfo *pji);
 
41
static  void print_header (PrintJobInfo *pji, unsigned int page);
 
42
static  void print_end_page (PrintJobInfo *pji);
 
43
static  void print_end_job (GnomePrintContext *pc);
 
44
 
 
45
/**
 
46
 * print_document:
 
47
 * @doc: the document to be printed, we need this for doc->filename
 
48
 * @pji: the PrintJobInfo struct
 
49
 * @printer: the printer to do the printing to, NULL for printpreview
 
50
 * 
 
51
 * prints *doc
 
52
 *
 
53
 **/
 
54
void
 
55
gedit_print_document (PrintJobInfo *pji)
 
56
{
 
57
        int current_page, current_line;
 
58
        
 
59
        gedit_debug (DEBUG_PRINT, "");
 
60
        
 
61
        pji->temp = g_malloc( pji->chars_per_line + 2);
 
62
 
 
63
        current_line = 0;
 
64
 
 
65
        gedit_print_progress_start (pji);
 
66
        
 
67
        print_start_job (pji);
 
68
        
 
69
        for (current_page = 1; current_page <= pji->pages; current_page++)
 
70
        {
 
71
                if (pji->range != GNOME_PRINT_RANGE_ALL)
 
72
                        pji->print_this_page = (current_page>=pji->page_first &&
 
73
                                                current_page<=pji->page_last) ? TRUE:FALSE;
 
74
                else
 
75
                        pji->print_this_page = TRUE;
 
76
 
 
77
                /* FIXME : This pji->print_this_page is not top hacking. I need
 
78
                   to advance the pointer to buffer to the rigth place not to
 
79
                   semi-print the non-printable pages. Chema */
 
80
                if (pji->print_this_page)
 
81
                {
 
82
                        /* We need to call gnome_print_beginpage so that it adds
 
83
                           "%% Page x" comment needed for viewing postcript files (i.e. in gv)*/
 
84
                        gchar * pagenumbertext;
 
85
                        pagenumbertext = g_strdup_printf ("%d", current_page);
 
86
                        gnome_print_beginpage (pji->pc, pagenumbertext);
 
87
                        g_free (pagenumbertext);
 
88
 
 
89
                        /* Print the header of the page */
 
90
                        if (pji->print_header)
 
91
                                print_header(pji, current_page);
 
92
                        gnome_print_setfont (pji->pc, pji->font_body);
 
93
                }
 
94
 
 
95
                /* we do this when the first line in the page is a continuation
 
96
                   of the last line in the previous page. This will prevent that
 
97
                   the line number in the previous page is repeated in the next*/
 
98
                if (pji->buffer [pji->file_offset-1] != '\n' && current_page>1 && pji->wrapping)
 
99
                        current_line--;
 
100
 
 
101
                for ( current_line++; current_line <= pji->total_lines; current_line++)
 
102
                {
 
103
                        print_line (pji, current_line);
 
104
 
 
105
                        if (pji->current_line % pji->lines_per_page == 0)
 
106
                                break;
 
107
                }
 
108
 
 
109
                if (pji->print_this_page)
 
110
                        print_end_page (pji);
 
111
 
 
112
                gedit_print_progress_tick (pji, current_page);
 
113
                if (pji->canceled)
 
114
                        break;
 
115
        }
 
116
        print_end_job (pji->pc);
 
117
        g_free (pji->temp);
 
118
 
 
119
        gnome_print_context_close (pji->pc);
 
120
 
 
121
        gedit_print_progress_end (pji);
 
122
}
 
123
 
 
124
 
 
125
/**
 
126
 * print_line:
 
127
 * @pji: 
 
128
 * @line: 
 
129
 * 
 
130
 * 
 
131
 **/
 
132
static void
 
133
print_line (PrintJobInfo *pji, int line)
 
134
{
 
135
        gint dump_info = FALSE;
 
136
        gint chars_in_this_line = 0;
 
137
        gint i, temp;
 
138
        gint first_line = TRUE;
 
139
 
 
140
        while ( pji->buffer [pji->file_offset ] != '\n' && pji->file_offset < pji->buffer_size)
 
141
        {
 
142
                chars_in_this_line++;
 
143
 
 
144
                /* Take care of tabs */
 
145
                if (pji->buffer [pji->file_offset] != '\t') {
 
146
                        /* Copy one character */
 
147
                        pji->temp  [chars_in_this_line-1] = pji->buffer [pji->file_offset];
 
148
                } else {
 
149
 
 
150
                        temp = chars_in_this_line;
 
151
 
 
152
                        /* chars in this line is added tab size, but if the spaces are going to
 
153
                         * end up in the next line, we don't insert them. This means tabs are not
 
154
                         * carried over to the next line */                        
 
155
                        chars_in_this_line += pji->tab_size - ( (chars_in_this_line-1) % pji->tab_size) - 1;
 
156
 
 
157
                        if (chars_in_this_line > pji->chars_per_line + 1)
 
158
                            chars_in_this_line = pji->chars_per_line + 1;
 
159
 
 
160
                        for (i=temp; i<chars_in_this_line+1; i++)
 
161
                        {
 
162
                                pji->temp [i-1] = ' ';
 
163
                        }
 
164
                }
 
165
 
 
166
 
 
167
                /* Is this line "full" ? If not, continue */
 
168
                if (chars_in_this_line < pji->chars_per_line + 1) {
 
169
                        /* next char please */
 
170
                        pji->file_offset++;
 
171
                        continue;
 
172
                }
 
173
 
 
174
                /* if we are not doing word wrapping, this is easy */
 
175
                if (!pji->wrapping)
 
176
                {
 
177
                        /* We need to advance pji->file_offset until the next NL char */
 
178
                        while( pji->buffer [pji->file_offset ] != '\n')
 
179
                                pji->file_offset++;
 
180
                        pji->file_offset--;
 
181
 
 
182
                        pji->temp [chars_in_this_line] = (guchar) '\0';
 
183
                        print_ps_line (pji, line, TRUE);
 
184
                        pji->current_line++;
 
185
                        chars_in_this_line = 0;
 
186
 
 
187
                        /* Ok, next char please */
 
188
                        pji->file_offset++;
 
189
                        
 
190
                        continue;
 
191
                }
 
192
                
 
193
                if (dump_info)
 
194
                        g_print ("\nThis lines needs breaking\n");
 
195
                        
 
196
                temp = pji->file_offset; /* We need to save the value of file_offset in case we have to break the line */
 
197
                        
 
198
                /* We back up till we find a space that we can break the line at */
 
199
                while (pji->buffer [pji->file_offset] != ' '  &&
 
200
                       pji->buffer [pji->file_offset] != '\t' &&
 
201
                       pji->file_offset > temp - pji->chars_per_line - 1 )
 
202
                {
 
203
                        pji->file_offset--;
 
204
                }
 
205
                
 
206
                if (dump_info)
 
207
                        g_print("file offset got backed up [%i] times\n", temp - pji->file_offset);
 
208
                
 
209
                /* If this line was "unbreakable" beacuse it contained a word longer than
 
210
                 * chars per line, we need to break it at chars_per_line */
 
211
                if (pji->file_offset == temp - pji->chars_per_line - 1)
 
212
                {
 
213
                        pji->file_offset = temp;
 
214
                        if (dump_info)
 
215
                                g_print ("We are breaking the line\n");
 
216
                }
 
217
                
 
218
                if (dump_info)
 
219
                {
 
220
                        g_print ("Breaking temp at : %i\n", chars_in_this_line + pji->file_offset - temp - 1);
 
221
                        g_print ("Chars_in_this_line %i File Offset %i Temp %i\n",
 
222
                                 chars_in_this_line,
 
223
                                 pji->file_offset,
 
224
                                 temp);
 
225
                }
 
226
                pji->temp [ chars_in_this_line + pji->file_offset - temp - 1] = (guchar) '\0';
 
227
                print_ps_line (pji, line, first_line);
 
228
                first_line = FALSE;
 
229
                pji->current_line++;
 
230
                chars_in_this_line = 0;
 
231
                
 
232
                /* We need to remove the trailing blanks so that the next line does not start with
 
233
                 *  a space or a tab char
 
234
                 */
 
235
                while (pji->buffer [pji->file_offset] == ' ' || pji->buffer [pji->file_offset] == '\t')
 
236
                        pji->file_offset++;
 
237
                
 
238
                /* If this is the last line of the page return */
 
239
                if (pji->current_line%pji->lines_per_page == 0)
 
240
                        return;
 
241
        }
 
242
 
 
243
        /* We need to terminate the string and send it to gnome-print */ 
 
244
        pji->temp [chars_in_this_line] = (guchar) '\0';
 
245
        print_ps_line (pji, line, first_line);
 
246
        pji->current_line++;
 
247
 
 
248
        /* We need to skip the newline char for the new line character */
 
249
        pji->file_offset++;
 
250
 
 
251
}
 
252
 
 
253
/**
 
254
 * print_ps_line:
 
255
 * @pji: 
 
256
 * @line: 
 
257
 * @first_line: 
 
258
 * 
 
259
 * print line leaves the chars to be printed in pji->temp.
 
260
 * this function performs the actual printing of that line.
 
261
 **/
 
262
static void
 
263
print_ps_line (PrintJobInfo * pji, gint line, gint first_line)
 
264
{
 
265
        gfloat y;
 
266
 
 
267
        gedit_debug (DEBUG_PRINT, "");
 
268
 
 
269
        /* Calculate the y position */
 
270
        y = pji->page_height -  pji->margin_top - pji->header_height -
 
271
                (pji->font_char_height*( (pji->current_line % pji->lines_per_page)+1 ));
 
272
 
 
273
        if (!pji->print_this_page)
 
274
                return;
 
275
        
 
276
        gnome_print_moveto (pji->pc, pji->margin_left, y);
 
277
        gedit_print_show_iso8859_1 (pji->pc, pji->temp);
 
278
 
 
279
        /* Print the line number */
 
280
        if (pji->print_line_numbers >0 &&
 
281
            line % pji->print_line_numbers == 0 &&
 
282
            first_line)
 
283
        {
 
284
                char * number_text = g_strdup_printf ("%i",line);
 
285
 
 
286
                gnome_print_setfont (pji->pc, pji->font_numbers);
 
287
                gnome_print_moveto (pji->pc, pji->margin_left - pji->margin_numbers, y);
 
288
                gedit_print_show_iso8859_1 (pji->pc, number_text);
 
289
                g_free (number_text);
 
290
                gnome_print_setfont (pji->pc, pji->font_body);
 
291
        }
 
292
}
 
293
 
 
294
 
 
295
/**
 
296
 * print_determine_lines: 
 
297
 * @pji: PrintJobInfo struct
 
298
 * @real: this flag determines if we count rows of text or lines
 
299
 * of rows splitted by wrapping.
 
300
 *
 
301
 * Determine the lines in the document so that we can calculate the pages
 
302
 * needed to print it. We need this in order for us to do page/pages
 
303
 *
 
304
 * Return Value: number of lines in the document
 
305
 *
 
306
 * The code for this function is small, but it is has a lot
 
307
 * of debuging code, remove later. Chema
 
308
 *
 
309
 **/
 
310
guint
 
311
gedit_print_document_determine_lines (PrintJobInfo *pji, gboolean real)
 
312
{
 
313
        gint lines = 0;
 
314
        gint i, temp_i, j;
 
315
        gint chars_in_this_line = 0;
 
316
 
 
317
        /* use local variables so that this code can be reused */
 
318
        guchar * buffer = pji->buffer;
 
319
        gint chars_per_line = pji->chars_per_line;
 
320
        gint tab_size = pji->tab_size;
 
321
        gint wrapping = pji->wrapping;
 
322
        gint buffer_size = pji->buffer_size;
 
323
        gint lines_per_page = pji->lines_per_page; /* Needed for dump_text stuff */ 
 
324
 
 
325
        int dump_info = FALSE;
 
326
        int dump_info_basic = FALSE;
 
327
        int dump_text = FALSE;
 
328
 
 
329
        gedit_debug (DEBUG_PRINT, "");
 
330
 
 
331
        /* here we modify real if !pji->wrapping */
 
332
        if (real && !wrapping)
 
333
                real = FALSE;
 
334
 
 
335
        if (!real)
 
336
        {
 
337
                dump_info = FALSE;
 
338
                dump_info_basic = FALSE;
 
339
                dump_text = FALSE;
 
340
        }
 
341
                
 
342
        if (dump_info_basic)
 
343
        {
 
344
                if (real)
 
345
                        g_print ("Determining lines in REAL mode. Lines Per page =%i\n", lines_per_page);
 
346
                else
 
347
                        g_print ("Determining lines in WRAPPING mode. Lines Per page =%i\n", lines_per_page);
 
348
        }
 
349
        
 
350
        if (dump_text && lines%lines_per_page == 0)
 
351
                g_print("\n\n-Page %i-\n\n", lines / lines_per_page + 1);
 
352
        
 
353
        for (i=0; i < buffer_size; i++)
 
354
        {
 
355
                chars_in_this_line++;
 
356
 
 
357
                if (buffer[i] != '\t' && dump_text)
 
358
                        g_print("%c", buffer[i]);
 
359
 
 
360
                if (buffer[i] == '\n')
 
361
                {
 
362
                        lines++;
 
363
                        if (dump_text && lines%lines_per_page == 0)
 
364
                                g_print("\n\n-Page %i-\n\n", lines/lines_per_page + 1);
 
365
                        
 
366
                        chars_in_this_line=0;
 
367
                        continue;
 
368
                }
 
369
 
 
370
                if (buffer[i] == '\t')
 
371
                {
 
372
                        temp_i = chars_in_this_line;
 
373
 
 
374
                        chars_in_this_line += tab_size - ((chars_in_this_line-1) % tab_size) - 1;
 
375
 
 
376
                        if (chars_in_this_line > chars_per_line + 1)
 
377
                            chars_in_this_line = chars_per_line + 1;
 
378
 
 
379
                        if (dump_text)
 
380
                                for (j=temp_i;j<chars_in_this_line+1;j++)
 
381
                                        g_print(".");
 
382
                        /*
 
383
                        g_print("\ntabs agregados = %i\n", chars_in_this_line - temp_i);
 
384
                        */
 
385
                }
 
386
 
 
387
 
 
388
                /* Do word wapping here */ 
 
389
                if (chars_in_this_line == chars_per_line + 1 && real)
 
390
                {
 
391
                        if (dump_info)
 
392
                                g_print ("\nThis lines needs breaking\n");
 
393
 
 
394
                        temp_i = i; /* We need to save the value of i in case we have to break the line */
 
395
 
 
396
                        /* We back i till we find a space that we can break the line at */
 
397
                        while (buffer[i] != ' ' && buffer[i] != '\t' && i > temp_i - chars_per_line - 1 )
 
398
                        {
 
399
                                i--;
 
400
                                if (dump_text)
 
401
                                        g_print("\b");
 
402
                        }
 
403
 
 
404
                        if (dump_info)
 
405
                                g_print("i got backed up [%i] times\n", temp_i - i);
 
406
 
 
407
                        /* If this line was "unbreakable" break it at chars_per_line width */
 
408
                        if (i == temp_i - chars_per_line - 1)
 
409
                        {
 
410
                                i = temp_i;
 
411
                                if (dump_info)
 
412
                                        g_print ("We are breaking the line\n");
 
413
                        }
 
414
 
 
415
                        /* We need to remove the trailing blanks so that the next line does not start with
 
416
                           a space or a tab char */
 
417
                        temp_i = i; /* Need to be able to determine who many spaces/tabs where removed */
 
418
                        while (buffer[i] == ' ' || buffer[i] == '\t')
 
419
                                i++;
 
420
                        if (dump_info && i!=temp_i)
 
421
                                g_print("We removed %i trailing spaces/tabs", i - temp_i);
 
422
 
 
423
                        /* We need to back i 1 time because this is a for loop and we did not processed the
 
424
                           last character */
 
425
                        i--;
 
426
                        lines++;
 
427
                        if (dump_text && lines%lines_per_page == 0)
 
428
                                g_print("\n\n-Page %i-\n\n", lines / lines_per_page + 1);
 
429
 
 
430
                        chars_in_this_line = 0;
 
431
 
 
432
                        if (dump_text)
 
433
                                g_print("\n");
 
434
                }
 
435
 
 
436
        }
 
437
 
 
438
        /* If the last line did not finished with a '\n' increment lines */
 
439
        if (buffer[i]!='\n')
 
440
        {
 
441
                lines++;
 
442
                if (dump_info_basic)
 
443
                        g_print("\nAdding one line because it was not terminated with a slash+n\n");
 
444
        }
 
445
 
 
446
        if (dump_info_basic)
 
447
        {
 
448
                g_print("determine_lines found %i lines.\n", lines);
 
449
        }
 
450
        
 
451
        temp_i = lines;
 
452
        
 
453
        /* After counting, scan the doc backwards to determine how many
 
454
           blanks lines there are (at the bottom),substract that from lines */
 
455
        for ( i = buffer_size-1; i>0; i--)
 
456
        {
 
457
                if ( buffer[i] != '\n' && buffer[i] != ' ' && buffer[i] != '\t')
 
458
                        break;
 
459
                else
 
460
                        if (buffer[i] == '\n')
 
461
                                lines--;
 
462
        }
 
463
 
 
464
        if (dump_info_basic && lines != temp_i)
 
465
        {
 
466
                g_print("We removed %i line(s) because they contained no text\n", temp_i - lines);
 
467
        }
 
468
 
 
469
        if (dump_text)
 
470
                g_print(".\n.\n.\n");
 
471
 
 
472
        return lines;
 
473
}
 
474
 
 
475
static void
 
476
print_start_job (PrintJobInfo *pji)
 
477
{
 
478
        gedit_debug (DEBUG_PRINT, "");
 
479
 
 
480
        print_set_orientation(pji);
 
481
}
 
482
 
 
483
static void
 
484
print_set_orientation (PrintJobInfo *pji)
 
485
{
 
486
        double affine [6];
 
487
 
 
488
        if (pji->orientation == PRINT_ORIENT_PORTRAIT)
 
489
                return;
 
490
 
 
491
        art_affine_rotate (affine, 90.0);
 
492
        gnome_print_concat (pji->pc, affine);
 
493
 
 
494
        art_affine_translate (affine, 0, -pji->page_height);
 
495
        gnome_print_concat (pji->pc, affine);
 
496
 
 
497
}
 
498
 
 
499
 
 
500
static void
 
501
print_header (PrintJobInfo *pji, unsigned int page)
 
502
{
 
503
        guchar* text1 = g_strdup (pji->filename);
 
504
        guchar* text2 = g_strdup_printf (_("Page: %i/%i"), page, pji->pages);
 
505
        float x,y,len;
 
506
        
 
507
        gedit_debug (DEBUG_PRINT, "");
 
508
 
 
509
        gnome_print_setfont (pji->pc, pji->font_header);
 
510
 
 
511
        /* Print the file name */
 
512
        y = pji->page_height - pji->margin_top - pji->header_height/2;
 
513
        len = gnome_font_get_width_string (pji->font_header, text1);
 
514
        x = pji->page_width/2 - len/2;
 
515
        gnome_print_moveto(pji->pc, x, y);
 
516
        gedit_print_show_iso8859_1 (pji->pc, text1);
 
517
 
 
518
        /* Print the page/pages  */
 
519
        y = pji->page_height - pji->margin_top - pji->header_height/4;
 
520
        len = gnome_font_get_width_string (pji->font_header, text2);
 
521
        x = pji->page_width - len - 36;
 
522
        gnome_print_moveto (pji->pc, x, y);
 
523
        gedit_print_show_iso8859_1 (pji->pc, text2);
 
524
 
 
525
        g_free (text1);
 
526
        g_free (text2);
 
527
}
 
528
 
 
529
        
 
530
 
 
531
static void
 
532
print_end_page (PrintJobInfo *pji)
 
533
{
 
534
        gedit_debug (DEBUG_PRINT, "");
 
535
 
 
536
        gnome_print_showpage (pji->pc);
 
537
        print_set_orientation (pji);
 
538
 
 
539
}
 
540
 
 
541
static void
 
542
print_end_job (GnomePrintContext *pc)
 
543
{
 
544
        gedit_debug (DEBUG_PRINT, "");
 
545
 
 
546
 
 
547
}
 
548