427 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			427 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						||
#include <image.h>
 | 
						||
#include <printer.h>                  
 | 
						||
#include <printwin.h>                  
 | 
						||
 | 
						||
HIDDEN int LEN_SPACES(WINDOW win, int x)
 | 
						||
{
 | 
						||
  HIDDEN int w = 0L;
 | 
						||
 | 
						||
  const int columns = 132;
 | 
						||
  if (x < 0)
 | 
						||
  {
 | 
						||
    x = columns;
 | 
						||
    w = 0L;
 | 
						||
  }
 | 
						||
  if (w == 0L)
 | 
						||
  {                                    
 | 
						||
    TString256 spc; spc.fill('m', columns);
 | 
						||
    w = xvt_dwin_get_text_width(win, spc.get_buffer(), columns);
 | 
						||
  }
 | 
						||
  const int tab = w * x / columns;
 | 
						||
  return tab;
 | 
						||
}
 | 
						||
 | 
						||
void TPrintwin::paint_background(long j)
 | 
						||
{
 | 
						||
  const bool isbackground = _bg->items() > 0 && printer().isgraphics();
 | 
						||
  const bool fink_mode = printer().get_fink_mode();
 | 
						||
  int rw = (int)(j % _formlen);
 | 
						||
  int cnt = 0; char ch;  
 | 
						||
  
 | 
						||
  char curcol  = 'n';
 | 
						||
  char curpen  = 'n';
 | 
						||
  char curpat  = 'n';
 | 
						||
  char curwid  = '1';
 | 
						||
 | 
						||
  unsigned int x1, y1, x2, y2, id;  
 | 
						||
  PNT b, e;
 | 
						||
 | 
						||
  if (!fink_mode)
 | 
						||
  {        
 | 
						||
    const char* line = printer().background_chars(rw);
 | 
						||
    set_color (COLOR_BLACK, COLOR_WHITE);
 | 
						||
    xvt_dwin_draw_text(win(), _hofs , (rw*_chary + _chary - _descent + _vofs), (char*)line, -1);                           
 | 
						||
    // return;
 | 
						||
  }
 | 
						||
  if (!isbackground) return;     
 | 
						||
 | 
						||
  TString& rwd = (TString&)(*_bg)[rw];  
 | 
						||
 | 
						||
  while ((ch = rwd[cnt++]))
 | 
						||
  {           
 | 
						||
    if (!fink_mode && (ch == 'v' || ch == 'o' || ch == 'u' || ch == 'h' || ch == 'r'))
 | 
						||
      continue;
 | 
						||
    switch(ch)
 | 
						||
    {
 | 
						||
    case 'v':  // verticale intera
 | 
						||
      x1  = (byte)rwd[cnt++]-1;
 | 
						||
      b.h = e.h = LEN_SPACES(win(), x1)+LEN_SPACES(win(), 1)/2+_hofs;
 | 
						||
      b.v = rw * _chary + _vofs; e.v = (rw+1) * _chary + _vofs;
 | 
						||
      xvt_dwin_draw_set_pos(win(),b);
 | 
						||
      xvt_dwin_draw_line(win(),e);
 | 
						||
      break;   
 | 
						||
    case 'o':  // verticale pezzo sopra
 | 
						||
      x1  = (byte)rwd[cnt++]-1;
 | 
						||
      b.h = e.h = LEN_SPACES(win(), x1)+LEN_SPACES(win(), 1)/2 + _hofs;
 | 
						||
      b.v = rw * _chary + _vofs; e.v = rw * _chary + _chary/2 + _vofs; 
 | 
						||
      xvt_dwin_draw_set_pos(win(),b);                 
 | 
						||
      xvt_dwin_draw_line(win(),e); 
 | 
						||
      break;   
 | 
						||
    case 'u':  // verticale pezzo sotto
 | 
						||
      x1 = (byte)rwd[cnt++]-1;
 | 
						||
      b.h = e.h = LEN_SPACES(win(), x1)+LEN_SPACES(win(), 1)/2 + _hofs;
 | 
						||
      b.v = rw*_chary + _chary/2 + _vofs; e.v = (rw+1) * _chary + _vofs; 
 | 
						||
      xvt_dwin_draw_set_pos(win(),b);                          
 | 
						||
      xvt_dwin_draw_line(win(),e); 
 | 
						||
      break;   
 | 
						||
    case 'h':  // orizzontale intera
 | 
						||
      x1 = (byte)rwd[cnt++]-1;
 | 
						||
      x2 = (byte)rwd[cnt++]-1;  
 | 
						||
      b.v = e.v = rw*_chary + _chary/2 + _vofs;
 | 
						||
      b.h = LEN_SPACES(win(), x1)+_hofs; e.h = LEN_SPACES(win(), x2)+_hofs;
 | 
						||
      xvt_dwin_draw_set_pos(win(),b);
 | 
						||
      xvt_dwin_draw_line(win(),e); 
 | 
						||
      break;   
 | 
						||
    case 'r':  // orizzontale scorciata agli estremi
 | 
						||
      x1 = (byte)rwd[cnt++]-1;
 | 
						||
      x2 = (byte)rwd[cnt++]-1;
 | 
						||
      b.v = e.v = rw*_chary + _chary/2 + _vofs;
 | 
						||
      b.h = LEN_SPACES(win(), x1)+LEN_SPACES(win(), 1)/2 + _hofs; 
 | 
						||
      e.h = LEN_SPACES(win(), x2)+LEN_SPACES(win(), 1)/2+_hofs;
 | 
						||
      xvt_dwin_draw_set_pos(win(),b);
 | 
						||
      xvt_dwin_draw_line(win(),e); 
 | 
						||
      break;       
 | 
						||
    case 'i':
 | 
						||
      id = (byte)(rwd[cnt++])-1;   // Numero immagine
 | 
						||
      y1 = (byte)(rwd[cnt++])-1;   // Riga sorgente
 | 
						||
      x1 = (byte)(rwd[cnt++])-1;   // Colonna sorgente
 | 
						||
      x2 = (byte)(rwd[cnt++]);     // Larghezza destinazione (in caratteri)
 | 
						||
      y2 = (byte)(rwd[cnt++]);     // Altezza destinazione (in caratteri)
 | 
						||
      if (id >= 0)
 | 
						||
      {     
 | 
						||
#ifndef XVAGA
 | 
						||
        // Ai tempi non veniva in mente un modo peggiore 
 | 
						||
        const short width = LEN_SPACES(win(), x2); // Larghezza in pixel
 | 
						||
        
 | 
						||
        TImage* i = (TImage*)_images.objptr(id);
 | 
						||
        if (i == NULL)
 | 
						||
        {
 | 
						||
          const TString_array& a = printer().image_names();
 | 
						||
          const TImage src(a.row(id));
 | 
						||
          if (src.ok())
 | 
						||
          {
 | 
						||
						// memorizzo l'immagine in risoluzione di stampa!  Visto che ho RAM da buttare.
 | 
						||
            i = new TImage(src, width, _chary*y2); 
 | 
						||
            _images.add(i, id);
 | 
						||
          }
 | 
						||
        }  
 | 
						||
        
 | 
						||
        if (i && i->ok())
 | 
						||
        {     
 | 
						||
          RCT src; xvt_rect_set(&src, 0, int(_chary*y1), 
 | 
						||
                                width, min(int(_chary*(y1+1)), i->height()));
 | 
						||
          if (src.top < i->height())
 | 
						||
          {
 | 
						||
            PNT p;                                                              
 | 
						||
            p.h = LEN_SPACES(win(), x1) + _hofs; 
 | 
						||
            p.v = _chary*rw + _vofs;
 | 
						||
            RCT dst = src; xvt_rect_set_pos(&dst, p);
 | 
						||
            i->draw(win(), dst, src);
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
#else
 | 
						||
				if (y1 == 0) // Disegno solo una volta per tutte alla prima fetta!
 | 
						||
				{   
 | 
						||
					TImage* i = (TImage*)_images.objptr(id);
 | 
						||
          if (i == NULL)
 | 
						||
					{
 | 
						||
						// memorizzo l'immagine cos<6F> com'<27> alla risoluzione originale!
 | 
						||
						const TString_array& a = printer().image_names();
 | 
						||
						i = new TImage(a.row(id));   
 | 
						||
						_images.add(i, id);
 | 
						||
					}
 | 
						||
          if (i != NULL && i->ok())
 | 
						||
					{
 | 
						||
 						RCT dst;
 | 
						||
						dst.left = LEN_SPACES(win(), x1) + _hofs;
 | 
						||
  					dst.top  = _chary*rw + _vofs;
 | 
						||
	  				dst.right = dst.left + LEN_SPACES(win(), x2);
 | 
						||
						dst.bottom = dst.top + _chary*y2;
 | 
						||
						i->draw(win(), dst);
 | 
						||
					}
 | 
						||
				}
 | 
						||
#endif
 | 
						||
      }  
 | 
						||
      break;
 | 
						||
    case 'W':
 | 
						||
      curwid = rwd[cnt++];
 | 
						||
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
 | 
						||
              trans_pen(curpen));
 | 
						||
      break;
 | 
						||
    case 'P':
 | 
						||
      curpen = rwd[cnt++];
 | 
						||
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
 | 
						||
              trans_pen(curpen));
 | 
						||
      break;
 | 
						||
    case 'B':
 | 
						||
      curpat = rwd[cnt++];
 | 
						||
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
 | 
						||
              trans_pen(curpen));
 | 
						||
      break;
 | 
						||
    case 'C':
 | 
						||
      curcol = rwd[cnt++];
 | 
						||
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
 | 
						||
              trans_pen(curpen));
 | 
						||
      break;
 | 
						||
    default:
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }                    
 | 
						||
  // restore default pen
 | 
						||
  set_pen(COLOR_BLACK);
 | 
						||
} 
 | 
						||
 | 
						||
