#include #include #include #include #include #include #include #include typedef struct view { int handle, page, lbc, /* left-border-count fr Fenster. */ tlc, /* top-line-count fr Fenster. */ bc, /* border-count fr Fenster. */ lc, /* line-count fr Fenster. */ xfac, yfac, /* Scroll- und Rastereinheiten. */ x, y, w, h, /* Arbeitsbereich des Fensters. */ hslide, vslide, /* Puffer fr Sliderpositionen. */ (*key)( struct view *tv, int code, int ks ); void (*draw)( struct view *tv, int *clip ), (*free)( struct view *tv ), (*sclick)( struct view *tv, int mx, int my, int flag ); char path[128]; /* Datei-Pfad (Fenstertitel). */ struct view *next; /* Zeiger auf n„chste Fensterstruktur. */ struct view *prev; /* Zeiger auf vorige Fensterstruktur. */ BASPAG *actpd; /* Zeiger auf Prozess-Descriptor. */ long offset, newoff, ow, oh, dw, dh, rw, rh; int ox, oy, vhandle, rcflag; bas0[1], base[3], code[1]; /* Datenbereich. */ } VIEW; #include "1stview.h" #include "util.h" FROM( image ) IMPORT VIEW *load_img( int fh ); #define V_CLRWK 3 #define V_ESC 5 #define V_PLINE 6 #define V_PMARKER 7 #define V_GTEXT 8 #define V_FILLAREA 9 #define V_GDP 11 #define VST_HEIGHT 12 #define VSL_WIDTH 16 #define VSM_HEIGHT 19 #define VST_POINT 107 #define VR_RECFL 114 #define VS_CLIP 129 #define V_ARC 2 #define V_PIESLICE 3 #define V_CIRCLE 4 #define V_ELLIPSE 5 #define V_ELLARC 6 #define V_ELLPIE 7 #define V_JUSTIFIED 10 #define V_BIT_IMAGE 23 #define V_TOPBOT 18501 typedef struct { int id, headlen, version, transform, min_x, min_y, max_x, max_y, pwidth, pheight, ll_x, ll_y, ur_x, ur_y, bit_image; } META_HEADER; static int ox, oy, dx, dy, page, rcflag, rect[4]; static long ow, oh, dw, dh, rh; static char *fname, pagestring[4], wstring[] = " Fenster ^E", ostring[] = " Original ^S"; #pragma warn -rpt static OBJECT popup[] = { 0, 1, 7, G_BOX, NONE, SHADOWED, 0xFF1100L, 0, 0, 19, 4, 2, -1, -1, G_STRING, NONE, DISABLED, "- Mažstab / Seite -", 0,0,19,1, 3, -1, -1, G_STRING, NONE, NORMAL, wstring, 0, 1, 19, 1, 4, -1, -1, G_BUTTON, NONE, NORMAL, "1 \001", 0, 2, 4, 1, 5, -1, -1, G_BUTTON, NONE, NORMAL, "^\004 -", 4, 2, 6, 1, 6, -1, -1, G_BUTTON, NONE, DISABLED, pagestring, 10,2, 3, 1, 7, -1, -1, G_BUTTON, NONE, NORMAL, "+ ^\003", 13,2, 6, 1, 0, -1, -1, G_STRING, LASTOB, NORMAL, ostring, 0, 3, 19, 1 }; #pragma warn +rpt static void new_item( VIEW *tv, int new ) { if (new -= 2) { if (tv->dw == tv->rw && tv->dh == tv->rh) return; tv->dw = tv->rw; tv->dh = tv->rh; } else { if (tv->dw == tv->w && tv->dh == tv->h) return; tv->dw = tv->w; tv->dh = tv->h; } tv->bc = ((int)tv->dw + 7) >> 3; tv->lc = ((int)tv->dh + 7) >> 3; if (tv->page) do { int *p = tv->bas0; (char *)p += tv->offset; tv->newoff = tv->offset; ((int *)&tv->offset)[0] = p[0]; p[0] = V_CLRWK; ((int *)&tv->offset)[1] = p[3]; } while (--tv->page); new_redraw(); } #pragma warn -sig static void transform( int n ) { int ix; for (ix = contrl[1] << 1; (ix -= 2) >= 0;) if (ix == n) { if ((ptsin[ix] = (ptsin[ix] * dw) / ow) == 0) ++ptsin[ix]; if ((ptsin[ix+1] = (ptsin[ix+1] * dh) / oh) == 0) ++ptsin[ix+1]; } else { ptsin[ix] -= ox; ptsin[ix] = (ptsin[ix] * dw) / ow; ptsin[ix] += dx; ptsin[ix+1] -= oy; ptsin[ix+1] = (ptsin[ix+1] * dh) / oh; if (rcflag == 0) ptsin[ix+1] = dh - ptsin[ix+1]; ptsin[ix+1] += dy; } } static void make_path( void ) { int i, k; i = contrl[3]; contrl[3] += k = (int)(strrchr( fname, PATHSEP ) - fname + 1); while (--i >= 5) intin[i + k] = intin[i]; while (--k >= 0) intin[k + 5] = fname[k]; } static void do_command( void ) { int n = -2; switch (contrl[0]) { case V_GDP: switch (contrl[5]) { case V_ARC: case V_PIESLICE: n += 2; case V_CIRCLE: n += 2; case V_ELLIPSE: case V_ELLARC: case V_ELLPIE: case V_JUSTIFIED: n += 4; } transform( n ); break; case VST_POINT: if (contrl[6] == ohandle) intin[0] = (intin[0] * dh) / rh; else { CALL_VDI(); contrl[0] = VST_HEIGHT; contrl[1] = 1; contrl[3] = 0; ptsin[0] = 0; if ((ptsin[1] = (ptsout[1] * dh) / rh) == 0) ++ptsin[1]; } break; case VST_HEIGHT: case VSM_HEIGHT: case V_TOPBOT: case VSL_WIDTH: n = 0; case V_ESC: if (contrl[5] == V_BIT_IMAGE) if (intin[6] != ':') make_path(); case V_PLINE: case V_PMARKER: case V_GTEXT: case V_FILLAREA: case VR_RECFL: transform( n ); break; case VS_CLIP: if (intin[0]) { { int t; t = ox; if (t > ptsin[0]) ptsin[0] = t; t += ow - 1; if (t < ptsin[2]) ptsin[2] = t; t = oy; if (t > ptsin[1]) ptsin[1] = t; t += oh - 1; if (t < ptsin[3]) ptsin[3] = t; } transform( n ); if (rect[0] > ptsin[0]) ptsin[0] = rect[0]; if (rect[1] > ptsin[1]) ptsin[1] = rect[1]; if (rect[2] < ptsin[2]) ptsin[2] = rect[2]; if (rect[3] < ptsin[3]) ptsin[3] = rect[3]; } else { ++intin[0]; *(long *)ptsin = *(long *)rect; *(long *)(ptsin + 2) = *(long *)(rect + 2); } } CALL_VDI(); } static void draw_meta( VIEW *tv, int *clip ) { long count; vr_recfl( handle, clip ); vs_clip( tv->vhandle, 1, clip ); dx = tv->x - (tv->lbc << 3); dy = tv->y - (tv->tlc << 3); ox = tv->ox; oy = tv->oy; rcflag = tv->rcflag; ow = tv->ow; oh = tv->oh; dw = tv->dw; dh = tv->dh; rh = tv->rh; *(long *)rect = *(long *)clip; *(long *)(rect + 2) = *(long *)(clip + 2); fname = tv->path; clip = tv->base; (char *)clip += tv->offset; count = 2; count += *clip++ << 2; count += *clip++ << 1; (char *)clip += count; for (;;) { switch (contrl[0] = *clip++) { case -1: clip = tv->base; case V_CLRWK: tv->newoff = (char *)clip - (char *)tv->base; return; } contrl[1] = *clip++; contrl[3] = *clip++; contrl[5] = *clip++; contrl[6] = tv->vhandle; if ((count = contrl[1] << 2) > 0) { memcpy( ptsin, clip, count ); (char *)clip += count; } if ((count = contrl[3] << 1) > 0) { memcpy( intin, clip, count ); (char *)clip += count; } do_command(); } } static void free_meta( VIEW *tv ) { if (vq_gdos()) vst_unload_fonts( tv->vhandle, 0 ); v_clsvwk( tv->vhandle ); } static int key_meta( VIEW *tv, int code, int ks ) { switch (code) { case CNTRL_E: new_item( tv, 2 ); return 0; case CNTRL_S: new_item( tv, 7 ); return 0; case CNTRL_CL: if (tv->offset) { ks &= 3; do { int *p = tv->bas0; (char *)p += tv->offset; tv->newoff = tv->offset; ((int *)&tv->offset)[0] = p[0]; p[0] = V_CLRWK; ((int *)&tv->offset)[1] = p[3]; } while (--tv->page && ks); full_redraw(); } return 0; case CNTRL_CR: if (tv->newoff) { int *p = tv->bas0; (char *)p += tv->newoff; p[0] = ((int *)&tv->offset)[0]; p[3] = ((int *)&tv->offset)[1]; tv->offset = tv->newoff; ++tv->page; full_redraw(); } return 0; } return 1; } static void sclick_meta( VIEW *tv, int mx, int my, int flag ) { if (flag) return; popup[3].ob_state = popup[4].ob_state = tv->offset ? NORMAL : DISABLED; popup[6].ob_state = tv->newoff ? NORMAL : DISABLED; itoa( tv->page + 1, pagestring, 10 ); *wstring = tv->dw == tv->w && tv->dh == tv->h ? 8 : ' '; *ostring = tv->dw == tv->rw && tv->dh == tv->rh ? 8 : ' '; switch (mx = popup_menu( popup, 5, mx, my, objc_draw )) { case 2: case 7: new_item( tv, mx ); break; case 3: case 4: do { int *p = tv->bas0; (char *)p += tv->offset; tv->newoff = tv->offset; ((int *)&tv->offset)[0] = p[0]; p[0] = V_CLRWK; ((int *)&tv->offset)[1] = p[3]; } while (--tv->page && mx != 4); full_redraw(); break; case 6: { int *p = tv->bas0; (char *)p += tv->newoff; p[0] = ((int *)&tv->offset)[0]; p[3] = ((int *)&tv->offset)[1]; tv->offset = tv->newoff; ++tv->page; full_redraw(); } } } static long read_header( int fh ) { META_HEADER header; Fread( fh, sizeof(META_HEADER), &header ); #ifdef __TOS__ flipwords( (char *)&header, sizeof(META_HEADER) ); #endif rcflag = header.ll_y > 0; ox = header.ll_x; oy = rcflag ? header.ur_y : -header.ll_y; ow = labs( (long)header.ur_x - (long)header.ll_x ) + 1; oh = labs( (long)header.ur_y - (long)header.ll_y ) + 1; dw = header.pwidth; dh = header.pheight; return header.headlen << 1; } static void set_dest( int handle, int pix_w, int pix_h ) { int point, pw, ph, val[7]; vst_font( handle, 2 ); point = vst_point ( handle, 99, val, val, val, val); vqt_fontinfo( handle, val, val, val + 2, val, val ); val[3] += val[5] + 1; ph = (point * 25400L) / (72L * val[3]); pw = ((long)ph * pix_w) / pix_h; dw = (dw * 100) / pw; dh = (dh * 100) / ph; vst_font( handle, 1 ); } VIEW *load_meta( int fh, long len ) { VIEW *rv; char *p; long hlen; int *code, i, vhandle, work_in[11], work_out[57]; len -= hlen = read_header( fh ); if ((rv = Malloc( sizeof(VIEW) + len )) == 0) { Fclose( fh ); form_error( EINVMEM ); return 0; } *(long *)rv->base = 0; code = rv->code; Fseek( hlen, fh, 0 ); len = Fread( fh, len, code ); Fclose( fh ); code[len >> 1] = -1; #ifdef __TOS__ flipwords( (char *)code, len ); #endif if (code[0] == V_ESC && code[3] == V_BIT_IMAGE) { p = strrchr( Path, PATHSEP ) + 1; i = code[2] - 5; code += (code[1] << 1) + 9; while (--i >= 0) *p++ = *code++; *p = 0; Mfree( rv ); if ((fh = Fopen( Path, 0 )) < 0) { form_error( -fh - 31 ); return 0; } return load_img( fh ); } if (popup->ob_next == 0) { --popup->ob_next; fix_tree( popup, 7 ); } vhandle = phys_handle; work_in[10] = 2; i = 9; do work_in[i] = 1; while (--i >= 0); v_opnvwk( work_in, &vhandle, work_out ); if (vhandle <= 0) { Mfree( rv ); form_error( EINVMEM ); return 0; } if (vq_gdos()) vst_load_fonts( vhandle, 0 ); set_dest( vhandle, work_out[3], work_out[4] ); rv->page = 0; rv->offset = 0; rv->newoff = 0; rv->ox = ox; rv->oy = oy; rv->rcflag = rcflag; rv->ow = ow; rv->oh = oh; rv->rw = rv->dw = dw; rv->rh = rv->dh = dh; rv->vhandle = vhandle; rv->xfac = rv->yfac = 8; rv->w = (int)rv->dw + 7; rv->h = (int)rv->dh + 7; rv->lc = rv->h >> 3; rv->bc = rv->w >> 3; rv->draw = draw_meta; rv->free = free_meta; rv->key = key_meta; rv->sclick = sclick_meta; return rv; } static int out_page( int fh ) { char *p; long count; *(p = strchr( fname, ' ' )) = 0; printbox( fname, ++page ); while (Fread( fh, 2, contrl ) - 2 == 0 && *contrl != -1) { Fread( fh, 2, contrl + 1 ); Fread( fh, 2, contrl + 3 ); Fread( fh, 2, contrl + 5 ); #ifdef __TOS__ flipwords( (char *)contrl, 12 ); #endif contrl[6] = ohandle; if ((count = contrl[1] << 2) > 0) { Fread( fh, count, ptsin ); #ifdef __TOS__ flipwords( (char *)ptsin, count ); #endif } if ((count = contrl[3] << 1) > 0) { Fread( fh, count, intin ); #ifdef __TOS__ flipwords( (char *)intin, count ); #endif } if (*contrl == V_CLRWK) { do_command(); printbox( 0, 0 ); *p = ' '; return 0; } do_command(); } v_updwk( ohandle ); v_clrwk( ohandle ); vs_clip( ohandle, 0, rect ); set_fonts( 0 ); printbox( 0, 0 ); *p = ' '; return 1; } int (*out_meta( char *name, int fh ))( int fh ) { fname = name; Fseek( read_header( fh ), fh, 0 ); set_fonts( 1 ); set_dest( ohandle, out_width, out_height ); rh = dh; if (par.meta_scale == 0) { dw = xpixel; dh = ypixel; } dx = 0; if (par.h_align) dx = xpixel - dw; if (par.h_align == 1) dx >>= 1; dy = 0; if (par.v_align) dy = ypixel - dh; if (par.v_align == 1) dy >>= 1; page = 0; *(long *)rect = 0; rect[2] = xpixel - 1; rect[3] = ypixel - 1; vs_clip( ohandle, 1, rect ); return out_page; }