campo-sirio/include/printwin.cpp
guy 577159c75e Correzioni su alberi
git-svn-id: svn://10.65.10.50/branches/R_10_00@22884 c028cbd2-c16b-5b4b-a496-9718f37d4682
2013-07-26 15:45:05 +00:00

392 lines
11 KiB
C++
Executable File
Raw Blame History

#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)
{
TPrinter& pr = printer();
const bool isbackground = _bg->items() > 0 && pr.isgraphics();
const bool fink_mode = pr.get_fink_mode();
const 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 = pr.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;
const TString* rbg = (const TString*)_bg->objptr(rw);
const TString& rwd = rbg ? *rbg : EMPTY_STRING;
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)
{
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 = pr.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;
if (pr.is_pdf())
{
const TString_array& a = pr.image_names();
const TString& name = a.row(id);
xvt_dwin_draw_image_on_pdf(win(), name, &dst);
}
else
i->draw(win(), dst);
}
}
}
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) // 28/05/2012 Guy: Non capisco perch<63> ci fosse quesata condizione che falsava p.get_dots_per_line()
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;
if (ispdf) // Guy: 06-02-2013
_formlen = _pagelen;
else
{
_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);
}