348 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			10 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);                 
 | |
|     TString s(_txt.line(j));                
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | |
|     if ((j % _realformlen) == 0 && (j != 0)) // Questo e' il patch per TTY.DRV.
 | |
|       s.insert("\n");                        // Quando uscira' un nuovo driver, si dovra' controllare 
 | |
| #endif                                       // se esiste ancora questo piccolo bigol.
 | |
|     xvt_dwin_draw_text(win(), 0, y, (char*)(const char*)s, -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
 | |
| {
 | |
|   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;
 | |
|   }
 | |
|   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);
 | |
| }
 | |
| 
 | |
| 
 |