Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 650 git-svn-id: svn://10.65.10.50/trunk@14148 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			408 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | ||
| #include <image.h>
 | ||
| #include <printer.h>                  
 | ||
| #include <printwin.h>                  
 | ||
| #include <utility.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);
 | ||
| 
 | ||
|   _txt.read_line(j);
 | ||
|   
 | ||
|   int pos = 0;
 | ||
|   int curr_style = -1;
 | ||
|   
 | ||
|   for (const char* cp = _txt.piece(); cp; cp = _txt.piece())
 | ||
|   {  
 | ||
|     const int st = _txt.get_style();
 | ||
|     const COLOR bg = trans_color(_txt.get_background());
 | ||
|     const COLOR fg = trans_color(_txt.get_foreground());
 | ||
|     
 | ||
|     if (bg != fg)  // Testo vero e visibile
 | ||
|     {
 | ||
|       if (st != curr_style)
 | ||
|       {
 | ||
|         set_font(printer().fontname(), st, _char_size);
 | ||
|         curr_style = st;
 | ||
|       }
 | ||
|       
 | ||
|       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, beg, len);                           
 | ||
|           pos += len;                   
 | ||
|           beg = end;
 | ||
|         }
 | ||
|       }  
 | ||
|     }
 | ||
|     else // Testo trasparente (elementi grafici aggiuntivi)
 | ||
|     {
 | ||
|       if (*cp == 'i')
 | ||
|         paint_image(row, cp);
 | ||
|     }  
 | ||
|   }
 | ||
| }                   
 | ||
| 
 | ||
| // @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
 | ||
| {
 | ||
|   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();
 | ||
|   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);
 | ||
| 
 | ||
|   _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, const char* title) 
 | ||
| : _aborted(FALSE), _txt(txt), _inited(FALSE)
 | ||
| {
 | ||
|   TPrinter& p = printer();
 | ||
| 
 | ||
|   _printrcd = p.get_printrcd();
 | ||
|   if (!xvt_print_is_valid(_printrcd))
 | ||
|   {
 | ||
|     _aborted = TRUE;
 | ||
|     return;
 | ||
|   }
 | ||
|   if (title == NULL)
 | ||
|     title = main_app().title();
 | ||
|   
 | ||
|   WINDOW prwin = xvt_print_create_win(_printrcd, title);
 | ||
| 
 | ||
|   if (prwin == NULL_WIN) 
 | ||
|   {
 | ||
|     _aborted = TRUE;
 | ||
|     return;
 | ||
|   }
 | ||
|   set_win(prwin);
 | ||
|   
 | ||
|   const bool ispdf = (xvt_print_is_pdf(_printrcd) != 0);
 | ||
| 
 | ||
|   if (ispdf)
 | ||
|   {
 | ||
|     if (_aborted = (xvt_print_open_page(_printrcd) == 0))
 | ||
|       return;
 | ||
|   }
 | ||
| 
 | ||
|   _char_size = p.get_char_size();   
 | ||
|   set_font(p.fontname(), XVT_FS_NONE, _char_size);           
 | ||
|   LEN_SPACES(win(), -1);          // force update 
 | ||
| 
 | ||
|   _pagelen = p.formlen(); 
 | ||
| 
 | ||
|   if (!ispdf) 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);
 | ||
| 
 | ||
|   _formwidth = p.formwidth();
 | ||
|   _inited = TRUE;
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TPrintwin::~TPrintwin()
 | ||
| {
 | ||
|   if (_inited && win() != NULL_WIN) 
 | ||
|     xvt_vobj_destroy(win());
 | ||
|   set_win(NULL_WIN);
 | ||
| }
 | ||
| 
 |