home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / pstoedit.zip / source.zip / pstoedit.2.50 / src / drvfig.cpp < prev    next >
C/C++ Source or Header  |  1997-01-02  |  9KB  |  291 lines

  1. /* 
  2.    drvFIG.cpp : This file is part of pstoedit
  3.    Based on the skeleton for the implementation of new backends
  4.  
  5.    Copyright (C) 1993,1994,1995,1996 Wolfgang Glunz, Wolfgang.Glunz@zfe.siemens.de
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. */
  22.  
  23. /*
  24.     FIG 3.1 driver by Ian MacPhedran (Ian_MacPhedran@engr.usask.ca)
  25.     April 1995
  26.  
  27.     Color support and conversion to use C++ streams done by Wolfgang Glunz
  28.  
  29.     Object depth support by Gerhard Kircher <kircher@edvz.tuwien.ac.at>
  30.     March 1996
  31. */
  32.  
  33. #include "drvfig.h"
  34.  
  35. #include <iostream.h>
  36. #include <string.h>
  37. // for sprintf
  38. #include <stdio.h>
  39. // for free
  40. #include <malloc.h>
  41.  
  42. static const char * colorstring(float r, float g, float b)
  43. {
  44. static char buffer[10];
  45.     sprintf(buffer,"%s%.2x%.2x%.2x","#", (int) (r * 255), (int) ( g * 255) ,  (int) (b * 255));
  46.     return buffer;
  47. }
  48.  
  49. static const char * fig_default_colors[] =  {
  50.                         "#000000",
  51.                         "#0000ff",
  52.                         "#00ff00",
  53.                         "#00ffff",
  54.                         "#ff0000",
  55.                         "#ff00ff",
  56.                         "#ffff00",
  57.                         "#ffffff",
  58.                         "#000090",      
  59.                         "#0000b0",
  60.                         "#0000d0",
  61.                         "#87ceff",
  62.                         "#009000",
  63.                         "#00b000",
  64.                         "#00d000",
  65.                         "#009090",
  66.                         "#00b0b0",
  67.                         "#00d0d0",
  68.                         "#900000",
  69.                         "#b00000",
  70.                         "#d00000",
  71.                         "#900090",
  72.                         "#b000b0",
  73.                         "#d000d0",
  74.                         "#803000",
  75.                         "#a04000",
  76.                         "#c06000",
  77.                         "#ff8080",
  78.                         "#ffa0a0",
  79.                         "#ffc0c0",
  80.                         "#ffe0e0",
  81.                         "#ffd700" };
  82.  
  83. const int defaults = sizeof(fig_default_colors)/sizeof(char*);
  84. static ColorTable colorTable(fig_default_colors,defaults,colorstring);
  85.  
  86. static int registercolor(float r, float g, float b)
  87. {
  88.     return colorTable.getColorIndex(r,g,b);
  89. }
  90.  
  91. static void dumpnewcolors(ostream & theoutStream)
  92. {
  93.     int current=defaults;
  94.     const char * colstring;
  95.     while ((colstring = colorTable.getColorString(current)) != 0) {
  96.         theoutStream << "0 " << current << " " << colstring << endl;
  97.         current++;
  98.     }
  99. }
  100.  
  101.  
  102. drvFIG::drvFIG(const char * driveroptions_p,ostream & theoutStream,ostream & theerrStream):
  103.     drvbase(driveroptions_p,theoutStream,theerrStream,0,0,0),
  104.         buffer(tempFile.asOutput())
  105. {
  106. // driver specific initializations
  107.  
  108.     // set FIG specific values
  109.     scale    = 1;        
  110.     currentDeviceHeight = 13200.0 * scale;
  111.     // We use objectId as depth value.
  112.     // We need this because editing will reorder objects of equal depth,
  113.     // which has an undesireable effect if objects overlap.
  114.     // Depth must be in the range 0..999 (FIG 3.1).
  115.     // If we have more than 1000 objects this will get negative and
  116.     // xfig will set negative depth values to zero.
  117.     // This feature will thus become useless if we have more
  118.     // than 1000 objects. This is an xfig limitation.
  119.     objectId = 999;
  120.  
  121.     x_offset = 0.0;
  122.     y_offset = currentDeviceHeight;
  123.                  // output buffer, needed because
  124.                  // color entries must be written at
  125.                  // top of output file, but are known
  126.                  // only after processing the full input
  127.  
  128.     // print the header part
  129.     outf << "#FIG 3.1\nPortrait\nFlush Left\nInches\n1200 2\n";
  130. }
  131.  
  132. drvFIG::~drvFIG() {
  133.     dumpnewcolors(outf);
  134.     // now we can copy the buffer the output
  135.     ifstream & inbuffer = tempFile.asInput();
  136.     copy_file(inbuffer,outf);
  137. }
  138.  
  139. void drvFIG::print_coords()
  140. {
  141.     int j;
  142.     float PntFig = 1200.0 / 72.0;
  143.  
  144.     j = 0;
  145.     for (unsigned int n = 0; n < numberOfElementsInPath(); n++) {
  146.     const Point & p = pathElement(n).getPoint(0);
  147.     if (j == 0) { buffer << "\t"; }
  148.     buffer << (int)(PntFig * p.x_) << " " 
  149.          << (int)(y_offset - (PntFig * p.y_)) <<  " ";
  150.     j++;
  151.     if (j == 5) { j=0; buffer << "\n"; }
  152.     }
  153.     if (j != 0) { buffer << "\n"; }
  154. }
  155.  
  156. void drvFIG::close_page()
  157. {
  158. // Well, since FIG doesn't support multipage output, we'll move down
  159. // 11 inches and start again.
  160.     y_offset += currentDeviceHeight;
  161.     // reset depth counter
  162.     objectId = 999;
  163. }
  164.  
  165. void drvFIG::open_page()
  166. {
  167. }
  168.  
  169. // 
  170. // FIG 3.1 uses an index for the popular fonts:
  171. //
  172. // (we cannot make this array local to drvFIG::show_textstring
  173. // because some CCs don't support that yet.
  174.  
  175. const char *FigFonts[] = {
  176.     "Times-Roman","Times-Italic", "Times-Bold", "Times-BoldItalic",
  177.     "AvantGarde-Book", "AvantGarde-BookOblique", "AvantGarde-Demi",
  178.     "AvantGarde-DemiOblique", "Bookman-Light", "Bookman-LightItalic",
  179.     "Bookman-Demi", "Bookman-DemiItalic", "Courier", "Courier-Oblique",
  180.     "Courier-Bold","Courier-BoldOblique","Helvetica","Helvetica-Oblique",
  181.     "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Narrow",
  182.     "Helvetica-Narrow-Oblique", "Helvetica-Narrow-Bold",
  183.     "Helvetica-Narrow-BoldOblique", "NewCenturySchlbk-Roman",
  184.     "NewCenturySchlbk-Italic", "NewCenturySchlbk-Bold",
  185.     "NewCenturySchlbk-BoldItalic", "Palatino-Roman",
  186.     "Palatino-Italic", "Palatino-Bold", "Palatino-BoldItalic",
  187.     "Symbol", "ZapfChancery-MediumItalic", "ZapfDingbats"};
  188.  
  189. void drvFIG::show_text(const TextInfo & textinfo)
  190. {
  191.     unsigned int MAXFNTNUM, fntlength;
  192.     int FigFontNum;
  193.     float FigHeight,FigLength;
  194.     float PntFig = 1200.0 / 72.0;
  195.     float toRadians = 3.14159265359 / 180.0;
  196.  
  197.     MAXFNTNUM = sizeof(FigFonts)/(sizeof(char *)) - 1;
  198.     FigFontNum = -1;
  199.     fntlength = strlen(textinfo.currentFontName.value());
  200.     for (unsigned int i=0; i<=MAXFNTNUM; i++) {
  201.     if (fntlength == strlen(FigFonts[i])) {
  202.         if (strncmp(textinfo.currentFontName.value(),FigFonts[i],fntlength) == 0)
  203.         FigFontNum = i;
  204.     }
  205.     }
  206.     if (FigFontNum == -1) {
  207.       errf << "Warning, unsupported font " << textinfo.currentFontName.value() <<
  208.               ", using ";
  209.       if (strstr (textinfo.currentFontName.value(), "Bold") == NULL) {
  210.         if (strstr (textinfo.currentFontName.value(), "Italic") == NULL) {
  211.           errf << "Times-Roman";
  212.           FigFontNum = 0; // Times-Roman
  213.         } else {
  214.           FigFontNum = 1;
  215.           errf << "Times-Italic";
  216.         }
  217.       } else {
  218.         if (strstr (textinfo.currentFontName.value(), "Italic") == NULL) {
  219.           errf << "Times-Bold";
  220.           FigFontNum = 2; // Times-Bold
  221.         } else {
  222.           FigFontNum = 3;
  223.           errf << "Times-BoldItalic";
  224.         }
  225.       }
  226.       errf << " instead." << endl;
  227.     }                                     
  228. #if 0
  229. // old stuff
  230.     if (FigFontNum == -1) {
  231.     errf << "Warning, unsupported font " << textinfo.currentFontName.value() << ", using Courier instead" << endl;
  232.     FigFontNum = 12; // Courier
  233.     } 
  234. #endif
  235.  
  236.     int color = registercolor(textinfo.currentR,textinfo.currentG,textinfo.currentB);
  237.     float localFontSize = textinfo.currentFontSize;
  238.     if (localFontSize <=  0.1) { localFontSize = 9; }
  239.     localFontSize++; // There appears to be a reduction for some reason
  240.     FigHeight = 1200.0 * localFontSize / 72.0;
  241.     FigLength = FigHeight * strlen(textinfo.thetext);
  242.     buffer << "4 0 ";
  243.     buffer << color;
  244.     buffer << " " << objectId-- << " -1 " 
  245.      << FigFontNum << " " 
  246.      << (int) localFontSize << " " 
  247.      << textinfo.currentFontAngle*toRadians << " 4 " 
  248.      << FigHeight << " " 
  249.      << FigLength << " " 
  250.      << (int)(PntFig * textinfo.x) << " " 
  251.      << (int)(y_offset - (PntFig * textinfo.y)) << " " 
  252.      << textinfo.thetext << "\\001\n";
  253. }
  254.  
  255. void drvFIG::show_path()
  256. {
  257.   
  258.     float localLineWidth = currentLineWidth();
  259.     if ((localLineWidth < 0.0) || 
  260.        ((localLineWidth > 0.0) && (localLineWidth <= 1.0)))
  261.                { localLineWidth = 1.0; }
  262.     int linestyle = 0;
  263.     switch (currentLineType()) {
  264.         case solid : linestyle = 0; break;
  265.         case dashed :
  266.         case dashdot : linestyle = 1; break;
  267.         case dotted :
  268.         case dashdotdot : linestyle = 2; break;
  269.     }
  270.     buffer << "2 1 " << linestyle << " " 
  271.      << (int)localLineWidth << " " ;
  272.     const int color = registercolor(currentR(),currentG(),currentB());
  273.     const int fill_or_nofill = (currentShowType() == drvbase::stroke) ? -1 : 20;
  274.     buffer << color <<  " " << color << " " << objectId-- << " 0 "
  275.         << fill_or_nofill            <<  " " << 4.0  << " 0 0 0 0 0 ";
  276.         // 4.0 is the gap spec. we could also derive this from the input
  277.     buffer << (int)(numberOfElementsInPath()) << "\n";
  278.  
  279.     print_coords();
  280. };
  281.  
  282. void drvFIG::show_rectangle(const float llx, const float lly, const float urx, const float ury)
  283. {
  284.  // just do show_polyline for a first guess
  285.   unused(&llx);
  286.   unused(&lly);
  287.   unused(&urx);
  288.   unused(&ury);
  289.  show_path();
  290. }
  291.