home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / pstoedit.zip / source.zip / pstoedit.2.50 / src / drvmet.cpp < prev    next >
C/C++ Source or Header  |  1996-10-29  |  22KB  |  681 lines

  1. #ifdef __OS2__
  2. // this file compiles only under OS/2
  3. /*
  4.    drvMET.cpp : This file is part of pstoedit
  5.    Backend for OS/2 Meta Files.
  6.    Contributed by : Christoph Jaeschke (jaeschke@imbe05.imbe.uni-bremen.de)
  7.  
  8.    Copyright (C) 1993,1994,1995,1996 Wolfgang Glunz, Wolfgang.Glunz@zfe.siemens.de
  9.  
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License as published by
  12.     the Free Software Foundation; either version 2 of the License, or
  13.     (at your option) any later version.
  14.  
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19.  
  20.     You should have received a copy of the GNU General Public License
  21.     along with this program; if not, write to the Free Software
  22.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24. */
  25.  
  26. #include <iostream.h>
  27. #include <fstream.h>
  28. #include <process.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <math.h>
  33. #include <float.h>
  34.  
  35. #include "drvMET.h"
  36.  
  37. #define GSFONTMAPENV "GS_LIB"
  38. #define GSFONTMAPFILE "FONTMAP"
  39.  
  40. #define FONT_ID 1
  41. #define DRAW_CLOSED 1
  42. #define DRAW_OPEN 0
  43. #define READ_pNumers 0
  44.  
  45. HAB hab;
  46. HMQ  hmq;
  47. HWND hwndClient;
  48. HWND hwndFrame;
  49. QMSG qmsg;
  50. DRVMETSETUP *pDrvMETsetup;
  51.  
  52. void strRemove(char *toRemoveStr, char *pRemoves) {
  53.  
  54.   int length = strlen(toRemoveStr);
  55.  
  56.   for (int i=0; i<length;i++)
  57.     if (strchr(pRemoves,toRemoveStr[i]))
  58.       {
  59.     memmove((void*)&toRemoveStr[i],
  60.         (void*)&toRemoveStr[i+1],length-1-i);
  61.     toRemoveStr[--length] = '\0';
  62.       }
  63. }
  64.  
  65. FONTMAPENTRY::FONTMAPENTRY(char* gsInitName, char* pmInitName) {
  66.  
  67.   strcpy(gsName,gsInitName);
  68.   strcpy(pmName,pmInitName);
  69. }
  70.  
  71. INTFONTMAP::INTFONTMAP(ostream *pOutstream) {
  72.  
  73.   pOutf = pOutstream;
  74.  
  75.   cntMapEntries = 0;
  76.   if (NULL!=(fontmapFile = scanEnv(GSFONTMAPENV, GSFONTMAPFILE)) ) {
  77.     readFontmap();
  78.     if (pDrvMETsetup->info) {
  79.       *pOutf << endl << "Extracted FONTMAP table:" << endl;
  80.       for(int i=0; i<cntMapEntries; i++)
  81.     *pOutf << mapEntry[i]->getgsName() << "->" << mapEntry[i]->getpmName() << endl;
  82.       *pOutf << "Fontmap table end." << endl << endl;
  83.     }
  84.   }
  85. }
  86. INTFONTMAP::~INTFONTMAP() {
  87.  
  88.   for(int i=0; i<cntMapEntries; i++) {
  89.     delete mapEntry[i];
  90.   }
  91. }
  92.  
  93. char* INTFONTMAP::searchMapEntry(char *gsName) {
  94.  
  95.   for(int i=0; i<cntMapEntries; i++)
  96.     if (!strcmp(gsName,mapEntry[i]->getgsName()))
  97.       return mapEntry[i]->getpmName(); // Found!
  98.   return gsName;
  99. }
  100.  
  101. void INTFONTMAP::addEntry(char *pLine) {
  102.  
  103.   char *gsName;
  104.   char *pmName;
  105.  
  106.   if (cntMapEntries < maxMapEntries) {
  107.     gsName = strtok(pLine," \t"); // First Token
  108.     pmName = strtok(NULL," \t");    // Second Token
  109.     if (pmName)
  110.       if (pmName[0]=='/') {        // Thats an alias
  111.     mapEntry[cntMapEntries++] = new FONTMAPENTRY(&gsName[1],&pmName[1]);
  112.     // Now: gsName is an alias for pmName!
  113.     // First search existing alias in List and replace
  114.     // match with further alias
  115.     for(int i=0; i<cntMapEntries-1; i++)
  116.       if (!strcmp(mapEntry[i]->getpmName(),&gsName[1]))
  117.         mapEntry[i]->reAllocpmName(&pmName[1]);
  118.       }
  119.   } else *pOutf << "WARNING: Max. number of FONTMAP-Entries succeeded: " << cntMapEntries << endl;
  120. }
  121.  
  122. void INTFONTMAP::readFontmap() {
  123.  
  124.   const int maxLine=255;
  125.   char pLine[maxLine];
  126.   char c;
  127.  
  128.   ifstream mapf(fontmapFile);
  129.   while (mapf.get(pLine,maxLine,'\n')) {
  130.     mapf.get(c);
  131.     if (pLine[0]=='/') addEntry(pLine);
  132.   }
  133.   mapf.close();
  134. }
  135.  
  136. char* INTFONTMAP::scanEnv(char* envName, char* fileName) {
  137.  
  138.   PCXCHAR resPointer;
  139.   static BYTE      resBuffer[128];
  140.   APIRET    rc;
  141.  
  142.   if(!(rc=DosScanEnv((PXCHAR)envName, &resPointer))) {
  143.     if (pDrvMETsetup->info)
  144.       *pOutf << envName << " is " << resPointer << endl;
  145.   } else {         // not found
  146.     *pOutf << "WARNING: " << envName << " not set, rc=" << rc << endl;
  147.     return (char*) 0;
  148.   }   if(!(rc=DosSearchPath(SEARCH_ENVIRONMENT,(PXCHAR)envName,
  149.                 (PXCHAR)fileName,resBuffer,sizeof(resBuffer)))) {
  150.     if (pDrvMETsetup->info)
  151.       *pOutf << "Found desired file: "<< resBuffer << endl;
  152.     return (char*) resBuffer;
  153.   }
  154.   else {         // not found
  155.     *pOutf << "WARNING: Desired file " << fileName << " in " << resPointer
  156.        << " not found, rc=" << rc << endl;
  157.     return (char*) 0;
  158.   }
  159. }
  160.  
  161. drvMET::drvMET(const char * driveroptions_p,ostream & theoutStream,ostream & theerrStream): 
  162. drvbase(driveroptions_p,theoutStream,theerrStream,0,0,0) {
  163.  
  164.   long cFonts;
  165.   SIZEL size={0,0};
  166.   const char *dData[2] =  { 0, "DISPLAY"};
  167.   
  168.   y_offset = 0;
  169.   x_offset = 0;
  170.   cntFonts = 0;
  171.   scale = 1; // 4.0 for PU_HIENGLISH
  172.   showFontList = 1;
  173.   switch (pDrvMETsetup->draw_target) {
  174.   case DRVMETSETUP::to_WINDOW : {
  175.     hps = WinGetPS(hwndClient);
  176.     GpiErase(hps);
  177.     scale = 1.0;
  178.     break;
  179.   }
  180.   case DRVMETSETUP::to_META : {
  181.     hdc = DevOpenDC(hab, OD_METAFILE, (PSZ)"*", 2L, (PDEVOPENDATA)dData, 0L);
  182.     if(!hdc) outf << "ERROR: Can't open DC!"    << endl;
  183.     hps = GpiCreatePS(hab, hdc, &size, PU_PELS|GPIF_DEFAULT|GPIT_MICRO|GPIA_ASSOC);
  184.     if(!hps) outf << "ERROR: Can't open PS!"    << endl;;
  185.     break;
  186.   }
  187.   }
  188.   DevQueryCaps(GpiQueryDevice(hps), CAPS_COLOR_INDEX, 1L, &maxPalEntries);
  189.  
  190.   alTable = new ULONG[maxPalEntries];
  191.  
  192.   long mp = maxPalEntries;
  193.   for(int i=0; i<maxPalEntries;i++) alTable[i]= palEntry(i/mp, i/mp, i/mp);
  194.   alTable[0] = palEntry(1,1,1);
  195.   alTable[1] = palEntry(0,0,0);
  196.   cntPalEntries = 2;
  197.   outf.seekp(0);
  198.   if (pDrvMETsetup->info)
  199.     outf << "Open driver for: " << pDrvMETsetup->pMetaFileName << endl;
  200.   if (!GpiCreateLogColorTable(hps,LCOL_PURECOLOR,LCOLF_CONSECRGB,0L,maxPalEntries-1,(long*)alTable))
  201.     outf << "ERROR: Can't update logical palette!"    << endl;
  202.   if (!GpiSetColor(hps,1))
  203.     outf << "ERROR: Can't set color: 1" << endl;
  204.  
  205.   // Now Count and retrieve Fontinformations
  206.  
  207.   pIntFontmap = new INTFONTMAP(&outf);
  208.  
  209.   cFonts = GpiQueryFonts (hps, QF_PUBLIC,(PSZ) NULL, &cntFonts,
  210.               sizeof (FONTMETRICS),(PFONTMETRICS) NULL);
  211.   cntFonts = cFonts;
  212.   if (DosAllocMem ((PVOID *) &pfm, sizeof (FONTMETRICS) * cFonts,
  213.            PAG_COMMIT | PAG_WRITE))
  214.     outf << "ERROR: Can't alloc memory for fontmetrics" << endl;
  215.   GpiQueryFonts (hps, QF_PUBLIC,(PSZ) NULL,
  216.          &cntFonts, sizeof (FONTMETRICS),pfm);
  217.   strcpy(textInfo_.currentFontName.value(),"TimesNewRoman");
  218.   FetchFont (FONT_ID,textInfo_.currentFontName.value(), 0L, &pfat);
  219.   strcpy(lastSelectedFontName,textInfo_.currentFontName.value());
  220. }
  221.  
  222. drvMET::~drvMET() {
  223.  
  224.   HMF hmf;
  225.  
  226.   DosFreeMem (pfm);
  227.   switch (pDrvMETsetup->draw_target) {
  228.   case DRVMETSETUP::to_WINDOW : {
  229.     WinReleasePS(hps);
  230.     break;
  231.   }
  232.   case DRVMETSETUP::to_META : {
  233.     GpiAssociate(hps, NULLHANDLE);
  234.     if(!GpiDestroyPS(hps))
  235.       outf << "ERROR: Can't destroy PS" << endl;
  236.     hmf = (HMF)DevCloseDC(hdc);
  237.     DosDelete((PXCHAR)pDrvMETsetup->pMetaFileName);
  238.     if(GpiSaveMetaFile(hmf,(PXCHAR) pDrvMETsetup->pMetaFileName)) {
  239.       if (pDrvMETsetup->info) outf << "Metafile saved!" << endl;
  240.     } else
  241.       outf << "ERROR: Can't save metafile." << endl;
  242.     GpiDeleteMetaFile(hmf);
  243.     break;
  244.   }
  245.   }
  246.   delete alTable;
  247.   delete pIntFontmap;
  248. }
  249.  
  250. long drvMET::palEntry(float r, float g, float b) {
  251.  
  252.   long lr, lg, lb;
  253.  
  254.   lr = (long)(r*255);
  255.   lg = (long)(g*255);
  256.   lb = (long)(b*255);
  257.   if (pDrvMETsetup->draw_noColor) lr = lg = lb = (lr + lg + lb ) / 3;
  258.   return (/*((PC_RESERVED | PC_EXPLICIT )*16777216)*/ + (lr*65536) + (lg*256) + lb);
  259. }
  260.  
  261. long drvMET::searchPalEntry(long palEntry) {
  262.  
  263.   for(int i=0; i<cntPalEntries; i++)
  264.     if (palEntry==alTable[i]) return i; // Found!
  265.   return -1;                              // Not found!
  266. }
  267.  
  268. void drvMET::setColor(float r, float g, float b) {
  269.  
  270.   long index;
  271.  
  272.   index = searchPalEntry(palEntry(r,g,b));
  273.   if (index < 0) {        // Not found!
  274.     if (cntPalEntries<maxPalEntries) {
  275.       alTable[cntPalEntries]=palEntry(r,g,b);
  276.       if (GpiCreateLogColorTable(hps,LCOL_PURECOLOR,LCOLF_CONSECRGB,0L,maxPalEntries,(long*)alTable)) {
  277.     if (pDrvMETsetup->info)
  278.       outf << "Added Colorindex: " << cntPalEntries << endl;
  279.       } else
  280.     outf << "ERROR: Can't update logical palette!" << endl;
  281.       if (!GpiSetColor(hps, cntPalEntries))
  282.     outf << "ERROR: Can't set color: " << cntPalEntries << endl;
  283.       cntPalEntries++;
  284.     } else outf << "WARNING: Max. number of colorentries ("<< maxPalEntries <<") exceeded!" << endl;
  285.   } else     // Found!
  286.     if (!GpiSetColor(hps, index))
  287.       outf << "ERROR: Can't set color: " << index << endl;
  288. }
  289.  
  290. int drvMET::FetchFont (SHORT idFont, PCHAR pFamilyName, long selection, PFATTRS *pfat) {
  291.  
  292.   FATTRS    fat;
  293.   PFONTMETRICS    pFontMetrics;
  294.   APIRET rc;
  295.   long    i;
  296.   long tableEntry;
  297.   char *pOrgFamilyName;
  298.   char     lastOutfName[FACESIZE];
  299.   char     tmpIsName[FACESIZE];
  300.   char     tmpSearchName[FACESIZE];
  301.  
  302.   pOrgFamilyName = pFamilyName;
  303.   pFamilyName = pIntFontmap->searchMapEntry(pFamilyName);
  304.   if (pDrvMETsetup->info) {
  305.     outf << "Font requested: ";
  306.     if (pOrgFamilyName != pFamilyName)
  307.       outf << pOrgFamilyName << ", FONTMAP maps to: ";
  308.     outf << pFamilyName << endl;
  309.   }
  310.   strcpy(tmpSearchName,pFamilyName);
  311.   strRemove(tmpSearchName," -");
  312.   lastOutfName[0] = '\0';
  313.   if (showFontList) {
  314.     if (pDrvMETsetup->info) outf << "Table of installed PM-Fonts: " << endl;
  315.     tableEntry = 0;
  316.     pFontMetrics = pfm;
  317.     for (i=0; i<cntFonts; i++) {
  318.       if (strcmp(pFontMetrics->szFacename,lastOutfName)) {
  319.     if (pDrvMETsetup->info)
  320.       outf << ++tableEntry << ": " << pFontMetrics->szFacename << endl;
  321.     strcpy(lastOutfName,pFontMetrics->szFacename);
  322.       }
  323.       pFontMetrics++;
  324.     }
  325.     if (pDrvMETsetup->info) outf << "End Table of PM-Fonts." << endl;
  326.   }
  327.   showFontList = 0;    // Show only once
  328.   pFontMetrics = pfm;
  329.   for (i=0; i<cntFonts; i++) {   // Real search
  330.     strcpy(tmpIsName,pFontMetrics->szFacename);
  331.     strRemove(tmpIsName," -");
  332.     if (!strcmp(tmpIsName,tmpSearchName)) break; // Font found in List!
  333.     pFontMetrics++;
  334.   }
  335.   if (i != cntFonts) {
  336.     strcpy (fat.szFacename, pFontMetrics->szFacename);
  337.     fat.usRecordLength = sizeof(FATTRS); /* sets size of structure   */
  338.     fat.fsSelection = (USHORT)selection;
  339.     fat.lMatch = pFontMetrics->lMatch;
  340.     fat.idRegistry = 0;          /* uses default registry            */
  341.     fat.usCodePage = 0;          /* code-page 0                      */
  342.     fat.lMaxBaselineExt = 0L;   /* requested default font height */
  343.     fat.lAveCharWidth = 0L;     /* requested default font width */
  344.     fat.fsType = 0;              /* uses default type                */
  345.     fat.fsFontUse = FATTR_FONTUSE_OUTLINE;/* outline font */
  346.     rc = GpiCreateLogFont (hps,NULL,idFont,&fat);
  347.     *pfat = &fat;
  348.     if (pDrvMETsetup->info) {
  349.       outf << "Found PM name: " << pFontMetrics->szFacename
  350.        << " (attributes: " << selection << ")" << endl;
  351.       outf << "CreateFont (";
  352.       if (rc==FONT_MATCH) outf << "selected)" << endl;
  353.       if (rc==FONT_DEFAULT) outf << "not selected -> defaultet)" << endl;
  354.     }
  355.     if (rc==GPI_ERROR) {
  356.       outf << "ERROR: Found PM name: " << pFontMetrics->szFacename
  357.        << ", but CreateFont yields to GPI_ERROR)" << endl;
  358.       return FALSE;
  359.     }
  360.     return TRUE;
  361.   } else {
  362.     outf << "WARNING: Font request: " << pFamilyName<< " not found!" << endl;
  363.     return 0;
  364.   }
  365. }
  366.  
  367. long drvMET::get_print_coords(POINTL aptlPoints[]) {
  368.   PLONG koords = (PLONG) aptlPoints;
  369.   for (int i = 0; i < numberOfElementsInPath(); i++) {
  370.     koords[2*i] = transX(pathElement(i).getPoint(0).x_);
  371.     koords[(2*i)+1] = transY(pathElement(i).getPoint(0).y_);
  372.   }
  373.   long pts = numberOfElementsInPath();
  374.   for (int n = 0; n < pts-1; n++)
  375.     if ((aptlPoints[n].x == aptlPoints[n+1].x)
  376.     && (aptlPoints[n].y == aptlPoints[n+1].y)) {// same coords
  377.       if (pDrvMETsetup->info) outf << "melted points due to coord.-transform, removing..." << endl;
  378.       memmove((void*)&aptlPoints[n],
  379.           (void*)&aptlPoints[n+1],sizeof(POINTL) * (pts-1-n));
  380.       pts--;
  381.     }
  382.   if ((aptlPoints[0].x == aptlPoints[pts-1].x)
  383.       && (aptlPoints[0].y == aptlPoints[pts-1].y)) {
  384.     if (pDrvMETsetup->info) outf << "first point equals last, removing..." << endl;
  385.     pts--;
  386.   }
  387.   return pts;
  388. }
  389.  
  390. void drvMET::close_page() {
  391.   if (pDrvMETsetup->info) outf << "End page: " << currentPageNumber << endl;
  392. }
  393.  
  394. void drvMET::open_page() {
  395.   LONG  plOutCount;
  396.   PBYTE pbOutData;
  397.   long rc;
  398.  
  399.   plOutCount = 0;
  400.   pbOutData = NULL;
  401.   if (pDrvMETsetup->info) outf << "Start page: " << currentPageNumber << endl;
  402.   if (currentPageNumber > 1) {
  403.     rc = DevEscape(hdc, DEVESC_NEWFRAME, 0L, NULL, &plOutCount, pbOutData);
  404.     if (rc==DEVESC_ERROR) outf << "New page error!" << endl;
  405.     if (rc==DEVESC_NOTIMPLEMENTED) outf << "WARNING: New page not implemented!" << endl;
  406.     if ((rc==DEV_OK) && (pDrvMETsetup->info)) outf << "New page ok" << endl;
  407.   }
  408. }
  409.  
  410. void    drvMET::show_text(const TextInfo & textinfo) {
  411. // void drvMET::show_textstring(float x, float y, const char *const thetext) {
  412.   SIZEF SizeBox;
  413.   POINTL ptl;
  414.   GRADIENTL grad;
  415.  
  416.   if (pDrvMETsetup->draw_noText) return;
  417.   setColor(textinfo.currentR,textinfo.currentG,textinfo.currentB);
  418.   if (strcmp(lastSelectedFontName,textinfo.currentFontName.value()))
  419.     FetchFont (FONT_ID, (PCHAR) textinfo.currentFontName.value() , 0L, &pfat);
  420.   strcpy(lastSelectedFontName,textinfo.currentFontName.value());
  421.   SizeBox.cx = MAKEFIXED ((textinfo.currentFontSize*scale),0);
  422.   SizeBox.cy = MAKEFIXED ((textinfo.currentFontSize*scale),0);
  423.   const float toRadians = 3.14159265359 / 180.0;
  424.   grad.x = (long) (100 * cos(textinfo.currentFontAngle * toRadians ));
  425.   grad.y = (long) (100 * sin(textinfo.currentFontAngle * toRadians ));
  426.   GpiSetCharAngle(hps, &grad);
  427.   GpiSetCharBox (hps,&SizeBox);
  428.   GpiSetCharSet (hps,FONT_ID);
  429.   ptl.x = transX(textinfo.x);
  430.   ptl.y = transY(textinfo.y);
  431.   GpiCharStringAt(hps,&ptl,strlen(textinfo.thetext),(PCH)textinfo.thetext);
  432. }
  433.  
  434. void drvMET::drawPoly(int cntPoints, PPOINTL aptlPoints,int closed) {
  435.   POLYGON polygon;
  436.   LONG ptsFollow, width;
  437.  
  438.   if (pDrvMETsetup->draw_noGraphic) return;
  439.   setColor(currentR(),currentG(),currentB());
  440.   if (!cntPoints) {        // transfer from pNumbers
  441.     if (DosAllocMem((PVOID *) &aptlPoints,
  442.             (LONG)8*numberOfElementsInPath(), // ((points *2)= coords) *4= Bytes
  443.             PAG_READ | PAG_WRITE | PAG_COMMIT))
  444.       outf << "ERROR: Can't alloc memory for point-array" << endl;
  445.     ptsFollow = get_print_coords( aptlPoints)-1;
  446.   } else
  447.     ptsFollow = cntPoints -1;
  448.   polygon.ulPoints = ptsFollow;
  449.   polygon.aPointl = &aptlPoints[1];
  450.   int filled = (currentShowType()==fill) || (currentShowType()==eofill);
  451.   if (filled && (!pDrvMETsetup->draw_noFill) && (ptsFollow>1) ) {
  452.     if (GPI_ERROR==GpiMove(hps,&aptlPoints[0]))
  453.       outf << "ERROR: GpiMove: " << aptlPoints[0].x << "," << aptlPoints[0].y << endl;
  454.     if (GPI_ERROR==GpiPolygons(hps,1,&polygon, POLYGON_BOUNDARY |
  455.                    ((currentShowType()==fill) ? POLYGON_WINDING : POLYGON_ALTERNATE),
  456.                    POLYGON_INCL)) {
  457.       outf << "ERROR: GpiPolygons: " << endl;
  458.       for(int i=0; i < ptsFollow; i++)
  459.     outf << aptlPoints[i+1].x << "," << aptlPoints[i+1].y << endl;
  460.     }
  461.   }
  462.   else {
  463.     if (!pDrvMETsetup->draw_noPath) {
  464.       width = (int)(((float)currentLineWidth())*2.0*scale);
  465.       if (GPI_ERROR==GpiSetLineWidthGeom(hps, width))
  466.     outf << "ERROR: GpiSetLineWidthGeom: " << width << endl;
  467.       if (GPI_ERROR==GpiBeginPath(hps,1L))
  468.     outf << "ERROR: GpiBeginPath" << endl;
  469.     }
  470.     if (GPI_ERROR==GpiMove(hps,&aptlPoints[0]))
  471.       outf << "ERROR: GpiMove: " << aptlPoints[0].x << "," << aptlPoints[0].y << endl;
  472.     if (GPI_ERROR==GpiPolyLine(hps,ptsFollow,&aptlPoints[1])) {
  473.       outf << "ERROR: GpiPolyLine: " << endl;
  474.       for(int i=0; i < ptsFollow; i++)
  475.     outf << aptlPoints[i+1].x << "," << aptlPoints[i+1].y << endl;
  476.     }
  477.     if (closed)
  478.       if (GPI_ERROR==GpiLine(hps,&aptlPoints[0]))     // and close it
  479.     outf << "ERROR: GpiLine: " << aptlPoints[0].x << "," << aptlPoints[0].y << endl;
  480.     if (!pDrvMETsetup->draw_noPath) {
  481.       if (GPI_ERROR==GpiEndPath(hps))
  482.     outf << "ERROR: GpiBeginPath" << endl;
  483.       if (GPI_ERROR==GpiSetLineJoin(hps,LINEJOIN_MITRE))
  484.     outf << "ERROR: GpiSetLineJoin" << endl;
  485.       if (GPI_ERROR==GpiSetLineEnd(hps,LINEEND_FLAT))
  486.     outf << "ERROR: GpiSetLineEnd" << endl;
  487.       if (GPI_ERROR==GpiStrokePath(hps,1L,0L))
  488.     outf << "ERROR: GpiStrokePath" << endl;
  489.     }
  490.   }
  491.   if (!cntPoints) DosFreeMem((PVOID)aptlPoints);
  492. }
  493.  
  494. void drvMET::show_path() {
  495.   PPOINTL aptlPoints = NULL;
  496.  
  497.   if (pDrvMETsetup->info) outf << "Path-ShowType: " << currentShowType() << endl;
  498.   drawPoly(READ_pNumers, aptlPoints, (isPolygon() ? DRAW_CLOSED : DRAW_OPEN));
  499. };
  500.  
  501. void drvMET::show_rectangle(const float llx, const float lly, const float urx, const float ury) {
  502.   POINTL Points[4];
  503.  
  504.   Points[0].x = transX(llx);Points[0].y = transY(lly);
  505.   Points[1].x = transX(urx);Points[1].y = transY(lly);
  506.   Points[2].x = transX(urx);Points[2].y = transY(ury);
  507.   Points[3].x = transX(llx);Points[3].y = transY(ury);
  508.   if (pDrvMETsetup->info) outf << "Rectangle-ShowType: " << currentShowType() << endl;
  509.   drawPoly(4L, &Points[0], DRAW_CLOSED);
  510. }
  511.  
  512. ofstream os2win_outStream;
  513.  
  514. #ifndef __GNUG__
  515. extern "OPTLINK" {
  516. #endif
  517.  
  518. void OS2WIN_WM_COMMAND_THREAD(void *hwnd) {
  519.  
  520.   drvbase * outputdriver;
  521.  
  522.   outputdriver = new drvMET(0,os2win_outStream);
  523.   outputdriver->run(0);
  524.   delete outputdriver;
  525.   if (pDrvMETsetup->draw_target != DRVMETSETUP::to_WINDOW)
  526.     WinPostMsg( (HWND)hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  527.   _endthread();
  528. }
  529. #ifndef __GNUG__
  530. }
  531. #endif
  532.  
  533. MRESULT EXPENTRY OS2WIN_WinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  534.  
  535.   static int thread_id;
  536.  
  537.   switch( msg )
  538.     {
  539.     case WM_CREATE:
  540.       {
  541.     WinPostMsg( hwnd, WM_COMMAND, (MPARAM)0,(MPARAM)0 );
  542.     break;
  543.       }
  544.     case WM_COMMAND: {
  545.     thread_id = _beginthread(OS2WIN_WM_COMMAND_THREAD,NULL,32768,(void *)hwnd);
  546.       if ( thread_id < 0)
  547.     DosBeep(2000,2000);
  548.       break;
  549.     }
  550.     case WM_CLOSE:
  551.       WinPostMsg( hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  552.       break;
  553.     case WM_DESTROY:
  554.       DosWaitThread((PTID)&thread_id, DCWW_WAIT);
  555.       break;
  556.     default:
  557.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  558.     }
  559.   return (MRESULT)FALSE;
  560. }
  561.  
  562. void OS2WIN::abort(HWND hwndFrame, HWND hwndClient) {
  563.  
  564.   PERRINFO  pErrInfoBlk;
  565.   PSZ       pszOffSet;
  566.   PSZ       pszErrMsg;
  567.   void      stdprint(void);
  568.  
  569.   DosBeep(1000,1000);
  570.   if ((pErrInfoBlk = WinGetErrorInfo(hab)) != (PERRINFO)NULL)
  571.     {
  572.       pszOffSet = ((PSZ)pErrInfoBlk) + pErrInfoBlk->offaoffszMsg;
  573.       pszErrMsg = ((PSZ)pErrInfoBlk) + *((PSHORT)pszOffSet);
  574.       if((INT)hwndFrame && (INT)hwndClient)
  575.     WinMessageBox(HWND_DESKTOP,hwndFrame,(PSZ)pszErrMsg,
  576.               (PXCHAR)"Error from PS2MET",
  577.               MSGBOXID,MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL );
  578.       WinFreeErrorInfo(pErrInfoBlk);
  579.     }
  580.   WinPostMsg(hwndClient, WM_QUIT, (MPARAM)NULL, (MPARAM)NULL);
  581. }
  582.  
  583. OS2WIN::OS2WIN() {
  584.  
  585.   ULONG flCreate;
  586.  
  587.   os2win_outStream.open("drvMET.out");    // used only for errors & warnings
  588.   if (os2win_outStream.fail() ) {
  589.     errf << "Could not open file " << "drvMET.out" << " for output" << endl;
  590.     exit(1);
  591.   }
  592.  
  593.   if ((hab = WinInitialize(0)) == 0L)
  594.     abort(hwndFrame, hwndClient);
  595.   if ((hmq = WinCreateMsgQueue( hab, 0 )) == 0L)
  596.     abort(hwndFrame, hwndClient);
  597.   if (!WinRegisterClass(hab,(PSZ)"PS2MET-Window",(PFNWP)OS2WIN_WinProc,
  598.             CS_SIZEREDRAW,0))
  599.     abort(hwndFrame, hwndClient);
  600.   flCreate =     FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | // FCF_SHELLPOSITION |
  601.     FCF_TASKLIST ;
  602.   long visible = ((pDrvMETsetup->draw_target == DRVMETSETUP::to_WINDOW)?WS_VISIBLE:0L);
  603.   if ((hwndFrame = WinCreateStdWindow(HWND_DESKTOP,visible,&flCreate,
  604.                       (PXCHAR)"PS2MET-Window",(PXCHAR)"PS to MET Converter", visible,
  605.                       (HMODULE)0L, ID_WINDOW, &hwndClient )) == 0L)
  606.     abort(hwndFrame, hwndClient);
  607.  
  608.   if (pDrvMETsetup->draw_target == DRVMETSETUP::to_WINDOW) {
  609.     RECTL rect;
  610.     WinQueryWindowRect(HWND_DESKTOP, &rect);
  611.     WinSetWindowPos( hwndFrame, HWND_TOP, rect.xLeft+15, rect.yBottom+15,
  612.              rect.xRight-30,rect.yTop-30,
  613.              SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW );
  614.   }
  615. }
  616.  
  617. OS2WIN::~OS2WIN() {
  618.  
  619.   WinDestroyWindow(hwndFrame);
  620.   WinDestroyMsgQueue( hmq );
  621.   WinTerminate( hab );
  622.   os2win_outStream.close();
  623. }
  624.  
  625. void OS2WIN::run() {
  626.  
  627.   while( WinGetMsg( hab, &qmsg, 0L, 0, 0 ) )
  628.     WinDispatchMsg( hab, &qmsg );
  629. }
  630.  
  631. DRVMETSETUP::DRVMETSETUP(char* optstring) {
  632.  
  633.   draw_target = to_META;
  634.   draw_noPath = false;
  635.   draw_noFill = false;
  636.   draw_noColor = false;
  637.   draw_noText = false;
  638.   draw_noGraphic = false;
  639.   info = false;
  640.   exit = false;
  641.   if (optstring) {
  642.     while (*(optstring) != '\0') {
  643.       if (*optstring =='w') {
  644.     draw_target = to_WINDOW;
  645.       } else if (*optstring =='p') {
  646.     draw_noPath = true;
  647.       } else if (*optstring =='l') {
  648.     draw_noFill = true;
  649.       } else if (*optstring =='c') {
  650.     draw_noColor = true;
  651.       } else if (*optstring =='t') {
  652.     draw_noText = true;
  653.       } else if (*optstring =='g') {
  654.     draw_noGraphic = true;
  655.       } else if (*optstring =='v') {
  656.     info = true;
  657.       } else if ((*optstring =='?') || (*optstring =='h')) {
  658.     exit = true;
  659.       } else if (*optstring !=' ') {
  660.     exit = true;
  661.     errf << "unknown option: " << *optstring << endl;
  662.     errf << endl;
  663.       }
  664.       optstring++;
  665.     }
  666.     if (exit) {
  667.       errf << "Metafile-Backend for pstoedit, (C) 1996 by Christoph Jaeschke" << endl;
  668.       errf << "email: jaeschke@item.uni-bremen.de" << endl;
  669.       errf << "-w    Draw into an opened window instead of a metafile" << endl;
  670.       errf << "-p    Draw no geometric linewidths, all lines with width 0" << endl;
  671.       errf << "-l    No filling of polygon interiors" << endl;
  672.       errf << "-c    No colors, only greyscales" << endl;
  673.       errf << "-t    Draw no text" << endl;
  674.       errf << "-g    Draw no graphics" << endl;
  675.       errf << "-v    Verbose infos in drvMET.out" << endl;
  676.     }
  677.   }
  678. }
  679.  
  680. #endif
  681.