void TPrintwin::paint_image(int row, const char* cp)
 | 
						||
{
 | 
						||
  TToken_string tok(cp+2, ',');
 | 
						||
  TImage img(tok.get(0));
 | 
						||
                       
 | 
						||
  const int x = _hofs + LEN_SPACES(win(), tok.get_int()-1);
 | 
						||
  const int y = _vofs + row * _chary;
 | 
						||
 | 
						||
  int dx = LEN_SPACES(win(), tok.get_int(3)-tok.get_int(1)+1);
 | 
						||
  int dy = _chary * (tok.get_int(4)-tok.get_int(2)+1);
 | 
						||
  if (img.ok())
 | 
						||
  {
 | 
						||
    const double ratiox = double(img.width()) / dx;
 | 
						||
    const double ratioy = double(img.height()) / dy;
 | 
						||
    const double ratio = ratiox > ratioy ? ratiox : ratioy;
 | 
						||
    dx = int(img.width() / ratio);
 | 
						||
    dy = int(img.height() / ratio);
 | 
						||
    RCT dst; xvt_rect_set(&dst, x, y, x+dx, y+dy);
 | 
						||
    img.draw(win(), dst);
 | 
						||
  }  
 | 
						||
  else
 | 
						||
  { 
 | 
						||
    RCT dst; xvt_rect_set(&dst, x, y, x+dx, y+dy);
 | 
						||
    set_pen(COLOR_RED);
 | 
						||
    xvt_dwin_draw_rect(win(), &dst);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPrintwin::paint_row(long j)
 | 
						||
{
 | 
						||
  const int row = (int)(j % _formlen);
 | 
						||
  const int y = row*_chary + _chary - _descent + ((_chary == 1) ? 0 : _vofs);
 | 
						||
  
 | 
						||
  paint_background(j);
 | 
						||
 | 
						||
  if (_chary > 1)
 | 
						||
  {  
 | 
						||
    _txt.read_line(j);
 | 
						||
    
 | 
						||
    int pos = 0;
 | 
						||
    
 | 
						||
    const char* cp;
 | 
						||
    while((cp = _txt.piece()) != NULL) 
 | 
						||
    {     
 | 
						||
      const int st = _txt.get_style();
 | 
						||
      const COLOR bg = trans_color(_txt.get_background());
 | 
						||
      const COLOR fg = trans_color(_txt.get_foreground());
 | 
						||
      set_color(fg, bg);
 | 
						||
      
 | 
						||
      if (bg != fg)  // Testo vero
 | 
						||
      {
 | 
						||
        set_color(fg, bg);
 | 
						||
        set_font(printer().fontname(), st, _char_size);
 | 
						||
        
 | 
						||
        const char* beg = cp;                    
 | 
						||
        while (*beg)
 | 
						||
        {                            
 | 
						||
          for (; *beg == ' '; beg++)               // Salta spazi iniziali
 | 
						||
            pos++;      
 | 
						||
          
 | 
						||
          if (*beg)
 | 
						||
          {  
 | 
						||
            int len = 0;
 | 
						||
            const char * end;
 | 
						||
            for (end = beg; *end && (*end != ' ' || *(end+1) != ' '); end++) 
 | 
						||
              len++;                                 // Misura stringa da stampare
 | 
						||
            xvt_dwin_draw_text(win(), _hofs + LEN_SPACES(win(), pos), y, (char*)beg, len);                           
 | 
						||
            pos += len;                   
 | 
						||
            beg = end;
 | 
						||
          }
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      else // Testo trasparente (elementi grafici aggiuntivi)
 | 
						||
      {
 | 
						||
        if (*cp == 'i')
 | 
						||
          paint_image(row, cp);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
  } 
 | 
						||
  else
 | 
						||
  {                                           
 | 
						||
    set_font(printer().fontname(), XVT_FS_NONE, _char_size);                 
 | 
						||
#if XVT_OS == XVT_OS_WIN32
 | 
						||
    // Questa e' la patch per TTY.DRV.
 | 
						||
    if (j > 0 && (j % _realformlen) == 0) 
 | 
						||
    {
 | 
						||
      _frlc++;
 | 
						||
      xvt_dwin_draw_text(win(), 0, y  , "", -1);                           
 | 
						||
    }                   
 | 
						||
    else  
 | 
						||
#endif                                      
 | 
						||
      xvt_dwin_draw_text(win(), 0, y, (char*)(const char*)_txt.line(j - _frlc), -1);                           
 | 
						||
  }        
 | 
						||
}                   
 | 
						||
 | 
						||
// @doc INTERNAL
 | 
						||
  
 | 
						||
// @mfunc Permette di stampare un rettangolo a video
 | 
						||
//
 | 
						||
// @rdesc Ritorna se e' riuscito a stampare in una unica pagina
 | 
						||
bool TPrintwin::print_band(
 | 
						||
  int page,     // @parm Numero della pagina da stampare
 | 
						||
  const RCT& r) // @parm Parte di finestra da stampare
 | 
						||
 | 
						||
  // @comm Di solito viene disegnata l'intera pagina, ma la cosa dipende dal driver di stampa
 | 
						||
{
 | 
						||
//  int i,l_ofst = printer().get_line_offset();
 | 
						||
//  const int offset = l_ofst < 0 ? abs(l_ofst) + 1: 0;
 | 
						||
//  const int offset = printer().get_line_offset();
 | 
						||
//  const bool generic = _chary == 1;
 | 
						||
 | 
						||
  const long first_row = (long)page * _formlen;
 | 
						||
  const int rows = (r.bottom - r.top) / _chary;  
 | 
						||
  const int top  = r.top / _chary;    
 | 
						||
  const long lines = _txt.lines() + _frlc;
 | 
						||
  int k;
 | 
						||
 
 | 
						||
  for (k = top; k < top+rows; k++) 
 | 
						||
  {
 | 
						||
    const long row = first_row + k;                
 | 
						||
    if (row < lines && k < _formlen) 
 | 
						||
      paint_row(row);
 | 
						||
    else
 | 
						||
      break;
 | 
						||
  }
 | 
						||
  return (first_row + k < lines);
 | 
						||
}
 | 
						||
 | 
						||
// @doc INTERNAL
 | 
						||
 | 
						||
// @mfunc Inizia la stampa
 | 
						||
//
 | 
						||
// @rdesc Ritorna se viene interrotta la stampa:
 | 
						||
//
 | 
						||
// @flag TRUE | La stampa e' andata a buon fine
 | 
						||
// @flag FALSE | La stampa e' stata interrotta
 | 
						||
bool TPrintwin::do_print(word page_from, word page_to, word copies)
 | 
						||
// @comm Quando possibile parte un processo concorrente (dipende dal sistema operativo)
 | 
						||
{               
 | 
						||
  CHECKD(page_from > 0, "Invalid page start ", page_from);
 | 
						||
  CHECKD(copies > 0, "Invalid number of copies ", copies);
 | 
						||
 | 
						||
  _frlc = 0;            
 | 
						||
  _blank_lines_to_print = 0;
 | 
						||
 | 
						||
  for (word c = 0; c < copies && !_aborted; c++)
 | 
						||
  {
 | 
						||
    bool finished = FALSE;
 | 
						||
    for (word page = page_from-1; !finished && !_aborted; page++)
 | 
						||
    {
 | 
						||
      if (page_to >= page_from && page >= page_to)
 | 
						||
        break;
 | 
						||
 | 
						||
      _aborted = xvt_print_open_page(_printrcd) == 0;                  
 | 
						||
      if (!_aborted)
 | 
						||
      {
 | 
						||
        for (const RCT* rct = xvt_print_get_next_band(); rct != NULL; rct = xvt_print_get_next_band())
 | 
						||
			  {
 | 
						||
				  set_font(XVT_FFN_SYSTEM, XVT_FS_NONE, _char_size); // ???
 | 
						||
				  set_font(printer().fontname(), XVT_FS_NONE, _char_size);                 
 | 
						||
  			  LEN_SPACES(win(), -1);  // Resetta bene le dimensioni font
 | 
						||
				  if (!print_band(page, *rct))
 | 
						||
          {
 | 
						||
            finished = TRUE;
 | 
						||
            while (xvt_print_get_next_band()); // Esce dalla lista delle bande
 | 
						||
            break;
 | 
						||
          }
 | 
						||
			  }
 | 
						||
        _aborted = xvt_print_close_page(_printrcd) == 0; 
 | 
						||
      }
 | 
						||
    }     
 | 
						||
  }
 | 
						||
  
 | 
						||
	return !_aborted;             
 | 
						||
}                                         
 | 
						||
 | 
						||
 | 
						||
TPrintwin::TPrintwin(TTextfile& txt) 
 | 
						||
: _aborted(FALSE), _txt(txt), _inited(FALSE)
 | 
						||
{
 | 
						||
  TPrinter& p = printer();
 | 
						||
 | 
						||
  _printrcd = p.get_printrcd();
 | 
						||
  if (!xvt_print_is_valid(_printrcd))
 | 
						||
  {
 | 
						||
    _aborted = TRUE;
 | 
						||
    return;
 | 
						||
  }
 | 
						||
  
 | 
						||
  WINDOW prwin = xvt_print_create_win(_printrcd, (char*)(const char*)main_app().title());
 | 
						||
  if (prwin == NULL_WIN) 
 | 
						||
  {
 | 
						||
    _aborted = TRUE;
 | 
						||
    return;
 | 
						||
  }
 | 
						||
  set_win(prwin);                                                                    
 | 
						||
  
 | 
						||
  _char_size = p.get_char_size();   
 | 
						||
  set_font(p.fontname(), XVT_FS_NONE, _char_size);           
 | 
						||
  LEN_SPACES(win(), -1);          // force update 
 | 
						||
 
 | 
						||
  _pagelen = p.formlen(); 
 | 
						||
 | 
						||
  p.init_formlen(prwin);       // Calcola offset e altre misure pagina
 | 
						||
  
 | 
						||
  int abs_column=p.get_column_offset();
 | 
						||
  int segno = abs_column>=0 ? 1 : -1;
 | 
						||
  abs_column*=segno;
 | 
						||
  xvt_dwin_get_font_metrics(prwin, &_lead, &_ascent, &_descent);
 | 
						||
  _bg        = &p.getbgdesc();
 | 
						||
  _chary     = p.get_dots_per_line(); 
 | 
						||
  _hofs      = p.get_horz_offset() + segno*LEN_SPACES(prwin,abs_column);
 | 
						||
  _vofs      = p.get_vert_offset() + p.get_line_offset()*_chary;
 | 
						||
               
 | 
						||
  _formlen   = p.formlen();
 | 
						||
  p.formlen(_pagelen);
 | 
						||
  
 | 
						||
  if (p.is_generic())
 | 
						||
  {
 | 
						||
    long pw, ph, phr, pvr; // Printer width, height, horizontal and vertical resolution
 | 
						||
    xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, p.get_printrcd(), &ph, &pw, &pvr, &phr);
 | 
						||
    if (pvr != 0)
 | 
						||
      _realformlen = int(ph * p.get_lines_per_inch() / pvr);
 | 
						||
    else
 | 
						||
      _realformlen = 66;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    _realformlen = 66; // Anche se non e' importante settarlo in altri casi.
 | 
						||
  _formwidth = p.formwidth();
 | 
						||
  _inited = TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TPrintwin::~TPrintwin()
 | 
						||
{
 | 
						||
  if (_inited && win() != NULL_WIN) 
 | 
						||
    xvt_vobj_destroy(win());
 | 
						||
  set_win(NULL_WIN);
 | 
						||
}
 | 
						||
 | 
						||
 |