diff options
| author | Manolo Gouy <Manolo> | 2016-02-26 15:24:08 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2016-02-26 15:24:08 +0000 |
| commit | cf4825eedf9ee529cd99e8b99b69cdd3ec6ffb69 (patch) | |
| tree | 147599508534f4db9a34b439ba6c0611e07094a2 /src/Fl_PostScript.cxx | |
| parent | 53993d4bd1476e6d7700b13a2ca0e1d489a740d4 (diff) | |
Move PostScript-support files to src/drivers/PostScript/
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11222 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_PostScript.cxx')
| -rw-r--r-- | src/Fl_PostScript.cxx | 1667 |
1 files changed, 0 insertions, 1667 deletions
diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx deleted file mode 100644 index 6ff365706..000000000 --- a/src/Fl_PostScript.cxx +++ /dev/null @@ -1,1667 +0,0 @@ -// -// "$Id$" -// -// PostScript device support for the Fast Light Tool Kit (FLTK). -// -// Copyright 2010-2016 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// Please report all bugs and problems to: -// -// http://www.fltk.org/str.php -// - -#include <FL/Fl_Printer.H> -#include <config.h> -#include <FL/Fl.H> -#include <FL/fl_ask.H> -#include <FL/fl_draw.H> -#include <stdio.h> -#include <FL/Fl_PostScript.H> -#include <FL/Fl_Native_File_Chooser.H> -#include <stdarg.h> -#if defined(USE_X11) -#include "Fl_Font.H" -#if USE_XFT -#include <X11/Xft/Xft.h> -#endif -#endif - -/** \brief Label of the PostScript file chooser window */ -const char *Fl_PostScript_File_Device::file_chooser_title = "Select a .ps file"; - -/** - @brief The constructor. - */ -Fl_PostScript_Graphics_Driver::Fl_PostScript_Graphics_Driver(void) -{ - close_cmd_ = 0; - //lang_level_ = 3; - lang_level_ = 2; - mask = 0; - ps_filename_ = NULL; - scale_x = scale_y = 1.; - bg_r = bg_g = bg_b = 255; -} - -/** \brief The destructor. */ -Fl_PostScript_Graphics_Driver::~Fl_PostScript_Graphics_Driver() { - if(ps_filename_) free(ps_filename_); -} - -/** - @brief The constructor. - */ -Fl_PostScript_File_Device::Fl_PostScript_File_Device(void) -{ - Fl_Surface_Device::driver( new Fl_PostScript_Graphics_Driver() ); -} - -/** - \brief Returns the PostScript driver of this drawing surface. - */ -Fl_PostScript_Graphics_Driver *Fl_PostScript_File_Device::driver() -{ - return (Fl_PostScript_Graphics_Driver*)Fl_Surface_Device::driver(); -} - - -/** - @brief Begins the session where all graphics requests will go to a local PostScript file. - * - Opens a file dialog entitled with Fl_PostScript_File_Device::file_chooser_title to select an output PostScript file. - @param pagecount The total number of pages to be created. Use 0 if this number is unknown when this function is called. - @param format Desired page format. - @param layout Desired page layout. - @return 0 if OK, 1 if user cancelled the file dialog, 2 if fopen failed on user-selected output file. - */ -int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_Paged_Device::Page_Format format, - enum Fl_Paged_Device::Page_Layout layout) -{ - Fl_Native_File_Chooser fnfc; - fnfc.title(Fl_PostScript_File_Device::file_chooser_title); - fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); - fnfc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM); - fnfc.filter("PostScript\t*.ps\n"); - // Show native chooser - if ( fnfc.show() ) return 1; - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->output = fl_fopen(fnfc.filename(), "w"); - if(ps->output == NULL) return 2; - ps->ps_filename_ = strdup(fnfc.filename()); - ps->start_postscript(pagecount, format, layout); - this->set_current(); - return 0; -} - -extern "C" { - static int dont_close(FILE *f) - { - return 0; - } -} - -/** - @brief Begins the session where all graphics requests will go to FILE pointer. - * - @param ps_output A writable FILE pointer that will receive PostScript output and that should not be closed - until after end_job() has been called. - @param pagecount The total number of pages to be created. Use 0 if this number is unknown when this function is called. - @param format Desired page format. - @param layout Desired page layout. - @return always 0. - */ -int Fl_PostScript_File_Device::start_job (FILE *ps_output, int pagecount, - enum Fl_Paged_Device::Page_Format format, enum Fl_Paged_Device::Page_Layout layout) -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->output = ps_output; - ps->ps_filename_ = NULL; - ps->start_postscript(pagecount, format, layout); - ps->close_command(dont_close); // so that end_job() doesn't close the file - this->set_current(); - return 0; -} - -/** Don't use with this class. */ -int Fl_PostScript_File_Device::start_job(int pagecount, int* from, int* to) -{ - return 1; -} - -/** - @brief The destructor. - */ -Fl_PostScript_File_Device::~Fl_PostScript_File_Device() { - Fl_PostScript_Graphics_Driver *ps = driver(); - if (ps) delete ps; -} - -/** Shields output PostScript data from modifications of the current locale. - It typically avoids PostScript errors caused if the current locale uses comma instead of dot - as "decimal point". - \param format directives controlling output PostScript data - \return value returned by vfprintf() call - */ -int Fl_PostScript_Graphics_Driver::clocale_printf(const char *format, ...) -{ -#ifdef FL_PORTING -# pragma message "FL_PORTING: must define LC_NUMERIC" - va_list args; - va_start(args, format); - int retval = vfprintf(output, format, args); - va_end(args); - return retval; -#else - char *saved_locale = setlocale(LC_NUMERIC, NULL); - setlocale(LC_NUMERIC, "C"); - va_list args; - va_start(args, format); - int retval = vfprintf(output, format, args); - va_end(args); - setlocale(LC_NUMERIC, saved_locale); - return retval; -#endif -} - -#ifndef FL_DOXYGEN - -#if ! (defined(__APPLE__) || defined(WIN32) ) // PORTME: Fl_Surface_Driver - platform PostScript -# include "print_panel.cxx" -#endif - -// Prolog string - -static const char * prolog = -"%%BeginProlog\n" -"/L { /y2 exch def\n" -"/x2 exch def\n" -"/y1 exch def\n" -"/x1 exch def\n" -"newpath x1 y1 moveto x2 y2 lineto\n" -"stroke}\n" -"bind def\n" - - -"/R { /dy exch def\n" -"/dx exch def\n" -"/y exch def\n" -"/x exch def\n" -"newpath\n" -"x y moveto\n" -"dx 0 rlineto\n" -"0 dy rlineto\n" -"dx neg 0 rlineto\n" -"closepath stroke\n" -"} bind def\n" - -"/CL {\n" -"/dy exch def\n" -"/dx exch def\n" -"/y exch def\n" -"/x exch def\n" -"newpath\n" -"x y moveto\n" -"dx 0 rlineto\n" -"0 dy rlineto\n" -"dx neg 0 rlineto\n" -"closepath\n" -"clip\n" -"} bind def\n" - -"/FR { /dy exch def\n" -"/dx exch def\n" -"/y exch def\n" -"/x exch def\n" -"currentlinewidth 0 setlinewidth newpath\n" -"x y moveto\n" -"dx 0 rlineto\n" -"0 dy rlineto\n" -"dx neg 0 rlineto\n" -"closepath fill setlinewidth\n" -"} bind def\n" - -"/GS { gsave } bind def\n" -"/GR { grestore } bind def\n" - -"/SP { showpage } bind def\n" -"/LW { setlinewidth } bind def\n" -"/CF /Courier def\n" -"/SF { /CF exch def } bind def\n" -"/fsize 12 def\n" -"/FS { /fsize exch def fsize CF findfont exch scalefont setfont }def \n" - - -"/GL { setgray } bind def\n" -"/SRGB { setrgbcolor } bind def\n" - -"/A85RLE { /ASCII85Decode filter /RunLengthDecode filter } bind def\n" // ASCII85Decode followed by RunLengthDecode filters - -// color images - -"/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n" -"translate \n" -"sx sy scale px py 8 \n" -"[ px 0 0 py neg 0 py ]\n" -"currentfile A85RLE\n false 3" -" colorimage GR\n" -"} bind def\n" - -// gray images - -"/GI { GS /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale px py 8 \n" - - -"[ px 0 0 py neg 0 py ]\n" -"currentfile A85RLE\n" -"image GR\n" -"} bind def\n" - -// single-color bitmask - -"/MI { GS /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale px py true \n" -"[ px 0 0 py neg 0 py ]\n" -"currentfile A85RLE\n" -"imagemask GR\n" -"} bind def\n" - - -// path - -"/BFP { newpath moveto } def\n" -"/BP { newpath } bind def \n" -"/PL { lineto } bind def \n" -"/PM { moveto } bind def \n" -"/MT { moveto } bind def \n" -"/LT { lineto } bind def \n" -"/EFP { closepath fill } bind def\n" //was:stroke -"/ELP { stroke } bind def\n" -"/ECP { closepath stroke } bind def\n" // Closed (loop) -"/LW { setlinewidth } bind def\n" - -// ////////////////////////// misc //////////////// -"/TR { translate } bind def\n" -"/CT { concat } bind def\n" -"/RCT { matrix invertmatrix concat} bind def\n" -"/SC { scale } bind def\n" -//"/GPD { currentpagedevice /PageSize get} def\n" - -// show at position with desired width -// usage: -// width (string) x y show_pos_width -"/show_pos_width {GS moveto dup dup stringwidth pop exch length 2 div dup 2 le {pop 9999} if " -"1 sub exch 3 index exch sub exch " -"div 0 2 index 1 -1 scale ashow pop pop GR} bind def\n" // spacing altered to match desired width -//"/show_pos_width {GS moveto dup stringwidth pop 3 2 roll exch div -1 matrix scale concat " -//"show GR } bind def\n" // horizontally scaled text to match desired width - -; - - -static const char * prolog_2 = // prolog relevant only if lang_level >1 - -// color image dictionaries -"/CII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale\n" -"/DeviceRGB setcolorspace\n" -"/IDD 8 dict def\n" -"IDD begin\n" -"/ImageType 1 def\n" -"/Width px def\n" -"/Height py def\n" -"/BitsPerComponent 8 def\n" -"/Interpolate inter def\n" -"/DataSource currentfile A85RLE def\n" -"/MultipleDataSources false def\n" -"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" -"/Decode [ 0 1 0 1 0 1 ] def\n" -"end\n" -"IDD image GR} bind def\n" - -// gray image dict -"/GII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale\n" -"/DeviceGray setcolorspace\n" -"/IDD 8 dict def\n" -"IDD begin\n" -"/ImageType 1 def\n" -"/Width px def\n" -"/Height py def\n" -"/BitsPerComponent 8 def\n" - -"/Interpolate inter def\n" -"/DataSource currentfile A85RLE def\n" -"/MultipleDataSources false def\n" -"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" -"/Decode [ 0 1 ] def\n" -"end\n" -"IDD image GR} bind def\n" - -// Create a custom PostScript font derived from PostScript standard text fonts -// The encoding of this custom font is as follows: -// 0000-00FF coincides with Unicode, that is to ASCII + Latin-1 -// 0100-017F coincides with Unicode, that is to Latin Extended-A -// 0180-01A6 encodes miscellaneous characters present in PostScript standard text fonts - -// use ISOLatin1Encoding for all text fonts -"/ToISO { dup findfont dup length dict copy begin /Encoding ISOLatin1Encoding def currentdict end definefont pop } def\n" -"/Helvetica ToISO /Helvetica-Bold ToISO /Helvetica-Oblique ToISO /Helvetica-BoldOblique ToISO \n" -"/Courier ToISO /Courier-Bold ToISO /Courier-Oblique ToISO /Courier-BoldOblique ToISO \n" -"/Times-Roman ToISO /Times-Bold ToISO /Times-Italic ToISO /Times-BoldItalic ToISO \n" - -// define LatinExtA, the encoding of Latin-extended-A + some additional characters -// see http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt for their names -"/LatinExtA \n" -"[ " -" /Amacron /amacron /Abreve /abreve /Aogonek /aogonek\n" // begin of Latin Extended-A code page -" /Cacute /cacute /Ccircumflex /ccircumflex /Cdotaccent /cdotaccent /Ccaron /ccaron \n" -" /Dcaron /dcaron /Dcroat /dcroat\n" -" /Emacron /emacron /Ebreve /ebreve /Edotaccent /edotaccent /Eogonek /eogonek /Ecaron /ecaron\n" -" /Gcircumflex /gcircumflex /Gbreve /gbreve /Gdotaccent /gdotaccent /Gcommaaccent /gcommaaccent \n" -" /Hcircumflex /hcircumflex /Hbar /hbar \n" -" /Itilde /itilde /Imacron /imacron /Ibreve /ibreve /Iogonek /iogonek /Idotaccent /dotlessi \n" -" /IJ /ij /Jcircumflex /jcircumflex\n" -" /Kcommaaccent /kcommaaccent /kgreenlandic \n" -" /Lacute /lacute /Lcommaaccent /lcommaaccent /Lcaron /lcaron /Ldotaccent /ldotaccent /Lslash /lslash \n" -" /Nacute /nacute /Ncommaaccent /ncommaaccent /Ncaron /ncaron /napostrophe /Eng /eng \n" -" /Omacron /omacron /Obreve /obreve /Ohungarumlaut /ohungarumlaut /OE /oe \n" -" /Racute /racute /Rcommaaccent /rcommaaccent /Rcaron /rcaron \n" -" /Sacute /sacute /Scircumflex /scircumflex /Scedilla /scedilla /Scaron /scaron \n" -" /Tcommaaccent /tcommaaccent /Tcaron /tcaron /Tbar /tbar \n" -" /Utilde /utilde /Umacron /umacron /Ubreve /ubreve /Uring /uring /Uhungarumlaut /uhungarumlaut /Uogonek /uogonek \n" -" /Wcircumflex /wcircumflex /Ycircumflex /ycircumflex /Ydieresis \n" -" /Zacute /zacute /Zdotaccent /zdotaccent /Zcaron /zcaron \n" -" /longs \n" // end of Latin Extended-A code page -" /florin /circumflex /caron /breve /dotaccent /ring \n" // remaining characters from PostScript standard text fonts -" /ogonek /tilde /hungarumlaut /endash /emdash \n" -" /quoteleft /quoteright /quotesinglbase /quotedblleft /quotedblright \n" -" /quotedblbase /dagger /daggerdbl /bullet /ellipsis \n" -" /perthousand /guilsinglleft /guilsinglright /fraction /Euro \n" -" /trademark /partialdiff /Delta /summation /radical \n" -" /infinity /notequal /lessequal /greaterequal /lozenge \n" -" /fi /fl /apple \n" -" ] def \n" -// deal with alternative PostScript names of some characters -" /mycharstrings /Helvetica findfont /CharStrings get def\n" -" /PSname2 { dup mycharstrings exch known {LatinExtA 3 -1 roll 3 -1 roll put}{pop pop} ifelse } def \n" -" 16#20 /Gdot PSname2 16#21 /gdot PSname2 16#30 /Idot PSname2 16#3F /Ldot PSname2 16#40 /ldot PSname2 16#7F /slong PSname2 \n" - -// proc that gives LatinExtA encoding to a font -"/ToLatinExtA { findfont dup length dict copy begin /Encoding LatinExtA def currentdict end definefont pop } def\n" -// create Ext-versions of standard fonts that use LatinExtA encoding \n" -"/HelveticaExt /Helvetica ToLatinExtA \n" -"/Helvetica-BoldExt /Helvetica-Bold ToLatinExtA /Helvetica-ObliqueExt /Helvetica-Oblique ToLatinExtA \n" -"/Helvetica-BoldObliqueExt /Helvetica-BoldOblique ToLatinExtA \n" -"/CourierExt /Courier ToLatinExtA /Courier-BoldExt /Courier-Bold ToLatinExtA \n" -"/Courier-ObliqueExt /Courier-Oblique ToLatinExtA /Courier-BoldObliqueExt /Courier-BoldOblique ToLatinExtA \n" -"/Times-RomanExt /Times-Roman ToLatinExtA /Times-BoldExt /Times-Bold ToLatinExtA \n" -"/Times-ItalicExt /Times-Italic ToLatinExtA /Times-BoldItalicExt /Times-BoldItalic ToLatinExtA \n" - -// proc to create a Type 0 font with 2-byte encoding -// that merges a text font with ISO encoding + same font with LatinExtA encoding -"/To2byte { 6 dict begin /FontType 0 def \n" -"/FDepVector 3 1 roll findfont exch findfont 2 array astore def \n" -"/FontMatrix [1 0 0 1 0 0] def /FMapType 6 def /Encoding [ 0 1 0 ] def\n" -// 100: Hexa count of ISO array; A7: hexa count of LatinExtA array -"/SubsVector < 01 0100 00A7 > def\n" -"currentdict end definefont pop } def\n" -// create Type 0 versions of standard fonts -"/Helvetica2B /HelveticaExt /Helvetica To2byte \n" -"/Helvetica-Bold2B /Helvetica-BoldExt /Helvetica-Bold To2byte \n" -"/Helvetica-Oblique2B /Helvetica-ObliqueExt /Helvetica-Oblique To2byte \n" -"/Helvetica-BoldOblique2B /Helvetica-BoldObliqueExt /Helvetica-BoldOblique To2byte \n" -"/Courier2B /CourierExt /Courier To2byte \n" -"/Courier-Bold2B /Courier-BoldExt /Courier-Bold To2byte \n" -"/Courier-Oblique2B /Courier-ObliqueExt /Courier-Oblique To2byte \n" -"/Courier-BoldOblique2B /Courier-BoldObliqueExt /Courier-BoldOblique To2byte \n" -"/Times-Roman2B /Times-RomanExt /Times-Roman To2byte \n" -"/Times-Bold2B /Times-BoldExt /Times-Bold To2byte \n" -"/Times-Italic2B /Times-ItalicExt /Times-Italic To2byte \n" -"/Times-BoldItalic2B /Times-BoldItalicExt /Times-BoldItalic To2byte \n" -; - -static const char * prolog_2_pixmap = // prolog relevant only if lang_level == 2 for pixmaps/masked color images -"/pixmap_mat {[ pixmap_sx 0 0 pixmap_sy neg 0 pixmap_sy ]} bind def\n" - -"/pixmap_dict {" -"<< /PatternType 1 " -"/PaintType 1 " -"/TilingType 2 " -"/BBox [0 0 pixmap_sx pixmap_sy] " -"/XStep pixmap_sx " -"/YStep pixmap_sy\n" -"/PaintProc " -"{ begin " -"pixmap_w pixmap_h scale " -"pixmap_sx pixmap_sy 8 " -"pixmap_mat " -"currentfile A85RLE " -"false 3 " -"colorimage " -"end " -"} bind " -">>\n" -"} bind def\n" - -"/pixmap_plot {" -"GS " -"/pixmap_sy exch def /pixmap_sx exch def\n" -"/pixmap_h exch def /pixmap_w exch def\n" -"translate\n" -"pixmap_dict matrix makepattern setpattern\n" -"pixmap_w pixmap_h scale\n" -"pixmap_sx pixmap_sy\n" -"true\n" -"pixmap_mat\n" -"currentfile A85RLE\n" -"imagemask\n" -"GR\n" -"} bind def\n" -; - -static const char * prolog_3 = // prolog relevant only if lang_level >2 - -// masked color images -"/CIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale\n" -"/DeviceRGB setcolorspace\n" - -"/IDD 8 dict def\n" - -"IDD begin\n" -"/ImageType 1 def\n" -"/Width px def\n" -"/Height py def\n" -"/BitsPerComponent 8 def\n" -"/Interpolate inter def\n" -"/DataSource currentfile A85RLE def\n" -"/MultipleDataSources false def\n" -"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" - -"/Decode [ 0 1 0 1 0 1 ] def\n" -"end\n" - -"/IMD 8 dict def\n" -"IMD begin\n" -"/ImageType 1 def\n" -"/Width mx def\n" -"/Height my def\n" -"/BitsPerComponent 1 def\n" -// "/Interpolate inter def\n" -"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" -"/Decode [ 1 0 ] def\n" -"end\n" - -"<<\n" -"/ImageType 3\n" -"/InterleaveType 2\n" -"/MaskDict IMD\n" -"/DataDict IDD\n" -">> image GR\n" -"} bind def\n" - - -// masked gray images -"/GIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" -"translate \n" -"sx sy scale\n" -"/DeviceGray setcolorspace\n" - -"/IDD 8 dict def\n" - -"IDD begin\n" -"/ImageType 1 def\n" -"/Width px def\n" -"/Height py def\n" -"/BitsPerComponent 8 def\n" -"/Interpolate inter def\n" -"/DataSource currentfile A85RLE def\n" -"/MultipleDataSources false def\n" -"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" - -"/Decode [ 0 1 ] def\n" -"end\n" - -"/IMD 8 dict def\n" - -"IMD begin\n" -"/ImageType 1 def\n" -"/Width mx def\n" -"/Height my def\n" -"/BitsPerComponent 1 def\n" -"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" -"/Decode [ 1 0 ] def\n" -"end\n" - -"<<\n" -"/ImageType 3\n" -"/InterleaveType 2\n" -"/MaskDict IMD\n" -"/DataDict IDD\n" -">> image GR\n" -"} bind def\n" - - -"\n" -; - -// end prolog - -int Fl_PostScript_Graphics_Driver::start_postscript (int pagecount, - enum Fl_Paged_Device::Page_Format format, enum Fl_Paged_Device::Page_Layout layout) -//returns 0 iff OK -{ - int w, h, x; - if (format == Fl_Paged_Device::A4) { - left_margin = 18; - top_margin = 18; - } - else { - left_margin = 12; - top_margin = 12; - } - page_format_ = (enum Fl_Paged_Device::Page_Format)(format | layout); - if (layout & Fl_Paged_Device::LANDSCAPE){ - ph_ = Fl_Paged_Device::page_formats[format].width; - pw_ = Fl_Paged_Device::page_formats[format].height; - } else { - pw_ = Fl_Paged_Device::page_formats[format].width; - ph_ = Fl_Paged_Device::page_formats[format].height; - } - - fputs("%!PS-Adobe-3.0\n", output); - fputs("%%Creator: FLTK\n", output); - if (lang_level_>1) - fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_); - if ((pages_ = pagecount)) - fprintf(output, "%%%%Pages: %i\n", pagecount); - else - fputs("%%Pages: (atend)\n", output); - fprintf(output, "%%%%BeginFeature: *PageSize %s\n", Fl_Paged_Device::page_formats[format].name ); - w = Fl_Paged_Device::page_formats[format].width; - h = Fl_Paged_Device::page_formats[format].height; - if (lang_level_ == 3 && (layout & Fl_Paged_Device::LANDSCAPE) ) { x = w; w = h; h = x; } - fprintf(output, "<</PageSize[%d %d]>>setpagedevice\n", w, h ); - fputs("%%EndFeature\n", output); - fputs("%%EndComments\n", output); - fputs(prolog, output); - if (lang_level_ > 1) { - fputs(prolog_2, output); - } - if (lang_level_ == 2) { - fputs(prolog_2_pixmap, output); - } - if (lang_level_ > 2) - fputs(prolog_3, output); - if (lang_level_ >= 3) { - fputs("/CS { clipsave } bind def\n", output); - fputs("/CR { cliprestore } bind def\n", output); - } else { - fputs("/CS { GS } bind def\n", output); - fputs("/CR { GR } bind def\n", output); - } - page_policy_ = 1; - - - fputs("%%EndProlog\n",output); - if (lang_level_ >= 2) - fprintf(output,"<< /Policies << /Pagesize 1 >> >> setpagedevice\n"); - - reset(); - nPages=0; - return 0; -} - -void Fl_PostScript_Graphics_Driver::recover(){ - color(cr_,cg_,cb_); - line_style(linestyle_,linewidth_,linedash_); - font(Fl_Graphics_Driver::font(), Fl_Graphics_Driver::size()); -} - -void Fl_PostScript_Graphics_Driver::reset(){ - gap_=1; - clip_=0; - cr_=cg_=cb_=0; - Fl_Graphics_Driver::font(FL_HELVETICA, 12); - linewidth_=0; - linestyle_=FL_SOLID; - strcpy(linedash_,""); - Clip *c=clip_; ////just not to have memory leaks for badly writen code (forgotten clip popping) - - while(c){ - clip_=clip_->prev; - delete c; - c=clip_; - } - -} - -void Fl_PostScript_Graphics_Driver::page_policy(int p){ - page_policy_ = p; - if(lang_level_>=2) - fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p); -} - -// //////////////////// paging ////////////////////////////////////////// - - - -void Fl_PostScript_Graphics_Driver::page(double pw, double ph, int media) { - - if (nPages){ - fprintf(output, "CR\nGR\nGR\nGR\nSP\nrestore\n"); - } - ++nPages; - fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages); - fprintf(output, "%%%%PageBoundingBox: 0 0 %d %d\n", pw > ph ? (int)ph : (int)pw , pw > ph ? (int)pw : (int)ph); - if (pw>ph){ - fprintf(output, "%%%%PageOrientation: Landscape\n"); - }else{ - fprintf(output, "%%%%PageOrientation: Portrait\n"); - } - - fprintf(output, "%%%%BeginPageSetup\n"); - if((media & Fl_Paged_Device::MEDIA) &&(lang_level_>1)){ - int r = media & Fl_Paged_Device::REVERSED; - if(r) r = 2; - fprintf(output, "<< /PageSize [%i %i] /Orientation %i>> setpagedevice\n", (int)(pw+.5), (int)(ph+.5), r); - } - fprintf(output, "%%%%EndPageSetup\n"); - -/* pw_ = pw; - ph_ = ph;*/ - reset(); - - fprintf(output, "save\n"); - fprintf(output, "GS\n"); - clocale_printf( "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/); - fprintf(output, "1 -1 SC\n"); - line_style(0); - fprintf(output, "GS\n"); - - if (!((media & Fl_Paged_Device::MEDIA) &&(lang_level_>1))){ - if (pw > ph) { - if(media & Fl_Paged_Device::REVERSED) { - fprintf(output, "-90 rotate %i 0 translate\n", int(-pw)); - } - else { - fprintf(output, "90 rotate -%i -%i translate\n", (lang_level_ == 2 ? int(pw - ph) : 0), int(ph)); - } - } - else { - if(media & Fl_Paged_Device::REVERSED) - fprintf(output, "180 rotate %i %i translate\n", int(-pw), int(-ph)); - } - } - fprintf(output, "GS\nCS\n"); -} - -void Fl_PostScript_Graphics_Driver::page(int format){ -/* if(format & Fl_Paged_Device::LANDSCAPE){ - ph_=Fl_Paged_Device::page_formats[format & 0xFF].width; - pw_=Fl_Paged_Device::page_formats[format & 0xFF].height; - }else{ - pw_=Fl_Paged_Device::page_formats[format & 0xFF].width; - ph_=Fl_Paged_Device::page_formats[format & 0xFF].height; - }*/ - page(pw_,ph_,format & 0xFF00);//,orientation only; -} - -void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) { - // Commented code does not work, i can't find the bug ;-( - // fprintf(output, "GS\n"); - // fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h); - // fprintf(output, "GR\n"); - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y); - fprintf(output, "%i %i LT\n", x+w-1 , y); - fprintf(output, "%i %i LT\n", x+w-1 , y+h-1); - fprintf(output, "%i %i LT\n", x , y+h-1); - fprintf(output, "ECP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) { - clocale_printf( "%g %g %i %i FR\n", x-0.5, y-0.5, w, h); -} - -void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) { - fprintf(output, "GS\n"); - fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) { - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x0 , y0); - fprintf(output, "%i %i LT\n", x1 , y1); - fprintf(output, "%i %i LT\n", x2 , y2); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3){ - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y ); - fprintf(output, "%i %i LT\n", x1 , y ); - fprintf(output, "%i %i LT\n", x1 , y2); - fprintf(output,"%i %i LT\n", x3 , y2); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - - -void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2){ - - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y); - fprintf(output,"%i %i LT\n", x1 , y); - fprintf(output, "%i %i LT\n", x1 , y2 ); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1){ - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y); - fprintf(output, "%i %i LT\n", x1 , y ); - fprintf(output, "ELP\n"); - - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3){ - fprintf(output, "GS\n"); - - fprintf(output,"BP\n"); - fprintf(output,"%i %i MT\n", x , y); - fprintf(output, "%i %i LT\n", x , y1 ); - fprintf(output, "%i %i LT\n", x2 , y1 ); - fprintf(output , "%i %i LT\n", x2 , y3); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2){ - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y); - fprintf(output, "%i %i LT\n", x , y1); - fprintf(output, "%i %i LT\n", x2 , y1); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1){ - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x , y); - fprintf(output, "%i %i LT\n", x , y1); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) { - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x0 , y0); - fprintf(output, "%i %i LT\n", x1 , y1); - fprintf(output, "%i %i LT\n", x2 , y2); - fprintf(output, "ECP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x0 , y0); - fprintf(output, "%i %i LT\n", x1 , y1); - fprintf(output, "%i %i LT\n", x2 , y2); - fprintf(output, "%i %i LT\n", x3 , y3); - fprintf(output, "ECP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x0 , y0); - fprintf(output,"%i %i LT\n", x1 , y1); - fprintf(output, "%i %i LT\n", x2 , y2); - fprintf(output, "EFP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { - fprintf(output, "GS\n"); - fprintf(output,"BP\n"); - fprintf(output, "%i %i MT\n", x0 , y0 ); - fprintf(output, "%i %i LT\n", x1 , y1 ); - fprintf(output, "%i %i LT\n", x2 , y2 ); - fprintf(output, "%i %i LT\n", x3 , y3 ); - - fprintf(output, "EFP\n"); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::point(int x, int y){ - rectf(x,y,1,1); -} - -static const int dashes_flat[5][7]={ -{-1,0,0,0,0,0,0}, -{3,1,-1,0,0,0,0}, -{1,1,-1,0,0,0,0}, -{3,1,1,1,-1,0,0}, -{3,1,1,1,1,1,-1} -}; - - -//yeah, hack... -static const double dashes_cap[5][7]={ -{-1,0,0,0,0,0,0}, -{2,2,-1,0,0,0,0}, -{0.01,1.99,-1,0,0,0,0}, -{2,2,0.01,1.99,-1,0,0}, -{2,2,0.01,1.99,0.01,1.99,-1} -}; - - -void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashes){ - //line_styled_=1; - - linewidth_=width; - linestyle_=style; - //dashes_= dashes; - if(dashes){ - if(dashes != linedash_) - strcpy(linedash_,dashes); - - }else - linedash_[0]=0; - char width0 = 0; - if(!width){ - width=1; //for screen drawing compatibility - width0=1; - } - - fprintf(output, "%i setlinewidth\n", width); - - if(!style && (!dashes || !(*dashes)) && width0) //system lines - style = FL_CAP_SQUARE; - - int cap = (style &0xf00) >> 8; - if(cap) cap--; - fprintf(output,"%i setlinecap\n", cap); - - int join = (style & 0xf000) >> 12; - - if(join) join--; - fprintf(output,"%i setlinejoin\n", join); - - - fprintf(output, "["); - if(dashes && *dashes){ - while(*dashes){ - fprintf(output, "%i ", *dashes); - dashes++; - } - }else{ - if(style & 0x200){ // round and square caps, dash length need to be adjusted - const double *dt = dashes_cap[style & 0xff]; - while (*dt >= 0){ - clocale_printf("%g ",width * (*dt)); - dt++; - } - }else{ - - const int *ds = dashes_flat[style & 0xff]; - while (*ds >= 0){ - fprintf(output, "%i ",width * (*ds)); - ds++; - } - } - } - fprintf(output, "] 0 setdash\n"); -} - -static const char *_fontNames[] = { -"Helvetica2B", -"Helvetica-Bold2B", -"Helvetica-Oblique2B", -"Helvetica-BoldOblique2B", -"Courier2B", -"Courier-Bold2B", -"Courier-Oblique2B", -"Courier-BoldOblique2B", -"Times-Roman2B", -"Times-Bold2B", -"Times-Italic2B", -"Times-BoldItalic2B", -"Symbol", -"Courier2B", -"Courier-Bold2B", -"ZapfDingbats" -}; - -void Fl_PostScript_Graphics_Driver::font(int f, int s) { - Fl_Graphics_Driver *driver = Fl_Display_Device::display_device()->driver(); - driver->font(f,s); // Use display fonts for font measurement - Fl_Graphics_Driver::font(f, s); - Fl_Font_Descriptor *desc = driver->font_descriptor(); - this->font_descriptor(desc); - if (f < FL_FREE_FONT) { - float ps_size = (float) s; - fprintf(output, "/%s SF\n" , _fontNames[f]); -#if defined(USE_X11) -#if USE_XFT - // Xft font height is sometimes larger than the required size (see STR 2566). - // Increase the PostScript font size by 15% without exceeding the display font height - int max = desc->font->height; - ps_size = s * 1.15; - if (ps_size > max) ps_size = max; -#else - // Non-Xft fonts can be smaller than required. - // Set the PostScript font size to the display font height - char *name = desc->font->font_name_list[0]; - char *p = strstr(name, "--"); - if (p) { - sscanf(p + 2, "%f", &ps_size); - } -#endif // USE_XFT -#endif // USE_X11 - clocale_printf("%.1f FS\n", ps_size); - } -} - -double Fl_PostScript_Graphics_Driver::width(const char *s, int n) { - return Fl_Display_Device::display_device()->driver()->width(s, n); -} - -double Fl_PostScript_Graphics_Driver::width(unsigned u) { - return Fl_Display_Device::display_device()->driver()->width(u); -} - -int Fl_PostScript_Graphics_Driver::height() { - return Fl_Display_Device::display_device()->driver()->height(); -} - -int Fl_PostScript_Graphics_Driver::descent() { - return Fl_Display_Device::display_device()->driver()->descent(); -} - -void Fl_PostScript_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { - Fl_Display_Device::display_device()->driver()->text_extents(c, n, dx, dy, w, h); -} - - -void Fl_PostScript_Graphics_Driver::color(Fl_Color c) { - Fl::get_color(c, cr_, cg_, cb_); - color(cr_, cg_, cb_); -} - -void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) { - Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); - cr_ = r; cg_ = g; cb_ = b; - if (r == g && g == b) { - double gray = r/255.0; - clocale_printf("%g GL\n", gray); - } else { - double fr, fg, fb; - fr = r/255.0; - fg = g/255.0; - fb = b/255.0; - clocale_printf("%g %g %g SRGB\n", fr , fg , fb); - } -} - -void Fl_PostScript_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) -{ - fprintf(output, "GS %d %d translate %d rotate\n", x, y, - angle); - this->transformed_draw(str, n, 0, 0); - fprintf(output, "GR\n"); -} - - -// computes the mask for the RGB image img of all pixels with color != bg -static uchar *calc_mask(uchar *img, int w, int h, Fl_Color bg) -{ - uchar red, green, blue, r, g, b; - uchar bit, byte, *q; - Fl::get_color(bg, red, green, blue); - int W = (w+7)/8; // width of mask - uchar* mask = new uchar[W * h]; - q = mask; - while (h-- > 0) { // for each row - bit = 0x80; // byte with last bit set - byte = 0; // next mask byte to compute - for (int j = 0; j < w; j++) { // for each column - r = *img++; // the pixel color components - g = *img++; - b = *img++; - // if pixel doesn't have bg color, put it in mask - if (r != red || g != green || b != blue) byte |= bit; - bit = bit>>1; // shift bit one step to the right - if (bit == 0) { // single set bit has fallen out - *q++ = byte; // enter byte in mask - byte = 0; // reset next mask byte to zero - bit = 0x80; // and this byte - } - } - if (bit != 0x80) *q++ = byte; // enter last columns' byte in mask - } - return mask; -} - -// write to PostScript a bitmap image of a UTF8 string -void Fl_PostScript_Graphics_Driver::transformed_draw_extra(const char* str, int n, double x, double y, int w, bool rtl) -{ - // scale for bitmask computation -#if defined(USE_X11) && !USE_XFT - float scale = 1; // don't scale because we can't expect to have scalable fonts -#else - float scale = 2; -#endif - Fl_Fontsize old_size = size(); - Fl_Font fontnum = Fl_Graphics_Driver::font(); - int w_scaled = (int)(w * (scale + 0.5)); - int h = (int)(height() * scale); - // create an offscreen image of the string - Fl_Color text_color = Fl_Graphics_Driver::color(); - Fl_Color bg_color = fl_contrast(FL_WHITE, text_color); - Fl_Offscreen off = fl_create_offscreen(w_scaled, (int)(h+3*scale) ); - fl_begin_offscreen(off); - fl_color(bg_color); - // color offscreen background with a shade contrasting with the text color - fl_rectf(0, 0, w_scaled, (int)(h+3*scale) ); - fl_color(text_color); -#if defined(USE_X11) && !USE_XFT - // force seeing this font as new so it's applied to the offscreen graphics context - fl_graphics_driver->font_descriptor(NULL); - fl_font(fontnum, 0); -#endif - fl_font(fontnum, (Fl_Fontsize)(scale * old_size) ); - int w2 = (int)fl_width(str, n); - // draw string in offscreen - if (rtl) fl_rtl_draw(str, n, w2, (int)(h * 0.8) ); - else fl_draw(str, n, 1, (int)(h * 0.8) ); - // read (most of) the offscreen image - uchar *img = fl_read_image(NULL, 1, 1, w2, h, 0); - fl_end_offscreen(); - font(fontnum, old_size); - fl_delete_offscreen(off); - // compute the mask of what is not the background - uchar *mask = calc_mask(img, w2, h, bg_color); - delete[] img; - // write the string image to PostScript as a scaled bitmask - scale = w2 / float(w); - clocale_printf("%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h); - uchar *di; - int wmask = (w2+7)/8; - void *rle85 = prepare_rle85(); - for (int j = h - 1; j >= 0; j--){ - di = mask + j * wmask; - for (int i = 0; i < wmask; i++){ - write_rle85(*di, rle85); - di++; - } - } - close_rle85(rle85); fputc('\n', output); - delete[] mask; -} - -static int is_in_table(unsigned utf) { - unsigned i; - static unsigned extra_table_roman[] = { // unicodes/*names*/ of other characters from PostScript standard fonts - 0x192/*florin*/, 0x2C6/*circumflex*/, 0x2C7/*caron*/, - 0x2D8/*breve*/, 0x2D9/*dotaccent*/, 0x2DA/*ring*/, 0x2DB/*ogonek*/, 0x2DC/*tilde*/, 0x2DD/*hungarumlaut*/, - 0x2013/*endash*/, 0x2014/*emdash*/, 0x2018/*quoteleft*/, 0x2019/*quoteright*/, - 0x201A/*quotesinglbase*/, 0x201C/*quotedblleft*/, 0x201D/*quotedblright*/, 0x201E/*quotedblbase*/, - 0x2020/*dagger*/, 0x2021/*daggerdbl*/, 0x2022/*bullet*/, - 0x2026/*ellipsis*/, 0x2030/*perthousand*/, 0x2039/*guilsinglleft*/, 0x203A/*guilsinglright*/, - 0x2044/*fraction*/, 0x20AC/*Euro*/, 0x2122/*trademark*/, - 0x2202/*partialdiff*/, 0x2206/*Delta*/, 0x2211/*summation*/, 0x221A/*radical*/, - 0x221E/*infinity*/, 0x2260/*notequal*/, 0x2264/*lessequal*/, - 0x2265/*greaterequal*/, - 0x25CA/*lozenge*/, 0xFB01/*fi*/, 0xFB02/*fl*/, - 0xF8FF/*apple*/ - }; - for ( i = 0; i < sizeof(extra_table_roman)/sizeof(int); i++) { - if (extra_table_roman[i] == utf) return i + 0x180; - } - return 0; -} - -// outputs in PostScript a UTF8 string using the same width in points as on display -void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) { - int len, code; - if (!n || !str || !*str) return; - // compute display width of string - int w = (int)width(str, n); - if (w == 0) return; - if (Fl_Graphics_Driver::font() >= FL_FREE_FONT) { - transformed_draw_extra(str, n, x, y, w, false); - return; - } - fprintf(output, "%d <~", w); - void *data = prepare85(); - // transforms UTF8 encoding to our custom PostScript encoding as follows: - // extract each unicode character - // if unicode <= 0x17F, unicode and PostScript codes are identical - // if unicode is one of the values listed in extra_table_roman above - // its PostScript code is 0x180 + the character's rank in extra_table_roman - // if unicode is something else, draw all string as bitmap image - - const char *last = str + n; - const char *str2 = str; - while (str2 < last) { - // Extract each unicode character of string. - unsigned utf = fl_utf8decode(str2, last, &len); - str2 += len; - if (utf <= 0x17F) { // until Latin Extended-A - ; - } - else if ( (code = is_in_table(utf)) != 0) { // other handled characters - utf = code; - } - else { // unhandled character: draw all string as bitmap image - fprintf(output, "~> pop pop\n"); // close and ignore the opened hex string - transformed_draw_extra(str, n, x, y, w, false); - return; - } - // 2 bytes per character, high-order byte first, encode that to ASCII85 - uchar c[2]; c[1] = utf & 0xFF; c[0] = (utf & 0xFF00)>>8; write85(data, c, 2); - } - close85(data); - clocale_printf(" %g %g show_pos_width\n", x, y); -} - -void Fl_PostScript_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y) { - int w = (int)width(str, n); - transformed_draw_extra(str, n, x - w, y, w, true); -} - -void Fl_PostScript_Graphics_Driver::concat(){ - clocale_printf("[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); -} - -void Fl_PostScript_Graphics_Driver::reconcat(){ - clocale_printf("[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); -} - -///////////////// transformed (double) drawings //////////////////////////////// - - -void Fl_PostScript_Graphics_Driver::begin_points(){ - fprintf(output, "GS\n"); - concat(); - - fprintf(output, "BP\n"); - gap_=1; - shape_=POINTS; -} - -void Fl_PostScript_Graphics_Driver::begin_line(){ - fprintf(output, "GS\n"); - concat(); - fprintf(output, "BP\n"); - gap_=1; - shape_=LINE; -} - -void Fl_PostScript_Graphics_Driver::begin_loop(){ - fprintf(output, "GS\n"); - concat(); - fprintf(output, "BP\n"); - gap_=1; - shape_=LOOP; -} - -void Fl_PostScript_Graphics_Driver::begin_polygon(){ - fprintf(output, "GS\n"); - concat(); - fprintf(output, "BP\n"); - gap_=1; - shape_=POLYGON; -} - -void Fl_PostScript_Graphics_Driver::vertex(double x, double y){ - if(shape_==POINTS){ - clocale_printf("%g %g MT\n", x , y); - gap_=1; - return; - } - if(gap_){ - clocale_printf("%g %g MT\n", x , y); - gap_=0; - }else - clocale_printf("%g %g LT\n", x , y); -} - -void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){ - if(shape_==NONE) return; - if(gap_) - clocale_printf("%g %g MT\n", x , y); - else - clocale_printf("%g %g LT\n", x , y); - gap_=0; - - clocale_printf("%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3); -} - - -void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){ - if(shape_==NONE){ - fprintf(output, "GS\n"); - concat(); - // fprintf(output, "BP\n"); - clocale_printf("%g %g %g 0 360 arc\n", x , y , r); - reconcat(); - // fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); - }else - - clocale_printf("%g %g %g 0 360 arc\n", x , y , r); - -} - -void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double start, double a){ - if(shape_==NONE) return; - gap_=0; - if(start>a) - clocale_printf("%g %g %g %g %g arc\n", x , y , r , -start, -a); - else - clocale_printf("%g %g %g %g %g arcn\n", x , y , r , -start, -a); - -} - -void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) { - if (w <= 1 || h <= 1) return; - fprintf(output, "GS\n"); - //fprintf(output, "BP\n"); - begin_line(); - clocale_printf("%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); - clocale_printf("%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); - arc(0,0,1,a2,a1); - // fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2); - clocale_printf("%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) ); - clocale_printf("%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5); - end_line(); - - // fprintf(output, "%g setlinewidth\n", 2/sqrt(w*h)); - // fprintf(output, "ELP\n"); - // fprintf(output, 2.0/w , 2.0/w , " SC\n"; - // fprintf(output, (-x - w/2.0) , (-y - h/2) , " TR\n"; - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) { - fprintf(output, "GS\n"); - begin_polygon(); - clocale_printf("%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); - clocale_printf("%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); - vertex(0,0); - arc(0.0,0.0, 1, a2, a1); - end_polygon(); - fprintf(output, "GR\n"); -} - -void Fl_PostScript_Graphics_Driver::end_points(){ - gap_=1; - reconcat(); - fprintf(output, "ELP\n"); //?? - fprintf(output, "GR\n"); - shape_=NONE; -} - -void Fl_PostScript_Graphics_Driver::end_line(){ - gap_=1; - reconcat(); - fprintf(output, "ELP\n"); - fprintf(output, "GR\n"); - shape_=NONE; -} -void Fl_PostScript_Graphics_Driver::end_loop(){ - gap_=1; - reconcat(); - fprintf(output, "ECP\n"); - fprintf(output, "GR\n"); - shape_=NONE; -} - -void Fl_PostScript_Graphics_Driver::end_polygon(){ - - gap_=1; - reconcat(); - fprintf(output, "EFP\n"); - fprintf(output, "GR\n"); - shape_=NONE; -} - -void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y){ - reconcat(); - if(gap_){ - clocale_printf("%g %g MT\n", x , y); - gap_=0; - }else - clocale_printf("%g %g LT\n", x , y); - concat(); -} - -///////////////////////////// Clipping ///////////////////////////////////////////// - -void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Clip * c=new Clip(); - clip_box(x,y,w,h,c->x,c->y,c->w,c->h); - c->prev=clip_; - clip_=c; - fprintf(output, "CR\nCS\n"); - if(lang_level_<3) - recover(); - clocale_printf("%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h); - -} - -void Fl_PostScript_Graphics_Driver::push_no_clip() { - Clip * c = new Clip(); - c->prev=clip_; - clip_=c; - clip_->x = clip_->y = clip_->w = clip_->h = -1; - fprintf(output, "CR\nCS\n"); - if(lang_level_<3) - recover(); -} - -void Fl_PostScript_Graphics_Driver::pop_clip() { - if(!clip_)return; - Clip * c=clip_; - clip_=clip_->prev; - delete c; - fprintf(output, "CR\nCS\n"); - if(clip_ && clip_->w >0) - clocale_printf("%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h); - // uh, -0.5 is to match screen clipping, for floats there should be something beter - if(lang_level_<3) - recover(); -} - -int Fl_PostScript_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){ - if(!clip_){ - X=x;Y=y;W=w;H=h; - return 1; - } - if(clip_->w < 0){ - X=x;Y=y;W=w;H=h; - return 1; - } - int ret=0; - if (x > (X=clip_->x)) {X=x; ret=1;} - if (y > (Y=clip_->y)) {Y=y; ret=1;} - if ((x+w) < (clip_->x+clip_->w)) { - W=x+w-X; - - ret=1; - - }else - W = clip_->x + clip_->w - X; - if(W<0){ - W=0; - return 1; - } - if ((y+h) < (clip_->y+clip_->h)) { - H=y+h-Y; - ret=1; - }else - H = clip_->y + clip_->h - Y; - if(H<0){ - W=0; - H=0; - return 1; - } - return ret; -} - -int Fl_PostScript_Graphics_Driver::not_clipped(int x, int y, int w, int h){ - if(!clip_) return 1; - if(clip_->w < 0) return 1; - int X, Y, W, H; - clip_box(x, y, w, h, X, Y, W, H); - if(W) return 1; - return 0; -} - -void Fl_PostScript_File_Device::margins(int *left, int *top, int *right, int *bottom) // to implement -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - if(left) *left = (int)(ps->left_margin / ps->scale_x + .5); - if(right) *right = (int)(ps->left_margin / ps->scale_x + .5); - if(top) *top = (int)(ps->top_margin / ps->scale_y + .5); - if(bottom) *bottom = (int)(ps->top_margin / ps->scale_y + .5); -} - -int Fl_PostScript_File_Device::printable_rect(int *w, int *h) -//returns 0 iff OK -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - if(w) *w = (int)((ps->pw_ - 2 * ps->left_margin) / ps->scale_x + .5); - if(h) *h = (int)((ps->ph_ - 2 * ps->top_margin) / ps->scale_y + .5); - return 0; -} - -void Fl_PostScript_File_Device::origin(int *x, int *y) -{ - Fl_Paged_Device::origin(x, y); -} - -void Fl_PostScript_File_Device::origin(int x, int y) -{ - x_offset = x; - y_offset = y; - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->clocale_printf("GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", - ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x, y, ps->angle); -} - -void Fl_PostScript_File_Device::scale (float s_x, float s_y) -{ - if (s_y == 0.) s_y = s_x; - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->scale_x = s_x; - ps->scale_y = s_y; - ps->clocale_printf("GR GR GS %d %d TR %f %f SC %f rotate GS\n", - ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, ps->angle); -} - -void Fl_PostScript_File_Device::rotate (float rot_angle) -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->angle = - rot_angle; - ps->clocale_printf("GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", - ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x_offset, y_offset, ps->angle); -} - -void Fl_PostScript_File_Device::translate(int x, int y) -{ - fprintf(driver()->output, "GS %d %d translate GS\n", x, y); -} - -void Fl_PostScript_File_Device::untranslate(void) -{ - fprintf(driver()->output, "GR GR\n"); -} - -int Fl_PostScript_File_Device::start_page (void) -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->page(ps->page_format_); - x_offset = 0; - y_offset = 0; - ps->scale_x = ps->scale_y = 1.; - ps->angle = 0; - fprintf(ps->output, "GR GR GS %d %d translate GS\n", ps->left_margin, ps->top_margin); - return 0; -} - -int Fl_PostScript_File_Device::end_page (void) -{ - return 0; -} - -void Fl_PostScript_File_Device::end_job (void) -// finishes PostScript & closes file -{ - Fl_PostScript_Graphics_Driver *ps = driver(); - if (ps->nPages) { // for eps nPages is 0 so it is fine .... - fprintf(ps->output, "CR\nGR\nGR\nGR\nSP\n restore\n"); - if (!ps->pages_){ - fprintf(ps->output, "%%%%Trailer\n"); - fprintf(ps->output, "%%%%Pages: %i\n" , ps->nPages); - }; - } else - fprintf(ps->output, "GR\n restore\n"); - fputs("%%EOF",ps->output); - ps->reset(); - fflush(ps->output); - if(ferror(ps->output)) { - fl_alert ("Error during PostScript data output."); - } - if (ps->close_cmd_) { - (*ps->close_cmd_)(ps->output); - } else { - fclose(ps->output); - } - while (ps->clip_){ - Fl_PostScript_Graphics_Driver::Clip * c= ps->clip_; - ps->clip_= ps->clip_->prev; - delete c; - } - Fl_Display_Device::display_device()->set_current(); -} - -#endif // FL_DOXYGEN - -#if defined(__APPLE__) // PORTME: Fl_Surface_Driver ? - platform PostScript -#elif defined(WIN32) -#elif defined(FL_PORTING) -# pragma message "FL_PORTING: implement postscript printing" -#else // X11 -/** Starts a print job. */ -int Fl_PostScript_Printer::start_job(int pages, int *firstpage, int *lastpage) { - enum Fl_Paged_Device::Page_Format format; - enum Fl_Paged_Device::Page_Layout layout; - - // first test version for print dialog - if (!print_panel) make_print_panel(); - printing_style style = print_load(); - print_selection->deactivate(); - print_all->setonly(); - print_all->do_callback(); - print_from->value("1"); - { char tmp[10]; snprintf(tmp, sizeof(tmp), "%d", pages); print_to->value(tmp); } - print_panel->show(); // this is modal - while (print_panel->shown()) Fl::wait(); - - if (!print_start) // user clicked cancel - return 1; - - // get options - - switch (print_page_size->value()) { - case 0: - format = Fl_Paged_Device::LETTER; - break; - case 2: - format = Fl_Paged_Device::LEGAL; - break; - case 3: - format = Fl_Paged_Device::EXECUTIVE; - break; - case 4: - format = Fl_Paged_Device::A3; - break; - case 5: - format = Fl_Paged_Device::A5; - break; - case 6: - format = Fl_Paged_Device::B5; - break; - case 7: - format = Fl_Paged_Device::ENVELOPE; - break; - case 8: - format = Fl_Paged_Device::DLE; - break; - default: - format = Fl_Paged_Device::A4; - } - - { // page range choice - int from = 1, to = pages; - if (print_pages->value()) { - sscanf(print_from->value(), "%d", &from); - sscanf(print_to->value(), "%d", &to); - } - if (from < 1) from = 1; - if (to > pages) to = pages; - if (to < from) to = from; - if (firstpage) *firstpage = from; - if (lastpage) *lastpage = to; - if (pages > 0) pages = to - from + 1; - } - - if (print_output_mode[0]->value()) layout = Fl_Paged_Device::PORTRAIT; - else if (print_output_mode[1]->value()) layout = Fl_Paged_Device::LANDSCAPE; - else if (print_output_mode[2]->value()) layout = Fl_Paged_Device::PORTRAIT; - else layout = Fl_Paged_Device::LANDSCAPE; - - int print_pipe = print_choice->value(); // 0 = print to file, >0 = printer (pipe) - - const char *media = print_page_size->text(print_page_size->value()); - const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); - if (!print_pipe) printer = "<File>"; - - if (!print_pipe) // fall back to file printing - return Fl_PostScript_File_Device::start_job (pages, format, layout); - - // Print: pipe the output into the lp command... - - char command[1024]; - if (style == SystemV) snprintf(command, sizeof(command), "lp -s -d %s -n %d -t '%s' -o media=%s", - printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5), "FLTK", media); - else snprintf(command, sizeof(command), "lpr -h -P%s -#%d -T FLTK ", - printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5)); - - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->output = popen(command, "w"); - if (!ps->output) { - fl_alert("could not run command: %s\n",command); - return 1; - } - ps->close_command(pclose); - this->set_current(); - return ps->start_postscript(pages, format, layout); // start printing -} - -#endif // ! (defined(__APPLE__) || defined(WIN32) ) // PORTME: Fl_Surface_Driver - platform PostScript - - -// -// End of "$Id$". -// |
