371 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						|
#include <printer.h>                  
 | 
						|
#include <printwin.h>                  
 | 
						|
#include <xvtility.h>
 | 
						|
 | 
						|
HIDDEN int LEN_SPACES(WINDOW win, int x)
 | 
						|
{
 | 
						|
  HIDDEN long w = 0L;
 | 
						|
  if (x < 0)
 | 
						|
  {
 | 
						|
    x = 80;
 | 
						|
    w = 0L;
 | 
						|
  }  
 | 
						|
  if (w == 0L)
 | 
						|
  {                                    
 | 
						|
    TString256 spc; spc.fill('m', 132);
 | 
						|
    w = xvt_dwin_get_text_width(win,(char*)(const char*)spc, 132);
 | 
						|
  }
 | 
						|
  const int k = int((w*x) / 132);
 | 
						|
  
 | 
						|
#ifdef DBG
 | 
						|
  static bool error_on = TRUE;
 | 
						|
  if (error_on)
 | 
						|
  {
 | 
						|
    TString256 spc; spc.fill('m', x);
 | 
						|
    const int k1 = xvt_dwin_get_text_width(win,(char*)(const char*)spc,x);
 | 
						|
    if (k != k1) 
 | 
						|
      error_on = error_box("Maguire disagrees: %d != %d", k, k1);
 | 
						|
  }  
 | 
						|
#endif
 | 
						|
  
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
void TPrintwin::paint_background(long j)
 | 
						|
{
 | 
						|
  const bool isbackground = _bg->items() > 0 && printer().isgraphics();
 | 
						|
  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 (!printer().isgraphics())
 | 
						|
  {        
 | 
						|
    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++])
 | 
						|
  {           
 | 
						|
    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 destinazione
 | 
						|
      x2 = (byte)(rwd[cnt++]);     // Larghezza destinazione (in caratteri)
 | 
						|
      y2 = (byte)(rwd[cnt++]);     // Altezza destinazione (in caratteri)
 | 
						|
      if (id >= 0)
 | 
						|
      {     
 | 
						|
        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())
 | 
						|
          {
 | 
						|
            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);
 | 
						|
          }  
 | 
						|
        }  
 | 
						|
      }  
 | 
						|
      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_row(long j)
 | 
						|
{
 | 
						|
  const int row = (int)(j % _formlen);
 | 
						|
  const int y = row*_chary + _chary - _descent + _vofs;
 | 
						|
  
 | 
						|
  if (_chary > 1)
 | 
						|
  {  
 | 
						|
    paint_background(j);
 | 
						|
    
 | 
						|
    _txt.read_line(j);
 | 
						|
    
 | 
						|
    int pos = 0;
 | 
						|
    
 | 
						|
    const char* cp;
 | 
						|
    while((cp = _txt.piece()) != NULL) 
 | 
						|
    {     
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
      const int st = _txt.get_style();
 | 
						|
      set_font(printer().fontname(), st, _char_size);                 
 | 
						|
      
 | 
						|
      const COLOR bg = trans_color(_txt.get_background());
 | 
						|
      const COLOR fg = trans_color(_txt.get_foreground());
 | 
						|
      set_color(fg, bg);
 | 
						|
#else
 | 
						|
      set_color(COLOR_BLACK, COLOR_WHITE);
 | 
						|
#endif      
 | 
						|
      
 | 
						|
      const char* beg = cp;                    
 | 
						|
      while (*beg)
 | 
						|
      {                            
 | 
						|
        for (; *beg == ' '; beg++)               // Salta spazi iniziali
 | 
						|
          pos++;      
 | 
						|
        
 | 
						|
        if (*beg)
 | 
						|
        {  
 | 
						|
          int len = 0;
 | 
						|
          for (const char * 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
 | 
						|
  {                                           
 | 
						|
    set_font(printer().fontname(), XVT_FS_NONE, _char_size);                 
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
    // Questa e' la patch per TTY.DRV.
 | 
						|
    if (j > 0 && (j % _realformlen) == 0) 
 | 
						|
    {
 | 
						|
      TString s(516);
 | 
						|
      s << '\r' << _txt.line(j-1) << "\n\r";
 | 
						|
      s << _txt.line(j);
 | 
						|
      xvt_dwin_draw_text(win(), 0, y, (char*)(const char*)s, -1);                           
 | 
						|
    }  
 | 
						|
    else  
 | 
						|
#endif                                      
 | 
						|
    xvt_dwin_draw_text(win(), 0, y, (char*)(const char*)_txt.line(j), -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 in cui stampare
 | 
						|
  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 long j   = ((long)page) * _formlen;
 | 
						|
  const int rows = (r.bottom - r.top) / _chary;  
 | 
						|
  const int top  = r.top / _chary;
 | 
						|
  
 | 
						|
  for (int k = top; k < top+rows; k++) 
 | 
						|
  {
 | 
						|
    if ((j+k) < _txt.lines() && k < _formlen ) 
 | 
						|
      paint_row(j+k);
 | 
						|
    else break;
 | 
						|
  }
 | 
						|
  // Se l'offset impostato era negativo (id est: sposta in alto la stampa)
 | 
						|
  if (offset > 0)
 | 
						|
    for (i=_formlen;i<=(offset+_formlen);i++)
 | 
						|
      if (_chary == 1 && (i % _realformlen) == 0) // se, sfortunatamente e' una generica, applica
 | 
						|
      {                                           // patch per TTY.DRV (vedi paint_row())
 | 
						|
        TString s(516);
 | 
						|
        s << '\r' << " " << "\n\r";
 | 
						|
        s << " ";
 | 
						|
        xvt_dwin_draw_text(win(), 0, i, (char*)(const char*)s, -1);                           
 | 
						|
      }  
 | 
						|
      else  
 | 
						|
        xvt_dwin_draw_text(win(), 0, i, " ", -1);
 | 
						|
  
 | 
						|
  return j+k < _txt.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()
 | 
						|
 | 
						|
  // @comm Quando possibile parte un processo concorrente (dipende dal sistema operativo)
 | 
						|
 | 
						|
{                    
 | 
						|
  int page = 0; 
 | 
						|
  RCT* rct;
 | 
						|
  bool ok = TRUE;          
 | 
						|
  
 | 
						|
#ifdef DBG
 | 
						|
  const long size = xvt_dwin_get_font_size_mapped(win());
 | 
						|
#endif   
 | 
						|
  while (ok && !_aborted)
 | 
						|
  {
 | 
						|
    _aborted = !(bool)xvt_print_open_page(_printrcd);                  
 | 
						|
    while (!_aborted && ok 
 | 
						|
           && (rct = xvt_print_get_next_band()) != NULL)
 | 
						|
    {
 | 
						|
      set_font(XVT_FFN_SYSTEM, XVT_FS_NONE, _char_size);                 
 | 
						|
      set_font(printer().fontname(), XVT_FS_NONE, _char_size);                 
 | 
						|
#ifdef DBG
 | 
						|
      long size1 = xvt_dwin_get_font_size_mapped(win());
 | 
						|
      CHECK(size == size1, "Failed to set font. xvt bugs???");
 | 
						|
#endif   
 | 
						|
      ok = print_band(page, *rct); 
 | 
						|
    }
 | 
						|
    _aborted |= !(bool)xvt_print_close_page(_printrcd); 
 | 
						|
    page++;
 | 
						|
  }     
 | 
						|
  return !_aborted;             
 | 
						|
}                                         
 | 
						|
 | 
						|
 | 
						|
TPrintwin::TPrintwin(TTextfile& txt) 
 | 
						|
: _txt(txt), _inited(FALSE), _aborted(FALSE)
 | 
						|
{
 | 
						|
  TPrinter& p = printer();
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  _printrcd = p.get_printrcd();
 | 
						|
  
 | 
						|
  WINDOW prwin = xvt_print_create_win(_printrcd, (char*)(const char*)main_app().title());
 | 
						|
  if (prwin == NULL_WIN) 
 | 
						|
  {
 | 
						|
    _aborted = TRUE;
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  set_win(prwin);                                                                    
 | 
						|
#endif  
 | 
						|
  
 | 
						|
  _char_size = p.get_char_size();   
 | 
						|
  set_font(p.fontname(), XVT_FS_NONE, _char_size);           
 | 
						|
  LEN_SPACES(win(), -1);          // force update 
 | 
						|
  
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  p.set_win_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;
 | 
						|
#endif
 | 
						|
 | 
						|
  _formlen   = p.formlen();
 | 
						|
  
 | 
						|
  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);
 | 
						|
}
 | 
						|
 | 
						|
 |