psview.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1991,1993 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the Computer Systems
  16.  * Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  * @(#) $Header: /cvsroot/nsnam/nam-1/psview.cc,v 1.10 2001/02/23 05:56:51 mehringe Exp $ (LBL)
  34.  */
  35. #include <stdlib.h>
  36. #ifdef WIN32
  37. #include <windows.h>
  38. #endif
  39. #include <ctype.h>
  40. #include <math.h>
  41. #include "bbox.h"
  42. #include "netview.h"
  43. #include "netmodel.h"
  44. #include "tclcl.h"
  45. #include "paint.h"
  46. #include "packet.h"
  47. #include "psview.h"
  48. void PSView::zoom(float mag)
  49. {
  50.         magnification_ *= mag;
  51.         resize(width_, height_);
  52. }
  53. void PSView::resize(int width, int height)
  54. {
  55. width_ = width;
  56. height_ = height;
  57. matrix_.clear();
  58. BBox bb;
  59. /*a model can choose to use these values, or can set its own*/
  60. bb.xmin=0;
  61. bb.ymin=0;
  62. bb.xmax=width;
  63. bb.ymax=height;
  64. BoundingBox(bb);
  65. double x = (0.0-panx_)*width;
  66. double y = (0.0-pany_)*height;
  67. double w = width;
  68. double h = height;
  69. /*
  70.  * Set up a transform that maps bb -> canvas.  I.e,
  71.  * bb -> unit square -> allocation, but which retains
  72.  * the aspect ratio.  Also, add a margin.
  73.  */
  74. double nw = bb.xmax - bb.xmin;
  75. double nh = bb.ymax - bb.ymin;
  76. /* 
  77.  * Grow a margin if we asked for square aspect ratio.
  78.  */
  79. double bbw;
  80. double bbh;
  81. if (aspect_==SQUARE) {
  82.   bbw = 1.1 * nw;
  83.   bbh = 1.1 * nh;
  84. } else {
  85.   bbw = nw;
  86.   bbh = nh;
  87. }
  88. #ifdef NOTDEF
  89. double tx = bb.xmin - 0.5 * (bbw - nw);
  90. double ty = bb.ymin - 0.5 * (bbh - nh);
  91. #endif
  92. /*
  93.  * move base coordinate system to origin
  94.  */
  95. #ifdef NOTDEF
  96. matrix_.translate(-tx, -ty);
  97. #endif
  98. matrix_.translate(-bb.xmin, -bb.ymin);
  99. /*
  100.  * flip vertical axis because X is backwards.
  101.  */
  102. double ws = w / bbw;
  103. double hs = h / bbh;
  104. if (aspect_==SQUARE) {
  105.   if (ws <= hs) {
  106.     matrix_.scale(ws, ws);
  107.     scale_=ws;
  108.     matrix_.translate(x, y + 0.5 * (h - ws * bbh));
  109.   } else {
  110.     matrix_.scale(hs, hs);
  111.     scale_=hs;
  112.     matrix_.translate(x + 0.5 * (w - hs * bbw), y);
  113.   }
  114. } else {
  115.   matrix_.scale(ws, hs);
  116.   matrix_.translate(x, y);
  117. }
  118. if ((width_<=0)||(height_<=0)) abort();
  119. matrix_.scale(magnification_, magnification_);
  120. if (xscroll_!=NULL) {
  121.   Tcl& tcl = Tcl::instance();
  122.   tcl.evalf("%s set %f %f", xscroll_, panx_, 
  123.   panx_+(1.0/magnification_));
  124. }
  125. if (yscroll_!=NULL) {
  126.   Tcl& tcl = Tcl::instance();
  127.   tcl.evalf("%s set %f %f", yscroll_, pany_, 
  128.   pany_+(1.0/magnification_));
  129. }
  130. }
  131. void PSView::draw()
  132. {
  133.   int xmin, ymin, xmax, ymax;
  134.   BBox bb;
  135.   BoundingBox(bb);
  136.   matrix_.map(bb.xmin, bb.ymin, xmin, ymin);
  137.   matrix_.map(bb.xmax, bb.ymax, xmax, ymax);
  138.   /*Ensure we have a half inch border*/
  139.   xmin+=36;
  140.   ymin+=36;
  141.   xmax+=36;
  142.   ymax+=36;
  143.   file_ = fopen(name_, "w+");
  144.   fprintf(file_, "%%!PS-Adobe-2.0 EPSF-2.0n");
  145.   fprintf(file_, "%%%%Creator: namn");
  146.   fprintf(file_, "%%%%DocumentFonts: Helvetican");
  147.   fprintf(file_, "%%%%BoundingBox: %d %d %d %dn", xmin, ymin, xmax, ymax);
  148.   fprintf(file_, "%%%%EndCommentsn");
  149.   fprintf(file_, "gsave 36 36 translaten");
  150.   fprintf(file_, "/namdict 20 dict defn");
  151.   fprintf(file_, "namdict beginn");
  152.   fprintf(file_, "/ft {/Helvetica findfont exch scalefont setfontn");
  153.   fprintf(file_, "newpath 0 0 moveto (0) true charpath flattenpathn");
  154.   fprintf(file_, "pathbbox /fh exch def pop pop pop} defn");
  155.   fprintf(file_, "/center_show {/s exch def moveto s stringwidthn");
  156.   fprintf(file_, "pop 2 div neg fh 2 div neg rmoveto s show} defn");
  157.   fprintf(file_, "/north_show {/s exch def moveto s stringwidthn");
  158.   fprintf(file_, "pop 2 div neg fh neg rmoveto s show} defn");
  159.   fprintf(file_, "/south_show {/s exch def moveto s stringwidthn");
  160.   fprintf(file_, "pop 2 div neg 0 rmoveto s show} defn");
  161.   fprintf(file_, "/east_show {/s exch def moveto s stringwidthn");
  162.   fprintf(file_, "pop neg fh 2 div neg rmoveto s show} defn");
  163.   fprintf(file_, "/west_show {/s exch def moveto n");
  164.   fprintf(file_, "0 fh 2 div neg rmoveto s show} defn");
  165.   fprintf(file_, "/rect {newpath /h exch def /w exch def moveton");
  166.   fprintf(file_, "w 0 rlineto 0 h rlineto w neg 0 rlineton");
  167.   fprintf(file_, "0 h neg rlineto closepath stroke} defn");
  168.   fprintf(file_, "/line {newpath moveto lineto stroke} defn");
  169.   fprintf(file_, "/circle {newpath 0 360 arc stroke} defn");
  170.   fprintf(file_, "endn");
  171.   fprintf(file_, "%%%%EndPrologn");
  172.   fprintf(file_, "namdict beginn");
  173.   model_->render(this);
  174.   fprintf(file_, "showpagen");
  175.   fprintf(file_, "endn");
  176.   fprintf(file_, "%%%%Trailern");
  177.   fclose(file_);
  178. }
  179. PSView::PSView(const char* name, NetModel* m)
  180.   : View(name, SQUARE,200,200), model_(m), scale_(1.0)
  181. {
  182.   name_=new char[strlen(name)+1];
  183.   strcpy(name_, name);
  184.   resize(540,720);
  185.   draw();
  186. }
  187. void PSView::getWorldBox(BBox & world_boundary) {
  188.           model_->BoundingBox(world_boundary);
  189. }
  190. extern void Parse(NetModel*, const char* layout);
  191. int PSView::command(ClientData cd, Tcl_Interp* tcl, int argc, char **argv)
  192. {
  193.   PSView *pv = (PSView *)cd;
  194.   if (argc < 2) {
  195.     Tcl_AppendResult(tcl, """, argv[0], "": arg mismatch", 0);
  196.     return (TCL_ERROR);
  197.   }
  198.   if (strcmp(argv[1], "xscroll") == 0) {
  199.     if (argc == 3) {
  200.       pv->xscroll_=new char[strlen(argv[2])+1];
  201.       strcpy(pv->xscroll_, argv[2]);
  202.       return TCL_OK;
  203.     } else {
  204.       Tcl_AppendResult(tcl, """, argv[0],
  205.                        "": arg mismatch", 0);
  206.       return TCL_ERROR;
  207.     }
  208.   }
  209.   if (strcmp(argv[1], "yscroll") == 0) {
  210.     if (argc == 3) {
  211.       pv->yscroll_=new char[strlen(argv[2])+1];
  212.       strcpy(pv->yscroll_, argv[2]);
  213.       return TCL_OK;
  214.     } else {
  215.       Tcl_AppendResult(tcl, """, argv[0],
  216.                        "": arg mismatch", 0);
  217.       return TCL_ERROR;
  218.     }
  219.   }
  220.   if (strcmp(argv[1], "zoom") == 0) {
  221.     if (argc == 3) {
  222.       float mag=atof(argv[2]);
  223.       if (mag>1.0) {
  224. pv->panx_+=(1.0-1.0/mag)/(2.0*pv->magnification_);
  225. pv->pany_+=(1.0-1.0/mag)/(2.0*pv->magnification_);
  226.       } else {
  227. pv->panx_-=(1.0-mag)/(2.0*pv->magnification_*mag);
  228. pv->pany_-=(1.0-mag)/(2.0*pv->magnification_*mag);
  229.       }
  230.       pv->zoom(mag);
  231.       pv->draw();
  232.       //pv->pan(panx, pany);
  233.       return TCL_OK;
  234.     } else {
  235.       Tcl_AppendResult(tcl, """, argv[0],
  236.        "": arg mismatch", 0);
  237.       return TCL_ERROR;
  238.     }
  239.   }
  240.   if ((strcmp(argv[1], "xview") == 0)||(strcmp(argv[1], "yview")==0)) {
  241.     if ((argc==4)&&(strcmp(argv[2], "moveto")==0)) {
  242.       if (strcmp(argv[1], "xview") == 0)
  243. pv->panx_=atof(argv[3]);
  244.       else
  245. pv->pany_=atof(argv[3]);
  246.       pv->resize(pv->width_, pv->height_);
  247.       pv->draw();
  248.     } else if ((argc==5)&&(strcmp(argv[2], "scroll")==0)) {
  249.       float step=atof(argv[3]);
  250.       if (strcmp(argv[4], "units")==0) {
  251. step*=0.05/pv->magnification_;
  252.       } else if (strcmp(argv[4], "pages")==0) {
  253. step*=0.8/pv->magnification_;
  254.       }
  255.       if (strcmp(argv[1], "xview") == 0)
  256. pv->panx_+=step;
  257.       else
  258. pv->pany_+=step;
  259.       pv->resize(pv->width_, pv->height_);
  260.       pv->draw();
  261.     } else {
  262.       Tcl_AppendResult(tcl, """, argv[0],
  263.        "": arg mismatch", 0);
  264.       return TCL_ERROR;
  265.     }
  266.     return TCL_OK;
  267.   }
  268.   Tcl_AppendResult(tcl, """, argv[0], "": unknown arg: ", argv[1], 0);
  269.   return (TCL_ERROR);
  270. }
  271. void 
  272. PSView::line(float x0, float y0, float x1, float y1, int paint)
  273. {
  274. float ax, ay;
  275. matrix_.map(x0, y0, ax, ay);
  276. float bx, by;
  277. matrix_.map(x1, y1, bx, by);
  278. #ifdef NOTDEF
  279. GC gc = Paint::instance()->paint_to_gc(paint);
  280. XDrawLine(Tk_Display(tk_), offscreen_, gc, ax, ay, bx, by);
  281. #endif
  282. rgb *color= Paint::instance()->paint_to_rgb(paint);
  283. fprintf(file_, "%.2f %.2f %.2f setrgbcolorn", color->red/65536.0,
  284. color->green/65536.0,
  285. color->blue/65536.0);
  286. fprintf(file_, "%.1f %.1f %.1f %.1f linen",
  287. ax, ay, bx, by);
  288. }
  289. void PSView::rect(float x0, float y0, float x1, float y1, int paint)
  290. {
  291. float x, y;
  292. matrix_.map(x0, y0, x, y);
  293. float xx, yy;
  294. matrix_.map(x1, y1, xx, yy);
  295. float w = xx - x;
  296. if (w < 0) {
  297. x = xx;
  298. w = -w;
  299. }
  300. float h = yy - y;
  301. if (h < 0) {
  302. h = -h;
  303. y = yy;
  304. }
  305. #ifdef NOTDEF
  306. GC gc = Paint::instance()->paint_to_gc(paint);
  307. XDrawRectangle(Tk_Display(tk_), offscreen_, gc, x, y, w, h);
  308. #endif
  309.   if (x>0 && y>0) {
  310.     rgb *color= Paint::instance()->paint_to_rgb(paint);
  311.     fprintf(file_, "%.2f %.2f %.2f setrgbcolorn", color->red/65536.0,
  312.             color->green/65536.0,
  313.             color->blue/65536.0);
  314.     fprintf(file_, "%.1f %.1f %.1f %.1f rectn", x, y, w, h);
  315.   }
  316. }
  317. typedef struct floatpoint_s {
  318.   float x, y;
  319. } floatpoint;
  320. void PSView::polygon(const float* x, const float* y, int n, int paint)
  321. {
  322. /*XXX*/
  323. floatpoint pts[10];
  324. int i;
  325. for (i = 0; i < n; ++i) {
  326. matrix_.map(x[i], y[i], pts[i].x, pts[i].y);
  327. }
  328. pts[n] = pts[0];
  329. #ifdef NOTDEF
  330. GC gc = Paint::instance()->paint_to_gc(paint);
  331. XDrawLines(Tk_Display(tk_), offscreen_, gc, pts, n + 1,
  332.    CoordModeOrigin);
  333. #endif
  334. fprintf(file_,"%%polygonn");
  335. rgb *color= Paint::instance()->paint_to_rgb(paint);
  336. fprintf(file_, "%.2f %.2f %.2f setrgbcolorn", color->red/65536.0,
  337. color->green/65536.0,
  338. color->blue/65536.0);
  339. fprintf(file_, "newpath %.1f %.1f moveton", pts[0].x, pts[0].y);
  340. for(i=1; i<=n; i++)
  341.   fprintf(file_, "%.1f %.1f lineton", pts[i].x, pts[i].y);
  342. fprintf(file_, "closepath stroken");
  343. }
  344. void PSView::fill(const float* x, const float* y, int n, int paint)
  345. {
  346. /*XXX*/
  347. floatpoint pts[10];
  348. int i;
  349. for (i = 0; i < n; ++i) {
  350. matrix_.map(x[i], y[i], pts[i].x, pts[i].y);
  351. }
  352. pts[n] = pts[0];
  353. #ifdef NOTDEF
  354. GC gc = Paint::instance()->paint_to_gc(paint);
  355. XFillPolygon(Tk_Display(tk_), offscreen_, gc, pts, n + 1,
  356.      Convex, CoordModeOrigin);
  357. #endif
  358. fprintf(file_,"%%filln");
  359. rgb *color= Paint::instance()->paint_to_rgb(paint);
  360. fprintf(file_, "%.2f %.2f %.2f setrgbcolorn", color->red/65536.0,
  361. color->green/65536.0,
  362. color->blue/65536.0);
  363. fprintf(file_, "newpath %.1f %.1f moveton", pts[0].x, pts[0].y);
  364. for(i=1; i<=n; i++)
  365.   fprintf(file_, "%.1f %.1f lineton", pts[i].x, pts[i].y);
  366. fprintf(file_, "filln");
  367. }
  368. void PSView::circle(float x, float y, float r, int paint)
  369. {
  370. float tx, ty;
  371. matrix_.map(x, y, tx, ty);
  372. float tr, dummy;
  373. matrix_.map(x + r, y, tr, dummy);
  374. tr -= tx;
  375. #ifdef NOTDEF
  376. GC gc = Paint::instance()->paint_to_gc(paint);
  377. XDrawArc(Tk_Display(tk_), offscreen_, gc, tx, ty, tr, tr, 0, 64 * 360);
  378. #endif
  379. rgb *color= Paint::instance()->paint_to_rgb(paint);
  380. fprintf(file_, "%.2f %.2f %.2f setrgbcolorn", color->red/65536.0,
  381. color->green/65536.0,
  382. color->blue/65536.0);
  383. fprintf(file_, "%.1f %.1f %.1f circlen", tx, ty, tr);
  384. }
  385. // We'll ignore string color in PS view!
  386. void PSView::string(float fx, float fy, float dim, const char* s, int anchor, 
  387.     const char*)
  388. {
  389.   float x, y;
  390.   matrix_.map(fx, fy, x, y);
  391.   float dummy, dlow, dhigh;
  392.   matrix_.map(0., 0., dummy, dlow);
  393.   matrix_.map(0., 0.6 * dim, dummy, dhigh);
  394.   int d = int(dhigh - dlow);
  395.   fprintf(file_, "%d ftn", d);
  396.   fprintf(file_, "0 0 0 setrgbcolorn");
  397.   switch (anchor) {
  398.   case ANCHOR_CENTER:
  399.     fprintf(file_, "%.1f %.1f (%s) center_shown", x, y, s);
  400.     break;
  401.   case ANCHOR_NORTH:
  402.     fprintf(file_, "%.1f %.1f (%s) north_shown", x, y, s);
  403.     break;
  404.   case ANCHOR_SOUTH:
  405.     fprintf(file_, "%.1f %.1f (%s) south_shown", x, y, s);
  406.     break;
  407.   case ANCHOR_WEST:
  408.     fprintf(file_, "%.1f %.1f (%s) west_shown", x, y, s);
  409.     break;
  410.   case ANCHOR_EAST:
  411.     fprintf(file_, "%.1f %.1f (%s) east_shown", x, y, s);
  412.     break;
  413.   }
  414. }