source: branches/port5/AWT/AWT_asciiprint.cxx

Last change on this file was 6102, checked in by westram, 16 years ago
  • fix warning "format not a string literal and no format arguments"
    • GB_information → GB_information/GB_informationf
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <arbdb.h>
6#include <arbdbt.h>
7
8#include <aw_root.hxx>
9#include <aw_device.hxx>
10#include <aw_window.hxx>
11#include "awt.hxx"
12#include "awt_asciiprint.hxx"
13
14double awt_aps_get_xy_ratio(AW_root *awr){
15    AWT_asciiprint_paper_size psize = (AWT_asciiprint_paper_size)awr->awar(AWAR_APRINT_PAPER_SIZE)->read_int();
16    AWT_asciiprint_orientation ori = AWT_asciiprint_orientation(awr->awar(AWAR_APRINT_ORIENTATION)->read_int());
17    double res = 1.0;
18    switch (ori){
19        case AWT_APRINT_ORIENTATION_PORTRAIT:
20            res = 112.0/90.0;
21            break;
22        case AWT_APRINT_ORIENTATION_LANDSCAPE:
23            res = 112.0/50.0;
24            break;
25        case AWT_APRINT_ORIENTATION_DOUBLE_PORTRAIT:
26            res = 103.0/90.0;
27            break;
28    }
29    if (psize == AWT_APRINT_PAPERSIZE_US) {
30        //res = res *.96;               // ?????
31    }
32    return res;
33}
34
35int awt_aps_get_default_lines_per_page(AW_root *awr){
36    AWT_asciiprint_orientation ori = AWT_asciiprint_orientation(awr->awar(AWAR_APRINT_ORIENTATION)->read_int());
37    switch (ori){
38        case AWT_APRINT_ORIENTATION_PORTRAIT:
39            return 80;
40        case AWT_APRINT_ORIENTATION_LANDSCAPE:
41            return 60;
42        case AWT_APRINT_ORIENTATION_DOUBLE_PORTRAIT:
43            return 80;
44    }
45    return -1;
46}
47
48
49void awt_aps_calc_pages_needed(AW_root *awr){
50    int mag = awr->awar(AWAR_APRINT_MAGNIFICATION)->read_int();
51    if (mag < 25) {
52        awr->awar(AWAR_APRINT_MAGNIFICATION)->write_int(mag*2);
53        return;
54    }
55    if (mag > 250 ) {
56        awr->awar(AWAR_APRINT_MAGNIFICATION)->write_int(250);
57        return;
58    }
59
60    int x = awr->awar(AWAR_APRINT_SX)->read_int() * mag / 100;
61    int y = awr->awar(AWAR_APRINT_SY)->read_int() * mag / 100;
62    int default_lpp = awt_aps_get_default_lines_per_page(awr);
63    double xy_ratio = awt_aps_get_xy_ratio(awr);
64    int default_cpp = int(default_lpp * xy_ratio);
65
66    awr->awar(AWAR_APRINT_DX)->write_float(double(x)/default_cpp);
67    awr->awar(AWAR_APRINT_DY)->write_float(double(y)/default_lpp);
68    x += default_cpp-1;
69    y += default_lpp-1;
70    x /= default_cpp;
71    y /= default_lpp;
72
73    awr->awar(AWAR_APRINT_PAGES)->write_int(x* y);
74}
75
76
77void awt_aps_set_magnification_to_fit_xpage(AW_root *awr){
78    int x = awr->awar(AWAR_APRINT_SX)->read_int();
79    //int y = awr->awar(AWAR_APRINT_SY)->read_int();
80
81    int dx = int(awr->awar(AWAR_APRINT_DX)->read_float()+.5);
82    if (dx < 1) dx = 1;
83    if (dx > 99) dx = 99;
84
85    int default_lpp = awt_aps_get_default_lines_per_page(awr);
86    double xy_ratio = awt_aps_get_xy_ratio(awr);
87    int default_cpp = int(default_lpp * xy_ratio);
88    int mag = 100 * default_cpp * dx / x;
89    awr->awar(AWAR_APRINT_MAGNIFICATION)->write_int(mag);
90    awt_aps_calc_pages_needed(awr);
91}
92
93void awt_aps_set_magnification_to_fit_ypage(AW_root *awr){
94    //int x = awr->awar(AWAR_APRINT_SX)->read_int();
95    int y = awr->awar(AWAR_APRINT_SY)->read_int();
96
97    int dy = int(awr->awar(AWAR_APRINT_DY)->read_float()+.5);
98    if (dy < 1) dy = 1;
99    if (dy > 99) dy = 99;
100
101    int default_lpp = awt_aps_get_default_lines_per_page(awr);
102    int mag = 100 * default_lpp * dy / y;
103    awr->awar(AWAR_APRINT_MAGNIFICATION)->write_int(mag);
104    awt_aps_calc_pages_needed(awr);
105}
106
107void awt_aps_set_magnification_to_fit_xpage(AW_window *aww){
108    awt_aps_set_magnification_to_fit_xpage(aww->get_root());
109}
110void awt_aps_set_magnification_to_fit_ypage(AW_window *aww){
111    awt_aps_set_magnification_to_fit_ypage(aww->get_root());
112}
113void awt_aps_text_changed(AW_root *awr){
114    char *text = awr->awar(AWAR_APRINT_TEXT)->read_string();
115    {
116        char *rtext = GBS_replace_tabs_by_spaces(text);
117        delete text;
118        text = rtext;
119    }    int maxx,y;
120    maxx = 1;y = 0;
121    char *s;
122    char *ns;
123    for (s = text;s;s=ns){
124        ns = strchr(s,'\n');
125        if (ns) {
126            ns[0] = 0;
127            ns++;
128        }
129        int slen = strlen(s);
130        if (slen > maxx) {
131            maxx = slen;
132        }
133        y++;
134    }
135    if (!y) y++;
136    awr->awar(AWAR_APRINT_SX)->write_int(maxx);
137    awr->awar(AWAR_APRINT_SY)->write_int(y);
138    delete text;
139    awt_aps_set_magnification_to_fit_xpage(awr);
140}
141
142void AWT_write_file(const char *filename,const char *file){
143    FILE *f = fopen(filename,"r");
144    if (f){
145        fclose(f);
146        if (aw_question(GBS_global_string("File '%s' already exist",filename),"Overwrt,Cancel")){
147            return;
148        }
149    }
150    f = fopen(filename,"w");
151    if (!f){
152        aw_message(GBS_global_string("Cannot write to '%s'",filename));
153        return;
154    }
155    fprintf(f,"%s",file);
156    fclose(f);
157}
158
159void awt_aps_go(AW_window *aww){
160    AW_root *awr  = aww->get_root();
161    char    *text = awr->awar(AWAR_APRINT_TEXT)->read_string();
162
163    freeset(text, GBS_replace_tabs_by_spaces(text));
164
165    AWT_asciiprint_destination dest = (AWT_asciiprint_destination)awr->awar(AWAR_APRINT_PRINTTO)->read_int();
166    if (dest == AWT_APRINT_DEST_AFILE){
167        char *file = awr->awar(AWAR_APRINT_FILE)->read_string();
168        AWT_write_file(file,text);
169        free(file);
170    }
171    else {
172        char *tmp_file;
173        FILE *tmpf;
174        {
175            char *name = GB_unique_filename("arb_aprint", "txt");
176            tmpf = GB_fopen_tempfile(name, "wt", &tmp_file);
177            free(name);
178        }
179
180        GB_ERROR error = NULL;
181        if (!tmpf){
182            error = GBS_global_string("awt_aps_go: %s", GB_await_error());
183        }
184        else {
185            char *y_begin = text;
186            int last_y = 0;
187
188            double xy_ratio = awt_aps_get_xy_ratio(awr);
189            int    mag      = awr->awar(AWAR_APRINT_MAGNIFICATION)->read_int();
190
191            int default_lpp = awt_aps_get_default_lines_per_page(awr);
192            int default_cpp = int(default_lpp * xy_ratio);
193            default_cpp     = default_cpp * 100 / mag;
194            default_lpp     = default_lpp * 100 / mag;
195
196            int text_width  = awr->awar(AWAR_APRINT_SX)->read_int();
197            int text_height = awr->awar(AWAR_APRINT_SY)->read_int();
198
199            int x;
200            int y;
201
202            for (y = 0; y < text_height; y+= default_lpp){
203                while(last_y < y){
204                    last_y ++;
205                    y_begin = strchr(y_begin,'\n');
206                    if (!y_begin) break;
207                    y_begin++;
208                }
209                if (!y_begin) break;
210
211                for (x = 0; x < text_width; x+= default_cpp){
212                    char *line = y_begin;
213                    int i;
214                    for (i=0;i<default_lpp;i++){
215                        if (line){
216                            char *next_line = strchr(line,'\n');
217                            int line_length;
218                            if (next_line){
219                                line_length = next_line - line; // exclusive '\n'
220                                next_line ++;
221                            }else{
222                                line_length = strlen(line);
223                            }
224                            if (line_length > x + default_cpp){
225                                line_length = x + default_cpp;
226                            }
227                            if (line_length > x) {
228                                fwrite(line + x, sizeof(char), line_length - x, tmpf);
229                            }
230                            line = next_line;
231                        }
232                        fprintf(tmpf,"\n");
233                    }
234                }
235            }
236            fclose(tmpf);
237
238            char *a2ps_call = 0;
239            {
240                AWT_asciiprint_orientation ori = AWT_asciiprint_orientation(awr->awar(AWAR_APRINT_ORIENTATION)->read_int());
241                const char *oristring = "";
242                switch (ori){
243                    case AWT_APRINT_ORIENTATION_PORTRAIT:
244                        oristring = "-p -1 ";
245                        break;
246                    case AWT_APRINT_ORIENTATION_LANDSCAPE:
247                        oristring = "-l -1 ";
248                        break;
249                    case AWT_APRINT_ORIENTATION_DOUBLE_PORTRAIT:
250                        oristring = "-p -2 ";
251                        break;
252                }
253                char *header = awr->awar(AWAR_APRINT_TITLE)->read_string();
254                a2ps_call = GBS_global_string_copy("arb_a2ps -ns -nP '-H%s' %s -l%i %s",
255                                                   header, oristring, default_lpp, tmp_file);
256                free(header);
257            }
258
259            const char *scall = 0;
260            switch(dest){
261                case AWT_APRINT_DEST_PRINTER: {
262                    char *printer = awr->awar(AWAR_APRINT_PRINTER)->read_string();
263                    scall = GBS_global_string("%s |%s; rm -f %s", a2ps_call, printer, tmp_file);
264                    free(printer);
265                    break;
266                }
267                case AWT_APRINT_DEST_FILE: {
268                    char *file = awr->awar(AWAR_APRINT_FILE)->read_string();
269                    scall = GBS_global_string("%s >%s;rm -f %s", a2ps_call, file, tmp_file);
270                    free(file);
271                    break;
272                }
273                case AWT_APRINT_DEST_PREVIEW: {
274                    char *tmp_file2;
275                    {
276                        char *name_only;
277                        GB_split_full_path(tmp_file, NULL, NULL, &name_only, NULL);
278                        tmp_file2 = GB_create_tempfile(GBS_global_string("%s.ps", name_only));
279                        free(name_only);
280                    }
281
282                    if (!tmp_file2) error = GB_await_error();
283                    else {
284                        scall = GBS_global_string("%s >%s;(%s %s;rm -f %s %s)&",
285                                                  a2ps_call, tmp_file2,
286                                                  GB_getenvARB_GS(), tmp_file2,
287                                                  tmp_file,tmp_file2);
288                        free(tmp_file2);
289                    }
290                    break;
291                }
292                default:
293                    gb_assert(0);
294                    break;
295            }
296
297            if (scall) {
298                GB_informationf("executing '%s'", scall);
299                if (system(scall) != 0) error = GBS_global_string("Error while calling '%s'", scall);
300            }
301
302            free(a2ps_call);
303        }
304        if (error) aw_message(error);
305        free(tmp_file);
306    }
307    free(text);
308}
309
310void AWT_create_ascii_print_window(AW_root *awr, const char *text_to_print,const char *title){
311    static AW_window_simple *aws = 0;
312
313    awr->awar_string(AWAR_APRINT_TEXT)->write_string(text_to_print);
314    if (title){
315        awr->awar_string(AWAR_APRINT_TITLE)->write_string(title);
316    }
317    if (aws) {
318        awr->awar_float(AWAR_APRINT_DX)->write_float(1.0);
319    }
320    else {
321        aws = new AW_window_simple();
322        aws->init(awr,"PRINT","PRINT");
323        aws->load_xfig("awt/ascii_print.fig");
324        awr->awar_string(AWAR_APRINT_TITLE);
325        awr->awar_string(AWAR_APRINT_TEXT)                                  ->add_callback(awt_aps_text_changed);
326
327        awr->awar_int(AWAR_APRINT_PAPER_SIZE,(int)AWT_APRINT_PAPERSIZE_A4)  ->add_callback(awt_aps_set_magnification_to_fit_xpage);
328        awr->awar_int(AWAR_APRINT_MAGNIFICATION,100)                        ->add_callback(awt_aps_calc_pages_needed);
329        awr->awar_int(AWAR_APRINT_PAGES,1);
330        awr->awar_int(AWAR_APRINT_SX,1);
331        awr->awar_int(AWAR_APRINT_SY,1);
332
333        awr->awar_float(AWAR_APRINT_DX,1.0);
334        awr->awar_float(AWAR_APRINT_DY,1.0);
335
336        awr->awar_int(AWAR_APRINT_ORIENTATION,(int)AWT_APRINT_ORIENTATION_PORTRAIT)->add_callback(awt_aps_set_magnification_to_fit_xpage);
337        awr->awar_int(AWAR_APRINT_PRINTTO,int(AWT_APRINT_DEST_PRINTER));
338        {
339            char *print_command;
340            if (getenv("PRINTER")){
341                print_command = GBS_eval_env("lpr -h -P$(PRINTER)");
342            }else{
343                print_command = strdup("lpr -h");
344            }
345
346            awr->awar_string(  AWAR_APRINT_PRINTER,print_command);
347            delete print_command;
348        }
349        awr->awar_string(AWAR_APRINT_FILE,"print.ps");
350
351        awt_aps_text_changed(awr);
352
353        aws->at("close");
354        aws->callback(AW_POPDOWN);
355        aws->create_button("CLOSE", "CLOSE");
356
357
358        aws->at("help");
359        aws->callback(AW_POPUP_HELP,(AW_CL)"asciiprint.hlp");
360        aws->create_button("HELP", "HELP");
361
362        aws->at("go");
363        aws->callback(awt_aps_go);
364        aws->create_button("PRINT", "PRINT");
365
366        aws->at("title");
367        aws->create_input_field(AWAR_APRINT_TITLE);
368
369        aws->at("text");
370        aws->create_text_field(AWAR_APRINT_TEXT);
371
372        aws->button_length(5);
373        aws->at("rows");
374        aws->create_button(0,AWAR_APRINT_SY);
375
376        aws->at("columns");
377        aws->create_button(0,AWAR_APRINT_SX);
378
379        aws->at("magnification");
380        aws->create_input_field(AWAR_APRINT_MAGNIFICATION,4);
381
382        aws->at("paper_size");
383        {
384            aws->create_toggle_field(AWAR_APRINT_PAPER_SIZE,1);
385            aws->insert_toggle("A4","A",int(AWT_APRINT_PAPERSIZE_A4));
386            aws->insert_toggle("US","U",int(AWT_APRINT_PAPERSIZE_US));
387            aws->update_toggle_field();
388        }
389
390        aws->at("orientation");
391        {
392            aws->create_toggle_field(AWAR_APRINT_ORIENTATION,1);
393            aws->insert_toggle("#print/portrait.bitmap","P",int(AWT_APRINT_ORIENTATION_PORTRAIT));
394            aws->insert_toggle("#print/landscape.bitmap","P",int(AWT_APRINT_ORIENTATION_LANDSCAPE));
395            aws->update_toggle_field();
396        }
397
398
399        aws->at("pages");
400        aws->create_button(0,AWAR_APRINT_PAGES);
401
402        aws->at("dcol");
403        aws->callback(awt_aps_set_magnification_to_fit_xpage);
404        aws->create_input_field(AWAR_APRINT_DX,4);
405
406        aws->at("drows");
407        aws->callback(awt_aps_set_magnification_to_fit_ypage);
408        aws->create_input_field(AWAR_APRINT_DY,4);
409
410
411        aws->at("printto");
412        aws->create_toggle_field( AWAR_APRINT_PRINTTO);
413        aws->insert_toggle("Printer","P",int(AWT_APRINT_DEST_PRINTER));
414        aws->insert_toggle("File (Postscript)","F",int(AWT_APRINT_DEST_FILE));
415        aws->insert_toggle("File (ASCII)","A",int(AWT_APRINT_DEST_AFILE));
416        aws->insert_toggle("Preview","V",int(AWT_APRINT_DEST_PREVIEW));
417        aws->update_toggle_field();
418
419        aws->at("printer");
420        aws->create_input_field(AWAR_APRINT_PRINTER, 16);
421
422        aws->at("filename");
423        aws->create_input_field(AWAR_APRINT_FILE, 16);
424    }
425    aws->activate();
426}
427
428
429void AWT_show_file(AW_root *awr, const char *filename){
430    char *text = GB_read_file(filename);
431    if (!text){
432        aw_message(GB_await_error());
433    }
434    else {
435        AWT_create_ascii_print_window(awr, text, filename);
436        free(text);
437    }
438}
Note: See TracBrowser for help on using the repository browser.