campo-sirio/include/printwin.cpp
angelo 696ca4e113 Rif. mod. 95/39. Correzione alla TPrintwin::print_band(). Cambiato
l'utilizzo di 'const int' in 'const long'. Cosi' facendo si evita
di stampare un numero infinito di pagine se il numero di quelle
effettive e' eccessivo. N.B. la modifica e' stata apportata anche alla
1.4.


git-svn-id: svn://10.65.10.50/trunk@1907 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-09-28 16:47:55 +00:00

302 lines
8.6 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();
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;
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_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;
}
}
}
} else
{
set_font(printer().fontname(), XVT_FS_NONE, _char_size);
xvt_dwin_draw_text(win(), 0, y, (char*)_txt.line(j), -1);
}
}
bool TPrintwin::print_band(int page, RCT& r)
{
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();
}
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);
}