コード例 #1
0
ファイル: printer.cpp プロジェクト: Gerardwx/Yzis
void YZPrinter::doPrint( )
{
    const double fontsize = 10.0;
    PSDoc *doc = PS_new();
    if (!doc)
        return ;
    QByteArray p = m_path.toLatin1();
    PS_open_file(doc, p.data());
    PS_set_info(doc, "Creator", "Yzis");
    PS_set_info(doc, "Author", "");
    PS_set_info(doc, "Title", p.data());
    // Set so it'll fit on both A4 and letter paper;
    // some of us live in the US, with archaic paper sizes. ;-)
    PS_set_info(doc, "BoundingBox", "0 0 596 792");
    int font;
    font = PS_findfont(doc, "Fixed", "", 0);
    dbg() << "findfont returned " << font << endl;
    if ( !font ) return ; //no font => abort

    QPrinter lpr(QPrinter::PrinterResolution);
    QPainter p( &lpr );

    QFont f( "fixed" );
    f.setFixedPitch( true );
    f.setStyleHint( QFont::TypeWriter );
    p.setFont( f );

    unsigned int height = lpr.height();
    unsigned int width = lpr.width();

    unsigned int linespace = p.fontMetrics().lineSpacing();
    unsigned int maxwidth = p.fontMetrics().maxWidth();

    p.end();

    PS_set_value(doc, "leading", linespace);

    unsigned int clipw = width / maxwidth - 1;
    unsigned int cliph = height / linespace - 1;

    unsigned int oldLinesVis = mView->getLinesVisible( );
    unsigned int oldColumnsVis = mView->getColumnsVisible( );

    //should be current's view setting no ? XXX
    bool number = mView->getLocalBooleanOption( "number" );
    unsigned int marginLeft = 0;

    double red, green, blue;

    if ( number ) {
        marginLeft = ( 2 + QString::number( mView->buffer()->lineCount() ).length() );
    }

    YOptionValue* ov_wrap = mView->getLocalOption( "wrap" );
    bool oldWrap = ov_wrap->boolean();
    ov_wrap->setBoolean( true );

    mView->setVisibleArea( clipw - marginLeft, cliph, false );
    unsigned int totalHeight = mView->drawTotalHeight();
    mView->setVisibleArea( clipw - marginLeft, totalHeight, false );
    mView->initDraw( 0, 0, 0, 0 );

    unsigned int lastLineNumber = 0;
    unsigned int pageNumber = 0;

    QRect titleRect( 0, 0, width, linespace + linespace / 2 );

    unsigned int topY = titleRect.height() + linespace;
    unsigned int curY = topY;
    unsigned int curX;

    cliph = ( height - topY ) / linespace;
    int nbPages = totalHeight / cliph + ( totalHeight % cliph ? 1 : 0 );
    PS_begin_page(doc, 596, 792);
    PS_setfont(doc, font, fontsize);
    PS_set_parameter(doc, "hyphenation", "false");
    PS_set_parameter(doc, "linebreak", "true");
    PS_set_parameter(doc, "parbreak", "false");
    PS_set_value(doc, "parindent", 0.0);
    PS_set_value(doc, "numindentlines", 0.0);

    while ( mView->drawNextLine( ) ) {
        if ( curY == topY ) {
            if ( pageNumber ) {
                PS_end_page(doc);
                PS_begin_page(doc, 596, 792);
                PS_setfont(doc, font, fontsize);
                PS_set_value(doc, "leading", linespace);
            }
            ++pageNumber;
            convertColor(Qt::black, red, green, blue);
            PS_setcolor(doc, "fillstroke", "rgb", red, green, blue, 0.0);
            QByteArray n = ( ' ' + mView->buffer()->fileName() ).toLatin1();
            PS_show_boxed(doc, n.data(),
                          titleRect.x(), titleRect.y(), titleRect.width(),
                          titleRect.height(), "left", "");
            QByteArray nb = ( QString::number( pageNumber ) + '/' + QString::number( nbPages ) + ' ' ).toLatin1();
            PS_show_boxed(doc,
                          nb.data(),
                          titleRect.x(), titleRect.y(), titleRect.width(),
                          titleRect.height(), "right", "");
        }
        if ( number ) {
            unsigned int lineNumber = mView->drawLineNumber();
            if ( lineNumber != lastLineNumber ) {
                //p.setPen( Qt::gray );
                convertColor(Qt::gray, red, green, blue);
                PS_setcolor(doc, "fillstroke", "rgb", red, green, blue, 0.0);
                PS_moveto(doc, 0, curY);
                QByteArray m = QString::number( lineNumber ).rightJustified( marginLeft - 1, ' ' ).toLatin1();
                PS_show(doc, m.data());
                lastLineNumber = lineNumber;
            }
        }
        curX = marginLeft * maxwidth;
        while ( mView->drawNextCol( ) ) {
            QColor c = mView->drawColor( );
            if ( c.isValid() && c != Qt::white )
                convertColor(mView->drawColor(), red, green, blue);
            else
                convertColor(Qt::black, red, green, blue);
            PS_setcolor(doc, "fillstroke", "rgb", red, green, blue, 0.0);
            char buf[2] = {
                              0, 0
                          };
            buf[0] = mView->drawChar().toLatin1();
            PS_show_xy(doc, buf, curX, curY);
            curX += mView->drawLength( ) * maxwidth;
        }
        curY += linespace * mView->drawHeight();
        if ( curY >= cliph * linespace + topY ) {
            // draw Rect
            convertColor(Qt::black, red, green, blue);
            PS_setcolor(doc, "fillstroke", "rgb", red, green, blue, 0.0);
            PS_rect(doc, 0, 0, width, curY);
            if ( number ) {
                PS_moveto(doc, marginLeft*maxwidth - maxwidth / 2, titleRect.height());
                PS_lineto(doc, marginLeft*maxwidth - maxwidth / 2, curY);
            }
            PS_moveto(doc, titleRect.x(), titleRect.height());
            PS_lineto(doc, titleRect.width(), titleRect.height());
            curY = topY;
        }
    }
    if ( curY != topY ) {
        // draw Rect
        convertColor(Qt::black, red, green, blue);
        PS_setcolor(doc, "fillstroke", "rgb", red, green, blue, 0.0);
        PS_rect(doc, 0, 0, width, curY);
        if ( number ) {
            PS_moveto(doc, marginLeft*maxwidth - maxwidth / 2, titleRect.height());
            PS_lineto(doc, marginLeft*maxwidth - maxwidth / 2, curY);
        }
        PS_moveto(doc, titleRect.x(), titleRect.height());
        PS_lineto(doc, titleRect.width(), titleRect.height());
    }
    PS_end_page(doc);
    PS_deletefont(doc, font);
    PS_close(doc);
    PS_delete(doc);
    PS_shutdown();

    ov_wrap->setBoolean( oldWrap );
    mView->setVisibleArea( oldColumnsVis, oldLinesVis, false );
}
コード例 #2
0
ファイル: deviceps.hpp プロジェクト: vedraiyani/GDL
  void pslibHacks()
  {
#  ifndef USE_PSLIB
    Warning("Warning: pslib support is mandatory for the PostScript driver to handle the following");
    Warning("         keywords:  [X,Y]OFFSET, SCALE_FACTOR, ENCAPSULATED");
#  else
    PSDoc *ps = PS_new(); 
    GDLGuard<PSDoc> psGuard( ps, PS_delete);
    
    if (ps == NULL)
    {
      Warning("Warning: pslib failed to allocate memory.");
      return;
    }
    
    FILE *fp = tmpfile(); // this creates a file which should be deleted automaticaly when it is closed
    FILEGuard fpGuard( fp, fclose);
    
    if (fp == NULL) 
    {
      Warning("Warning: failed to create temporary PostScript file.");
//       PS_delete(ps);
      return;
    }
    if (PS_open_fp(ps, fp) == -1) 
    { 
      Warning("Warning: pslib failed to open a new PostScript file.");
      goto cleanup;
    }
    
    PS_set_parameter(ps, "imagereuse", "false");
    PS_set_info(ps, "Title", "Graphics produced by GDL"); 
    PS_set_info(ps, "Orientation", orient_portrait ? "Portrait" : "Landscape"); 
    {
      struct utsname uts;
      uname(&uts);
      string tmp;
      tmp = "GDL Version " + string(VERSION) + ", " + string(uts.sysname) + " " + string(uts.machine);
      PS_set_info(ps, "Creator", tmp.c_str()); 
      char* login = getlogin();
      if (login == NULL) Warning("Warning: getlogin() failed!");
      tmp = (login == NULL ? "?" : login) + string("@") + uts.nodename;
      PS_set_info(ps, "Author", tmp.c_str());
    }
    //bug: PSLIB does not return the correct boundingbox, it forgets offx and offy. Try to get it
    //back (using pslib own code!)!
        char *bb;
        FILE *feps;
        char buffer[1024]; //largely sufficient
        int nbytes;
        feps=fopen(fileName.c_str(), "r");
        nbytes=fread(buffer,sizeof(char),1023,feps);
        fclose(feps);
        buffer[1023]=0;
	bb = strstr(buffer, "%%BoundingBox:");
        float offx, offy, width, height;
	if(bb) {
            bb += 15;
            sscanf(bb, "%f %f %f %f", &offx, &offy, &width, &height);
	} else {
            offx=0;
            offy=0;
            width=500;
            height=500; //silly values, will be replaced afterwards hopefully.
        }

    // TODO
    //psfont = PS_findfont(ps, "Helvetica", "", 0); 
    //PS_setfont(ps, psfont, 8.0); 

      char bbstr [20], offstr [20];
      int bbXSize, bbYSize;
    {

      int bbXoff = XOffset*cm2in*dpi;
      int bbYoff = YOffset*cm2in*dpi;
      bbXSize = orient_portrait ? bbXoff + XPageSize*cm2in*dpi*scale : bbXoff + YPageSize*cm2in*dpi*scale;
      bbYSize = orient_portrait ? bbYoff + YPageSize*cm2in*dpi*scale : bbYoff + XPageSize*cm2in*dpi*scale;
      sprintf(bbstr,"%i %i %i %i",bbXoff,bbYoff,bbXSize,bbYSize);
      sprintf(offstr,"%i %i",bbXoff,bbYoff);
    
      PS_set_info(ps,"BoundingBox",bbstr);
      PS_begin_page(ps, bbXSize, bbYSize);
      {
        int psimage = PS_open_image_file(ps, "eps", fileName.c_str(), NULL, 0);
        if (psimage == 0)
        {
          Warning("Warning: pslib failed to load plPlot output file.");
          goto cleanup;
        }
	
        float scl = 0.98*min((bbXSize-bbXoff) / (width-offx), (bbYSize-bbYoff) / (height-offy) );
	int margx = ((bbXSize-bbXoff) - scl*(width-offx))/2;
	int margy = ((bbYSize-bbYoff) - scl*(height-offy))/2;
        PS_place_image(ps, psimage, 
		       bbXoff-offx*scl + margx,
		       bbYoff-offy*scl + margy,
		       scl
        );
        PS_close_image(ps, psimage); 
      }
      PS_end_page(ps);
      PS_close(ps);
    }
    
    // Replace PageBoundingBox and CropBox and write contents to fileName
    {
      rewind(fp);
      FILE *fp_plplot = fopen(fileName.c_str(), "w");
      FILEGuard fp_plplotGuard( fp_plplot, fclose);
      if (fp_plplot == NULL)
      {
        Warning("Warning: failed to open plPlot-generated file");
        goto cleanup;
      }

      // When multiple pages are supported, PageBoundingBox and the cropbox
      // will appear more than once. Then this section will need to be redone.

      // Edit: change the two 0's after the PageBoundingBox
      string pbstr=string("%%PageBoundingBox: ")+offstr;
      // edits will be in the first 12288 bytes; add the length of offstr-3
      const size_t buflen=12288 + pbstr.length()-22;
      //const size_t buflen=4096;
      char buff[buflen];

      //do the first read:
      size_t cnt = fread(&buff, 1, 12288, fp);
      string sbuff;
      sbuff = string(buff);

      // find the PageBoundingBox statement
      size_t pos = sbuff.find("%%PageBoundingBox: 0 0");
      if (pos != string::npos) {
	sbuff.replace(pos,22,pbstr); // will change the size of sbuff by offstr-3
	cnt = cnt + pbstr.length()-22;
      }

      // PSlib outputs pdfmarks which resize the PDF to the size of the boundingbox
      // this is nice, but not IDL behaviour (and anyway, the two 0's are wrong)
      char mychar[60];
      sprintf(mychar,"[ /CropBox [0 0 %i.00 %i.00] /PAGE pdfmark",bbXSize,bbYSize);
      string pdfstr=string(mychar); 
      string pdfrepl(pdfstr.length(),' ');
      pos = sbuff.find(pdfstr);
      if (pos != string::npos) {sbuff.replace(pos,pdfstr.length(),pdfrepl);} // will not change size of sbuff

      // write the first buflen to file
      strcpy(buff,sbuff.c_str());
      if (fwrite(&buff, 1, buflen, fp_plplot) < buflen)
        {
          Warning("Warning: failed to overwrite the plPlot-generated file with pslib output");
        }

      // read the rest of fp and write to file
      while (true)
      {
       cnt = fread(&buff, 1, buflen, fp);
         if (!cnt) break;
        if (fwrite(&buff, 1, cnt, fp_plplot) < cnt)
        {
          Warning("Warning: failed to overwrite the plPlot-generated file with pslib output");
        }
      }
//       fclose(fp_plplot);
    }

    cleanup:
//    PS_delete(ps);
//     fclose(fp); // this deletes the temporary file as well
    // PSlib changes locale - bug no. 3428043
#    ifdef HAVE_LOCALE_H
    setlocale(LC_ALL, "C");
#    endif
#  endif
  }