home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / i / iv26_w_3.zip / EXAMPLES / IDRAW / SLLINES.C < prev    next >
C/C++ Source or Header  |  1992-01-17  |  11KB  |  357 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. // $Header: sllines.c,v 1.13 89/10/09 14:49:31 linton Exp $
  24. // implements classes LineSelection and MultiLineSelection.
  25.  
  26. #include "ilines.h"
  27. #include "rubbands.h"
  28. #include "sllines.h"
  29. #include <iostream.h>
  30.  
  31. // LineSelection creates its line.
  32.  
  33. LineSelection::LineSelection (Coord x0, Coord y0, Coord x1, Coord y1,
  34. Graphic* gs) : (gs) {
  35.     myname = "Line";
  36.     line = new Line(x0, y0, x1, y1);
  37. }
  38.  
  39. // LineSelection reads data to initialize its graphic state and create
  40. // its line.
  41.  
  42. LineSelection::LineSelection (istream& from, State* state) : (nil) {
  43.     myname = "Line";
  44.     line = nil;
  45.     ReadGS(from, state);
  46.     Skip(from);
  47.     Coord x0, y0, x1, y1;
  48.     from >> x0 >> y0 >> x1 >> y1;
  49.     line = new Line(x0, y0, x1, y1);
  50. }
  51.  
  52. // Copy returns a copy of the LineSelection.
  53.  
  54. Graphic* LineSelection::Copy () {
  55.     Coord x0, y0, x1, y1;
  56.     GetOriginal2(x0, y0, x1, y1);
  57.     return new LineSelection(x0, y0, x1, y1, this);
  58. }
  59.  
  60. // GetOriginal2 returns the two endpoints that were passed to the
  61. // LineSelection's constructor.
  62.  
  63. void LineSelection::GetOriginal2 (Coord& x0, Coord& y0, Coord& x1, Coord& y1) {
  64.     ((Line*) line)->GetOriginal(x0, y0, x1, y1);
  65. }
  66.  
  67. // GetOriginal returns within two arrays the two endpoints that were
  68. // passed to the LineSelection's constructor.
  69.  
  70. int LineSelection::GetOriginal (const Coord*& x, const Coord*& y) {
  71.     static Coord sx[2], sy[2];
  72.     GetOriginal2(sx[0], sy[0], sx[1], sy[1]);
  73.     x = sx;
  74.     y = sy;
  75.     return 2;
  76. }
  77.  
  78. // WriteData writes the LineSelection's data and Postscript code to
  79. // draw it.
  80.  
  81. void LineSelection::WriteData (ostream& to) {
  82.     Coord x0, y0, x1, y1;
  83.     GetOriginal2(x0, y0, x1, y1);
  84.     to << "Begin " << startdata << " Line\n";
  85.     WriteGS(to);
  86.     to << startdata << "\n";
  87.     to << x0 << " " << y0 << " " << x1 << " " << y1 << " Line\n";
  88.     to << "End\n\n";
  89. }
  90.  
  91. // CreateRubberVertex creates and returns the right kind of
  92. // RubberVertex to represent the LineSelection's shape.
  93.  
  94. RubberVertex* LineSelection::CreateRubberVertex (Coord* x, Coord* y, int n,
  95. int rubpt) {
  96.     return new RubberMultiLine(nil, nil, x, y, n, rubpt);
  97. }
  98.  
  99. // CreateReshapedCopy creates and returns a reshaped copy of itself
  100. // using the passed points and its graphic state.
  101.  
  102. Selection* LineSelection::CreateReshapedCopy (Coord* x, Coord* y, int) {
  103.     return new LineSelection(x[0], y[0], x[1], y[1], this);
  104. }
  105.  
  106. // uncacheChildren uncaches the graphic's components' extents.
  107.  
  108. void LineSelection::uncacheChildren () {
  109.     if (line != nil) {
  110.     uncacheExtentGraphic(line);
  111.     }
  112. }
  113.  
  114. // getExtent returns the graphic's extent including a tolerance for
  115. // the arrowheads.
  116.  
  117. void LineSelection::getExtent (float& l, float& b, float& cx, float& cy,
  118. float& tol, Graphic* gs) {
  119.     getExtentGraphic(line, l, b, cx, cy, tol, gs);
  120.     tol = MergeArrowHeadTol(tol, gs);
  121. }
  122.  
  123. // contains returns true if the graphic contains the point.
  124.  
  125. boolean LineSelection::contains (PointObj& po, Graphic* gs) {
  126.     BoxObj b;
  127.     getBox(b, gs);
  128.     if (b.Contains(po)) {
  129.     Coord x0, y0, x1, y1;
  130.     GetOriginal2(x0, y0, x1, y1);
  131.  
  132.     if (containsGraphic(line, po, gs)) {
  133.         return true;
  134.     } else if (LeftAcont(x0, y0, x1, y1, po, gs)) {
  135.         return true;
  136.     } else if (RightAcont(x1, y1, x0, y0, po, gs)) {
  137.         return true;
  138.     }
  139.     }
  140.     return false;
  141. }
  142.  
  143. // intersects returns true if the graphic intersects the box.
  144.  
  145. boolean LineSelection::intersects (BoxObj& userb, Graphic* gs) {
  146.     BoxObj b;
  147.     getBox(b, gs);
  148.     if (b.Intersects(userb)) {
  149.     Coord x0, y0, x1, y1;
  150.     GetOriginal2(x0, y0, x1, y1);
  151.  
  152.     if (intersectsGraphic(line, userb, gs)) {
  153.         return true;
  154.     } else if (LeftAints(x0, y0, x1, y1, userb, gs)) {
  155.         return true;
  156.     } else if (RightAints(x1, y1, x0, y0, userb, gs)) {
  157.         return true;
  158.     }
  159.     }
  160.     return false;
  161. }
  162.  
  163. // draw draws the graphic.
  164.  
  165. void LineSelection::draw (Canvas* c, Graphic* gs) {
  166.     drawGraphic(line, c, gs);
  167.     Coord x0, y0, x1, y1;
  168.     GetOriginal2(x0, y0, x1, y1);
  169.     drawLeftA(x0, y0, x1, y1, c, gs);
  170.     drawRightA(x1, y1, x0, y0, c, gs);
  171. }
  172.  
  173. // drawClipped draws the graphic if it intersects the clipping box.
  174.  
  175. void LineSelection::drawClipped (Canvas* c, Coord l, Coord b, Coord r,
  176. Coord t, Graphic* gs) {
  177.     BoxObj box;
  178.     getBox(box, gs);
  179.  
  180.     BoxObj clipBox(l, b, r, t);
  181.     if (clipBox.Intersects(box)) {
  182.     draw(c, gs);
  183.     }
  184. }
  185.  
  186. // Skew comments/code ratio to work around cpp bug
  187. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  188. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  189.  
  190. // MultiLineSelection creates its components.
  191.  
  192. MultiLineSelection::MultiLineSelection (Coord* x, Coord* y, int n, Graphic* gs)
  193. : (gs) {
  194.     Init(x, y, n);
  195. }
  196.  
  197. // MultiLineSelection reads data to initialize its graphic state and
  198. // create its components.
  199.  
  200. MultiLineSelection::MultiLineSelection (istream& from, State* state) : (nil) {
  201.     multiline = nil;
  202.     ReadGS(from, state);
  203.     Coord* x;
  204.     Coord* y;
  205.     int n;
  206.     ReadPoints(from, x, y, n);
  207.     Init(x, y, n);
  208. }
  209.  
  210. // Copy returns a copy of the MultiLineSelection.
  211.  
  212. Graphic* MultiLineSelection::Copy () {
  213.     Coord* x;
  214.     Coord* y;
  215.     int n = GetOriginal(x, y);
  216.     Graphic* copy = new MultiLineSelection(x, y, n, this);
  217.     return copy;
  218. }
  219.  
  220. // GetOriginal returns the vertices that were passed to the
  221. // MultiLineSelection's constructor.
  222.  
  223. int MultiLineSelection::GetOriginal (const Coord*& x, const Coord*& y) {
  224.     return ((MultiLine*) multiline)->GetOriginal(x, y);
  225. }
  226.  
  227. // Init creates the graphic's components and stores the arrowheads'
  228. // endpoints.
  229.  
  230. void MultiLineSelection::Init (Coord* x, Coord* y, int n) {
  231.     myname = "MLine";
  232.     ifillmultiline = new IFillMultiLine(x, y, n);
  233.     multiline = new MultiLine(x, y, n);
  234.     lx0 = x[0];
  235.     ly0 = y[0];
  236.     lx1 = x[1];
  237.     ly1 = y[1];
  238.     rx0 = x[n-1];
  239.     ry0 = y[n-1];
  240.     rx1 = x[n-2];
  241.     ry1 = y[n-2];
  242. }
  243.  
  244. // CreateRubberVertex creates and returns the right kind of
  245. // RubberVertex to represent the MultiLineSelection's shape.
  246.  
  247. RubberVertex* MultiLineSelection::CreateRubberVertex (Coord* x, Coord* y,
  248. int n, int rubpt) {
  249.     return new RubberMultiLine(nil, nil, x, y, n, rubpt);
  250. }
  251.  
  252. // CreateReshapedCopy creates and returns a reshaped copy of itself
  253. // using the passed points and its graphic state.
  254.  
  255. Selection* MultiLineSelection::CreateReshapedCopy (Coord* x, Coord* y, int n) {
  256.     return new MultiLineSelection(x, y, n, this);
  257. }
  258.  
  259. // uncacheChildren uncaches the graphic's components' extents.
  260.  
  261. void MultiLineSelection::uncacheChildren () {
  262.     if (multiline != nil) {
  263.     uncacheExtentGraphic(ifillmultiline);
  264.     uncacheExtentGraphic(multiline);
  265.     }
  266. }
  267.  
  268. // getExtent returns the graphic's extent including a tolerance for
  269. // the arrowheads.
  270.  
  271. void MultiLineSelection::getExtent (float& l, float& b, float& cx, float& cy,
  272. float& tol, Graphic* gs) {
  273.     Extent e;
  274.     if (extentCached()) {
  275.     getCachedExtent(e.left, e.bottom, e.cx, e.cy, e.tol);
  276.     } else {
  277.     FullGraphic gstmp;
  278.     concatGSGraphic(ifillmultiline, this, gs, &gstmp);
  279.     getExtentGraphic(
  280.             ifillmultiline, e.left, e.bottom, e.cx, e.cy, e.tol, &gstmp
  281.         );
  282.     Extent te;
  283.     concatGSGraphic(multiline, this, gs, &gstmp);
  284.     getExtentGraphic(
  285.             multiline, te.left, te.bottom, te.cx, te.cy, te.tol, &gstmp
  286.         );
  287.     e.Merge(te);
  288.     cacheExtent(e.left, e.bottom, e.cx, e.cy, e.tol);
  289.     }
  290.     float right = 2*e.cx - e.left;
  291.     float top = 2*e.cy - e.bottom;
  292.     float dummy1, dummy2;
  293.     transformRect(e.left, e.bottom, right, top, l, b, dummy1, dummy2, gs);
  294.     transform(e.cx, e.cy, cx, cy, gs);
  295.     tol = MergeArrowHeadTol(e.tol, gs);
  296. }
  297.  
  298. // contains returns true if the graphic contains the point.
  299.  
  300. boolean MultiLineSelection::contains (PointObj& po, Graphic* gs) {
  301.     BoxObj b;
  302.     getBox(b, gs);
  303.     if (b.Contains(po)) {
  304.     if (containsGraphic(ifillmultiline, po, gs)) {
  305.         return true;
  306.     } else if (containsGraphic(multiline, po, gs)) {
  307.         return true;
  308.     } else if (LeftAcont(lx0, ly0, lx1, ly1, po, gs)) {
  309.         return true;
  310.     } else if (RightAcont(rx0, ry0, rx1, ry1, po, gs)) {
  311.         return true;
  312.     }
  313.     }
  314.     return false;
  315. }
  316.  
  317. // intersects returns true if the graphic intersects the box.
  318.  
  319. boolean MultiLineSelection::intersects (BoxObj& userb, Graphic* gs) {
  320.     BoxObj b;
  321.     getBox(b, gs);
  322.     if (b.Intersects(userb)) {
  323.     if (intersectsGraphic(ifillmultiline, userb, gs)) {
  324.         return true;
  325.     } else if (intersectsGraphic(multiline, userb, gs)) {
  326.         return true;
  327.     } else if (LeftAints(lx0, ly0, lx1, ly1, userb, gs)) {
  328.         return true;
  329.     } else if (RightAints(rx0, ry0, rx1, ry1, userb, gs)) {
  330.         return true;
  331.     }
  332.     }
  333.     return false;
  334. }
  335.  
  336. // draw draws the graphic.
  337.  
  338. void MultiLineSelection::draw (Canvas* c, Graphic* gs) {
  339.     drawGraphic(ifillmultiline, c, gs);
  340.     drawGraphic(multiline, c, gs);
  341.     drawLeftA(lx0, ly0, lx1, ly1, c, gs);
  342.     drawRightA(rx0, ry0, rx1, ry1, c, gs);
  343. }
  344.  
  345. // drawClipped draws the graphic if it intersects the clipping box.
  346.  
  347. void MultiLineSelection::drawClipped (Canvas* c, Coord l, Coord b, Coord r,
  348. Coord t, Graphic* gs) {
  349.     BoxObj box;
  350.     getBox(box, gs);
  351.  
  352.     BoxObj clipBox(l, b, r, t);
  353.     if (clipBox.Intersects(box)) {
  354.     draw(c, gs);
  355.     }
  356. }
  357.