Exemple #1
0
static Side crosside (BoxRegion  &region, BoxPoint &p)
{
    BoxPoint center = region.origin() + (region.space() / BoxPoint(2)) ;
    BoxPoint delta = center  - p ;
	
    int side = North | South | East | West ;
    
    // exclude opposite side
    
    if (p[X] > center[X]) 
	side &= ~West ;
    else
	side &= ~East ;
    if (p[Y] > center[Y])
	side &= ~North ;
    else
	side &= ~South ;
    
    delta[X] = abs(delta[X]);
    delta[Y] = abs(delta[Y]);
    
    if (region.space(Y) * delta[X] > region.space(X) * delta[Y]) 
	side &= ~(North | South);
    else
	side &= ~(East | West);
    
    return Side(side);
}
Exemple #2
0
// Draw
void LineBox::_draw(Widget w, 
		    const BoxRegion& r, 
		    const BoxRegion& exposed, 
		    GC gc,
		    bool context_selected) const
{
    XGCValues gcvalues;

    // Set width and cap style; project beyond end point up to 1/2
    // line thickness
    gcvalues.line_width = _linethickness;
    gcvalues.cap_style = CapProjecting;
    XChangeGC(XtDisplay(w), gc, GCLineWidth | GCCapStyle, &gcvalues);

    // Keep an empty frame of 1/2 line thickness around R (X may cross
    // R's boundaries otherwise)
    BoxPoint origin = r.origin();
    BoxSize space   = r.space();
    origin += _linethickness / 2;
    space  -= _linethickness;

    // Draw children
    __draw(w, BoxRegion(origin, space), exposed, gc, context_selected);

    // Attention: We leave LINE_WIDTH and CAP_STYLE changed!
    // (Works within Box::draw(), but the used GC may be changed)
}
Exemple #3
0
// Draw RuleBox
void RuleBox::_draw(Widget w, 
		    const BoxRegion& r, 
		    const BoxRegion&, 
		    GC gc,
		    bool) const
{
    BoxSize space   = r.space();
    BoxPoint origin = r.origin();

    BoxPoint width(extend(X) ? space[X] : size(X),
		   extend(Y) ? space[Y] : size(Y));

    if (width[Y] == 1)
    {
	// Horizontal line
	XDrawLine(XtDisplay(w), XtWindow(w), gc,
		  origin[X], origin[Y], origin[X] + width[X], origin[Y]);
    }
    else if (width[X] == 1)
    {
	// Vertical line
	XDrawLine(XtDisplay(w), XtWindow(w), gc,
		  origin[X], origin[Y], origin[X], origin[Y] + width[Y]);
    }
    else
    {
	// Rectangle
	XFillRectangle(XtDisplay(w), XtWindow(w), gc, origin[X], origin[Y],
		       width[X], width[Y]);
    }
}
Exemple #4
0
// Region occupied by edge
BoxRegion LineGraphEdge::region(const GraphGC& gc) const
{
    BoxRegion r;
    if (gc.drawAnnotations && annotation() != 0)
    {
	BoxPoint anno_pos = annotationPosition(gc);
	if (anno_pos.isValid())
	{
	    BoxRegion anno_region = annotation()->region(anno_pos, gc);
	    if (r.origin().isValid())
		r = r | anno_region;
	    else
		r = anno_region;
	}
    }

    if (from() == to())
    {
	BoxRegion region = from()->region(gc);
       	if (from()->selected())
	    region.origin() += gc.offsetIfSelected;

	LineGraphEdgeSelfInfo info(region, gc);

	BoxRegion self_region(info.arc_pos,
			      BoxSize(info.diameter, info.diameter));

	if (r.origin().isValid())
	    r = r | self_region;
	else
	    r = self_region;
    }

    return r;
}
Exemple #5
0
// Draw self edge
void LineGraphEdge::drawSelf(Widget w,
			     const BoxRegion& exposed,
			     const GraphGC& gc) const
{
    assert(from() == to());

    // Get region
    BoxRegion region = from()->region(gc);
    if (from()->selected())
	region.origin() += gc.offsetIfSelected;

    LineGraphEdgeSelfInfo info(region, gc);

    XDrawArc(XtDisplay(w), XtWindow(w), gc.edgeGC, info.arc_pos[X],
	     info.arc_pos[Y], info.diameter, info.diameter,
	     info.arc_start * 64, info.arc_extend * 64);

    if (annotation() != 0)
    {
	// Draw annotation
	annotation()->draw(w, info.anno_pos, exposed, gc);
    }

    // Find arrow angle
    drawArrowHead(w, exposed, gc, info.arrow_pos, info.arrow_alpha);
}
Exemple #6
0
// cleanRegion
// clean a region with white ink
//
static void cleanRegion (std::ostream& os, const GraphGC& gc, BoxRegion region)
{
      BoxPoint origin = region.origin();
      BoxPoint width = region.space();

      if (gc.printGC->isPostScript())
      {
	  os << origin[X] << " " << origin[Y] << " ";
	  os << origin[X] + width[X] << " " << origin[Y];
	  os << " ";
	  os << origin[X] + width[X] << " ";
	  os << origin[Y] + width[Y] << " ";
	  os << origin[X] << " " << origin[Y] + width[Y];
	  os << " clean*\n";
      }
      else if (gc.printGC->isFig())
      {
	  os << CLEANHEAD;
	  os << origin[X] << " " << origin[Y] << " ";
	  os << origin[X] + width[X] << " " << origin[Y];
	  os << " ";
	  os << origin[X] + width[X] << " ";
	  os << origin[Y] + width[Y] << " ";
	  os << origin[X] << " " << origin[Y] + width[Y];
	  os << " ";
	  os << origin[X] << " "<< origin[Y] << " 9999 9999\n";
      }	  
}
Exemple #7
0
static BoxPoint crosspoint (BoxRegion &region, BoxPoint &p)
{
    int side = crosside (region, p);
    
    BoxDimension d1, d2;
    BoxPoint center = region.origin() + (region.space() / BoxPoint(2)) ;
    BoxPoint cross = center;
    int offset;
    
    offset = (side & (North | West)? -1 : 1) ;
    if (side & (North | South)) {
	d1 = X ; 
	d2 = Y ;
    } else {
	d1 = Y ;
	d2 = X ;
    }
    
    if (center[d1] != p[d1] && center[d2] != p[d2]) {
	cross[d1] += offset * (region.space(d2) / 2) 
	    * ( center[d1] - p[d1]) / ( center[d2] - p[d2] ) ;
    } 
    cross[d2] += offset * region.space(d2) / 2;
    
    return cross ;
}
Exemple #8
0
void LineGraphEdge::printSelf(ostream& os, const GraphGC &gc) const
{
    assert(from() == to());

    // Get region
    BoxRegion region = from()->region(gc);
    if (from()->selected())
	region.origin() += gc.offsetIfSelected;

    LineGraphEdgeSelfInfo info(region, gc);

    if (gc.printGC->isPostScript())
    {
	int start = (720 - info.arc_start - info.arc_extend) % 360 ;
	int end   = (720 - info.arc_start) % 360 ;

	BoxCoordinate line_width = 1;

	// Draw arc
	os << start << " " << end << " " 
	   << info.radius << " " << info.radius << " "
	   << info.arc_center[X] << " " << info.arc_center[Y] << " " 
	   << line_width << " arc*\n";

	// Now draw the arrow head
	int angle = (720 - info.arrow_angle) % 360;

	os << gc.arrowAngle << " " << gc.arrowLength << " " << angle << " "
	   << info.arrow_pos[X] << " " << info.arrow_pos[Y] << " arrowhead*\n";
    }
    else if (gc.printGC->isFig())
    {
	BoxCoordinate line_width = 1;

	os << ARCARROWHEAD1 << line_width << ARCARROWHEAD2;
	switch (gc.selfEdgeDirection)
	{
	case Clockwise:
	    os << ARCCLOCKWISE;
	    break;
	case Counterclockwise:
	    os << ARCCOUNTERCLOCKWISE;
	    break;
	}
	os << ARCARROWHEAD3
	   << float(info.arc_center[X]) << " " 
	   << float(info.arc_center[Y]) << " ";
	for (int i = 0; i < 3; i++)
	    os << info.fig_pos[i][X] << " " << info.fig_pos[i][Y] << " ";
	os << ARCARROWHEAD4;
    }

    if (annotation() != 0)
    {
	// Print annotation
	annotation()->_print(os, info.anno_pos, gc);
    }
}
Exemple #9
0
// mark the following objects as one XFIG compound object
static void startCompound(std::ostream& os, BoxRegion region)
{
    BoxPoint origin = region.origin();
    BoxPoint width = region.space();

    os << CMPHEAD;
    os << origin[X] + width[X] + 1 << " " << origin[Y] - 1 << " ";
    os << origin[X] - 1 << " " << origin[Y] + width[Y] + 1 << "\n";
}
Exemple #10
0
// Draw
void RiseBox::__draw(Widget w, 
		     const BoxRegion& r, 
		     const BoxRegion&, 
		     GC gc,
		     bool) const
{
    BoxSize space   = r.space();
    BoxPoint origin = r.origin();

    XDrawLine(XtDisplay(w), XtWindow(w), gc, origin[X], origin[Y] + space[Y],
	origin[X] + space[X], origin[Y]);
}
Exemple #11
0
// Print
void HatBox::_print(std::ostream& os, 
		    const BoxRegion& region, 
		    const PrintGC& gc) const
{
    BoxRegion childRegion = region;

    if (extend(X) == 0)
	childRegion.space(X) = size(X);
    if (extend(Y) == 0)
	childRegion.space(Y) = size(Y);
	
    _box->_print(os, childRegion, gc);
}
Exemple #12
0
// Clip point P to side SIDE of region B centered around C.  Assume
// that B contains a circle.
void LineGraphEdge::clipToCircle(const BoxRegion& b, int /* side */, 
				 BoxPoint& p, const BoxPoint& c)
{
    // assert(side == North || side == South || side == East || side == West);

    double radius = max(b.space(X), b.space(Y)) / 2;
    if (radius > 0.0)
    {
	double hyp = hypot(c[X] - p[X], c[Y] - p[Y]);

	p[X] += BoxCoordinate((radius * (c[X] - p[X])) / hyp);
	p[Y] += BoxCoordinate((radius * (c[Y] - p[Y])) / hyp);
    }
}
Exemple #13
0
// Draw
void HatBox::_draw(Widget w, 
		   const BoxRegion& r, 
		   const BoxRegion& exposed, GC gc,
		   bool context_selected) const
{
    BoxRegion childRegion = r;

    // If not extensible, shrink to minimal size
    if (extend(X) == 0)
	childRegion.space(X) = size(X);
    if (extend(Y) == 0)
	childRegion.space(Y) = size(Y);

    _box->draw(w, childRegion, exposed, gc, context_selected);
}
Exemple #14
0
// Print
void RiseBox::_print(std::ostream& os, 
		     const BoxRegion& region, 
		     const PrintGC& gc) const
{
    BoxPoint origin = region.origin();
    BoxPoint space  = region.space();
	
    if (gc.isFig()) {
	os << LINEHEAD1 ;
	os << linethickness() << LINEHEAD2 ;
	os << origin[X] << " " << origin[Y] + space[Y] << " " ;
	os << origin[X] + space[X] << " " << origin[Y] << " " ;
	os << "9999 9999\n" ;
    } else if (gc.isPostScript()) {
	os << origin[X] << " " << origin[Y] + space[Y] << " " ;
	os << origin[X] + space[X] << " " << origin[Y] << " " ;
	os << linethickness() << " line*\n";
    }
}
Exemple #15
0
// Draw a BoxGraphNode
void BoxGraphNode::forceDraw(Widget w, 
			     const BoxRegion& /* exposed */,
			     const GraphGC& gc) const
{
    assert(box() != 0);
    // assert(box()->OK());

    // We do not check for exposures here --
    // boxes are usually small and partial display
    // doesn't work well with scrolling
    static BoxRegion exposed(BoxPoint(0, 0), BoxSize(INT_MAX, INT_MAX));

    if (selected() && highlight())
    {
	box()->draw(w, region(gc), exposed, gc.nodeGC, false);

	bool use_color = ColorBox::use_color;
	ColorBox::use_color = false;
	BoxRegion r = highlightRegion(gc);

	if (r <= exposed)
	{
	    XFillRectangle(XtDisplay(w), XtWindow(w), gc.clearGC,
			   r.origin(X), r.origin(Y),
			   r.space(X), r.space(Y));
	    highlight()->draw(w, r, r, gc.nodeGC, false);
	}
	ColorBox::use_color = use_color;
    }
    else if (selected())
    {
	bool use_color = ColorBox::use_color;
	ColorBox::use_color = false;
	box()->draw(w, region(gc), exposed, gc.nodeGC, false);
	ColorBox::use_color = use_color;
    }
    else
    {
	box()->draw(w, region(gc), exposed, gc.nodeGC, false);
    }
}
Exemple #16
0
// Clip point P to side SIDE of region B.
void LineGraphEdge::moveToSide(const BoxRegion& b, int side, 
			       BoxPoint& p, const BoxPoint&)
{
    assert(side == North || side == South || side == East || side == West);

    p = b.origin();

    // Fetch points
    if (side & (North | South))
    {
	p[X] += b.space(X) / 2;
	if (side & South)
	    p[Y] += b.space(Y);
    }

    if (side & (East | West))
    {
	p[Y] += b.space(Y) / 2;
	if (side & East)
	    p[X] += b.space(X);
    }
}
Exemple #17
0
// Draw
void StringBox::_draw(Widget w, 
		      const BoxRegion& r, 
		      const BoxRegion&, 
		      GC gc,
		      bool) const
{
    BoxPoint origin = r.origin();

    if (_font != 0)
	XSetFont(XtDisplay(w), gc, _font->fid);

    XDrawString(XtDisplay(w), XtWindow(w), gc, origin[X], origin[Y] + _ascent,
		_string.chars(), _string.length());
}
Exemple #18
0
// Clip point P to side SIDE of region B centered around C.
void LineGraphEdge::clipToSide(const BoxRegion& b, int side, 
			       BoxPoint& p, const BoxPoint& c)
{
    assert(side == North || side == South || side == East || side == West);

    BoxDimension d1, d2;

    if (side & (North | South))
	d1 = X, d2 = Y;
    else
	d1 = Y, d2 = X;

    int offset;
    if (side & (North | West))
	offset = -1;
    else
	offset = 1;

    if (c[d1] != p[d1] && c[d2] != p[d2])
	p[d1] += offset * (b.space(d2) / 2) * (c[d1] - p[d1]) 
	    / (c[d2] - p[d2]);
    p[d2] += offset * b.space(d2) / 2;
}
Exemple #19
0
BoxPoint LineGraphEdge::annotationPosition(const GraphGC &gc) const
{
    if (from() == to())
    {
	BoxRegion region = from()->region(gc);
	if (from()->selected())
	    region.origin() += gc.offsetIfSelected;

	LineGraphEdgeSelfInfo info(region, gc);
	return info.anno_pos;
    }

    BoxPoint pos1     = from()->pos();
    BoxRegion region1 = from()->region(gc);

    BoxPoint pos2     = to()->pos();
    BoxRegion region2 = to()->region(gc);

    BoxPoint l1, l2;
    findLine(pos1, pos2, region1, region2, l1, l2, gc);

    if (from()->isHint() && to()->isHint())
    {
	// Between two hints -- don't draw anything
	return BoxPoint();
    }

    if (to()->isHint())
    {
	// Draw at hint position
	return to()->pos();
    }

    // Draw at mid-distance
    return l1 + (l2 - l1) / 2;
}
Exemple #20
0
// Draw DiagBox
void DiagBox::_draw(Widget w, 
		    const BoxRegion& r, 
		    const BoxRegion& exposed, GC gc,
		    bool context_selected) const
{
    const BoxSize space   = r.space();
    const BoxPoint origin = r.origin();

    // Draw a 10-pixel-grid
    BoxCoordinate i;
    for (i = 0; i < space[X]; i += 10)
	XDrawLine(XtDisplay(w), XtWindow(w), gc,
	    origin[X] + i, origin[Y], origin[X] + i, origin[Y] + space[Y]);

    for (i = 0; i < space[Y]; i += 10)
	XDrawLine(XtDisplay(w), XtWindow(w), gc,
	    origin[X], origin[Y] + i, origin[X] + space[X], origin[Y] + i);

    // Make space info
    std::ostringstream oss;
    oss << space << '\0';
    const string ss(oss);

    // Draw it (centered)
    StringBox *s = new StringBox(ss);

    const BoxSize  stringSize = s->size();
    const BoxPoint stringOrigin = origin + space/2 - stringSize/2;

    XClearArea(XtDisplay(w), XtWindow(w), stringOrigin[X], stringOrigin[Y],
	stringSize[X], stringSize[Y], False);
    s->draw(w, BoxRegion(stringOrigin, stringSize), exposed,
	    gc, context_selected);

    s->unlink();
}
Exemple #21
0
void GraphEdge::_print(std::ostream& os, const GraphGC &gc) const
{
    // Don't print if we're hidden
    if (hidden())
	return;
    
    // Fetch the regions
    BoxRegion start = from()->region(gc);
    BoxRegion end   = to()->region(gc);

    // Don't print edges with zero length
    if (start <= end)
	return;
    
    BoxPoint startc = start.origin() + (start.space() / BoxPoint(2));
    BoxPoint endc   = end.origin()   + (end.space()   / BoxPoint(2));

    BoxPoint startp = crosspoint (start, endc);
    BoxPoint endp   = crosspoint (end, startc);

    // This should come from gc.edgeGC
    BoxCoordinate line_width = 1;

    if (gc.printGC->isFig()) {
	if (!gc.drawArrowHeads || to()->isHint()) {
	    os << EDGEHEAD1 << line_width;
	    os << EDGEHEAD2 ;
	    os << startp[X] << " " << startp[Y] << " " ;
	    os << endp[X] << " " << endp[Y] << " " ;
	    os << "9999 9999\n" ;
	} else {
	    os << ARROWHEAD1 << line_width;
	    os << ARROWHEAD2 ;
	    os << startp[X] << " " << startp[Y] << " " ;
	    os << endp[X] << " " << endp[Y] << " " ;
	    os << "9999 9999\n" ;
	}
    } else if (gc.printGC->isPostScript()) {
	if (!gc.drawArrowHeads || to()->isHint()) {
	    os << startp[X] << " " << startp[Y] << " " ;
	    os << endp[X] << " " << endp[Y] << " " ;
	    os << line_width << " line*\n";
	} else {
	    os << gc.arrowAngle << " " << gc.arrowLength << " ";
	    os << startp[X] << " " << startp[Y] << " " ;
	    os << endp[X] << " " << endp[Y] << " " ;
	    os << line_width << " arrowline*\n";
	}
    }
}
Exemple #22
0
void StringBox::_print(std::ostream& os, 
		       const BoxRegion& region, 
		       const PrintGC& gc) const
{
    // Don't draw empty strings
    if (str().empty())
	return;

    BoxPoint origin = region.origin() ;
    const FONTMAP *fmap = matchFont (fontName_c());

    if (gc.isFig()) {
	os << TEXTHEAD1 << fmap->figfont << " "
	   << size(Y) - 3 << " " << TEXTHEAD2
	   << size(X) << " " << size(Y) << " "
	   << origin[X] << " " << origin [Y] + size(Y) - 2 << " "
	   << str() << "\001\n";
    } else if (gc.isPostScript()) {
	os << fmap->psfont << " " << size(X) << " " << size(Y)
	   << " " << origin[X] << " " << origin[Y] + size(Y) << " "
	   << "(" << pscook(str()) << ") text*\n";
    }
}   
Exemple #23
0
// Find line from region B1 centered around C1 to region B2 centered
// around C2.  Resulting line shall be drawn from P1 to P2
void LineGraphEdge::findLine(const BoxPoint& c1, const BoxPoint& c2,
			     const BoxRegion& b1, const BoxRegion& b2, 
			     BoxPoint& p1, BoxPoint& p2, 
			     const GraphGC& gc)
{
    // allow all sizes to begin
    int side1 = North | South | East | West;
    int side2 = North | South | East | West;

    // exclude opposite side
    if (c2[X] > c1[X]) { side1 &= ~West; side2 &= ~East; }
    else               { side1 &= ~East; side2 &= ~West; }

    if (c2[Y] > c1[Y]) { side1 &= ~North; side2 &= ~South; }
    else               { side1 &= ~South; side2 &= ~North; }

    // find edge cutting the line between the two center points c1, c2
    BoxCoordinate dx = abs(c1[X] - c2[X]);
    BoxCoordinate dy = abs(c1[Y] - c2[Y]);

    if (b1.space(Y) * dx > b1.space(X) * dy)
	side1 &= ~(North | South);
    else
	side1 &= ~(East | West);

    if (b2.space(Y) * dx > b2.space(X) * dy)
	side2 &= ~(North | South);
    else
	side2 &= ~(East | West);

    p1 = c1;
    p2 = c2;

    // Select appropriate clipping procedure
    typedef void (*ClipProc)(const BoxRegion& b, int side,
			     BoxPoint& p, const BoxPoint& c);

    struct ClipMapRec {
	EdgeAttachMode mode;
	ClipProc       proc;
    };

    static const ClipMapRec clipMap[] = 
    {
	{Straight, LineGraphEdge::clipToSide},
	{Circle,   LineGraphEdge::clipToCircle},
	{Centered, LineGraphEdge::moveToSide},
	{Straight, 0}
    };

    for (int i = 0; clipMap[i].proc != 0; i++)
	if (gc.edgeAttachMode == clipMap[i].mode)
	{
	    clipMap[i].proc(b1, side1, p1, c2);
	    clipMap[i].proc(b2, side2, p2, c1);

	    return;
	}

    assert(0);
}
void Box::epsHeader (std::ostream& os, 
		     const BoxRegion& region, 
		     const PostScriptPrintGC& gc)
{
    // check size of graph

    BoxPoint space  = region.space();
    BoxPoint origin = region.origin();

    BoxPoint size;
    switch (gc.orientation)
    {
    case PostScriptPrintGC::PORTRAIT:
	size = BoxPoint(gc.hsize, gc.vsize);
	break;

    case PostScriptPrintGC::LANDSCAPE:
	size = BoxPoint(gc.vsize, gc.hsize);
	break;
    }

    double scale = 1.0;
    if (space > size)
    {
	// Scale down ...
	double hscale = double(size[X]) / region.space(X);
	double vscale = double(size[Y]) / region.space(Y);
	scale = (hscale < vscale ? hscale : vscale);
	
	space[X] = int(double(space[X]) * scale + 0.5);
	space[Y] = int(double(space[Y]) * scale + 0.5);

	origin[X] = int(double(origin[X]) * scale + 0.5);
	origin[Y] = int(double(origin[Y]) * scale + 0.5);
    }

    // Determine bounding box
    BoxPoint llcorner, urcorner;
    switch (gc.orientation)
    {
    case PostScriptPrintGC::PORTRAIT:
	llcorner = BoxPoint(gc.hoffset,
			    gc.voffset);
	urcorner = BoxPoint(gc.hoffset + space[X], 
			    gc.voffset + space[Y]);
	break;

    case PostScriptPrintGC::LANDSCAPE:
        llcorner = BoxPoint(gc.hsize - space[Y] + gc.hoffset - gc.voffset, 
			    gc.hoffset);
	urcorner = BoxPoint(gc.hsize + gc.hoffset - gc.voffset,
			    gc.hoffset + space[X]);
	break;
    }

    os << EPSHEAD
       << CREATOR
       << BOUND 
       << llcorner[X] << " " << llcorner[Y] << " "
       << urcorner[X] << " " << urcorner[Y] << "\n"
       << PAGES << ENDC
       << "\ngsave\n";

    // Write rotation
    if (gc.orientation == PostScriptPrintGC::LANDSCAPE)
	os << gc.hsize + gc.hoffset << " 0 translate 90 rotate\n";

    // Write scaling
    int hmove = gc.hoffset - origin[X];
    int vmove = gc.voffset + space[Y] + origin[Y];

    os << hmove << " " << vmove << " translate\n"
       << scale << " " << -scale << " scale\n";
}
Exemple #25
0
void RuleBox::_print(std::ostream& os, 
		     const BoxRegion& region, 
		     const PrintGC& gc) const
{
    BoxSize space = region.space();
    BoxPoint origin = region.origin();
    BoxPoint width ;
    
    width = BoxPoint ( extend(X) ? space[X] : size(X) ,
		       extend(Y) ? space[Y] : size(Y) );

    if (width == BoxPoint (0,1) || width == BoxPoint (1,0)) {
	return ;
    }
    if (width[X] && width[X] < 3 && gc.isFig()) {
	// 
	// vertical Line
	//
	
	os << LINEHEAD1 ;
	os << width[X] << LINEHEAD2 ;
	os << origin[X] + width[X]/2 << " " << origin[Y] ;
	os << " " ;
	os << origin[X] + width[X]/2 << " " ;
	os << origin[Y] + width[Y] << " " ;
	os << "9999 9999\n" ;

    } else if (width[Y] && width[Y] < 3 && gc.isFig()) {
	//
	// horizontal line
	//
	
	os << LINEHEAD1 ;
	os << width[Y] << LINEHEAD2 ;
	os << origin[X] << " " << origin[Y]+width[Y]/2 ;
	os << " " ;
	os << origin[X] + width[X] << " " ;
	os << origin[Y] + width[Y]/2 << " " ;
	os << "9999 9999\n" ;
	
    } else {
	//
	// filled rectangle
	//
	if (gc.isFig()) {
	    os << RULEHEAD ;
	    os << origin[X] << " " << origin[Y] << " " ;
	    os << origin[X] + width[X] << " " << origin[Y] ;
	    os << " " ;
	    os << origin[X] + width[X] << " " ;
	    os << origin[Y] + width[Y] << " ";
	    os << origin[X] << " " << origin[Y] + width[Y] ; 
	    os << " " ;
	    os << origin[X] << " "<< origin[Y] << " 9999 9999\n" ;

	} else if (gc.isPostScript()) {

	    os << origin[X] << " " << origin[Y] << " " ;
	    os << origin[X] + width[X] << " " << origin[Y] ;
	    os << " " ;
	    os << origin[X] + width[X] << " " ;
	    os << origin[Y] + width[Y] << " ";
	    os << origin[X] << " " << origin[Y] + width[Y] ; 
	    os << " box*" << " %" <<  region << "\n"; ;
	}
    }
}