summaryrefslogtreecommitdiff
path: root/src/Fl_PostScript.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_PostScript.cxx')
-rw-r--r--src/Fl_PostScript.cxx1667
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$".
-//