1 #include <stdio.h>
2 #include <math.h>
3 #include <string.h>
4 
5 #include <FL/Fl_PS_Printer.H>
6 #include <FL/Fl.H>
7 //#include <FL/Fl_Printer.H>
8 #include <FL/Fl_Pixmap.H>
9 #include <FL/Fl_Bitmap.H>
10 
11 
12 
13 
14 
15 static int dashes_flat[5][7]={
16   {-1,0,0,0,0,0,0},
17   {3,1,-1,0,0,0,0},
18   {1,1,-1,0,0,0,0},
19   {3,1,1,1,-1,0,0},
20   {3,1,1,1,1,1,-1}
21 };
22 
23 
24 //yeah, hack...
25 static double dashes_cap[5][7]={
26   {-1,0,0,0,0,0,0},
27   {2,2,-1,0,0,0,0},
28   {0.01,1.99,-1,0,0,0,0},
29   {2,2,0.01,1.99,-1,0,0},
30   {2,2,0.01,1.99,0.01,1.99,-1}
31 };
32 
33 
34 
35 
36 
37 
38 
39 
40 ////////////////////// Prolog string ////////////////////////////////////////
41 
42 
43 static const char * prolog =
44 "%%%%BeginProlog\n"
45 "/L { /y2 exch def\n"
46   "/x2 exch def\n"
47   "/y1 exch def\n"
48   "/x1 exch def\n"
49   "newpath   x1 y1 moveto x2 y2 lineto\n"
50   "stroke}\n"
51 "bind def\n"
52 
53 
54 "/R { /dy exch def\n"
55   "/dx exch def\n"
56   "/y exch def\n"
57   "/x exch def\n"
58   "newpath\n"
59   "x y moveto\n"
60   "dx 0 rlineto\n"
61   "0 dy rlineto\n"
62   "dx neg 0 rlineto\n"
63   "closepath stroke\n"
64 "} bind def\n"
65 
66 "/CL {\n"
67   "/dy exch def\n"
68   "/dx exch def\n"
69   "/y exch def\n"
70   "/x exch def\n"
71   "newpath\n"
72   "x y moveto\n"
73   "dx 0 rlineto\n"
74   "0 dy rlineto\n"
75   "dx neg 0 rlineto\n"
76   "closepath\n"
77   "clip\n"
78 "} bind def\n"
79 
80 "/FR { /dy exch def\n"
81   "/dx exch def\n"
82   "/y exch def\n"
83   "/x exch def\n"
84   "currentlinewidth 0 setlinewidth newpath\n"
85   "x y moveto\n"
86   "dx 0 rlineto\n"
87   "0 dy rlineto\n"
88   "dx neg 0 rlineto\n"
89   "closepath fill setlinewidth\n"
90 "} bind def\n"
91 
92 "/GS { gsave } bind  def\n"
93 "/GR { grestore } bind def\n"
94 
95 "/SP { showpage } bind def\n"
96 "/LW { setlinewidth } bind def\n"
97 "/CF /Courier def\n"
98 "/SF { /CF exch def } bind def\n"
99 "/fsize 12 def\n"
100 "/FS { /fsize exch def fsize CF findfont exch scalefont setfont }def \n"
101 
102 
103 "/GL { setgray } bind def\n"
104 "/SRGB { setrgbcolor } bind def\n"
105 
106 //////////////////// color images ////////////////////////
107 
108 "/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n"
109   "translate \n"
110   "sx sy scale px py 8 \n"
111   "[ px 0 0 py neg 0 py ]\n"
112   "currentfile /ASCIIHexDecode filter\n false 3"
113   " colorimage GR\n"
114 "} bind def\n"
115 
116 ///////////////////  gray images //////////////////////////
117 
118 "/GI { GS /py exch def /px exch def /sy exch def /sx exch def \n"
119   "translate \n"
120   "sx sy scale px py 8 \n"
121 
122 
123   "[ px 0 0 py neg 0 py ]\n"
124   "currentfile /ASCIIHexDecode filter\n"
125   "image GR\n"
126 "} bind def\n"
127 
128 ////////////////// single-color bitmask ///////////////////
129 
130 "/MI { GS /py exch def /px exch def /sy exch def /sx exch def \n"
131   "translate \n"
132   "sx sy scale px py false \n"
133   "[ px 0 0 py neg 0 py ]\n"
134   "currentfile /ASCIIHexDecode filter\n"
135   "imagemask GR\n"
136 "} bind def\n"
137 
138 ////////////////   color image dict /////////////
139 
140 "/CII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n"
141   "translate \n"
142   "sx sy scale\n"
143   "/DeviceRGB setcolorspace\n"
144   "/IDD 8 dict def\n"
145   "IDD begin\n"
146     "/ImageType 1 def\n"
147     "/Width px def\n"
148     "/Height py def\n"
149     "/BitsPerComponent 8 def\n"
150     "/Interpolate inter def\n"
151     "/DataSource currentfile /ASCIIHexDecode filter def\n"
152     "/MultipleDataSources false def\n"
153     "/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
154     "/Decode [ 0 1 0 1 0 1 ] def\n"
155   "end\n"
156 "IDD image GR} bind def\n"
157 
158 //////////////// gray image dict ///////////////////
159 
160 
161 "/GII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n"
162   "translate \n"
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175   "sx sy scale\n"
176   "/DeviceGray setcolorspace\n"
177   "/IDD 8 dict def\n"
178   "IDD begin\n"
179     "/ImageType 1 def\n"
180     "/Width px def\n"
181     "/Height py def\n"
182     "/BitsPerComponent 8 def\n"
183 
184     "/Interpolate inter def\n"
185     "/DataSource currentfile /ASCIIHexDecode filter def\n"
186     "/MultipleDataSources false def\n"
187     "/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
188     "/Decode [ 0 1 ] def\n"
189   "end\n"
190 "IDD image GR} bind def\n"
191 
192 
193 ///////////////////  masked color images   ///////
194 "/CIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n"
195   "translate \n"
196   "sx sy scale\n"
197   "/DeviceRGB setcolorspace\n"
198 
199 
200 
201 "/IDD 8 dict def\n"
202 
203 "IDD begin\n"
204     "/ImageType 1 def\n"
205     "/Width px def\n"
206     "/Height py def\n"
207     "/BitsPerComponent 8 def\n"
208   "/Interpolate inter def\n"
209     "/DataSource currentfile /ASCIIHexDecode filter def\n"
210     "/MultipleDataSources false def\n"
211     "/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
212 
213     "/Decode [ 0 1 0 1 0 1 ] def\n"
214 "end\n"
215 
216 "/IMD 8 dict def\n"
217 "IMD begin\n"
218     "/ImageType 1 def\n"
219     "/Width mx def\n"
220     "/Height my def\n"
221     "/BitsPerComponent 1 def\n"
222 //  "/Interpolate inter def\n"
223     "/ImageMatrix [ mx 0 0 my neg 0 my ] def\n"
224     "/Decode [ 1 0 ] def\n"
225 "end\n"
226 
227 "<<\n"
228   "/ImageType 3\n"
229   "/InterleaveType 2\n"
230   "/MaskDict IMD\n"
231   "/DataDict IDD\n"
232 ">> image GR\n"
233 "} bind def\n"
234 
235 
236 
237 ///////////////////  masked gray images   ////////////////
238 
239 
240 
241 
242 
243 "/GIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n"
244   "translate \n"
245   "sx sy scale\n"
246   "/DeviceGray setcolorspace\n"
247 
248   "/IDD 8 dict def\n"
249 
250 
251   "IDD begin\n"
252     "/ImageType 1 def\n"
253     "/Width px def\n"
254     "/Height py def\n"
255     "/BitsPerComponent 8 def\n"
256     "/Interpolate inter def\n"
257     "/DataSource currentfile /ASCIIHexDecode filter def\n"
258     "/MultipleDataSources false def\n"
259     "/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
260 
261     "/Decode [ 0 1 ] def\n"
262   "end\n"
263 
264   "/IMD 8 dict def\n"
265 
266   "IMD begin\n"
267     "/ImageType 1 def\n"
268     "/Width mx def\n"
269     "/Height my def\n"
270     "/BitsPerComponent 1 def\n"
271     "/ImageMatrix [ mx 0 0 my neg 0 my ] def\n"
272     "/Decode [ 1 0 ] def\n"
273   "end\n"
274 
275   "<<\n"
276     "/ImageType 3\n"
277     "/InterleaveType 2\n"
278     "/MaskDict IMD\n"
279     "/DataDict IDD\n"
280   ">> image GR\n"
281 "} bind def\n"
282 
283 
284 "\n"
285         ///////////////////////////  path ////////////////////
286 
287 "/BFP { newpath moveto }  def\n"
288 "/BP { newpath } bind def \n"
289 "/PL { lineto } bind def \n"
290 "/PM { moveto } bind def \n"
291 "/MT { moveto } bind def \n"
292 "/LT { lineto } bind def \n"
293 "/EFP { closepath fill } bind def\n"  //was:stroke
294 "/ELP { stroke } bind def\n"
295 "/ECP { closepath stroke } bind def\n"  // Closed (loop)
296 "/LW { setlinewidth } bind def\n"
297 
298         //////////////////////////// misc ////////////////
299 "/TR { translate } bind def\n"
300 "/CT { concat } bind def\n"
301 "/RCT { matrix invertmatrix concat} bind def\n"
302 "/SC { scale } bind def\n"
303 //"/GPD { currentpagedevice /PageSize get} def\n"
304 
305 ;
306 
307 
308 ////////////////////// end prolog ////////////////////////
309 
310 //////////////////////  fonts   ////////////////////////////////////
311 
312 static const char *_fontNames[] = {
313   "Helvetica",
314   "Helvetica-Bold",
315   "Helvetica-Oblique",
316   "Helvetica-BoldOblique",
317   "Courier",
318   "Courier-Bold",
319   "Courier-Oblique",
320   "Courier-BoldOblique",
321   "Times",
322   "Times-Bold",
323   "Times-Italic",
324 
325   "Times-BoldItalic",
326   "Symbol",
327   "Courier",
328   "CourierBold",
329   "ZapfDingbats"
330 };
331 
332 struct matrix {double a, b, c, d, x, y;};
333 extern matrix  * fl_get_matrix();
334 
335 
336 ///////////////////////// Implementations : matrix ////////////////////////////////////////
337 
concat()338 void Fl_PS_Printer::concat(){
339   matrix * m = fl_get_matrix();
340   //double a,b,c,d,x,y;
341   //fl_matrix(a,b,c,d,x,y);
342   fprintf(output,"[%g %g %g %g %g %g] CT\n", m->a , m->b , m->c , m->d , m->x , m->y);
343 }
344 
reconcat()345 void Fl_PS_Printer::reconcat(){
346   matrix * m = fl_get_matrix();
347   //double a,b,c,d,x,y;
348   //fl_matrix(a,b,c,d,x,y);
349   fprintf(output, "[%g %g %g %g %g %g] RCT\n" , m->a , m->b , m->c , m->d , m->x , m->y);
350 }
351 
352 
353 //////////////// for language level <3 ///////////////////////
354 
recover()355 void Fl_PS_Printer::recover(){
356   //if (colored_)
357     color(cr_,cg_,cb_);
358   //if (line_styled_)
359     line_style(linestyle_,linewidth_,linedash_);
360   //if (fonted_)
361     font(font_,size_);
362   //colored_=line_styled_=fonted_=0;
363 };
364 
reset()365 void Fl_PS_Printer::reset(){
366   gap_=1;
367   clip_=0;
368   cr_=cg_=cb_=0;
369   font_=FL_HELVETICA;
370   size_=12;
371   linewidth_=0;
372   linestyle_=FL_SOLID;
373   strcpy(linedash_,"");
374   Clip *c=clip_;   ////just not to have memory leaks for badly writen code (forgotten clip popping)
375 
376   while(c){
377     clip_=clip_->prev;
378     delete c;
379     c=clip_;
380   }
381   //line_style(0);
382   //colored_=1;
383   //line_styled_=1;
384   //fonted_=1;
385 };
386 
387 
388 
389 ///////////////// destructor, finishes postscript, closes FILE  ///////////////
390 
~Fl_PS_Printer()391 Fl_PS_Printer::~Fl_PS_Printer() {
392   if(nPages){  // for eps nPages is 0 so it is fine ....
393     fprintf(output, "CR\nGR\n GR\nSP\n restore\n");
394     if(!pages_){
395       fprintf(output, "%%%%Trailer\n");
396       fprintf(output, "%%%%Pages: %i\n" , nPages);
397     };
398   }else
399     fprintf(output, "GR\n restore\n");
400   reset();
401   //fclose(output);
402 
403   while(clip_){
404     Clip * c= clip_;
405     clip_= clip_->prev;
406     delete c;
407   }
408   if(close_cmd_)
409     (*close_cmd_)(output);
410 
411 }
412 
413 
414 ///////////////// PostScript constructors /////////////////////////////////////
415 
416 
Fl_PS_Printer(FILE * o,int lang_level,int pages)417 Fl_PS_Printer::Fl_PS_Printer(FILE *o, int lang_level, int pages):clip_(0),interpolate_(0){
418   close_cmd_=0;
419   lang_level_=lang_level;
420   output=o;
421   mask = 0;
422   //orientation_=0;
423   //orientation_=orientation;
424 //  lm_=rm_=bm_=tm_=72;
425   //pw_ =pw;
426   //ph_= ph;
427   bg_=FL_GRAY;
428   fprintf(output, "%%!PS-Adobe-3.0\n");
429   if(lang_level_>1)
430     fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_);
431   if(pages_==pages)
432     fprintf(output, "%%%%Pages: %i\n", pages);
433   else
434     fprintf(output, "%%%%Pages: (atend)\n");
435   fprintf(output, "%%%%EndComments\n");
436   fprintf(output, prolog);
437   if(lang_level_>=3){
438     fprintf(output, "/CS { clipsave } bind def\n");
439     fprintf(output, "/CR { cliprestore } bind def\n");
440   }else{
441     fprintf(output, "/CS { GS } bind def\n");
442     fprintf(output, "/CR { GR } bind def\n");
443   }
444   page_policy_=1;
445 
446 
447   fprintf(output, "%%%%EndProlog\n");
448   if(lang_level_>=2)
449     fprintf(output,"<< /Policies << /Pagesize 1 >> >> setpagedevice\n");
450 
451   reset();
452   nPages=0;
453   type_ = 0x100;
454 
455 };
456 
page_policy(int p)457 void Fl_PS_Printer::page_policy(int p){
458   page_policy_ = p;
459   if(lang_level_>=2)
460     fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p);
461 };
462 
463 
464 /////////////////////////////////////////////////////
465  /*
466 Fl_PS_Printer::Fl_PS_Printer(FILE *o, int lang_level, int pages)
467   :clip_(0),interpolate_(0)
468 {
469   lang_level_=lang_level;
470   output=o;
471   mask = 0;
472   //clip_=0;
473   lm_=rm_=bm_=tm_=72;
474   bg_=FL_GRAY;
475 
476   if (orientation&1){
477     ph_= Fl_Printer::page_formats[format][0];
478     pw_= Fl_Printer::page_formats[format][1];
479   }else{
480     ph_= Fl_Printer::page_formats[format][1];
481     pw_= Fl_Printer::page_formats[format][0];
482   }
483 
484   pw_ = ph_ = 0;
485   fprintf(output, "%%!PS-Adobe-3.0\n");
486   if(lang_level_>1)
487     fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_);
488   if(pages)
489     fprintf(output, "%%%%Pages: %i\n", pages);
490   else
491     fprintf(output, "%%%%Pages: (atend)\n");
492 
493   fprintf(output, prolog);
494   if(lang_level_>=3){
495     fprintf(output, "/CS { clipsave } bind def\n");
496     fprintf(output, "/CR { cliprestore } bind def\n");
497   }else{
498     fprintf(output, "/CS { GS } bind def\n");
499     fprintf(output, "/CR { GR } bind def\n");
500   }
501   fprintf(output, "%%%%EndProlog\n");
502 
503   reset();
504   nPages=0;
505   line_style(0);
506 
507 };
508 
509 */
510 
511 ///////////////////  eps constructor ////////////////////////////////////
512 
Fl_PS_Printer(FILE * o,int lang_level,int x,int y,int w,int h)513 Fl_PS_Printer::Fl_PS_Printer(FILE *o, int lang_level, int x, int y, int w, int h)
514   :clip_(0),interpolate_(0)
515 {
516   close_cmd_=0;
517   output=o;
518   mask = 0;
519   pages_=0;
520   //clip_=0;
521   lang_level_=lang_level;
522   bg_=FL_GRAY;
523   fprintf(output, "%%!PS-Adobe-3.0 EPSF-3.0\n");
524   if(lang_level_>1)
525     fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_);
526   fprintf(output, "%%%%BoundingBox: %i %i %i %i\n", x , y , x+w , y+h);
527   width_ = w;
528   height_ = h;
529  // lm_=x;
530  // tm_=0;
531  // rm_=0;
532  // bm_=y;
533   fprintf(output, prolog);
534   if(lang_level_>=3){
535     fprintf(output, "/CS { clipsave } bind def\n");
536     fprintf(output, "/CR { cliprestore } bind def\n");
537   }else{
538     fprintf(output, "/CS { GS } bind def\n");
539     fprintf(output, "/CR { GR } bind def\n");
540   }
541   fprintf(output, "%%%%EndProlog\n");
542   fprintf(output, "%%%%Page: 1 1\n");
543   fprintf(output, "%%%%PageOrientation: Portrait\n");
544   fprintf(output, "save\n");
545   fprintf(output, "GS\n");
546 
547   reset();
548   fprintf(output, "%g %g TR\n", double(x) , double(y+h));
549   fprintf(output, "1 -1  SC\n");
550   fprintf(output, "GS\nCS\n");
551   line_style(0);
552 
553   nPages=0;  //must be 0 also for eps!
554   type_= 0x100;
555 
556 };
557 
558 
559 ////////////////////// paging //////////////////////////////////////////
560 /*
561 void Fl_PS_Printer::page(){
562   if (nPages){
563     fprintf(output, "CR\nGR\nGR\nSP\nrestore\n");
564   }
565   ++nPages;
566   fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages);
567   fprintf(output, "save\n");
568   fprintf(output, "GS\n");
569   if(ph_)
570      fprintf(output, "%g %g TR\n", lm_ , ph_ - tm_);
571   else{
572     fprintf(output, "%g GPD exch pop %g sub TR\n", lm_, tm_);
573   }
574   fprintf(output, "1 -1 SC\n");
575   fprintf(output, "GS\nCS\n");
576 };
577 */
578 
579 
page(double pw,double ph,int media)580 void Fl_PS_Printer::page(double pw, double ph, int media) {
581 
582   if (nPages){
583     fprintf(output, "CR\nGR\nGR\nSP\nrestore\n");
584   }
585 
586   ++nPages;
587   fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages);
588 
589 
590 
591   if (pw>ph){
592     fprintf(output, "%%%%PageOrientation: Landscape\n");
593     //fprintf(output, "%i Orientation\n", 1);
594   }else{
595     fprintf(output, "%%%%PageOrientation: Portrait\n");
596     //fprintf(output, "%i Orientation\n", 0);
597   }
598 
599 
600 
601   fprintf(output, "%%%%BeginPageSetup\n");
602 
603   if((media & MEDIA) &&(lang_level_>1)){
604       int r = media & REVERSED;
605       if(r) r = 2;
606       fprintf(output, "<< /PageSize [%i %i] /Orientation %i>> setpagedevice\n", (int)(pw+.5), (int)(ph+.5), r);
607   }else
608     if(pw>ph)
609       if(media & REVERSED)
610         fprintf(output, "-90 rotate %i 0 translate\n", int(-pw));
611       else
612         fprintf(output, "90 rotate 0 %i translate\n", int(-ph));
613     else
614       if(media & REVERSED)
615         fprintf(output, "180 rotate %i %i translate\n", int(-pw), int(-ph));
616 
617 
618 
619 
620   fprintf(output, "%%%%EndPageSetup\n");
621 
622 
623   pw_=pw;
624   ph_=ph;
625 
626   reset();
627 
628   fprintf(output, "save\n");
629   fprintf(output, "GS\n");
630 
631   fprintf(output, "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/);
632   fprintf(output, "1 -1 SC\n");
633   line_style(0);
634   fprintf(output, "GS\nCS\n");
635 
636 };
637 
638 
page(int format)639 void Fl_PS_Printer::page(int format){
640 
641 
642   //orientation_=orientation;
643   if(format &  LANDSCAPE){
644     ph_=Fl_Printer::page_formats[format & 0xFF][0];
645     pw_=Fl_Printer::page_formats[format & 0xFF][1];
646   }else{
647     pw_=Fl_Printer::page_formats[format & 0xFF][0];
648     ph_=Fl_Printer::page_formats[format & 0xFF][1];
649   }
650   page(pw_,ph_,format & 0xFF00);//,orientation only;
651 };
652 
653 
654 
655 
place(double x,double y,double tx,double ty,double scale)656 void Fl_PS_Printer::place(double x, double y, double tx, double ty, double scale){
657 
658  fprintf(output, "CR\nGR\nGS\n");
659  reset();
660  fprintf(output, "%g %g TR\n", -x*scale + tx , -y*scale + ty);
661  fprintf(output, "%g %g SC\n", scale , scale );
662  fprintf(output, "CS\n");
663 
664 
665 }
666 
667 
668 
669 
670 
671 
672 
673 
674 //////////////////////////////  setting background for alpha /////////////////////////////////
675 
bg_color(Fl_Color bg)676 void Fl_PS_Printer::bg_color(Fl_Color bg){bg_=bg;};
677 
678 //////////////////////////////// Primitives: Colors  ////////////////////////////////////////////
679 
color(Fl_Color c)680 void Fl_PS_Printer::color(Fl_Color c) {
681   //colored_=1;
682   color_=c;
683   Fl::get_color(c, cr_, cg_, cb_);
684   if (cr_==cg_ && cg_==cb_) {
685     double gray = cr_/255.0;
686     fprintf(output, "%g GL\n", gray);
687 
688   } else {
689     double fr, fg, fb;
690     fr = cr_/255.0;
691     fg = cg_/255.0;
692     fb = cb_/255.0;
693     fprintf(output,"%g %g %g SRGB\n", fr , fg , fb);
694   }
695 }
696 
color(unsigned char r,unsigned char g,unsigned char b)697 void Fl_PS_Printer::color(unsigned char r, unsigned char g, unsigned char b) {
698 
699   //colored_=1;
700   cr_=r;cg_=g;cb_=b;
701   if (r==g && g==b) {
702     double gray = r/255.0;
703     fprintf(output, "%g GL\n", gray);
704   } else {
705     double fr, fg, fb;
706     fr = r/255.0;
707     fg = g/255.0;
708     fb = b/255.0;
709     fprintf(output, "%g %g %g SRGB\n", fr , fg , fb);
710   }
711 }
712 
713 /////////////////////////////   Clipping /////////////////////////////////////////////
714 
push_clip(int x,int y,int w,int h)715 void Fl_PS_Printer::push_clip(int x, int y, int w, int h) {
716   Clip * c=new Clip();
717   clip_box(x,y,w,h,c->x,c->y,c->w,c->h);
718   c->prev=clip_;
719   clip_=c;
720   fprintf(output, "CR\nCS\n");
721   if(lang_level_<3)
722     recover();
723   fprintf(output, "%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w  , clip_->h);
724 
725 }
push_no_clip()726 void Fl_PS_Printer::push_no_clip() {
727   Clip * c = new Clip();
728   c->prev=clip_;
729   clip_=c;
730   clip_->x = clip_->y = clip_->w = clip_->h = -1;
731   fprintf(output, "CR\nCS\n");
732   if(lang_level_<3)
733     recover();
734 }
735 
pop_clip()736 void Fl_PS_Printer::pop_clip() {
737   if(!clip_)return;
738   Clip * c=clip_;
739   clip_=clip_->prev;
740   delete c;
741   fprintf(output, "CR\nCS\n");
742   if(clip_ && clip_->w >0)
743     fprintf(output, "%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w  , clip_->h);
744     // uh, -0.5 is to match screen clipping, for floats there should be something beter
745   if(lang_level_<3)
746     recover();
747 }
748 
749 
750 
clip_box(int x,int y,int w,int h,int & X,int & Y,int & W,int & H)751 int Fl_PS_Printer::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){
752   if(!clip_){
753     X=x;Y=y;W=w;H=h;
754     return 1;
755   }
756   if(clip_->w < 0){
757     X=x;Y=y;W=w;H=h;
758     return 1;
759   }
760   int ret=0;
761   if (x > (X=clip_->x)) {X=x; ret=1;}
762   if (y > (Y=clip_->y)) {Y=y; ret=1;}
763   if ((x+w) < (clip_->x+clip_->w)) {
764     W=x+w-X;
765 
766     ret=1;
767 
768   }else
769     W = clip_->x + clip_->w - X;
770   if(W<0){
771     W=0;
772     return 1;
773   }
774   if ((y+h) < (clip_->y+clip_->h)) {
775     H=y+h-Y;
776     ret=1;
777   }else
778     H = clip_->y + clip_->h - Y;
779   if(H<0){
780     W=0;
781     H=0;
782     return 1;
783   }
784   return ret;
785 };
786 
787 
not_clipped(int x,int y,int w,int h)788 int Fl_PS_Printer::not_clipped(int x, int y, int w, int h){
789   if(!clip_) return 1;
790   if(clip_->w < 0) return 1;
791   int X, Y, W, H;
792   clip_box(x, y, w, h, X, Y, W, H);
793   if(W) return 1;
794   return 0;
795 };
796 
797 
798 ///////////////////////////////// rect  /////////////////////////////////////////
799 
800 
801 
802 
803 
rect(int x,int y,int w,int h)804 void Fl_PS_Printer::rect(int x, int y, int w, int h) {
805 // Commented code does not work, i can't find the bug ;-(
806 // fprintf(output, "GS\n");
807 //  fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h);
808 //  fprintf(output, "GR\n");
809 
810 
811   fprintf(output, "GS\n");
812   fprintf(output,"BP\n");
813   fprintf(output, "%i %i MT\n", x , y);
814   fprintf(output, "%i %i LT\n", x+w-1 , y);
815   fprintf(output, "%i %i LT\n", x+w-1 , y+h-1);
816   fprintf(output, "%i %i LT\n", x , y+h-1);
817   fprintf(output, "ECP\n");
818   fprintf(output, "GR\n");
819 }
820 
821 
822 
rectf(int x,int y,int w,int h)823 void Fl_PS_Printer::rectf(int x, int y, int w, int h) {
824   fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h);
825 }
826 
point(int x,int y)827 void Fl_PS_Printer::point(int x, int y){
828   rectf(x,y,1,1);
829 }
830 
rectf(int x,int y,int w,int h,uchar r,uchar g,uchar b)831 void Fl_PS_Printer::rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
832 
833   fprintf(output, "GS\n");
834   double fr = r/255.0;
835   double fg = g/255.0;
836   double fb = b/255.0;
837   fprintf(output, "%g %g %g SRGB\n",fr , fg , fb);
838   rectf(x,y,w,h);
839   //fprintf(output, "%i %i %i %i FR\n", x , y , w  , h );
840   fprintf(output, "GR\n");
841 }
842 
843 ///////////////////////////////// lines  /////////////////////////////////////////
844 
line(int x1,int y1,int x2,int y2)845 void Fl_PS_Printer::line(int x1, int y1, int x2, int y2) {
846   fprintf(output, "GS\n");
847   fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2);
848   fprintf(output, "GR\n");
849 }
850 
line(int x0,int y0,int x1,int y1,int x2,int y2)851 void Fl_PS_Printer::line(int x0, int y0, int x1, int y1, int x2, int y2) {
852   fprintf(output, "GS\n");
853   fprintf(output,"BP\n");
854   fprintf(output, "%i %i MT\n", x0 , y0);
855   fprintf(output, "%i %i LT\n", x1 , y1);
856   fprintf(output, "%i %i LT\n", x2 , y2);
857   fprintf(output, "ELP\n");
858   fprintf(output, "GR\n");
859 }
860 
loop(int x0,int y0,int x1,int y1,int x2,int y2)861 void Fl_PS_Printer::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
862   fprintf(output, "GS\n");
863   fprintf(output,"BP\n");
864   fprintf(output, "%i %i MT\n", x0 , y0);
865   fprintf(output, "%i %i LT\n", x1 , y1);
866   fprintf(output, "%i %i LT\n", x2 , y2);
867   fprintf(output, "ECP\n");
868   fprintf(output, "GR\n");
869 }
870 
loop(int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3)871 void Fl_PS_Printer::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
872   fprintf(output, "GS\n");
873   fprintf(output,"BP\n");
874   fprintf(output, "%i %i MT\n", x0 , y0);
875   fprintf(output, "%i %i LT\n", x1 , y1);
876   fprintf(output, "%i %i LT\n", x2 , y2);
877   fprintf(output, "%i %i LT\n", x3 , y3);
878   fprintf(output, "ECP\n");
879   fprintf(output, "GR\n");
880 }
881 
polygon(int x0,int y0,int x1,int y1,int x2,int y2)882 void Fl_PS_Printer::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
883   fprintf(output, "GS\n");
884   fprintf(output,"BP\n");
885   fprintf(output, "%i %i MT\n", x0 , y0);
886   fprintf(output,"%i %i LT\n", x1 , y1);
887   fprintf(output, "%i %i LT\n", x2 , y2);
888   fprintf(output, "EFP\n");
889   fprintf(output, "GR\n");
890 }
891 
polygon(int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3)892 void Fl_PS_Printer::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
893   fprintf(output, "GS\n");
894   fprintf(output,"BP\n");
895   fprintf(output, "%i %i MT\n", x0 , y0 );
896   fprintf(output, "%i %i LT\n", x1 , y1 );
897   fprintf(output, "%i %i LT\n", x2 , y2 );
898   fprintf(output, "%i %i LT\n", x3 , y3 );
899 
900   fprintf(output, "EFP\n");
901   fprintf(output, "GR\n");
902 }
903 
xyline(int x,int y,int x1,int y2,int x3)904 void Fl_PS_Printer::xyline(int x, int y, int x1, int y2, int x3){
905   fprintf(output, "GS\n");
906   fprintf(output,"BP\n");
907   fprintf(output, "%i %i MT\n", x , y );
908   fprintf(output, "%i %i LT\n", x1 , y );
909   fprintf(output, "%i %i LT\n", x1 , y2);
910   fprintf(output,"%i %i LT\n", x3 , y2);
911   fprintf(output, "ELP\n");
912   fprintf(output, "GR\n");
913 };
914 
915 
xyline(int x,int y,int x1,int y2)916 void Fl_PS_Printer::xyline(int x, int y, int x1, int y2){
917 
918   fprintf(output, "GS\n");
919   fprintf(output,"BP\n");
920   fprintf(output, "%i %i MT\n", x , y);
921   fprintf(output,"%i %i LT\n", x1 , y);
922   fprintf(output, "%i %i LT\n", x1 , y2 );
923   fprintf(output, "ELP\n");
924   fprintf(output, "GR\n");
925 };
926 
xyline(int x,int y,int x1)927 void Fl_PS_Printer::xyline(int x, int y, int x1){
928   fprintf(output, "GS\n");
929   fprintf(output,"BP\n");
930   fprintf(output, "%i %i MT\n", x , y);
931   fprintf(output, "%i %i LT\n", x1 , y );
932   fprintf(output, "ELP\n");
933 
934   fprintf(output, "GR\n");
935 };
936 
yxline(int x,int y,int y1,int x2,int y3)937 void Fl_PS_Printer::yxline(int x, int y, int y1, int x2, int y3){
938   fprintf(output, "GS\n");
939 
940   fprintf(output,"BP\n");
941   fprintf(output,"%i %i MT\n", x , y);
942   fprintf(output, "%i %i LT\n", x , y1 );
943   fprintf(output, "%i %i LT\n", x2 , y1 );
944   fprintf(output , "%i %i LT\n", x2 , y3);
945   fprintf(output, "ELP\n");
946   fprintf(output, "GR\n");
947 };
948 
yxline(int x,int y,int y1,int x2)949 void Fl_PS_Printer::yxline(int x, int y, int y1, int x2){
950   fprintf(output, "GS\n");
951   fprintf(output,"BP\n");
952   fprintf(output, "%i %i MT\n", x , y);
953   fprintf(output, "%i %i LT\n", x , y1);
954   fprintf(output, "%i %i LT\n", x2 , y1);
955   fprintf(output, "ELP\n");
956   fprintf(output, "GR\n");
957 };
958 
yxline(int x,int y,int y1)959 void Fl_PS_Printer::yxline(int x, int y, int y1){
960   fprintf(output, "GS\n");
961   fprintf(output,"BP\n");
962   fprintf(output, "%i %i MT\n", x , y);
963   fprintf(output, "%i %i LT\n", x , y1);
964   fprintf(output, "ELP\n");
965 
966   fprintf(output, "GR\n");
967 };
968 
969 
970 
arc(int x,int y,int w,int h,double a1,double a2)971 void Fl_PS_Printer::arc(int x, int y, int w, int h, double a1, double a2) {
972 
973 
974   fprintf(output, "GS\n");
975   //fprintf(output, "BP\n");
976   begin_line();
977   fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
978   fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
979   arc(0,0,1,a2,a1);
980 //  fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2);
981   fprintf(output, "%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) );
982   fprintf(output, "%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
983   end_line();
984 
985 
986 //  fprintf(output, "%g setlinewidth\n",  2/sqrt(w*h));
987   //fprintf(output, "ELP\n");
988 //  fprintf(output, 2.0/w , 2.0/w , " SC\n";
989 
990 //  fprintf(output, (-x - w/2.0) , (-y - h/2)  , " TR\n";
991   fprintf(output, "GR\n");
992 }
993 
pie(int x,int y,int w,int h,double a1,double a2)994 void Fl_PS_Printer::pie(int x, int y, int w, int h, double a1, double a2) {
995 
996   fprintf(output, "GS\n");
997   fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
998   fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
999   begin_polygon();
1000   vertex(0,0);
1001   arc(0.0,0.0, 1, a2, a1);
1002   end_polygon();
1003   fprintf(output, "GR\n");
1004 
1005 }
1006 
1007 /////////////////  transformed (double) drawings ////////////////////////////////
1008 
1009 
begin_points()1010 void Fl_PS_Printer::begin_points(){
1011   fprintf(output, "GS\n");
1012   concat();
1013 
1014   fprintf(output, "BP\n");
1015   gap_=1;
1016   shape_=POINTS;
1017 };
1018 
begin_line()1019 void Fl_PS_Printer::begin_line(){
1020   fprintf(output, "GS\n");
1021   concat();
1022   fprintf(output, "BP\n");
1023   gap_=1;
1024   shape_=LINE;
1025 };
1026 
begin_loop()1027 void Fl_PS_Printer::begin_loop(){
1028   fprintf(output, "GS\n");
1029   concat();
1030   fprintf(output, "BP\n");
1031   gap_=1;
1032   shape_=LOOP;
1033 };
1034 
begin_polygon()1035 void Fl_PS_Printer::begin_polygon(){
1036   fprintf(output, "GS\n");
1037   concat();
1038   fprintf(output, "BP\n");
1039   gap_=1;
1040   shape_=POLYGON;
1041 };
1042 
vertex(double x,double y)1043 void Fl_PS_Printer::vertex(double x, double y){
1044   if(shape_==POINTS){
1045     fprintf(output,"%g %g MT\n", x , y);
1046     gap_=1;
1047     return;
1048   }
1049   if(gap_){
1050     fprintf(output,"%g %g MT\n", x , y);
1051     gap_=0;
1052   }else
1053     fprintf(output, "%g %g LT\n", x , y);
1054 };
1055 
curve(double x,double y,double x1,double y1,double x2,double y2,double x3,double y3)1056 void Fl_PS_Printer::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){
1057   if(shape_==NONE) return;
1058     if(gap_)
1059       fprintf(output,"%g %g MT\n", x , y);
1060     else
1061       fprintf(output, "%g %g LT\n", x , y);
1062     gap_=0;
1063 
1064   fprintf(output, "%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3);
1065 };
1066 
1067 
circle(double x,double y,double r)1068 void Fl_PS_Printer::circle(double x, double y, double r){
1069   if(shape_==NONE){
1070     fprintf(output, "GS\n");
1071     concat();
1072 //    fprintf(output, "BP\n");
1073     fprintf(output,"%g %g %g 0 360 arc\n", x , y , r);
1074     reconcat();
1075 //    fprintf(output, "ELP\n");
1076     fprintf(output, "GR\n");
1077   }else
1078 
1079     fprintf(output, "%g %g %g 0 360 arc\n", x , y , r);
1080 
1081 };
1082 
1083 
1084 
1085 
1086 
arc(double x,double y,double r,double start,double a)1087 void Fl_PS_Printer::arc(double x, double y, double r, double start, double a){
1088   if(shape_==NONE) return;
1089   gap_=0;
1090   if(start>a)
1091     fprintf(output, "%g %g %g %g %g arc\n", x , y , r , -start, -a);
1092   else
1093     fprintf(output, "%g %g %g %g %g arcn\n", x , y , r , -start, -a);
1094 
1095 };
1096 
end_points()1097 void Fl_PS_Printer::end_points(){
1098   gap_=1;
1099   reconcat();
1100   fprintf(output, "ELP\n"); //??
1101   fprintf(output, "GR\n");
1102   shape_=NONE;
1103 }
1104 
end_line()1105 void Fl_PS_Printer::end_line(){
1106   gap_=1;
1107   reconcat();
1108   fprintf(output, "ELP\n");
1109   fprintf(output, "GR\n");
1110   shape_=NONE;
1111 }
end_loop()1112 void Fl_PS_Printer::end_loop(){
1113   gap_=1;
1114   reconcat();
1115   fprintf(output, "ECP\n");
1116   fprintf(output, "GR\n");
1117   shape_=NONE;
1118 }
1119 
end_polygon()1120 void Fl_PS_Printer::end_polygon(){
1121 
1122   gap_=1;
1123   reconcat();
1124   fprintf(output, "EFP\n");
1125   fprintf(output, "GR\n");
1126   shape_=NONE;
1127 }
1128 
transformed_vertex(double x,double y)1129 void Fl_PS_Printer::transformed_vertex(double x, double y){
1130   reconcat();
1131   if(gap_){
1132     fprintf(output, "%g %g MT\n", x , y);
1133     gap_=0;
1134   }else
1135     fprintf(output, "%g %g LT\n", x , y);
1136   concat();
1137 };
1138 
1139 
1140 ///////////////////////// misc ////////////////////////////////////////////
1141 
font(int f,int s)1142 void Fl_PS_Printer::font(int f, int s) {
1143 
1144   //fonted_=1;
1145   if (f >= FL_FREE_FONT)
1146     f = FL_COURIER;
1147   fprintf(output, "/%s SF\n" , _fontNames[f]);
1148   fprintf(output,"%i FS\n", s);
1149   fltk.font(f,s); //Dirty hack for font measurement ;-(
1150   font_=f; size_=s;
1151 };
1152 
1153 
line_style(int style,int width,char * dashes)1154 void Fl_PS_Printer::line_style(int style, int width, char* dashes){
1155   //line_styled_=1;
1156 
1157   linewidth_=width;
1158   linestyle_=style;
1159   //dashes_= dashes;
1160   if(dashes){
1161     if(dashes != linedash_)
1162       strcpy(linedash_,dashes);
1163 
1164   }else
1165     linedash_[0]=0;
1166   char width0 = 0;
1167   if(!width){
1168     width=1; //for screen drawing compatability
1169     width0=1;
1170   }
1171 
1172   fprintf(output, "%i setlinewidth\n", width);
1173 
1174   if(!style && (!dashes || !(*dashes)) && width0) //system lines
1175     style = FL_CAP_SQUARE;
1176 
1177   int cap = (style &0xf00) >> 8;
1178   if(cap) cap--;
1179   fprintf(output,"%i setlinecap\n", cap);
1180 
1181   int join = (style & 0xf000) >> 12;
1182 
1183   if(join) join--;
1184   fprintf(output,"%i setlinejoin\n", join);
1185 
1186 
1187   fprintf(output, "[");
1188   if(dashes && *dashes){
1189     while(*dashes){
1190       fprintf(output, "%i ", *dashes);
1191       dashes++;
1192     }
1193   }else{
1194     int * ds;
1195     if(style & 0x200){ // round and square caps, dash length need to be adjusted
1196         double *dt = dashes_cap[style & 0xff];
1197         while (*dt >= 0){
1198           fprintf(output, "%g ",width * (*dt));
1199           dt++;
1200         }
1201       }else{
1202 
1203         ds = dashes_flat[style & 0xff];
1204         while (*ds >= 0){
1205           fprintf(output, "%i ",width * (*ds));
1206         ds++;
1207       }
1208     }
1209   }
1210   fprintf(output, "] 0 setdash\n");
1211 };
1212 
width(const char * s)1213 double Fl_PS_Printer::width(const char* s){
1214   return fltk.width(s); //Dirty...
1215 }
1216 
width(uchar c)1217 double Fl_PS_Printer::width(uchar c){
1218   return fltk.width(c); //Dirty...
1219 }
1220 
width(const char * s,int n)1221 double Fl_PS_Printer::width(const char* s, int n){;
1222   return fltk.width(s,n); //Very Dirty...
1223 }
descent()1224 int Fl_PS_Printer::descent(){
1225   return fltk.descent(); //A bit Dirty...
1226 }
height()1227 int Fl_PS_Printer::height(){
1228   return fltk.height(); //Still Dirty...
1229 }
1230 
1231 ///////////////////////////////  text ////////////////////////////////////
1232 
1233 /* a pathetic quick & dirty UTF-8 parser
1234  *
1235  * adapted from Markus Kuhn -- Public Domain --
1236  * (Get uniset from <http://www.cl.cam.ac.uk/~mgk25/download/uniset.tar.gz>.)
1237  */
1238 
1239 // convert UTF-8 string to wchar_t *, return adjusted length
wchar_convert(wchar_t * wline,const char * line,unsigned int n)1240 unsigned int wchar_convert(wchar_t * wline,const char * line,unsigned int n){
1241   unsigned int i=0,j=0,c;
1242   for (;i<n;i++){
1243     c=line[i];
1244     if ( (c & 0xc0) == 0x80)
1245       continue;
1246     if (c < 128){
1247       wline[j]=c;
1248       j++;
1249       continue;
1250     }
1251     if ( (c & 0xe0) == 0xc0) {
1252       i++;
1253       c = (c & 0x1f) << 6 | (line[i] & 0x3f);
1254       wline[j]=c;
1255       j++;
1256       continue;
1257     }
1258     if ( (c & 0xf0) == 0xe0) {
1259       i++;
1260       c = (c & 0x0f) << 6 | (line[i] & 0x3f);
1261       i++;
1262       c = c << 6 | (line[i] & 0x3f);
1263       wline[j]=c;
1264       j++;
1265       continue;
1266     }
1267     if ( (c & 0xf1) == 0xf0) {
1268       i++;
1269       c = (c & 0x0f) << 6 | (line[i] & 0x3f);
1270       i++;
1271       c = c << 6 | (line[i] & 0x3f);
1272       i++;
1273       c = c << 6 | (line[i] & 0x3f);
1274     } else
1275       c = 0xfffd;
1276     wline[j]=c;
1277     j++;
1278   }
1279   wline[j]=0;
1280   return j;
1281 }
1282 
1283 
1284 #define GRAVE        " (\301) "
1285 #define ACUTE        " (\302) "
1286 #define CIRCUMFLEX   " (\303) "
1287 #define TILDE        " (\304) "
1288 #define MACRON       " (\305) "
1289 #define BREVE        " (\306) "
1290 #define DOTACCENT    " (\307) "
1291 #define DIERESIS     " (\310) "
1292 #define RING         " (\312) "
1293 #define CEDILLA      " (\313) "
1294 #define HUNGARUMLAUT " (\315) "
1295 #define OGONEK       " (\316) "
1296 #define CARON        " (\317) "
1297 #define DOTLESSI     "(\365)"
1298 
1299 struct charentry {
1300   unsigned short ucs;
1301   char execute; /* 0: s is a glyphname, 1: s is executable code */
1302   const char *s;
1303 } chartab[] ={
1304   { 0x0027, 0, "quotesingle" },
1305   { 0x0060, 0, "grave" },
1306   { 0x00A0, 0, "space" },
1307   { 0x00A1, 0, "exclamdown" },
1308   { 0x00A2, 0, "cent" },
1309   { 0x00A3, 0, "sterling" },
1310   { 0x00A4, 0, "currency" },
1311   { 0x00A5, 0, "yen" },
1312   { 0x00A6, 0, "brokenbar" },
1313   { 0x00A7, 0, "section" },
1314   { 0x00A8, 0, "dieresis" },
1315   { 0x00A9, 0, "copyright" },
1316   { 0x00AA, 0, "ordfeminine" },
1317   { 0x00AB, 0, "guillemotleft" },
1318   { 0x00AC, 0, "logicalnot" },
1319   { 0x00AD, 0, "hyphen" },
1320   { 0x00AE, 0, "registered" },
1321   { 0x00AF, 0, "macron" },
1322   { 0x00B0, 0, "degree" },
1323   { 0x00B1, 0, "plusminus" },
1324   { 0x00B2, 0, "twosuperior" },
1325   { 0x00B3, 0, "threesuperior" },
1326   { 0x00B4, 0, "acute" },
1327   { 0x00B5, 0, "mu" },
1328   { 0x00B6, 0, "paragraph" },
1329   { 0x00B7, 0, "periodcentered" },
1330   { 0x00B8, 0, "cedilla" },
1331   { 0x00B9, 0, "onesuperior" },
1332   { 0x00BA, 0, "ordmasculine" },
1333   { 0x00BB, 0, "guillemotright" },
1334   { 0x00BC, 0, "onequarter" },
1335   { 0x00BD, 0, "onehalf" },
1336   { 0x00BE, 0, "threequarters" },
1337   { 0x00BF, 0, "questiondown" },
1338   { 0x00C0, 0, "Agrave" },
1339   { 0x00C1, 0, "Aacute" },
1340   { 0x00C2, 0, "Acircumflex" },
1341   { 0x00C3, 0, "Atilde" },
1342   { 0x00C4, 0, "Adieresis" },
1343   { 0x00C5, 0, "Aring" },
1344   { 0x00C6, 0, "AE" },
1345   { 0x00C7, 0, "Ccedilla" },
1346   { 0x00C8, 0, "Egrave" },
1347   { 0x00C9, 0, "Eacute" },
1348   { 0x00CA, 0, "Ecircumflex" },
1349   { 0x00CB, 0, "Edieresis" },
1350   { 0x00CC, 0, "Igrave" },
1351   { 0x00CD, 0, "Iacute" },
1352   { 0x00CE, 0, "Icircumflex" },
1353   { 0x00CF, 0, "Idieresis" },
1354   { 0x00D0, 0, "Eth" },
1355   { 0x00D1, 0, "Ntilde" },
1356   { 0x00D2, 0, "Ograve" },
1357   { 0x00D3, 0, "Oacute" },
1358   { 0x00D4, 0, "Ocircumflex" },
1359   { 0x00D5, 0, "Otilde" },
1360   { 0x00D6, 0, "Odieresis" },
1361   { 0x00D7, 0, "multiply" },
1362   { 0x00D8, 0, "Oslash" },
1363   { 0x00D9, 0, "Ugrave" },
1364   { 0x00DA, 0, "Uacute" },
1365   { 0x00DB, 0, "Ucircumflex" },
1366   { 0x00DC, 0, "Udieresis" },
1367   { 0x00DD, 0, "Yacute" },
1368   { 0x00DE, 0, "Thorn" },
1369   { 0x00DF, 0, "germandbls" },
1370   { 0x00E0, 0, "agrave" },
1371   { 0x00E1, 0, "aacute" },
1372   { 0x00E2, 0, "acircumflex" },
1373   { 0x00E3, 0, "atilde" },
1374   { 0x00E4, 0, "adieresis" },
1375   { 0x00E5, 0, "aring" },
1376   { 0x00E6, 0, "ae" },
1377   { 0x00E7, 0, "ccedilla" },
1378   { 0x00E8, 0, "egrave" },
1379   { 0x00E9, 0, "eacute" },
1380   { 0x00EA, 0, "ecircumflex" },
1381   { 0x00EB, 0, "edieresis" },
1382   { 0x00EC, 0, "igrave" },
1383   { 0x00ED, 0, "iacute" },
1384   { 0x00EE, 0, "icircumflex" },
1385   { 0x00EF, 0, "idieresis" },
1386   { 0x00F0, 0, "eth" },
1387   { 0x00F1, 0, "ntilde" },
1388   { 0x00F2, 0, "ograve" },
1389   { 0x00F3, 0, "oacute" },
1390   { 0x00F4, 0, "ocircumflex" },
1391   { 0x00F5, 0, "otilde" },
1392   { 0x00F6, 0, "odieresis" },
1393   { 0x00F7, 0, "divide" },
1394   { 0x00F8, 0, "oslash" },
1395   { 0x00F9, 0, "ugrave" },
1396   { 0x00FA, 0, "uacute" },
1397   { 0x00FB, 0, "ucircumflex" },
1398   { 0x00FC, 0, "udieresis" },
1399   { 0x00FD, 0, "yacute" },
1400   { 0x00FE, 0, "thorn" },
1401   { 0x00FF, 0, "ydieresis" },
1402   { 0x0100, 1, "(A)" MACRON "Cp"},
1403   { 0x0101, 1, "(a)" MACRON "cp"},
1404   { 0x0102, 1, "(A)" BREVE  "Cp"},
1405   { 0x0103, 1, "(a)" BREVE  "cp"},
1406   { 0x0104, 1, "(A)" OGONEK "cp" },
1407   { 0x0105, 1, "(a)" OGONEK "cp" },
1408   { 0x0106, 1, "(C)" ACUTE "Cp" },
1409   { 0x0107, 1, "(c)" ACUTE "cp" },
1410   { 0x0108, 1, "(C)" CIRCUMFLEX "Cp" },
1411   { 0x0109, 1, "(c)" CIRCUMFLEX "cp" },
1412   { 0x010A, 1, "(C)" DOTACCENT "Cp" },
1413   { 0x010B, 1, "(c)" DOTACCENT "cp" },
1414   { 0x010C, 1, "(C)" CARON "Cp" },
1415   { 0x010D, 1, "(c)" CARON "cp" },
1416   { 0x010E, 1, "(D)" CARON "Cp" },
1417   { 0x010F, 1, "(d)" CARON "Cp" },
1418   { 0x0110, 0, "Eth" },
1419   { 0x0111, 1, "(d) (-) 0.1 0.2 scp" },
1420   { 0x0112, 1, "(E)" MACRON "Cp" },
1421   { 0x0113, 1, "(e)" MACRON "cp" },
1422   { 0x0114, 1, "(E)" BREVE "Cp" },
1423   { 0x0115, 1, "(e)" BREVE "cp" },
1424   { 0x0116, 1, "(E)" DOTACCENT "Cp" },
1425   { 0x0117, 1, "(e)" DOTACCENT "cp" },
1426   { 0x0118, 1, "(E)" OGONEK "cp" },
1427   { 0x0119, 1, "(e)" OGONEK "cp" },
1428   { 0x011A, 1, "(E)" CARON "Cp" },
1429   { 0x011B, 1, "(e)" CARON "cp" },
1430   { 0x011C, 1, "(G)" CIRCUMFLEX "Cp" },
1431   { 0x011D, 1, "(g)" CIRCUMFLEX "cp" },
1432   { 0x011E, 1, "(G)" BREVE "Cp" },
1433   { 0x011F, 1, "(g)" BREVE "cp" },
1434   { 0x0120, 1, "(G)" DOTACCENT "Cp" },
1435   { 0x0121, 1, "(g)" DOTACCENT "cp" },
1436   { 0x0122, 1, "(G)" CEDILLA "cp" },
1437   { 0x0124, 1, "(H)" CIRCUMFLEX "Cp" },
1438   { 0x0125, 1, "(h)" CIRCUMFLEX "Cp" },
1439   { 0x0126, 1, "(H) (-) 0 0.15 scp" },
1440   { 0x0127, 1, "(h) (-) -0.1 0.2 scp" },
1441   { 0x0128, 1, "(I)" TILDE "Cp" },
1442   { 0x0129, 1, DOTLESSI TILDE "cp" },
1443   { 0x012A, 1, "(I)" MACRON "Cp" },
1444   { 0x012B, 1, DOTLESSI MACRON "cp" },
1445   { 0x012C, 1, "(I)" BREVE "Cp" },
1446   { 0x012D, 1, DOTLESSI BREVE "cp" },
1447   { 0x012E, 1, "(I)" OGONEK "cp" },
1448   { 0x012F, 1, "(i)" OGONEK "cp" },
1449   { 0x0130, 1, "(I)" DOTACCENT "Cp" },
1450   { 0x0131, 0, "dotlessi" },
1451   { 0x0134, 1, "(J)" CIRCUMFLEX "Cp" },
1452   { 0x0135, 1, "(j)" CIRCUMFLEX "cp" },
1453   { 0x0136, 1, "(K)" CEDILLA "cp" },
1454   { 0x0137, 1, "(k)" CEDILLA "cp" },
1455   { 0x0138, 1, "gsave currentpoint translate 1 0.7 scale (K) show grestore "
1456     "(K) stringwidth rmoveto" },
1457   { 0x0139, 1, "(L)" ACUTE "Cp" },
1458   { 0x013A, 1, "(l)" ACUTE "Cp" },
1459   { 0x013B, 1, "(L)" CEDILLA "cp" },
1460   { 0x013C, 1, "(l)" CEDILLA "cp" },
1461   { 0x013D, 1, "(L)" CARON "Cp" },
1462   { 0x013E, 1, "(l)" CARON "Cp" },
1463   { 0x0141, 0, "Lslash" },
1464   { 0x0142, 0, "lslash" },
1465   { 0x0143, 1, "(N)" ACUTE "Cp" },
1466   { 0x0144, 1, "(n)" ACUTE "cp" },
1467   { 0x0145, 1, "(N)" CEDILLA "cp" },
1468   { 0x0146, 1, "(n)" CEDILLA "cp" },
1469   { 0x0147, 1, "(N)" CARON "Cp" },
1470   { 0x0148, 1, "(n)" CARON "cp" },
1471   { 0x014C, 1, "(O)" MACRON "Cp" },
1472   { 0x014D, 1, "(o)" MACRON "cp" },
1473   { 0x014E, 1, "(O)" BREVE "Cp" },
1474   { 0x014F, 1, "(o)" BREVE "cp" },
1475   { 0x0150, 1, "(O)" HUNGARUMLAUT "Cp" },
1476   { 0x0151, 1, "(o)" HUNGARUMLAUT "cp" },
1477   { 0x0152, 0, "OE" },
1478   { 0x0153, 0, "oe" },
1479   { 0x0154, 1, "(R)" ACUTE "Cp" },
1480   { 0x0155, 1, "(r)" ACUTE "cp" },
1481   { 0x0156, 1, "(R)" CEDILLA "cp" },
1482   { 0x0157, 1, "(r)" CEDILLA "cp" },
1483   { 0x0158, 1, "(R)" CARON "Cp" },
1484   { 0x0159, 1, "(r)" CARON "cp" },
1485   { 0x015A, 1, "(S)" ACUTE "Cp" },
1486   { 0x015B, 1, "(s)" ACUTE "cp" },
1487   { 0x015C, 1, "(S)" CIRCUMFLEX "Cp" },
1488   { 0x015D, 1, "(s)" CIRCUMFLEX "cp" },
1489   { 0x015E, 1, "(S)" CEDILLA "cp" },
1490   { 0x015F, 1, "(s)" CEDILLA "cp" },
1491   { 0x0160, 0, "Scaron" },
1492   { 0x0161, 0, "scaron" },
1493   { 0x0162, 1, "(T)" CEDILLA "cp" },
1494   { 0x0163, 1, "(t)" CEDILLA "cp" },
1495   { 0x0164, 1, "(T)" CARON "Cp" },
1496   { 0x0165, 1, "(t)" CARON "Cp" },
1497   { 0x0166, 1, "(T) (-) cp" },
1498   { 0x0167, 1, "(t) (-) -0.1 0 scp" },
1499   { 0x0168, 1, "(U)" TILDE "Cp" },
1500   { 0x0169, 1, "(u)" TILDE "cp" },
1501   { 0x016A, 1, "(U)" MACRON "Cp" },
1502   { 0x016B, 1, "(u)" MACRON "cp" },
1503   { 0x016C, 1, "(U)" BREVE "Cp" },
1504   { 0x016D, 1, "(u)" BREVE "cp" },
1505   { 0x016E, 1, "(U)" RING "Cp" },
1506   { 0x016F, 1, "(u)" RING "cp" },
1507   { 0x0170, 1, "(U)" HUNGARUMLAUT "Cp" },
1508   { 0x0171, 1, "(u)" HUNGARUMLAUT "cp" },
1509   { 0x0172, 1, "(U)" OGONEK "cp" },
1510   { 0x0173, 1, "(u)" OGONEK "cp" },
1511   { 0x0174, 1, "(W)" CIRCUMFLEX "Cp" },
1512   { 0x0175, 1, "(w)" CIRCUMFLEX "cp" },
1513   { 0x0176, 1, "(Y)" CIRCUMFLEX "Cp" },
1514   { 0x0177, 1, "(y)" CIRCUMFLEX "cp" },
1515   { 0x0178, 0, "Ydieresis" },
1516   { 0x0179, 1, "(Z)" ACUTE "Cp" },
1517   { 0x017A, 1, "(z)" ACUTE "cp" },
1518   { 0x017B, 1, "(Z)" DOTACCENT "Cp" },
1519   { 0x017C, 1, "(z)" DOTACCENT "cp" },
1520   { 0x017D, 0, "Zcaron" },
1521   { 0x017E, 0, "zcaron" },
1522   { 0x0189, 0, "Eth" },
1523   { 0x0192, 0, "florin" },
1524   { 0x02C6, 0, "circumflex" },
1525   { 0x02C7, 0, "caron" },
1526   { 0x02C9, 0, "macron" },
1527   { 0x02D8, 0, "breve" },
1528   { 0x02D9, 0, "dotaccent" },
1529   { 0x02DA, 0, "ring" },
1530   { 0x02DB, 0, "ogonek" },
1531   { 0x02DC, 0, "tilde" },
1532   { 0x02DD, 0, "hungarumlaut" },
1533   { 0x0386, 3, "A"}, // FIXME
1534   { 0x0388, 3, "E"}, // FIXME
1535   { 0x0389, 3, "H"}, // FIXME
1536   { 0x038A, 3, "I"}, // FIXME
1537   { 0x038C, 3, "O"}, // FIXME
1538   { 0x038E, 3, "Y"}, // FIXME
1539   { 0x038F, 3, "W"}, // FIXME
1540   { 0x0390, 3, "i"}, // FIXME
1541   { 0x0391, 3, "A"},
1542   { 0x0392, 3, "B"},
1543   { 0x0393, 3, "G"},
1544   { 0x0394, 3, "D"},
1545   { 0x0395, 3, "E"},
1546   { 0x0396, 3, "Z"},
1547   { 0x0397, 3, "H"},
1548   { 0x0398, 3, "Q"},
1549   { 0x0399, 3, "I"},
1550   { 0x039A, 3, "K"},
1551   { 0x039B, 3, "L"},
1552   { 0x039C, 3, "M"},
1553   { 0x039D, 3, "N"},
1554   { 0x039E, 3, "X"},
1555   { 0x039F, 3, "O"},
1556   { 0x03A0, 3, "P"},
1557   { 0x03A1, 3, "R"},
1558   { 0x03A3, 3, "S"},
1559   { 0x03A4, 3, "T"},
1560   { 0x03A5, 3, "U"},
1561   { 0x03A6, 3, "F"},
1562   { 0x03A7, 3, "C"},
1563   { 0x03A8, 3, "Y"},
1564   { 0x03A9, 3, "W"},
1565   { 0x03AA, 3, "I"}, // FIXME
1566   { 0x03AB, 3, "Y"}, // FIXME
1567   { 0x03AC, 3, "a"}, // FIXME
1568   { 0x03AD, 3, "e"}, // FIXME
1569   { 0x03AE, 3, "h"}, // FIXME
1570   { 0x03AF, 3, "i"}, // FIXME
1571   { 0x03B0, 3, "u"}, // FIXME
1572   { 0x03B1, 3, "a"},
1573   { 0x03B2, 3, "b"},
1574   { 0x03B3, 3, "g"},
1575   { 0x03B4, 3, "d"},
1576   { 0x03B5, 3, "e"},
1577   { 0x03B6, 3, "z"},
1578   { 0x03B7, 3, "h"},
1579   { 0x03B8, 3, "q"},
1580   { 0x03B9, 3, "i"},
1581   { 0x03BA, 3, "k"},
1582   { 0x03BB, 3, "l"},
1583   { 0x03BC, 3, "m" },
1584   { 0x03BD, 3, "n"},
1585   { 0x03BE, 3, "x"},
1586   { 0x03BF, 3, "o"},
1587   { 0x03C0, 3, "p"},
1588   { 0x03C1, 3, "r"},
1589   { 0x03C2, 3, "V"},
1590   { 0x03C3, 3, "s"},
1591   { 0x03C4, 3, "t"},
1592   { 0x03C5, 3, "u"},
1593   { 0x03C6, 3, "f"},
1594   { 0x03C7, 3, "c"},
1595   { 0x03C8, 3, "y"},
1596   { 0x03C9, 3, "w"},
1597   { 0x03CA, 3, "i"},
1598   { 0x03CB, 3, "u"},
1599   { 0x03CC, 3, "o"},
1600   { 0x03CD, 3, "u"},
1601   { 0x03CE, 3, "w"},
1602   { 0x03D1, 3, "J"},
1603   { 0x03D2, 3, "j"},
1604   { 0x03D6, 3, "v"},
1605   { 0x1F00, 3, "a"}, // FIXME accents
1606   { 0x1F01, 3, "a"},
1607   { 0x1F02, 3, "a"},
1608   { 0x1F03, 3, "a"},
1609   { 0x1F04, 3, "a"},
1610   { 0x1F05, 3, "a"},
1611   { 0x1F06, 3, "a"},
1612   { 0x1F07, 3, "a"},
1613   { 0x1F08, 3, "A"},
1614   { 0x1F09, 3, "A"},
1615   { 0x1F0A, 3, "A"},
1616   { 0x1F0B, 3, "A"},
1617   { 0x1F0C, 3, "A"},
1618   { 0x1F0D, 3, "A"},
1619   { 0x1F0E, 3, "A"},
1620   { 0x1F0F, 3, "A"},
1621   { 0x1F10, 3, "e"}, // FIXME eccents
1622   { 0x1F11, 3, "e"},
1623   { 0x1F12, 3, "e"},
1624   { 0x1F13, 3, "e"},
1625   { 0x1F14, 3, "e"},
1626   { 0x1F15, 3, "e"},
1627   { 0x1F16, 3, "e"},
1628   { 0x1F17, 3, "e"},
1629   { 0x1F18, 3, "E"},
1630   { 0x1F19, 3, "E"},
1631   { 0x1F1A, 3, "E"},
1632   { 0x1F1B, 3, "E"},
1633   { 0x1F1C, 3, "E"},
1634   { 0x1F1D, 3, "E"},
1635   { 0x1F1E, 3, "E"},
1636   { 0x1F1F, 3, "E"},
1637   { 0x1F20, 3, "h"}, // FIXME hccents
1638   { 0x1F21, 3, "h"},
1639   { 0x1F22, 3, "h"},
1640   { 0x1F23, 3, "h"},
1641   { 0x1F24, 3, "h"},
1642   { 0x1F25, 3, "h"},
1643   { 0x1F26, 3, "h"},
1644   { 0x1F27, 3, "h"},
1645   { 0x1F28, 3, "H"},
1646   { 0x1F29, 3, "H"},
1647   { 0x1F2A, 3, "H"},
1648   { 0x1F2B, 3, "H"},
1649   { 0x1F2C, 3, "H"},
1650   { 0x1F2D, 3, "H"},
1651   { 0x1F2E, 3, "H"},
1652   { 0x1F2F, 3, "H"},
1653   { 0x1F30, 3, "i"}, // FIXME iccents
1654   { 0x1F31, 3, "i"},
1655   { 0x1F32, 3, "i"},
1656   { 0x1F33, 3, "i"},
1657   { 0x1F34, 3, "i"},
1658   { 0x1F35, 3, "i"},
1659   { 0x1F36, 3, "i"},
1660   { 0x1F37, 3, "i"},
1661   { 0x1F38, 3, "I"},
1662   { 0x1F39, 3, "I"},
1663   { 0x1F3A, 3, "I"},
1664   { 0x1F3B, 3, "I"},
1665   { 0x1F3C, 3, "I"},
1666   { 0x1F3D, 3, "I"},
1667   { 0x1F3E, 3, "I"},
1668   { 0x1F3F, 3, "I"},
1669   { 0x1F40, 3, "o"}, // FIXME occents
1670   { 0x1F41, 3, "o"},
1671   { 0x1F42, 3, "o"},
1672   { 0x1F43, 3, "o"},
1673   { 0x1F44, 3, "o"},
1674   { 0x1F45, 3, "o"},
1675   { 0x1F46, 3, "o"},
1676   { 0x1F47, 3, "o"},
1677   { 0x1F48, 3, "O"},
1678   { 0x1F49, 3, "O"},
1679   { 0x1F4A, 3, "O"},
1680   { 0x1F4B, 3, "O"},
1681   { 0x1F4C, 3, "O"},
1682   { 0x1F4D, 3, "O"},
1683   { 0x1F4E, 3, "O"},
1684   { 0x1F4F, 3, "O"},
1685   { 0x1F50, 3, "u"}, // FIXME accents
1686   { 0x1F51, 3, "u"},
1687   { 0x1F52, 3, "u"},
1688   { 0x1F53, 3, "u"},
1689   { 0x1F54, 3, "u"},
1690   { 0x1F55, 3, "u"},
1691   { 0x1F56, 3, "u"},
1692   { 0x1F57, 3, "u"},
1693   { 0x1F58, 3, "U"},
1694   { 0x1F59, 3, "U"},
1695   { 0x1F5A, 3, "U"},
1696   { 0x1F5B, 3, "U"},
1697   { 0x1F5C, 3, "U"},
1698   { 0x1F5D, 3, "U"},
1699   { 0x1F5E, 3, "U"},
1700   { 0x1F5F, 3, "U"},
1701   { 0x1F60, 3, "w"}, // FIXME accents
1702   { 0x1F61, 3, "w"},
1703   { 0x1F62, 3, "w"},
1704   { 0x1F63, 3, "w"},
1705   { 0x1F64, 3, "w"},
1706   { 0x1F65, 3, "w"},
1707   { 0x1F66, 3, "w"},
1708   { 0x1F67, 3, "w"},
1709   { 0x1F68, 3, "W"},
1710   { 0x1F69, 3, "W"},
1711   { 0x1F6A, 3, "W"},
1712   { 0x1F6B, 3, "W"},
1713   { 0x1F6C, 3, "W"},
1714   { 0x1F6D, 3, "W"},
1715   { 0x1F6E, 3, "W"},
1716   { 0x1F6F, 3, "W"},
1717   { 0x1F70, 3, "a"}, // FIXME accents
1718   { 0x1F71, 3, "a"},
1719   { 0x1F72, 3, "e"},
1720   { 0x1F73, 3, "e"},
1721   { 0x1F74, 3, "h"},
1722   { 0x1F75, 3, "h"},
1723   { 0x1F76, 3, "i"},
1724   { 0x1F77, 3, "i"},
1725   { 0x1F78, 3, "o"},
1726   { 0x1F79, 3, "o"},
1727   { 0x1F7A, 3, "u"},
1728   { 0x1F7B, 3, "u"},
1729   { 0x1F7C, 3, "w"},
1730   { 0x1F7D, 3, "w"},
1731   { 0x1F7E, 3, "A"},
1732   { 0x1F7F, 3, "A"},
1733   { 0x1F80, 3, "a"}, // FIXME accents
1734   { 0x1F81, 3, "a"},
1735   { 0x1F82, 3, "a"},
1736   { 0x1F83, 3, "a"},
1737   { 0x1F84, 3, "a"},
1738   { 0x1F85, 3, "a"},
1739   { 0x1F86, 3, "a"},
1740   { 0x1F87, 3, "a"},
1741   { 0x1F88, 3, "A"},
1742   { 0x1F89, 3, "A"},
1743   { 0x1F8A, 3, "A"},
1744   { 0x1F8B, 3, "A"},
1745   { 0x1F8C, 3, "A"},
1746   { 0x1F8D, 3, "A"},
1747   { 0x1F8E, 3, "A"},
1748   { 0x1F8F, 3, "A"},
1749   { 0x1F90, 3, "h"}, // FIXME hccents
1750   { 0x1F91, 3, "h"},
1751   { 0x1F92, 3, "h"},
1752   { 0x1F93, 3, "h"},
1753   { 0x1F94, 3, "h"},
1754   { 0x1F95, 3, "h"},
1755   { 0x1F96, 3, "h"},
1756   { 0x1F97, 3, "h"},
1757   { 0x1F98, 3, "H"},
1758   { 0x1F99, 3, "H"},
1759   { 0x1F9A, 3, "H"},
1760   { 0x1F9B, 3, "H"},
1761   { 0x1F9C, 3, "H"},
1762   { 0x1F9D, 3, "H"},
1763   { 0x1F9E, 3, "H"},
1764   { 0x1F9F, 3, "H"},
1765   { 0x1FA0, 3, "w"}, // FIXME accents
1766   { 0x1FA1, 3, "w"},
1767   { 0x1FA2, 3, "w"},
1768   { 0x1FA3, 3, "w"},
1769   { 0x1FA4, 3, "w"},
1770   { 0x1FA5, 3, "w"},
1771   { 0x1FA6, 3, "w"},
1772   { 0x1FA7, 3, "w"},
1773   { 0x1FA8, 3, "W"},
1774   { 0x1FA9, 3, "W"},
1775   { 0x1FAA, 3, "W"},
1776   { 0x1FAB, 3, "W"},
1777   { 0x1FAC, 3, "W"},
1778   { 0x1FAD, 3, "W"},
1779   { 0x1FAE, 3, "W"},
1780   { 0x1FAF, 3, "W"},
1781   { 0x1FB0, 3, "a"}, // FIXME accents
1782   { 0x1FB1, 3, "a"},
1783   { 0x1FB2, 3, "a"},
1784   { 0x1FB3, 3, "a"},
1785   { 0x1FB4, 3, "a"},
1786   { 0x1FB5, 3, "a"},
1787   { 0x1FB6, 3, "a"},
1788   { 0x1FB7, 3, "a"},
1789   { 0x1FB8, 3, "A"},
1790   { 0x1FB9, 3, "A"},
1791   { 0x1FBA, 3, "A"},
1792   { 0x1FBB, 3, "A"},
1793   { 0x1FBC, 3, "A"},
1794   { 0x1FBD, 3, "?"},
1795   { 0x1FBE, 3, "?"},
1796   { 0x1FBF, 3, "?"},
1797   { 0x1FC0, 3, "~"}, // FIXME accents
1798   { 0x1FC1, 3, "~"},
1799   { 0x1FC2, 3, "h"},
1800   { 0x1FC3, 3, "h"},
1801   { 0x1FC4, 3, "h"},
1802   { 0x1FC5, 3, "h"},
1803   { 0x1FC6, 3, "h"},
1804   { 0x1FC7, 3, "h"},
1805   { 0x1FC8, 3, "E"},
1806   { 0x1FC9, 3, "E"},
1807   { 0x1FCA, 3, "H"},
1808   { 0x1FCB, 3, "H"},
1809   { 0x1FCC, 3, "H"},
1810   { 0x1FCD, 3, "?"},
1811   { 0x1FCE, 3, "?"},
1812   { 0x1FCF, 3, "?"},
1813   { 0x1FD0, 3, "i"}, // FIXME accents
1814   { 0x1FD1, 3, "i"},
1815   { 0x1FD2, 3, "i"},
1816   { 0x1FD3, 3, "i"},
1817   { 0x1FD4, 3, "i"},
1818   { 0x1FD5, 3, "i"},
1819   { 0x1FD6, 3, "i"},
1820   { 0x1FD7, 3, "i"},
1821   { 0x1FD8, 3, "I"},
1822   { 0x1FD9, 3, "I"},
1823   { 0x1FDA, 3, "I"},
1824   { 0x1FDB, 3, "I"},
1825   { 0x1FDC, 3, "?"},
1826   { 0x1FDD, 3, "?"},
1827   { 0x1FDE, 3, "?"},
1828   { 0x1FDF, 3, "?"},
1829   { 0x1FE0, 3, "u"}, // FIXME accents
1830   { 0x1FE1, 3, "u"},
1831   { 0x1FE2, 3, "u"},
1832   { 0x1FE3, 3, "u"},
1833   { 0x1FE4, 3, "r"},
1834   { 0x1FE5, 3, "r"},
1835   { 0x1FE6, 3, "u"},
1836   { 0x1FE7, 3, "u"},
1837   { 0x1FE8, 3, "Y"},
1838   { 0x1FE9, 3, "Y"},
1839   { 0x1FEA, 3, "Y"},
1840   { 0x1FEB, 3, "Y"},
1841   { 0x1FEC, 3, "P"},
1842   { 0x1FED, 3, "?"},
1843   { 0x1FEE, 3, "?"},
1844   { 0x1FEF, 3, "?"},
1845   { 0x1FF0, 3, "w"}, // FIXME accents
1846   { 0x1FF1, 3, "w"},
1847   { 0x1FF2, 3, "w"},
1848   { 0x1FF3, 3, "w"},
1849   { 0x1FF4, 3, "w"},
1850   { 0x1FF5, 3, "w"},
1851   { 0x1FF6, 3, "w"},
1852   { 0x1FF7, 3, "w"},
1853   { 0x1FF8, 3, "O"},
1854   { 0x1FF9, 3, "O"},
1855   { 0x1FFA, 3, "W"},
1856   { 0x1FFB, 3, "W"},
1857   { 0x1FFC, 3, "W"},
1858   { 0x1FFD, 3, "?"},
1859   { 0x1FFE, 3, "?"},
1860   { 0x1FFF, 3, "?"},
1861   { 0x2000, 0, "space" },
1862   { 0x2001, 0, "space" },
1863   { 0x2002, 0, "space" },
1864   { 0x2003, 0, "space" },
1865   { 0x2004, 0, "space" },
1866   { 0x2005, 0, "space" },
1867   { 0x2006, 0, "space" },
1868   { 0x2007, 1, "(0) stringwidth rmoveto" },
1869   { 0x2008, 1, "(.) stringwidth rmoveto" },
1870   { 0x2009, 0, "space" },
1871   { 0x200A, 0, "space" },
1872   { 0x200B, 1, "" },
1873   { 0x2010, 0, "hyphen" },
1874   { 0x2011, 0, "hyphen" },
1875   { 0x2012, 0, "endash" },
1876   { 0x2013, 0, "endash" },
1877   { 0x2014, 0, "emdash" },
1878   { 0x2015, 0, "emdash" },
1879   { 0x2018, 0, "quoteleft" },
1880   { 0x2019, 0, "quoteright" },
1881   { 0x201A, 0, "quotesinglbase" },
1882   { 0x201B, 1, "(\047) rev" },
1883   { 0x201C, 0, "quotedblleft" },
1884   { 0x201D, 0, "quotedblright" },
1885   { 0x201E, 0, "quotedblbase" },
1886   { 0x201F, 1, "(\272) rev" },
1887   { 0x2020, 0, "dagger" },
1888   { 0x2021, 0, "daggerdbl" },
1889   { 0x2022, 0, "bullet" },
1890   { 0x2026, 0, "ellipsis" },
1891   { 0x2030, 0, "perthousand" },
1892   { 0x2039, 0, "guilsinglleft" },
1893   { 0x203A, 0, "guilsinglright" },
1894   { 0x203D, 1, "(!) (?) cp" },
1895   { 0x2044, 0, "fraction" },
1896   { 0x20AC, 1, "(C) (=) -0.1 0 scp" },
1897   { 0x2122, 0, "trademark" },
1898   { 0x2212, 0, "minus" },
1899   { 0x2215, 0, "slash" },
1900   { 0x2219, 0, "periodcentered" },
1901   { 0x2259, 1, "(=)" CIRCUMFLEX "cp" },
1902   { 0x2260, 1, "(=) (/) cp" },
1903   { 0x2264, 1, "(<) (-) 0 -0.3 scp" },
1904   { 0x2265, 1, "(>) (-) 0 -0.3 scp" },
1905   { 0x226E, 1, "(<) (/) cp" },
1906   { 0x226F, 1, "(>) (/) cp" },
1907   { 0x2500, 1, "{0.05 setlinewidth 0 1 moveto 1 1 lineto stroke} bgr" },
1908   { 0x2501, 1, "{0.2 setlinewidth 0 1 moveto 1 1 lineto stroke} bgr" },
1909   { 0x2502, 1, "{0.05 setlinewidth 0.5 0 moveto 0.5 2 lineto stroke} bgr" },
1910   { 0x2503, 1, "{0.2 setlinewidth 0.5 0 moveto 0.5 2 lineto stroke} bgr" },
1911   { 0x250C, 1, "{0.05 setlinewidth 0.5 0 moveto 0.5 1 lineto 1 1 lineto stroke} bgr" },
1912   { 0x2510, 1, "{0.05 setlinewidth 0.5 0 moveto 0.5 1 lineto 0 1 lineto stroke} bgr" },
1913   { 0x2514, 1, "{0.05 setlinewidth 0.5 2 moveto 0.5 1 lineto 1 1 lineto stroke} bgr" },
1914   { 0x2518, 1, "{0.05 setlinewidth 0.5 2 moveto 0.5 1 lineto 0 1 lineto stroke} bgr" },
1915   { 0x253C, 1, "{0.05 setlinewidth 0.5 0 moveto 0.5 2 lineto stroke "
1916     "0 1 moveto 1 1 lineto stroke} bgr" },
1917   { 0x254B, 1, "{0.2 setlinewidth 0.5 0 moveto 0.5 2 lineto stroke "
1918     "0 1 moveto 1 1 lineto stroke} bgr" },
1919   { 0xFB01, 0, "fi" },
1920   { 0xFB02, 0, "fl" }
1921 };
1922 
1923 
get_charentry(wchar_t c)1924 int get_charentry(wchar_t c)
1925 {
1926   int min = 0;
1927   int max = sizeof(chartab) / sizeof(struct charentry) - 1;
1928   int mid;
1929 
1930   /* binary search in table */
1931   while (max >= min) {
1932     mid = (min + max) / 2;
1933     if (chartab[mid].ucs < c)
1934       min = mid + 1;
1935     else if (chartab[mid].ucs > c)
1936       max = mid - 1;
1937     else {
1938       /* found it */
1939       return mid;
1940     }
1941   }
1942 
1943   return -1;
1944 }
1945 
show_line(wchar_t * line,FILE * output,int font_,int size_)1946 void show_line(wchar_t *line,FILE * output,int font_,int size_)
1947 {
1948   int i, g;
1949 
1950   fprintf(output,"(");
1951   for (i = 0; line[i]; i++) {
1952     if (line[i] == '(' || line[i] == ')' || line[i] == '\\'){
1953       fprintf(output,"\\%c", (int) line[i]);
1954       continue;
1955     }
1956     if (line[i] > 128 || line[i] == '\'' || line[i] == '`') {
1957       g = get_charentry(line[i]);
1958       if (g < 0){
1959 	fprintf(output,"?");
1960 	continue;
1961       }
1962       if (chartab[g].execute==1){
1963 	fprintf(output,") show %s (", chartab[g].s);
1964 	continue;
1965       }
1966       if (chartab[g].execute==0){
1967 	fprintf(output,") show /%s glyphshow (", chartab[g].s);
1968 	continue;
1969       }
1970       if (chartab[g].execute==3){
1971 	fprintf(output,") show /Symbol SF %d FS (%s) show /%s SF %d FS (",size_,chartab[g].s,_fontNames[font_],size_);
1972 	continue;
1973       }
1974       if (chartab[g].execute==2){
1975 	fprintf(output,") show /Symbol SF %d FS /%s glyphshow /%s SF %d FS (",size_,chartab[g].s,_fontNames[font_],size_);
1976 	continue;
1977       }
1978     }
1979     else
1980       fprintf(output,"%c", (int) line[i]);
1981   } // end for
1982   fprintf(output,") show\n");
1983 }
1984 
transformed_draw(const char * STR,int n,double x,double y)1985 void Fl_PS_Printer::transformed_draw(const char* STR, int n, double x, double y){
1986 
1987   if (!n||!STR||!*STR)return;
1988   wchar_t * str=new wchar_t[n+1];
1989   n=wchar_convert(str,STR,n);
1990   fprintf(output, "GS\n");
1991   fprintf(output,"%g %g moveto\n", x , y);
1992   fprintf(output, "[1 0 0 -1 0 0] concat\n");
1993   int i=1;
1994   show_line(str,output,font_,size_);
1995   fprintf(output, "GR\n");
1996   delete [] str;
1997 }
1998 
1999 
2000 
transformed_draw(const char * s,double x,double y)2001 void Fl_PS_Printer::transformed_draw(const char* s, double x, double y){
2002   transformed_draw(s,strlen(s),x,y);
2003 };
2004 
2005 ////////////////////////////      Images      /////////////////////////////////////
2006 
2007 
2008 
2009 
alpha_mask(const uchar * data,int w,int h,int D,int LD)2010 int Fl_PS_Printer::alpha_mask(const uchar * data, int w, int h, int D, int LD){
2011 
2012   mask = 0;
2013   if((D/2)*2 != D){ //no mask info
2014     return 0;
2015   }
2016   int xx;
2017   int i,j, k, l;
2018   LD += w*D;
2019   int V255=0;
2020   int V0 =0;
2021   int V_=0;
2022 //  uchar d;
2023   for(j=0;j<h;j++){
2024     for(i=0;i<w;i++)
2025       switch(data[j*LD+D*i+D-1]){
2026         case 255: V255 = 1; break;
2027         case 0: V0 = 1; break;
2028         default: V_= 1;
2029       }
2030     if(V_) break;
2031   };
2032   if(!V_){
2033     if(V0)
2034       if(V255){// not true alpha, only masking
2035         xx = (w+7)/8;
2036         mask = new uchar[h * xx];
2037         for(i=0;i<h * xx;i++) mask[i]=0;
2038         for(j=0;j<h;j++)
2039           for(i=0;i<w;i++)
2040             if(data[j*LD+D*i+D-1])
2041               mask[j*xx+i/8] |= 1 << (i % 8);
2042         mx = w;
2043         my = h; //mask imensions
2044         return 0;
2045       }else{
2046         mask=0;
2047         return 1; //everything masked
2048       }
2049     else
2050       return 0;
2051   }
2052 
2053 
2054 
2055   /////   Alpha dither, generating (4*w) * 4 mask area       /////
2056   /////         with Floyd-Steinberg error diffusion         /////
2057 
2058   mask = new uchar[((w+1)/2) * h * 4];
2059 
2060   for(i=0;i<((w+1)/2) * h * 4; i++) mask[i] = 0; //cleaning
2061 
2062 
2063 
2064   mx= w*4;
2065   my=h*4; // mask dimensions
2066 
2067   xx = (w+1)/2;                //  mask line width in bytes
2068 
2069   short * errors1 = new short [w*4+2]; //  two rows of dither errors
2070   short * errors2 = new short [w*4+2]; //  two rows of dither errors
2071 
2072   for(i=0;i<w*4+2;i++) errors2[i] = 0; // cleaning,after first swap will become current
2073   for(i=0;i<w*4+2;i++) errors1[i] = 0; // cleaning,after first swap will become current
2074 
2075   short * current = errors1;
2076   short * next = errors2;
2077   short * swap;
2078 
2079   for(j=0;j<h;j++){
2080     for(l=0;l<4;){           // generating 4 rows of mask lines for 1 RGB line
2081       int jj = j*4+l;
2082 
2083       /// mask row index
2084       swap = next;
2085       next = current;
2086       current = swap;
2087       *(next+1) = 0;          // must clean the first cell, next are overriden by *1
2088       for(i=0;i<w;i++){
2089         for(k=0;k<4;k++){   // generating 4 x-pixels for 1 RGB
2090           short error, o1, o2, o3;
2091           int ii = i*4+k;   // mask cell index
2092           short val = data[j*LD+D*i+D-1] + current[1+ii];
2093           if (val>127){
2094             mask[jj*xx+ii/8]  |= 1 << (ii % 8); //set mask bit
2095             error =  val-255;
2096           }else
2097             error = val;
2098 
2099           ////// error spreading /////
2100           if(error >0){
2101             next[ii] +=  o1 = (error * 3 + 8)/16;
2102             current[ii+2] += o2 = (error * 7 + 8)/16;
2103             next[ii+2] = o3 =(error + 8)/16;  // *1 - ok replacing (cleaning)
2104           }else{
2105             next[ii] += o1 = (error * 3 - 8)/16;
2106             current[ii+2] += o2 = (error * 7 - 8)/16;
2107             next[ii+2] = o3 = (error - 8)/16;
2108           }
2109           next[1+ii] += error - o1 - o2 - o3;
2110         }
2111       }
2112       l++;
2113 
2114       ////// backward
2115 
2116       jj = j*4+l;
2117       swap = next;
2118       next = current;
2119       current = swap;
2120       *(next+1) = 0;          // must clean the first cell, next are overriden by *1
2121 
2122       for(i=w-1;i>=0;i--){
2123 
2124         for(k=3;k>=0;k--){   // generating 4 x-pixels for 1 RGB
2125           short error, o1, o2, o3;
2126 
2127           int ii = i*4+k;   // mask cell index
2128           short val = data[j*LD+D*i+D-1] + current[1+ii];
2129           if (val>127){
2130 
2131             mask[jj*xx+ii/8]  |= 1 << (ii % 8); //set mask bit
2132             error =  val-255;
2133           }else
2134             error = val;
2135 
2136           ////// error spreading /////
2137           if(error >0){
2138             next[ii+2] +=  o1 = (error * 3 + 8)/16;
2139             current[ii] += o2 = (error * 7 + 8)/16;
2140             next[ii] = o3 =(error + 8)/16;  // *1 - ok replacing (cleaning)
2141           }else{
2142             next[ii+2] += o1 = (error * 3 - 8)/16;
2143 
2144             current[ii] += o2 = (error * 7 - 8)/16;
2145             next[ii] = o3 = (error - 8)/16;
2146           }
2147           next[1+ii] += error - o1 - o2 - o3;
2148         }
2149       }
2150       l++;
2151     }
2152   }
2153   delete[] errors1;
2154   delete[] errors2;
2155   return 0;
2156 }
2157 
2158 
2159 
2160 
swap_byte(const uchar i)2161 static inline uchar swap_byte(const uchar i){
2162   uchar b =0;
2163   if(i & 1) b |= 128;
2164   if(i & 2) b |= 64;
2165   if(i & 4) b |= 32;
2166   if(i & 8) b |= 16;
2167   if(i & 16) b |= 8;
2168   if(i & 32) b |= 4;
2169   if(i & 64) b |= 2;
2170   if(i & 128) b |= 1;
2171   return b;
2172 }
2173 
2174 
2175 extern uchar **fl_mask_bitmap;
2176 
2177 
draw_scalled_image(const uchar * data,double x,double y,double w,double h,int iw,int ih,int D,int LD)2178 void Fl_PS_Printer::draw_scalled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
2179 
2180 
2181   if(D<3){ //mono
2182     draw_scalled_image_mono(data, x, y, w, h, iw, ih, D, LD);
2183     return;
2184   }
2185 
2186 
2187   int i,j, k;
2188 
2189   fprintf(output,"save\n");
2190 
2191   char * interpol;
2192   if(lang_level_>1){
2193     if(interpolate_)
2194       interpol="true";
2195     else
2196       interpol="false";
2197     if(mask && lang_level_>2)
2198       fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
2199     else
2200       fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol);
2201   }else
2202     fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
2203 
2204 
2205   if(!LD) LD = iw*D;
2206   uchar *curmask=mask;
2207   uchar bg_r, bg_g, bg_b;
2208 
2209   Fl::get_color(bg_, bg_r,bg_g,bg_b);
2210   for (j=0; j<ih;j++){
2211     if(mask){
2212 
2213       for(k=0;k<my/ih;k++){
2214         for (i=0; i<((mx+7)/8);i++){
2215           if (!(i%80)) fprintf(output, "\n");
2216           fprintf(output, "%.2x",swap_byte(*curmask));
2217           curmask++;
2218         }
2219         fprintf(output,"\n");
2220       }
2221     }
2222     const uchar *curdata=data+j*LD;
2223     for(i=0 ; i<iw ; i++) {
2224       uchar r = curdata[0];
2225       uchar g =  curdata[1];
2226       uchar b =  curdata[2];
2227       if(lang_level_<3 && D>3) { //can do  mixing using bg_* colors)
2228         unsigned int a2 = curdata[3]; //must be int
2229         unsigned int a = 255-a2;
2230         r = (a2 * r + bg_r * a)/255;
2231         g = (a2 * g + bg_g * a)/255;
2232         b = (a2 * b + bg_b * a)/255;
2233       }
2234       if (!(i%40)) fprintf(output, "\n");
2235       fprintf(output, "%.2x%.2x%.2x", r, g, b);
2236       curdata +=D;
2237     }
2238     fprintf(output,"\n");
2239 
2240   }
2241 
2242   fprintf(output," >\nrestore\n" );
2243 
2244 
2245 };
2246 
draw_scalled_image(Fl_Draw_Image_Cb call,void * data,double x,double y,double w,double h,int iw,int ih,int D)2247 void Fl_PS_Printer::draw_scalled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
2248 
2249 
2250   fprintf(output,"save\n");
2251   int i,j,k;
2252   char * interpol;
2253   if(lang_level_>1){
2254     if(interpolate_) interpol="true";
2255     else interpol="false";
2256     if(mask && lang_level_>2)
2257       fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
2258     else
2259       fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol);
2260   }else
2261     fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
2262 
2263   int LD=iw*D;
2264   uchar *rgbdata=new uchar[LD];
2265   uchar *curmask=mask;
2266 
2267   for (j=0; j<ih;j++){
2268     if(mask && lang_level_>2){  // InterleaveType 2 mask data
2269       for(k=0; k<my/ih;k++){ //for alpha pseudo-masking
2270         for (i=0; i<((mx+7)/8);i++){
2271           if (!(i%40)) fprintf(output, "\n");
2272           fprintf(output, "%.2x",swap_byte(*curmask));
2273           curmask++;
2274         }
2275         fprintf(output,"\n");
2276       }
2277     }
2278     call(data,0,j,iw,rgbdata);
2279     uchar *curdata=rgbdata;
2280     for(i=0 ; i<iw ; i++) {
2281       uchar r = curdata[0];
2282       uchar g =  curdata[1];
2283       uchar b =  curdata[2];
2284 
2285 
2286       if (!(i%40)) fprintf(output, "\n");
2287       fprintf(output, "%.2x%.2x%.2x", r, g, b);
2288 
2289       curdata +=D;
2290     }
2291     fprintf(output,"\n");
2292 
2293   }
2294   fprintf(output,">\n");
2295 
2296   fprintf(output,"restore\n");
2297   delete[] rgbdata;
2298 }
2299 
draw_scalled_image_mono(const uchar * data,double x,double y,double w,double h,int iw,int ih,int D,int LD)2300 void Fl_PS_Printer::draw_scalled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
2301 
2302   fprintf(output,"save\n");
2303 
2304   int i,j, k;
2305 
2306   char * interpol;
2307   if(lang_level_>1){
2308     if(interpolate_)
2309       interpol="true";
2310     else
2311       interpol="false";
2312     if(mask && lang_level_>2)
2313       fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
2314     else
2315       fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol);
2316   }else
2317     fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih);
2318 
2319 
2320   if(!LD) LD = iw*D;
2321 
2322   uchar bg_r, bg_g, bg_b;
2323   Fl::get_color(bg_, bg_r,bg_g,bg_b);
2324   int bg = (bg_r + bg_g + bg_b)/3;
2325 
2326   uchar *curmask=mask;
2327   for (j=0; j<ih;j++){
2328     if(mask){
2329       for(k=0;k<my/ih;k++){
2330         for (i=0; i<((mx+7)/8);i++){
2331           if (!(i%80)) fprintf(output, "\n");
2332           fprintf(output, "%.2x",swap_byte(*curmask));
2333           curmask++;
2334         }
2335         fprintf(output,"\n");
2336       }
2337     }
2338     const uchar *curdata=data+j*LD;
2339     for(i=0 ; i<iw ; i++) {
2340       if (!(i%80)) fprintf(output, "\n");
2341       uchar r = curdata[0];
2342       if(lang_level_<3 && D>1) { //can do  mixing
2343 
2344         unsigned int a2 = curdata[1]; //must be int
2345         unsigned int a = 255-a2;
2346         r = (a2 * r + bg * a)/255;
2347       }
2348       if (!(i%120)) fprintf(output, "\n");
2349       fprintf(output, "%.2x", r);
2350       curdata +=D;
2351     }
2352     fprintf(output,"\n");
2353 
2354   }
2355 
2356   fprintf(output," >\nrestore\n" );
2357 
2358 };
2359 
2360 
2361 
draw_scalled_image_mono(Fl_Draw_Image_Cb call,void * data,double x,double y,double w,double h,int iw,int ih,int D)2362 void Fl_PS_Printer::draw_scalled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
2363 
2364   fprintf(output,"save\n");
2365   int i,j,k;
2366   char * interpol;
2367   if(lang_level_>1){
2368     if(interpolate_) interpol="true";
2369     else interpol="false";
2370     if(mask && lang_level_>2)
2371       fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
2372     else
2373       fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol);
2374   }else
2375     fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih);
2376 
2377   int LD=iw*D;
2378   uchar *rgbdata=new uchar[LD];
2379   uchar *curmask=mask;
2380   for (j=0; j<ih;j++){
2381 
2382     if(mask && lang_level_>2){  // InterleaveType 2 mask data
2383       for(k=0; k<my/ih;k++){ //for alpha pseudo-masking
2384         for (i=0; i<((mx+7)/8);i++){
2385           if (!(i%40)) fprintf(output, "\n");
2386           fprintf(output, "%.2x",swap_byte(*curmask));
2387           curmask++;
2388         }
2389         fprintf(output,"\n");
2390       }
2391     }
2392     call(data,0,j,iw,rgbdata);
2393     uchar *curdata=rgbdata;
2394     for(i=0 ; i<iw ; i++) {
2395       uchar r = curdata[0];
2396       if (!(i%120)) fprintf(output, "\n");
2397       fprintf(output, "%.2x", r);
2398       curdata +=D;
2399     }
2400     fprintf(output,"\n");
2401   }
2402   fprintf(output,">\n");
2403   fprintf(output,"restore\n");
2404   delete[] rgbdata;
2405 }
2406 
2407 
2408 ////////////////////////////// Image classes //////////////////////
2409 
2410 
draw(Fl_Pixmap * pxm,int XP,int YP,int WP,int HP,int cx,int cy)2411 void Fl_PS_Printer::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){
2412   const char * const * di =pxm->data();
2413   int w,h;
2414   if (!fl_measure_pixmap(di, w, h)) return;
2415   mask=0;
2416   fl_mask_bitmap=&mask;
2417   mx = WP;
2418   my = HP;
2419   push_clip(XP, YP, WP, HP);
2420   fl_draw_pixmap(di,XP -cx, YP -cy, bg_); //yes, it is dirty, but fl is dispatched, so it works!
2421   pop_clip();
2422   delete[] mask;
2423   mask=0;
2424   fl_mask_bitmap=0;
2425 };
2426 
draw(Fl_RGB_Image * rgb,int XP,int YP,int WP,int HP,int cx,int cy)2427 void Fl_PS_Printer::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){
2428   const uchar  * di = rgb->array;
2429   int w = rgb->w();
2430   int h = rgb->h();
2431   mask=0;
2432   if(lang_level_>2) //when not true, not making alphamask, mixing colors instead...
2433   if (alpha_mask(di, w, h, rgb->d(),rgb->ld())) return; //everthing masked, no need for painting!
2434   push_clip(XP, YP, WP, HP);
2435   draw_scalled_image(di, XP + cx, YP + cy, w, h,  w,  h, rgb->d(), rgb->ld());
2436   pop_clip();
2437   delete[]mask;
2438   mask=0;
2439 };
2440 
draw(Fl_Bitmap * bitmap,int XP,int YP,int WP,int HP,int cx,int cy)2441 void Fl_PS_Printer::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){
2442   const uchar  * di = bitmap->array;
2443   int w,h;
2444   int LD=(bitmap->w()+7)/8;
2445   int xx;
2446 
2447   if (WP> bitmap->w() - cx){// to assure that it does not go out of bounds;
2448      w = bitmap->w() - cx;
2449      xx = (bitmap->w()+7)/8 - cx/8; //length of mask in bytes
2450   }else{
2451     w =WP;
2452     xx = (w+7)/8 - cx/8;
2453   }
2454   if( HP > bitmap->h()-cy)
2455     h = bitmap->h() - cy;
2456   else
2457     h = HP;
2458 
2459   di += cy*LD + cx/8;
2460   int si = cx % 8; // small shift to be clipped, it is simpler than shifting whole mask
2461 
2462   int i,j;
2463   push_clip(XP, YP, WP, HP);
2464   fprintf(output , "%i %i %i %i %i %i MI", XP - si, YP + HP , WP , -HP , w , h);
2465 
2466   for (j=0; j<HP; j++){
2467     for (i=0; i<xx; i++){
2468       if (!(i%80)) fprintf(output, "\n"); // not have lines longer than 255 chars
2469       fprintf(output, "%.2x",swap_byte(~(*di)));
2470       di++;
2471     }
2472     fprintf(output,"\n");
2473   }
2474   fprintf(output,">\n");
2475   pop_clip();
2476 };
2477 
2478 #ifndef WIN32
2479 
2480 char * kprinter = "/usr/bin/kprinter";
2481 FL_EXPORT char * fl_ps_command = access(kprinter,X_OK)?0:kprinter;
2482 
2483 
2484 #endif
2485 
2486 
2487 
2488 
2489 
2490 
2491 
2492 
2493 
2494 
2495 
2496 
2497 
2498 
2499 
2500 
2501 
2502 
2503