#include #include #include #include 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(); if (!isbackground) return; int rw = (int)(j % _formlen); TString& rwd = (TString&)(*_bg)[rw]; 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; 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 * _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 * _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; paint_background(j); _txt.read_line(j); int pos = 0; const char* cp; while((cp = _txt.piece()) != NULL) { #if XVT_OS != XVT_OS_SCOUNIX 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 sringa da stampare xvt_dwin_draw_text(win(), _hofs + LEN_SPACES(win(), pos), y, (char*)beg, len); pos += len; beg = end; } } } } bool TPrintwin::print_band(int page, RCT& r) { const int j = 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(); } bool TPrintwin::do_print() { 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_SCOUNIX _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_SCOUNIX p.set_win_formlen(prwin); // Calcola offset e altre misure pagina xvt_dwin_get_font_metrics(prwin, &_lead, &_ascent, &_descent); _bg = &p.getbgdesc(); _chary = p.get_dots_per_line(); _hofs = p.get_horz_offset(); _vofs = p.get_vert_offset(); #endif _formlen = p.formlen(); _formwidth = p.formwidth(); _inited = TRUE; } TPrintwin::~TPrintwin() { if (_inited && win() != NULL_WIN) xvt_vobj_destroy(win()); set_win(NULL_WIN); }