Rectangle.st
branchjv
changeset 20344 152b525b5c63
parent 20079 8d884971c2ed
parent 20308 9110f117d260
child 20727 fb8c5591428b
equal deleted inserted replaced
20343:0719a15ae26d 20344:152b525b5c63
    47 
    47 
    48     (aside from that, you will not see any difference from the outside)
    48     (aside from that, you will not see any difference from the outside)
    49 
    49 
    50     Instance variables:
    50     Instance variables:
    51 
    51 
    52         left           <Number>        the left coordinate (i.e origin x)
    52 	left           <Number>        the left coordinate (i.e origin x)
    53         top            <Number>        the top coordinate (i.e origin y)
    53 	top            <Number>        the top coordinate (i.e origin y)
    54         width          <Number>        the width of the rectangle
    54 	width          <Number>        the width of the rectangle
    55         height         <Number>        the height of the rectangle
    55 	height         <Number>        the height of the rectangle
    56 
    56 
    57     I am not certain, if implementing Rectangle different was a good idea - 
    57     I am not certain, if implementing Rectangle different was a good idea -
    58     subclasses may expect things to be different ...
    58     subclasses may expect things to be different ...
    59     Therefore, this may change.
    59     Therefore, this may change.
    60 
    60 
    61     [author:]
    61     [author:]
    62         Claus Gittinger
    62 	Claus Gittinger
    63 
    63 
    64     [see also:]
    64     [see also:]
    65         Point Polygon Circle EllipticalArc Spline
    65 	Point Polygon Circle EllipticalArc Spline
    66         LayoutOrigin LayoutFrame AlignmentOrigin Layout 
    66 	LayoutOrigin LayoutFrame AlignmentOrigin Layout
    67         View GraphicsContext StrokingWrapper FillingWrapper
    67 	View GraphicsContext StrokingWrapper FillingWrapper
    68 "
    68 "
    69 ! !
    69 ! !
    70 
    70 
    71 !Rectangle class methodsFor:'instance creation'!
    71 !Rectangle class methodsFor:'instance creation'!
    72 
    72 
    73 center:centerPoint extent:extentPoint 
    73 center:centerPoint extent:extentPoint
    74     "return an instance of me whose center is centerPoint and width 
    74     "return an instance of me whose center is centerPoint and width
    75      by height is extentPoint."
    75      by height is extentPoint."
    76 
    76 
    77     ^ self 
    77     ^ self
    78         origin:centerPoint - (extentPoint//2) 
    78 	origin:centerPoint - (extentPoint//2)
    79         extent:extentPoint
    79 	extent:extentPoint
    80 !
    80 !
    81 
    81 
    82 decodeFromLiteralArray:anArray
    82 decodeFromLiteralArray:anArray
    83     "create & return a new instance from information encoded in anArray.
    83     "create & return a new instance from information encoded in anArray.
    84      Redefined for faster creation."
    84      Redefined for faster creation."
    90     w := (anArray at:4) - l.
    90     w := (anArray at:4) - l.
    91     h := (anArray at:5) - t.
    91     h := (anArray at:5) - t.
    92     ^ self left:l top:t width:w height:h
    92     ^ self left:l top:t width:w height:h
    93 
    93 
    94     "
    94     "
    95      Rectangle decodeFromLiteralArray:#(Rectangle 100 200 300 500) 
    95      Rectangle decodeFromLiteralArray:#(Rectangle 100 200 300 500)
    96     "
    96     "
    97 
    97 
    98     "Created: / 28.1.1998 / 17:46:52 / cg"
    98     "Created: / 28.1.1998 / 17:46:52 / cg"
    99 !
    99 !
   100 
   100 
   102     "Return a rectangle, which encompasses all of the given points."
   102     "Return a rectangle, which encompasses all of the given points."
   103 
   103 
   104     |topLeft bottomRight|
   104     |topLeft bottomRight|
   105 
   105 
   106     topLeft := bottomRight := nil.
   106     topLeft := bottomRight := nil.
   107     listOfPoints do:[:p | 
   107     listOfPoints do:[:p |
   108         topLeft == nil
   108 	topLeft == nil
   109             ifTrue: [topLeft := bottomRight := p]
   109 	    ifTrue: [topLeft := bottomRight := p]
   110             ifFalse: [topLeft := topLeft min: p.
   110 	    ifFalse: [topLeft := topLeft min: p.
   111                       bottomRight := bottomRight max: p]
   111 		      bottomRight := bottomRight max: p]
   112     ].
   112     ].
   113     ^ topLeft corner: bottomRight
   113     ^ topLeft corner: bottomRight
   114 
   114 
   115     "
   115     "
   116      Rectangle encompassing:(Array with:10@10 with:50@0 with:0@50)
   116      Rectangle encompassing:(Array with:10@10 with:50@0 with:0@50)
   146     REGISTER OBJ newRect;
   146     REGISTER OBJ newRect;
   147     OBJ t;
   147     OBJ t;
   148     int spc;
   148     int spc;
   149 
   149 
   150     if (__CanDoQuickNew(OHDR_SIZE + 4*sizeof(OBJ))) {   /* OBJECT ALLOCATION */
   150     if (__CanDoQuickNew(OHDR_SIZE + 4*sizeof(OBJ))) {   /* OBJECT ALLOCATION */
   151         if (self == Rectangle) {
   151 	if (self == Rectangle) {
   152             /*
   152 	    /*
   153              * short cut - rectangles are created so often ...
   153 	     * short cut - rectangles are created so often ...
   154              */
   154 	     */
   155             __qCheckedAlignedNew(newRect, OHDR_SIZE + 4*sizeof(OBJ));
   155 	    __qCheckedNew(newRect, OHDR_SIZE + 4*sizeof(OBJ));
   156 
   156 
   157             __InstPtr(newRect)->o_class = Rectangle;
   157 	    __InstPtr(newRect)->o_class = Rectangle;
   158             __qSTORE(newRect, Rectangle);
   158 	    __qSTORE(newRect, Rectangle);
   159 
   159 
   160             __InstPtr(newRect)->i_instvars[0] = left;
   160 	    __InstPtr(newRect)->i_instvars[0] = left;
   161             __InstPtr(newRect)->i_instvars[1] = top;
   161 	    __InstPtr(newRect)->i_instvars[1] = top;
   162             __InstPtr(newRect)->i_instvars[2] = w;
   162 	    __InstPtr(newRect)->i_instvars[2] = w;
   163             __InstPtr(newRect)->i_instvars[3] = h;
   163 	    __InstPtr(newRect)->i_instvars[3] = h;
   164 
   164 
   165             if (! (__bothSmallInteger(left, top) && 
   165 	    if (! (__bothSmallInteger(left, top) &&
   166                    __bothSmallInteger(w, h))) {
   166 		   __bothSmallInteger(w, h))) {
   167                 spc = __qSpace(newRect);
   167 		spc = __qSpace(newRect);
   168                 __STORE_SPC(newRect, left, spc);
   168 		__STORE_SPC(newRect, left, spc);
   169                 __STORE_SPC(newRect, top, spc);
   169 		__STORE_SPC(newRect, top, spc);
   170                 __STORE_SPC(newRect, w, spc);
   170 		__STORE_SPC(newRect, w, spc);
   171                 __STORE_SPC(newRect, h, spc);
   171 		__STORE_SPC(newRect, h, spc);
   172             }
   172 	    }
   173 
   173 
   174             RETURN ( newRect );
   174 	    RETURN ( newRect );
   175         }
   175 	}
   176     }
   176     }
   177 %}.
   177 %}.
   178     ^ (self basicNew) left:left top:top width:w height:h
   178     ^ (self basicNew) left:left top:top width:w height:h
   179 !
   179 !
   180 
   180 
   183      Avoids creation of temp garbage."
   183      Avoids creation of temp garbage."
   184 
   184 
   185     | topLeft bottomRight |
   185     | topLeft bottomRight |
   186 
   186 
   187     topLeft := bottomRight := nil.
   187     topLeft := bottomRight := nil.
   188     listOfRects do:[:r | 
   188     listOfRects do:[:r |
   189         topLeft == nil ifTrue: [
   189 	topLeft == nil ifTrue: [
   190             topLeft := r topLeft.
   190 	    topLeft := r topLeft.
   191             bottomRight := r bottomRight
   191 	    bottomRight := r bottomRight
   192         ] ifFalse: [
   192 	] ifFalse: [
   193             topLeft := topLeft min: r topLeft.
   193 	    topLeft := topLeft min: r topLeft.
   194             bottomRight := bottomRight max: r bottomRight
   194 	    bottomRight := bottomRight max: r bottomRight
   195         ]
   195 	]
   196     ].
   196     ].
   197     ^ topLeft corner: bottomRight
   197     ^ topLeft corner: bottomRight
   198 !
   198 !
   199 
   199 
   200 origin:origin corner:corner
   200 origin:origin corner:corner
   210     REGISTER OBJ newRect;
   210     REGISTER OBJ newRect;
   211     OBJ t;
   211     OBJ t;
   212     int spc;
   212     int spc;
   213 
   213 
   214     if (__CanDoQuickNew(OHDR_SIZE + 4*sizeof(OBJ))) {   /* OBJECT ALLOCATION */
   214     if (__CanDoQuickNew(OHDR_SIZE + 4*sizeof(OBJ))) {   /* OBJECT ALLOCATION */
   215         /*
   215 	/*
   216          * short cut - rectangles are created so often ...
   216 	 * short cut - rectangles are created so often ...
   217          */
   217 	 */
   218         if (self == Rectangle) {
   218 	if (self == Rectangle) {
   219             if (__isPoint(origin) && __isPoint(extent)) {
   219 	    if (__isPoint(origin) && __isPoint(extent)) {
   220                 __qCheckedAlignedNew(newRect, OHDR_SIZE + 4*sizeof(OBJ));
   220 		__qCheckedNew(newRect, OHDR_SIZE + 4*sizeof(OBJ));
   221                 __InstPtr(newRect)->o_class = Rectangle;
   221 		__InstPtr(newRect)->o_class = Rectangle;
   222                 __qSTORE(newRect, Rectangle);
   222 		__qSTORE(newRect, Rectangle);
   223                 spc = __qSpace(newRect);
   223 		spc = __qSpace(newRect);
   224 
   224 
   225                 t = __PointInstPtr(origin)->p_x;
   225 		t = __PointInstPtr(origin)->p_x;
   226                 __InstPtr(newRect)->i_instvars[0] = t;
   226 		__InstPtr(newRect)->i_instvars[0] = t;
   227                 __STORE_SPC(newRect, t, spc);
   227 		__STORE_SPC(newRect, t, spc);
   228 
   228 
   229                 t = __PointInstPtr(origin)->p_y;
   229 		t = __PointInstPtr(origin)->p_y;
   230                 __InstPtr(newRect)->i_instvars[1] = t;
   230 		__InstPtr(newRect)->i_instvars[1] = t;
   231                 __STORE_SPC(newRect, t, spc);
   231 		__STORE_SPC(newRect, t, spc);
   232 
   232 
   233                 t = __PointInstPtr(extent)->p_x;
   233 		t = __PointInstPtr(extent)->p_x;
   234                 __InstPtr(newRect)->i_instvars[2] = t;
   234 		__InstPtr(newRect)->i_instvars[2] = t;
   235                 __STORE_SPC(newRect, t, spc);
   235 		__STORE_SPC(newRect, t, spc);
   236 
   236 
   237                 t = __PointInstPtr(extent)->p_y;
   237 		t = __PointInstPtr(extent)->p_y;
   238                 __InstPtr(newRect)->i_instvars[3] = t;
   238 		__InstPtr(newRect)->i_instvars[3] = t;
   239                 __STORE_SPC(newRect, t, spc);
   239 		__STORE_SPC(newRect, t, spc);
   240                 RETURN ( newRect );
   240 		RETURN ( newRect );
   241             }
   241 	    }
   242         }
   242 	}
   243     }
   243     }
   244 %}.
   244 %}.
   245     ^ (self basicNew) origin:origin extent:extent
   245     ^ (self basicNew) origin:origin extent:extent
   246 !
   246 !
   247 
   247 
   252     ^ (self basicNew) origin:origin width:w height:h
   252     ^ (self basicNew) origin:origin width:w height:h
   253 
   253 
   254     "Created: 8.5.1996 / 20:55:53 / cg"
   254     "Created: 8.5.1996 / 20:55:53 / cg"
   255 !
   255 !
   256 
   256 
   257 vertex:vertex1Point vertex:vertex2Point 
   257 vertex:vertex1Point vertex:vertex2Point
   258     "create and return a new instance of the receiver,
   258     "create and return a new instance of the receiver,
   259      given two diagonally opposite vertices."
   259      given two diagonally opposite vertices."
   260 
   260 
   261     ^ self
   261     ^ self
   262         origin: (vertex1Point min: vertex2Point)
   262 	origin: (vertex1Point min: vertex2Point)
   263         corner: (vertex1Point max: vertex2Point)
   263 	corner: (vertex1Point max: vertex2Point)
   264 
   264 
   265     "Created: 10.2.1997 / 12:14:32 / cg"
   265     "Created: 10.2.1997 / 12:14:32 / cg"
   266 ! !
   266 ! !
   267 
   267 
   268 !Rectangle class methodsFor:'instance creation-interactive'!
   268 !Rectangle class methodsFor:'instance creation-interactive'!
   272      If the user presses ESC, an AbortOperationRequest is raised."
   272      If the user presses ESC, an AbortOperationRequest is raised."
   273 
   273 
   274     ^ Screen current rectangleFromUser
   274     ^ Screen current rectangleFromUser
   275 
   275 
   276     "
   276     "
   277      Rectangle fromUser     
   277      Rectangle fromUser
   278     "
   278     "
   279 !
   279 !
   280 
   280 
   281 originFromUser:extent
   281 originFromUser:extent
   282     "let user specify an origin on the screen, return it"
   282     "let user specify an origin on the screen, return it"
   283 
   283 
   284     ^ Screen current originFromUser:extent
   284     ^ Screen current originFromUser:extent
   285 
   285 
   286     "
   286     "
   287      Rectangle originFromUser:50@50     
   287      Rectangle originFromUser:50@50
   288     "
   288     "
   289 ! !
   289 ! !
   290 
   290 
   291 !Rectangle methodsFor:'Compatibility-Squeak'!
   291 !Rectangle methodsFor:'Compatibility-Squeak'!
   292 
   292 
   327     "Answer a copy of the receiver that does not extend beyond aRectangle.  7/8/96 sw"
   327     "Answer a copy of the receiver that does not extend beyond aRectangle.  7/8/96 sw"
   328 
   328 
   329     ^ self translateBy: (self amountToTranslateWithin: aRectangle)
   329     ^ self translateBy: (self amountToTranslateWithin: aRectangle)
   330 !
   330 !
   331 
   331 
   332 withHeight:height 
   332 withHeight:height
   333     "Return a copy of me with a different height"
   333     "Return a copy of me with a different height"
   334 
   334 
   335     |origin corner|
   335     |origin corner|
   336 
   336 
   337     origin := self origin.
   337     origin := self origin.
   340 ! !
   340 ! !
   341 
   341 
   342 !Rectangle methodsFor:'accessing'!
   342 !Rectangle methodsFor:'accessing'!
   343 
   343 
   344 area
   344 area
   345     "return the area 
   345     "return the area
   346      - for screen Rectangles this is the number of pixels"
   346      - for screen Rectangles this is the number of pixels"
   347 
   347 
   348     ^ width * height
   348     ^ width * height
   349 !
   349 !
   350 
   350 
   391 corner
   391 corner
   392     "return the corner"
   392     "return the corner"
   393 
   393 
   394 %{  /* NOCONTEXT */
   394 %{  /* NOCONTEXT */
   395     if (self == @global(Rectangle)) {
   395     if (self == @global(Rectangle)) {
   396         OBJ _tleft = __INST(left);
   396 	OBJ _tleft = __INST(left);
   397         OBJ _ttop = __INST(top);
   397 	OBJ _ttop = __INST(top);
   398         OBJ _twidth = __INST(width);
   398 	OBJ _twidth = __INST(width);
   399         OBJ _theight = __INST(height);
   399 	OBJ _theight = __INST(height);
   400 
   400 
   401         if (__bothSmallInteger(_tleft, _ttop)
   401 	if (__bothSmallInteger(_tleft, _ttop)
   402          && __bothSmallInteger(_twidth, _theight)) {
   402 	 && __bothSmallInteger(_twidth, _theight)) {
   403             if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   403 	    if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   404                 OBJ newPoint;
   404 		OBJ newPoint;
   405                 int spc;
   405 		int spc;
   406                 int cX = __intVal(_tleft) + __intVal(_twidth);
   406 		int cX = __intVal(_tleft) + __intVal(_twidth);
   407                 int cY = __intVal(_ttop) + __intVal(_theight);
   407 		int cY = __intVal(_ttop) + __intVal(_theight);
   408 
   408 
   409                 if (__ISVALIDINTEGER(cX) && __ISVALIDINTEGER(cY)) {
   409 		if (__ISVALIDINTEGER(cX) && __ISVALIDINTEGER(cY)) {
   410                     __qCheckedAlignedNew(newPoint, sizeof(struct __Point));
   410 		    __qCheckedNew(newPoint, sizeof(struct __Point));
   411                     __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   411 		    __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   412                     __PointInstPtr(newPoint)->p_x = __MKSMALLINT(cX);
   412 		    __PointInstPtr(newPoint)->p_x = __MKSMALLINT(cX);
   413                     __PointInstPtr(newPoint)->p_y = __MKSMALLINT(cY);
   413 		    __PointInstPtr(newPoint)->p_y = __MKSMALLINT(cY);
   414                     RETURN ( newPoint );
   414 		    RETURN ( newPoint );
   415                 }
   415 		}
   416             }
   416 	    }
   417         }
   417 	}
   418     }
   418     }
   419 %}.
   419 %}.
   420     ^ (left + width) @ (top + height)
   420     ^ (left + width) @ (top + height)
   421 !
   421 !
   422 
   422 
   431     "return the extent"
   431     "return the extent"
   432 
   432 
   433 %{  /* NOCONTEXT */
   433 %{  /* NOCONTEXT */
   434 
   434 
   435     if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   435     if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   436         if (self == @global(Rectangle)) {
   436 	if (self == @global(Rectangle)) {
   437             OBJ newPoint;
   437 	    OBJ newPoint;
   438             int spc;
   438 	    int spc;
   439             OBJ newX = __INST(width);
   439 	    OBJ newX = __INST(width);
   440             OBJ newY = __INST(height);
   440 	    OBJ newY = __INST(height);
   441 
   441 
   442             __qCheckedAlignedNew(newPoint, sizeof(struct __Point));
   442 	    __qCheckedNew(newPoint, sizeof(struct __Point));
   443             __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   443 	    __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   444             __PointInstPtr(newPoint)->p_x = newX;
   444 	    __PointInstPtr(newPoint)->p_x = newX;
   445             __PointInstPtr(newPoint)->p_y = newY;
   445 	    __PointInstPtr(newPoint)->p_y = newY;
   446             if (! __bothSmallInteger(newX, newY)) {
   446 	    if (! __bothSmallInteger(newX, newY)) {
   447                 spc = __qSpace(newPoint);
   447 		spc = __qSpace(newPoint);
   448                 __STORE_SPC(newPoint, newX, spc);
   448 		__STORE_SPC(newPoint, newX, spc);
   449                 __STORE_SPC(newPoint, newY, spc);
   449 		__STORE_SPC(newPoint, newY, spc);
   450             }
   450 	    }
   451             RETURN ( newPoint );
   451 	    RETURN ( newPoint );
   452         }
   452 	}
   453     }
   453     }
   454 %}.
   454 %}.
   455     ^ Point x:width y:height
   455     ^ Point x:width y:height
   456 !
   456 !
   457 
   457 
   488 
   488 
   489 left:aNumber
   489 left:aNumber
   490     "set the left edge, adjust width - warning: destructive"
   490     "set the left edge, adjust width - warning: destructive"
   491 
   491 
   492     left notNil ifTrue:[
   492     left notNil ifTrue:[
   493         "adjust width"
   493 	"adjust width"
   494         width := width + (left - aNumber).
   494 	width := width + (left - aNumber).
   495     ].
   495     ].
   496     left := aNumber
   496     left := aNumber
   497 !
   497 !
   498 
   498 
   499 left:newLeft right:right top:newTop bottom:bottom
   499 left:newLeft right:right top:newTop bottom:bottom
   553 
   553 
   554     /*
   554     /*
   555      * claus: I am no longer certain, if this primitive is worth the effort
   555      * claus: I am no longer certain, if this primitive is worth the effort
   556      */
   556      */
   557     if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   557     if (__CanDoQuickNew(sizeof(struct __Point))) {      /* OBJECT ALLOCATION */
   558         if (self == @global(Rectangle)) {
   558 	if (self == @global(Rectangle)) {
   559             OBJ newPoint;
   559 	    OBJ newPoint;
   560             int spc;
   560 	    int spc;
   561             OBJ newX = __INST(left);
   561 	    OBJ newX = __INST(left);
   562             OBJ newY = __INST(top);
   562 	    OBJ newY = __INST(top);
   563 
   563 
   564             __qCheckedAlignedNew(newPoint, sizeof(struct __Point));
   564 	    __qCheckedNew(newPoint, sizeof(struct __Point));
   565             __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   565 	    __InstPtr(newPoint)->o_class = self; __qSTORE(newPoint, self);
   566             __PointInstPtr(newPoint)->p_x = newX;
   566 	    __PointInstPtr(newPoint)->p_x = newX;
   567             __PointInstPtr(newPoint)->p_y = newY;
   567 	    __PointInstPtr(newPoint)->p_y = newY;
   568             if (! __bothSmallInteger(newX, newY)) {
   568 	    if (! __bothSmallInteger(newX, newY)) {
   569                 spc = __qSpace(newPoint);
   569 		spc = __qSpace(newPoint);
   570                 __STORE_SPC(newPoint, newX, spc);
   570 		__STORE_SPC(newPoint, newX, spc);
   571                 __STORE_SPC(newPoint, newY, spc);
   571 		__STORE_SPC(newPoint, newY, spc);
   572             }
   572 	    }
   573             RETURN ( newPoint );
   573 	    RETURN ( newPoint );
   574         }
   574 	}
   575     }
   575     }
   576 %}.
   576 %}.
   577     ^ Point x:left y:top
   577     ^ Point x:left y:top
   578 !
   578 !
   579 
   579 
   584     |newTop newLeft|
   584     |newTop newLeft|
   585 
   585 
   586     newLeft := aPoint x.
   586     newLeft := aPoint x.
   587     newTop := aPoint y.
   587     newTop := aPoint y.
   588     left notNil ifTrue:[
   588     left notNil ifTrue:[
   589         width := width + (left - newLeft).
   589 	width := width + (left - newLeft).
   590     ].
   590     ].
   591     top notNil ifTrue:[
   591     top notNil ifTrue:[
   592         height := height + (top - newTop).
   592 	height := height + (top - newTop).
   593     ].
   593     ].
   594     left := newLeft.
   594     left := newLeft.
   595     top := newTop
   595     top := newTop
   596 !
   596 !
   597 
   597 
   612     width := extent x.
   612     width := extent x.
   613     height := extent y
   613     height := extent y
   614 !
   614 !
   615 
   615 
   616 origin:origin width:w height:h
   616 origin:origin width:w height:h
   617     "set both origin and extent; 
   617     "set both origin and extent;
   618      the extent is given as individual width and height.
   618      the extent is given as individual width and height.
   619      warning: destructive"
   619      warning: destructive"
   620 
   620 
   621     left := origin x.
   621     left := origin x.
   622     top := origin y.
   622     top := origin y.
   678 
   678 
   679 top:aNumber
   679 top:aNumber
   680     "set the top edge, adjust height - warning: destructive"
   680     "set the top edge, adjust height - warning: destructive"
   681 
   681 
   682     top notNil ifTrue:[
   682     top notNil ifTrue:[
   683         "adjust height"
   683 	"adjust height"
   684         height := height + (top - aNumber).
   684 	height := height + (top - aNumber).
   685     ].
   685     ].
   686     top := aNumber
   686     top := aNumber
   687 !
   687 !
   688 
   688 
   689 topCenter
   689 topCenter
   718 
   718 
   719     ^ (left + width) @ top
   719     ^ (left + width) @ top
   720 !
   720 !
   721 
   721 
   722 topRight:aPoint
   722 topRight:aPoint
   723     "Set the top and right edges. 
   723     "Set the top and right edges.
   724      The bottom left remains unchanged.
   724      The bottom left remains unchanged.
   725      warning: destructive"
   725      warning: destructive"
   726 
   726 
   727     |newTop|
   727     |newTop|
   728 
   728 
   733 !
   733 !
   734 
   734 
   735 vertices
   735 vertices
   736     "return the array containing my points as a closed polygon (for Polygon compatibility)"
   736     "return the array containing my points as a closed polygon (for Polygon compatibility)"
   737 
   737 
   738     ^ Array 
   738     ^ Array
   739         with:(self topLeft)
   739 	with:(self topLeft)
   740         with:(self topRight)
   740 	with:(self topRight)
   741         with:(self bottomRight)
   741 	with:(self bottomRight)
   742         with:(self bottomLeft)
   742 	with:(self bottomLeft)
   743         with:(self topLeft)
   743 	with:(self topLeft)
   744 
   744 
   745     "
   745     "
   746      (Rectangle origin:100@100 extent:20@30) vertices            
   746      (Rectangle origin:100@100 extent:20@30) vertices
   747      (Rectangle origin:100@100 extent:20@30) asPolygon vertices  
   747      (Rectangle origin:100@100 extent:20@30) asPolygon vertices
   748     "
   748     "
   749 
   749 
   750     "Modified: / 16-07-2010 / 16:59:16 / cg"
   750     "Modified: / 16-07-2010 / 16:59:16 / cg"
   751 !
   751 !
   752 
   752 
   775 %{  /* NOCONTEXT */
   775 %{  /* NOCONTEXT */
   776     /*
   776     /*
   777      * because rectangles are often compared in the graphics code,
   777      * because rectangles are often compared in the graphics code,
   778      * handle the common case quickly
   778      * handle the common case quickly
   779      */
   779      */
   780     if (__isNonNilObject(aRectangle) 
   780     if (__isNonNilObject(aRectangle)
   781      && __qClass(aRectangle) == Rectangle) {
   781      && __qClass(aRectangle) == Rectangle) {
   782 	if ((__InstPtr(self)->i_instvars[0] == __InstPtr(aRectangle)->i_instvars[0])
   782 	if ((__InstPtr(self)->i_instvars[0] == __InstPtr(aRectangle)->i_instvars[0])
   783 	 && (__InstPtr(self)->i_instvars[1] == __InstPtr(aRectangle)->i_instvars[1])
   783 	 && (__InstPtr(self)->i_instvars[1] == __InstPtr(aRectangle)->i_instvars[1])
   784 	 && (__InstPtr(self)->i_instvars[2] == __InstPtr(aRectangle)->i_instvars[2])
   784 	 && (__InstPtr(self)->i_instvars[2] == __InstPtr(aRectangle)->i_instvars[2])
   785 	 && (__InstPtr(self)->i_instvars[3] == __InstPtr(aRectangle)->i_instvars[3])) {
   785 	 && (__InstPtr(self)->i_instvars[3] == __InstPtr(aRectangle)->i_instvars[3])) {
   826 	topFraction:(self top);
   826 	topFraction:(self top);
   827 	bottomFraction:(self bottom).
   827 	bottomFraction:(self bottom).
   828     ^ l
   828     ^ l
   829 
   829 
   830     "
   830     "
   831      (0.5@0.5 corner:0.75@0.75) asFractionalLayout 
   831      (0.5@0.5 corner:0.75@0.75) asFractionalLayout
   832      (0.5@0.5 corner:0.75@0.75) asOffsetLayout      
   832      (0.5@0.5 corner:0.75@0.75) asOffsetLayout
   833      (0.5@0.5 corner:0.75@0.75) asLayout        
   833      (0.5@0.5 corner:0.75@0.75) asLayout
   834     "
   834     "
   835 !
   835 !
   836 
   836 
   837 asLayout
   837 asLayout
   838     "return a layoutFrame in which offsets (top, left, bottom, right)
   838     "return a layoutFrame in which offsets (top, left, bottom, right)
   849     b := (self bottom).
   849     b := (self bottom).
   850     ((l between:0.0 and:1.0)
   850     ((l between:0.0 and:1.0)
   851     and:[(r between:0.0 and:1.0)
   851     and:[(r between:0.0 and:1.0)
   852     and:[(t between:0.0 and:1.0)
   852     and:[(t between:0.0 and:1.0)
   853     and:[(b between:0.0 and:1.0)]]]) ifTrue:[
   853     and:[(b between:0.0 and:1.0)]]]) ifTrue:[
   854         newLayout
   854 	newLayout
   855             leftFraction:l;
   855 	    leftFraction:l;
   856             rightFraction:r;
   856 	    rightFraction:r;
   857             topFraction:t;
   857 	    topFraction:t;
   858             bottomFraction:b.
   858 	    bottomFraction:b.
   859     ] ifFalse:[
   859     ] ifFalse:[
   860         newLayout
   860 	newLayout
   861             leftOffset:l;
   861 	    leftOffset:l;
   862             rightFraction:0 offset:r;
   862 	    rightFraction:0 offset:r;
   863             topOffset:t;
   863 	    topOffset:t;
   864             bottomFraction:0 offset:b.
   864 	    bottomFraction:0 offset:b.
   865     ].
   865     ].
   866     ^ newLayout
   866     ^ newLayout
   867 
   867 
   868     "
   868     "
   869      (0.5@0.5 corner:0.75@0.75) asFractionalLayout  
   869      (0.5@0.5 corner:0.75@0.75) asFractionalLayout
   870      (0.5@0.5 corner:0.75@0.75) asOffsetLayout       
   870      (0.5@0.5 corner:0.75@0.75) asOffsetLayout
   871      (0.5@0.5 corner:0.75@0.75) asLayout              
   871      (0.5@0.5 corner:0.75@0.75) asLayout
   872      (0@0 corner:1@1) asLayout                      
   872      (0@0 corner:1@1) asLayout
   873      (0@0 corner:1@1) asFractionalLayout             
   873      (0@0 corner:1@1) asFractionalLayout
   874      (0@0 corner:1@1) asOffsetLayout                 
   874      (0@0 corner:1@1) asOffsetLayout
   875     "
   875     "
   876 
   876 
   877     "Modified: 5.6.1996 / 00:45:46 / cg"
   877     "Modified: 5.6.1996 / 00:45:46 / cg"
   878 !
   878 !
   879 
   879 
   891 	topOffset:(self top);
   891 	topOffset:(self top);
   892 	bottomFraction:0 offset:(self bottom).
   892 	bottomFraction:0 offset:(self bottom).
   893     ^ newLayout
   893     ^ newLayout
   894 
   894 
   895     "
   895     "
   896      (0.5@0.5 corner:0.75@0.75) asFractionalLayout 
   896      (0.5@0.5 corner:0.75@0.75) asFractionalLayout
   897      (0.5@0.5 corner:0.75@0.75) asOffsetLayout      
   897      (0.5@0.5 corner:0.75@0.75) asOffsetLayout
   898      (0.5@0.5 corner:0.75@0.75) asLayout        
   898      (0.5@0.5 corner:0.75@0.75) asLayout
   899 
   899 
   900      (10@10 corner:20@20) asFractionalLayout 
   900      (10@10 corner:20@20) asFractionalLayout
   901      (10@10 corner:20@20) asOffsetLayout     
   901      (10@10 corner:20@20) asOffsetLayout
   902      (10@10 corner:20@20) asLayout             
   902      (10@10 corner:20@20) asLayout
   903     "
   903     "
   904 
   904 
   905 !
   905 !
   906 
   906 
   907 asPointArray
   907 asPointArray
   913 
   913 
   914     ^ Array with:(org := self origin)
   914     ^ Array with:(org := self origin)
   915 	    with:self topRight
   915 	    with:self topRight
   916 	    with:self corner
   916 	    with:self corner
   917 	    with:self bottomLeft
   917 	    with:self bottomLeft
   918 	    with:org 
   918 	    with:org
   919 
   919 
   920     "
   920     "
   921      (10@10 corner:100@100) asPointArray 
   921      (10@10 corner:100@100) asPointArray
   922     "
   922     "
   923 !
   923 !
   924 
   924 
   925 asPolygon
   925 asPolygon
   926     "return a polygon from the receiver"
   926     "return a polygon from the receiver"
   943     width := (encoding at:4) - left.
   943     width := (encoding at:4) - left.
   944     height := (encoding at:5) - top
   944     height := (encoding at:5) - top
   945 
   945 
   946 
   946 
   947     "
   947     "
   948      Rectangle new fromLiteralArrayEncoding:#(Rectangle 100 200 300 500) 
   948      Rectangle new fromLiteralArrayEncoding:#(Rectangle 100 200 300 500)
   949     "
   949     "
   950 !
   950 !
   951 
   951 
   952 literalArrayEncoding
   952 literalArrayEncoding
   953     "encode myself as an array, from which a copy of the receiver
   953     "encode myself as an array, from which a copy of the receiver
   954      can be reconstructed with #decodeAsLiteralArray.
   954      can be reconstructed with #decodeAsLiteralArray.
   955      The encoding is: (Rectangle orgX orgY cornX cornY)"
   955      The encoding is: (Rectangle orgX orgY cornX cornY)"
   956 
   956 
   957     ^ Array
   957     ^ Array
   958         with:#Rectangle
   958 	with:#Rectangle
   959         with:left
   959 	with:left
   960         with:top
   960 	with:top
   961         with:(left + width)
   961 	with:(left + width)
   962         with:(top + height)
   962 	with:(top + height)
   963 
   963 
   964 
   964 
   965     "
   965     "
   966      Rectangle new fromLiteralArrayEncoding:#(Rectangle 100 200 300 500) 
   966      Rectangle new fromLiteralArrayEncoding:#(Rectangle 100 200 300 500)
   967      (100@200 corner:300@500) literalArrayEncoding 
   967      (100@200 corner:300@500) literalArrayEncoding
   968     "
   968     "
   969 
   969 
   970     "Modified: 1.9.1995 / 02:16:54 / claus"
   970     "Modified: 1.9.1995 / 02:16:54 / claus"
   971     "Modified: 22.4.1996 / 13:00:36 / cg"
   971     "Modified: 22.4.1996 / 13:00:36 / cg"
   972 !
   972 !
   973 
   973 
   974 rectangleRelativeTo:aRectangle preferred:prefRectHolder
   974 rectangleRelativeTo:aRectangle preferred:prefRectHolder
   975     "compute a displayRectangle, treating the receiver like a
   975     "compute a displayRectangle, treating the receiver like a
   976      layoutFrame. 
   976      layoutFrame.
   977      This allows rectangles to be used interchangable with Layouts."
   977      This allows rectangles to be used interchangable with Layouts."
   978 
   978 
   979     ^ (self asLayout) rectangleRelativeTo:aRectangle preferred:prefRectHolder
   979     ^ (self asLayout) rectangleRelativeTo:aRectangle preferred:prefRectHolder
   980 
   980 
   981     "
   981     "
   982      (10@20 corner:20@30) rectangleRelativeTo:(0@0 corner:100@100) preferred:(0@0 corner:50@50) 
   982      (10@20 corner:20@30) rectangleRelativeTo:(0@0 corner:100@100) preferred:(0@0 corner:50@50)
   983 
   983 
   984      (0.5@0.5) rectangleRelativeTo:(0@0 corner:100@100) preferred:(0@0 corner:50@50) 
   984      (0.5@0.5) rectangleRelativeTo:(0@0 corner:100@100) preferred:(0@0 corner:50@50)
   985     "
   985     "
   986 
   986 
   987     "Modified: / 27.5.1998 / 10:20:20 / cg"
   987     "Modified: / 27.5.1998 / 10:20:20 / cg"
   988 ! !
   988 ! !
   989 
   989 
  1054     self origin:aPoint corner:self corner + diff
  1054     self origin:aPoint corner:self corner + diff
  1055 !
  1055 !
  1056 
  1056 
  1057 scaleBy:scale
  1057 scaleBy:scale
  1058     "scale the receiver rectangle by scale (a Number or Point).
  1058     "scale the receiver rectangle by scale (a Number or Point).
  1059      This is destructive (modifies the receiver, not a copy) and 
  1059      This is destructive (modifies the receiver, not a copy) and
  1060      should only be used if you know, that you are the exclusive owner 
  1060      should only be used if you know, that you are the exclusive owner
  1061      of the receiver. (use scaledBy if in doubt)"
  1061      of the receiver. (use scaledBy if in doubt)"
  1062 
  1062 
  1063     |scalePoint sx sy|
  1063     |scalePoint sx sy|
  1064 
  1064 
  1065     (scale isMemberOf:Point) ifTrue:[  "type hint to stc"
  1065     (scale isMemberOf:Point) ifTrue:[  "type hint to stc"
  1074     height := height * sy.
  1074     height := height * sy.
  1075     left := left * sx.
  1075     left := left * sx.
  1076     top := top * sy
  1076     top := top * sy
  1077 
  1077 
  1078     "
  1078     "
  1079      (Rectangle origin:10@10 corner:50@50) scaleBy:2 
  1079      (Rectangle origin:10@10 corner:50@50) scaleBy:2
  1080     "
  1080     "
  1081 
  1081 
  1082     "its destructive:"
  1082     "its destructive:"
  1083     "
  1083     "
  1084      |r1 r2|
  1084      |r1 r2|
  1085 
  1085 
  1086      r1 := Rectangle origin:10@10 corner:50@50.
  1086      r1 := Rectangle origin:10@10 corner:50@50.
  1087      r2 := r1 scaleBy:2.
  1087      r2 := r1 scaleBy:2.
  1088      r1 
  1088      r1
  1089     "
  1089     "
  1090 !
  1090 !
  1091 
  1091 
  1092 translateBy:amount
  1092 translateBy:amount
  1093     "translate (i.e. move) the receiver rectangle 
  1093     "translate (i.e. move) the receiver rectangle
  1094      by amount, a Point or Number.
  1094      by amount, a Point or Number.
  1095      This is destructive (modifies the receiver, not a copy) and 
  1095      This is destructive (modifies the receiver, not a copy) and
  1096      should only be used if you know, that you are the exclusive owner 
  1096      should only be used if you know, that you are the exclusive owner
  1097      of the receiver. (use translatedBy if in doubt)"
  1097      of the receiver. (use translatedBy if in doubt)"
  1098 
  1098 
  1099     |amountPoint|
  1099     |amountPoint|
  1100 
  1100 
  1101     (amount isMemberOf:Point) ifTrue:[  "type hint to stc"
  1101     (amount isMemberOf:Point) ifTrue:[  "type hint to stc"
  1115     "
  1115     "
  1116      |r1 r2|
  1116      |r1 r2|
  1117 
  1117 
  1118      r1 := Rectangle origin:10@10 corner:50@50.
  1118      r1 := Rectangle origin:10@10 corner:50@50.
  1119      r2 := r1 translateBy:10.
  1119      r2 := r1 translateBy:10.
  1120      r1 
  1120      r1
  1121     "
  1121     "
  1122 ! !
  1122 ! !
  1123 
  1123 
  1124 !Rectangle methodsFor:'displaying'!
  1124 !Rectangle methodsFor:'displaying'!
  1125 
  1125 
  1126 displayFilledOn:aGC
  1126 displayFilledOn:aGC
  1127     "display a filled rectangle as represented by the receiver in 
  1127     "display a filled rectangle as represented by the receiver in
  1128      the graphicsContext, aGC"
  1128      the graphicsContext, aGC"
  1129 
  1129 
  1130     aGC fillRectangleX:left y:top width:width height:height
  1130     aGC fillRectangleX:left y:top width:width height:height
  1131 
  1131 
  1132     "
  1132     "
  1139 
  1139 
  1140     "Modified: 8.5.1996 / 14:40:42 / cg"
  1140     "Modified: 8.5.1996 / 14:40:42 / cg"
  1141 !
  1141 !
  1142 
  1142 
  1143 displayStrokedOn:aGC
  1143 displayStrokedOn:aGC
  1144     "display an unfilled rectangle as represented by the receiver in 
  1144     "display an unfilled rectangle as represented by the receiver in
  1145      the graphicsContext, aGC"
  1145      the graphicsContext, aGC"
  1146 
  1146 
  1147     aGC displayRectangleX:left y:top width:width height:height
  1147     aGC displayRectangleX:left y:top width:width height:height
  1148 
  1148 
  1149     "
  1149     "
  1218      * speeds that up by almost a factor of 2 ...
  1218      * speeds that up by almost a factor of 2 ...
  1219      */
  1219      */
  1220     OBJ slf = self;
  1220     OBJ slf = self;
  1221     OBJ rct = aRectangle;
  1221     OBJ rct = aRectangle;
  1222 
  1222 
  1223     if (__isNonNilObject(rct) 
  1223     if (__isNonNilObject(rct)
  1224      && __qClass(rct) == Rectangle) {
  1224      && __qClass(rct) == Rectangle) {
  1225         OBJ r_l, r_w, r_t, r_h, l, w, t, h;
  1225 	OBJ r_l, r_w, r_t, r_h, l, w, t, h;
  1226         INT r_ir, r_il, r_ib, r_it;
  1226 	INT r_ir, r_il, r_ib, r_it;
  1227         INT il, it, ir, ib, iw, ih;
  1227 	INT il, it, ir, ib, iw, ih;
  1228 
  1228 
  1229         r_l = __OINST(rct, left);
  1229 	r_l = __OINST(rct, left);
  1230         l = __OINST(slf, left);
  1230 	l = __OINST(slf, left);
  1231         if (__bothSmallInteger(r_l, l)) {
  1231 	if (__bothSmallInteger(r_l, l)) {
  1232 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1232 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1233             il = (INT)(l);
  1233 	    il = (INT)(l);
  1234             r_il = (INT)(r_l);
  1234 	    r_il = (INT)(r_l);
  1235 #else
  1235 #else
  1236             il = __intVal(l);
  1236 	    il = __intVal(l);
  1237             r_il = __intVal(r_l);
  1237 	    r_il = __intVal(r_l);
  1238 #endif
  1238 #endif
  1239             if (il > r_il) { RETURN (false); }   /* left > aRectangle left */
  1239 	    if (il > r_il) { RETURN (false); }   /* left > aRectangle left */
  1240 
  1240 
  1241             r_t = __OINST(rct, top);
  1241 	    r_t = __OINST(rct, top);
  1242             t = __OINST(slf, top);
  1242 	    t = __OINST(slf, top);
  1243             if (__bothSmallInteger(r_t, t)) {
  1243 	    if (__bothSmallInteger(r_t, t)) {
  1244 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1244 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1245                 it = (INT)(t);
  1245 		it = (INT)(t);
  1246                 r_it = (INT)(r_t);
  1246 		r_it = (INT)(r_t);
  1247 #else
  1247 #else
  1248                 it = __intVal(t);
  1248 		it = __intVal(t);
  1249                 r_it = __intVal(r_t);
  1249 		r_it = __intVal(r_t);
  1250 #endif
  1250 #endif
  1251                 if (it > r_it) { RETURN (false); }   /* top > aRectangle top */
  1251 		if (it > r_it) { RETURN (false); }   /* top > aRectangle top */
  1252 
  1252 
  1253                 r_w = __OINST(rct, width);
  1253 		r_w = __OINST(rct, width);
  1254                 w = __OINST(slf, width);
  1254 		w = __OINST(slf, width);
  1255                 if (__bothSmallInteger(r_w, w)) {
  1255 		if (__bothSmallInteger(r_w, w)) {
  1256 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1256 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1257                     ir = il + (INT)(w);
  1257 		    ir = il + (INT)(w);
  1258                     r_ir = r_il + (INT)(r_w);
  1258 		    r_ir = r_il + (INT)(r_w);
  1259 #else
  1259 #else
  1260                     ir = il + __intVal(w);
  1260 		    ir = il + __intVal(w);
  1261                     r_ir = r_il + __intVal(r_w);
  1261 		    r_ir = r_il + __intVal(r_w);
  1262 #endif
  1262 #endif
  1263                     if (ir < r_ir) { RETURN (false); }   /* (left + width) < aRectangle right */
  1263 		    if (ir < r_ir) { RETURN (false); }   /* (left + width) < aRectangle right */
  1264 
  1264 
  1265                     r_h = __OINST(rct, height);
  1265 		    r_h = __OINST(rct, height);
  1266                     h = __OINST(slf, height);
  1266 		    h = __OINST(slf, height);
  1267                     if (__bothSmallInteger(r_h, h)) {
  1267 		    if (__bothSmallInteger(r_h, h)) {
  1268 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1268 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1269                         ib = it + (INT)(h);
  1269 			ib = it + (INT)(h);
  1270                         r_ib = r_it + (INT)(r_h);
  1270 			r_ib = r_it + (INT)(r_h);
  1271 #else
  1271 #else
  1272                         ib = it + __intVal(h);
  1272 			ib = it + __intVal(h);
  1273                         r_ib = r_it + __intVal(r_h);
  1273 			r_ib = r_it + __intVal(r_h);
  1274 #endif
  1274 #endif
  1275                         if (ib < r_ib) { RETURN (false); }   /* (top + height) < aRectangle bottom */
  1275 			if (ib < r_ib) { RETURN (false); }   /* (top + height) < aRectangle bottom */
  1276                         RETURN (true);
  1276 			RETURN (true);
  1277                     }
  1277 		    }
  1278                 }
  1278 		}
  1279             }
  1279 	    }
  1280         }
  1280 	}
  1281     }
  1281     }
  1282 %}.
  1282 %}.
  1283     (left <= aRectangle left) ifTrue:[
  1283     (left <= aRectangle left) ifTrue:[
  1284       ((left + width) >= aRectangle right) ifTrue:[
  1284       ((left + width) >= aRectangle right) ifTrue:[
  1285         (top <= aRectangle top) ifTrue:[
  1285 	(top <= aRectangle top) ifTrue:[
  1286           ((top + height) >= aRectangle bottom) ifTrue:[
  1286 	  ((top + height) >= aRectangle bottom) ifTrue:[
  1287             ^ true
  1287 	    ^ true
  1288           ]
  1288 	  ]
  1289         ]
  1289 	]
  1290       ]
  1290       ]
  1291     ].
  1291     ].
  1292     ^ false
  1292     ^ false
  1293 
  1293 
  1294     "
  1294     "
  1295      (0@0 corner:100@100) contains:(10@10 corner:90@90) 
  1295      (0@0 corner:100@100) contains:(10@10 corner:90@90)
  1296      (0@0 corner:100@100) contains:(10@10 corner:100@100)  
  1296      (0@0 corner:100@100) contains:(10@10 corner:100@100)
  1297      (0@0 corner:100@100) contains:(10@10 corner:110@100) 
  1297      (0@0 corner:100@100) contains:(10@10 corner:110@100)
  1298      (0@0 corner:100@100) contains:(10@10 corner:100@110) 
  1298      (0@0 corner:100@100) contains:(10@10 corner:100@110)
  1299      (10@10 corner:100@100) contains:(0@10 corner:100@100) 
  1299      (10@10 corner:100@100) contains:(0@10 corner:100@100)
  1300     "
  1300     "
  1301 !
  1301 !
  1302 
  1302 
  1303 containsPoint:aPoint
  1303 containsPoint:aPoint
  1304     "return true, if the argument, aPoint is contained in the receiver"
  1304     "return true, if the argument, aPoint is contained in the receiver"
  1329 
  1329 
  1330 corners
  1330 corners
  1331     "Return an array of corner points"
  1331     "Return an array of corner points"
  1332 
  1332 
  1333     ^ Array
  1333     ^ Array
  1334         with: self topLeft
  1334 	with: self topLeft
  1335         with: self bottomLeft
  1335 	with: self bottomLeft
  1336         with: self bottomRight
  1336 	with: self bottomRight
  1337         with: self topRight
  1337 	with: self topRight
  1338 
  1338 
  1339 
  1339 
  1340 !
  1340 !
  1341 
  1341 
  1342 innerCorners
  1342 innerCorners
  1345      Added for Aqueak compatibility."
  1345      Added for Aqueak compatibility."
  1346 
  1346 
  1347     ^ (self topLeft corner:(self bottomRight - (1@1))) corners
  1347     ^ (self topLeft corner:(self bottomRight - (1@1))) corners
  1348 
  1348 
  1349     "
  1349     "
  1350      (10@10 corner:100@100) corners   
  1350      (10@10 corner:100@100) corners
  1351      (10@10 corner:100@100) innerCorners 
  1351      (10@10 corner:100@100) innerCorners
  1352     "
  1352     "
  1353 !
  1353 !
  1354 
  1354 
  1355 intersects:aRectangle
  1355 intersects:aRectangle
  1356     "return true, if the intersection between the argument, aRectangle
  1356     "return true, if the intersection between the argument, aRectangle
  1365      * speeds up drawing by almost a factor of 2 ...
  1365      * speeds up drawing by almost a factor of 2 ...
  1366      */
  1366      */
  1367     OBJ slf = self;
  1367     OBJ slf = self;
  1368     OBJ rct = aRectangle;
  1368     OBJ rct = aRectangle;
  1369 
  1369 
  1370     if (__isNonNilObject(rct) 
  1370     if (__isNonNilObject(rct)
  1371      && __qClass(rct) == Rectangle) {
  1371      && __qClass(rct) == Rectangle) {
  1372         OBJ r_l, r_w, r_t, r_h, l, w, t, h;
  1372 	OBJ r_l, r_w, r_t, r_h, l, w, t, h;
  1373         INT r_ir, r_il, r_ib, r_it;
  1373 	INT r_ir, r_il, r_ib, r_it;
  1374         INT il, it, ir, ib, iw, ih;
  1374 	INT il, it, ir, ib, iw, ih;
  1375 
  1375 
  1376         r_l = __OINST(rct, left);
  1376 	r_l = __OINST(rct, left);
  1377         r_w = __OINST(rct, width);
  1377 	r_w = __OINST(rct, width);
  1378 
  1378 
  1379         if (__bothSmallInteger(r_l, r_w)) {
  1379 	if (__bothSmallInteger(r_l, r_w)) {
  1380             r_t = __OINST(rct, top);
  1380 	    r_t = __OINST(rct, top);
  1381             r_h = __OINST(rct, height);
  1381 	    r_h = __OINST(rct, height);
  1382 
  1382 
  1383             l = __OINST(slf, left);
  1383 	    l = __OINST(slf, left);
  1384             w = __OINST(slf, width);
  1384 	    w = __OINST(slf, width);
  1385 
  1385 
  1386             if (__bothSmallInteger(l, w)) {
  1386 	    if (__bothSmallInteger(l, w)) {
  1387                 t = __OINST(slf, top);
  1387 		t = __OINST(slf, top);
  1388                 h = __OINST(slf, height);
  1388 		h = __OINST(slf, height);
  1389 
  1389 
  1390 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1390 #ifndef POSITIVE_ADDRESSES      /* tag in low-bit */
  1391                 r_il = (INT)(r_l);
  1391 		r_il = (INT)(r_l);
  1392                 r_ir = r_il + (INT)(r_w) - 1;
  1392 		r_ir = r_il + (INT)(r_w) - 1;
  1393                 il = (INT)(l);
  1393 		il = (INT)(l);
  1394                 if (r_ir < il) { RETURN (false); }
  1394 		if (r_ir < il) { RETURN (false); }
  1395                 ir = il + (INT)(w) - 1;
  1395 		ir = il + (INT)(w) - 1;
  1396                 if (r_il > ir) { RETURN (false); }
  1396 		if (r_il > ir) { RETURN (false); }
  1397 #else                           /* tag in hi-bit */
  1397 #else                           /* tag in hi-bit */
  1398                 r_il = __intVal(r_l);
  1398 		r_il = __intVal(r_l);
  1399                 r_ir = r_il + __intVal(r_w);        /* aRectangle right */
  1399 		r_ir = r_il + __intVal(r_w);        /* aRectangle right */
  1400                 il = __intVal(l);
  1400 		il = __intVal(l);
  1401                 if (r_ir < il) { RETURN (false); }  /* (aRectangle right) < left */
  1401 		if (r_ir < il) { RETURN (false); }  /* (aRectangle right) < left */
  1402 
  1402 
  1403                 ir = il + __intVal(w);
  1403 		ir = il + __intVal(w);
  1404                 if (r_il > ir) { RETURN (false); }   /* (aRectangle left) > r */
  1404 		if (r_il > ir) { RETURN (false); }   /* (aRectangle left) > r */
  1405 #endif
  1405 #endif
  1406 
  1406 
  1407                 if (__bothSmallInteger(r_t, r_h)) {
  1407 		if (__bothSmallInteger(r_t, r_h)) {
  1408                     if (__bothSmallInteger(t, h)) {
  1408 		    if (__bothSmallInteger(t, h)) {
  1409 #ifndef POSITIVE_ADDRESSES
  1409 #ifndef POSITIVE_ADDRESSES
  1410                         r_it = (INT)(r_t);
  1410 			r_it = (INT)(r_t);
  1411                         r_ib = r_it + (INT)(r_h) - 1; /* aRectangle bottom */
  1411 			r_ib = r_it + (INT)(r_h) - 1; /* aRectangle bottom */
  1412                         it = (INT)(t);
  1412 			it = (INT)(t);
  1413                         if (r_ib < it) { RETURN (false); } /* (aRectangle bottom) < top */
  1413 			if (r_ib < it) { RETURN (false); } /* (aRectangle bottom) < top */
  1414 
  1414 
  1415                         ib = it + (INT)(h) - 1;
  1415 			ib = it + (INT)(h) - 1;
  1416                         if (r_it > ib) { RETURN (false); } /* (aRectangle top) > b */
  1416 			if (r_it > ib) { RETURN (false); } /* (aRectangle top) > b */
  1417 #else
  1417 #else
  1418                         r_it = __intVal(r_t);
  1418 			r_it = __intVal(r_t);
  1419                         r_ib = r_it + __intVal(r_h); /* aRectangle bottom */
  1419 			r_ib = r_it + __intVal(r_h); /* aRectangle bottom */
  1420                         it = __intVal(t);
  1420 			it = __intVal(t);
  1421                         if (r_ib < it) { RETURN (false); } /* (aRectangle bottom) < top */
  1421 			if (r_ib < it) { RETURN (false); } /* (aRectangle bottom) < top */
  1422 
  1422 
  1423                         ib = it + __intVal(h);
  1423 			ib = it + __intVal(h);
  1424                         if (r_it > ib) { RETURN (false); } /* (aRectangle top) > b */
  1424 			if (r_it > ib) { RETURN (false); } /* (aRectangle top) > b */
  1425 #endif
  1425 #endif
  1426                         RETURN (true);
  1426 			RETURN (true);
  1427                     }
  1427 		    }
  1428                 }
  1428 		}
  1429             }
  1429 	    }
  1430         }
  1430 	}
  1431     }
  1431     }
  1432 %}.
  1432 %}.
  1433     (aRectangle right)  < left ifTrue:[^ false].
  1433     (aRectangle right)  < left ifTrue:[^ false].
  1434     (aRectangle bottom) < top  ifTrue:[^ false].
  1434     (aRectangle bottom) < top  ifTrue:[^ false].
  1435     r := left + width.
  1435     r := left + width.
  1438     (aRectangle top)    > b    ifTrue:[^ false].
  1438     (aRectangle top)    > b    ifTrue:[^ false].
  1439     ^ true
  1439     ^ true
  1440 !
  1440 !
  1441 
  1441 
  1442 isContainedIn:aRectangle
  1442 isContainedIn:aRectangle
  1443     "return true, if the receiver is fully contained within 
  1443     "return true, if the receiver is fully contained within
  1444      the argument, aRectangle"
  1444      the argument, aRectangle"
  1445 
  1445 
  1446     (aRectangle left <= left) ifTrue:[
  1446     (aRectangle left <= left) ifTrue:[
  1447       (aRectangle right >= (left + width)) ifTrue:[
  1447       (aRectangle right >= (left + width)) ifTrue:[
  1448         (aRectangle top <= top) ifTrue:[
  1448 	(aRectangle top <= top) ifTrue:[
  1449           (aRectangle bottom >= (top + height)) ifTrue:[
  1449 	  (aRectangle bottom >= (top + height)) ifTrue:[
  1450             ^ true
  1450 	    ^ true
  1451           ]
  1451 	  ]
  1452         ]
  1452 	]
  1453       ]
  1453       ]
  1454     ].
  1454     ].
  1455     ^ false
  1455     ^ false
  1456 
  1456 
  1457     "
  1457     "
  1471      origin translated by the argument, aPoint"
  1471      origin translated by the argument, aPoint"
  1472 
  1472 
  1473     |amountPoint|
  1473     |amountPoint|
  1474 
  1474 
  1475     (aPoint isMemberOf:SmallInteger) ifTrue:[
  1475     (aPoint isMemberOf:SmallInteger) ifTrue:[
  1476         "/ this is an stc optimization
  1476 	"/ this is an stc optimization
  1477         ^ Rectangle 
  1477 	^ Rectangle
  1478             left:(left + aPoint)
  1478 	    left:(left + aPoint)
  1479             top:(top + aPoint)
  1479 	    top:(top + aPoint)
  1480             width:width
  1480 	    width:width
  1481             height:height
  1481 	    height:height
  1482     ].
  1482     ].
  1483 
  1483 
  1484     amountPoint := aPoint asPoint.
  1484     amountPoint := aPoint asPoint.
  1485     ^ Rectangle left:(left + amountPoint x)
  1485     ^ Rectangle left:(left + amountPoint x)
  1486                  top:(top + amountPoint y)
  1486 		 top:(top + amountPoint y)
  1487                width:width
  1487 	       width:width
  1488               height:height
  1488 	      height:height
  1489 
  1489 
  1490     "Modified: 25.1.1997 / 17:29:53 / cg"
  1490     "Modified: 25.1.1997 / 17:29:53 / cg"
  1491 !
  1491 !
  1492 
  1492 
  1493 - aPoint
  1493 - aPoint
  1495      origin translated by the argument, aPoint"
  1495      origin translated by the argument, aPoint"
  1496 
  1496 
  1497     |amountPoint|
  1497     |amountPoint|
  1498 
  1498 
  1499     (aPoint isMemberOf:SmallInteger) ifTrue:[
  1499     (aPoint isMemberOf:SmallInteger) ifTrue:[
  1500         "/ this is an stc optimization
  1500 	"/ this is an stc optimization
  1501         ^ Rectangle 
  1501 	^ Rectangle
  1502             left:(left - aPoint)
  1502 	    left:(left - aPoint)
  1503             top:(top - aPoint)
  1503 	    top:(top - aPoint)
  1504             width:width
  1504 	    width:width
  1505             height:height
  1505 	    height:height
  1506     ].
  1506     ].
  1507 
  1507 
  1508     amountPoint := aPoint asPoint.
  1508     amountPoint := aPoint asPoint.
  1509     ^ Rectangle left:(left - amountPoint x)
  1509     ^ Rectangle left:(left - amountPoint x)
  1510                  top:(top - amountPoint y)
  1510 		 top:(top - amountPoint y)
  1511                width:width
  1511 	       width:width
  1512               height:height
  1512 	      height:height
  1513 
  1513 
  1514     "Modified: 25.1.1997 / 17:29:53 / cg"
  1514     "Modified: 25.1.1997 / 17:29:53 / cg"
  1515     "Created: 25.1.1997 / 17:30:21 / cg"
  1515     "Created: 25.1.1997 / 17:30:21 / cg"
  1516 !
  1516 !
  1517 
  1517 
  1518 areasOutside: aRectangle
  1518 areasOutside: aRectangle
  1519     "Answer an Array of Rectangles comprising the parts of the receiver not 
  1519     "Answer an Array of Rectangles comprising the parts of the receiver not
  1520     intersecting aRectangle."
  1520     intersecting aRectangle."
  1521 
  1521 
  1522     | areas yOrigin yCorner origin corner|
  1522     | areas yOrigin yCorner origin corner|
  1523 
  1523 
  1524     origin := self origin.
  1524     origin := self origin.
  1525     corner := self corner.
  1525     corner := self corner.
  1526 
  1526 
  1527     "Make sure the intersection is non-empty"
  1527     "Make sure the intersection is non-empty"
  1528     (origin <= aRectangle corner and: [aRectangle origin <= corner])
  1528     (origin <= aRectangle corner and: [aRectangle origin <= corner])
  1529             ifFalse: [^ Array with: self].
  1529 	    ifFalse: [^ Array with: self].
  1530     areas := OrderedCollection new.
  1530     areas := OrderedCollection new.
  1531     aRectangle origin y > origin y
  1531     aRectangle origin y > origin y
  1532             ifTrue: [areas addLast: (origin corner: corner x @ (yOrigin := aRectangle origin y))]
  1532 	    ifTrue: [areas addLast: (origin corner: corner x @ (yOrigin := aRectangle origin y))]
  1533             ifFalse: [yOrigin := origin y].
  1533 	    ifFalse: [yOrigin := origin y].
  1534     aRectangle corner y < corner y
  1534     aRectangle corner y < corner y
  1535             ifTrue: [areas addLast: (origin x @ (yCorner := aRectangle corner y) corner: corner)]
  1535 	    ifTrue: [areas addLast: (origin x @ (yCorner := aRectangle corner y) corner: corner)]
  1536             ifFalse: [yCorner := corner y].
  1536 	    ifFalse: [yCorner := corner y].
  1537     aRectangle origin x > origin x 
  1537     aRectangle origin x > origin x
  1538             ifTrue: [areas addLast: (origin x @ yOrigin corner: aRectangle origin x @ yCorner)].
  1538 	    ifTrue: [areas addLast: (origin x @ yOrigin corner: aRectangle origin x @ yCorner)].
  1539     aRectangle corner x < corner x 
  1539     aRectangle corner x < corner x
  1540             ifTrue: [areas addLast: (aRectangle corner x @ yOrigin corner: corner x @ yCorner)].
  1540 	    ifTrue: [areas addLast: (aRectangle corner x @ yOrigin corner: corner x @ yCorner)].
  1541     ^areas    
  1541     ^areas
  1542 
  1542 
  1543     "/ cg: the old code below was wrong ...
  1543     "/ cg: the old code below was wrong ...
  1544 
  1544 
  1545 "/    "----------------------------------------------------------------
  1545 "/    "----------------------------------------------------------------
  1546 "/    | added for GNU-ST compatibility
  1546 "/    | added for GNU-ST compatibility
  1547 "/    |
  1547 "/    |
  1548 "/    | author: Doug McCallum <uunet!!ico.isc.com!!dougm>
  1548 "/    | author: Doug McCallum <uunet!!ico.isc.com!!dougm>
  1549 "/    |
  1549 "/    |
  1550 "/    |areasOutside: aRectangle
  1550 "/    |areasOutside: aRectangle
  1551 "/    | most complicated of the Rectangle primitives
  1551 "/    | most complicated of the Rectangle primitives
  1552 "/    | The basic methodology is to first determine that there is an 
  1552 "/    | The basic methodology is to first determine that there is an
  1553 "/    | intersection by finding the overlapping rectangle.  From the
  1553 "/    | intersection by finding the overlapping rectangle.  From the
  1554 "/    | overlapping rectangle, first determine if it runs along an edge.
  1554 "/    | overlapping rectangle, first determine if it runs along an edge.
  1555 "/    | If it doesn't, extend the rectangle up to the top edge and add
  1555 "/    | If it doesn't, extend the rectangle up to the top edge and add
  1556 "/    | the new rectangle to the collection and start the rest of the
  1556 "/    | the new rectangle to the collection and start the rest of the
  1557 "/    | process.  If the left edge does not touch the left edge of self,
  1557 "/    | process.  If the left edge does not touch the left edge of self,
  1558 "/    | extend it to the edge saving the new rectangle.  Then do the 
  1558 "/    | extend it to the edge saving the new rectangle.  Then do the
  1559 "/    | same to the right edge.  Then check top and bottom edges.  Most
  1559 "/    | same to the right edge.  Then check top and bottom edges.  Most
  1560 "/    | of the time only 2 or 3 rectangles get formed, occasionally 4.
  1560 "/    | of the time only 2 or 3 rectangles get formed, occasionally 4.
  1561 "/    | It should be possible to never get more than 3 but requires more
  1561 "/    | It should be possible to never get more than 3 but requires more
  1562 "/    | work.
  1562 "/    | work.
  1563 "/     ----------------------------------------------------------------"
  1563 "/     ----------------------------------------------------------------"
  1567 "/    iRect := self intersect: aRectangle.
  1567 "/    iRect := self intersect: aRectangle.
  1568 "/    iRect isNil ifTrue: [^nil]. "case of no intersection"
  1568 "/    iRect isNil ifTrue: [^nil]. "case of no intersection"
  1569 "/                                "the collect collection gathers Rectangles"
  1569 "/                                "the collect collection gathers Rectangles"
  1570 "/    collect := OrderedCollection new: 4.
  1570 "/    collect := OrderedCollection new: 4.
  1571 "/                                "is it floating or on the edge?"
  1571 "/                                "is it floating or on the edge?"
  1572 "/    (((((iRect top) ~= self top) 
  1572 "/    (((((iRect top) ~= self top)
  1573 "/         and: [ (iRect bottom) ~= self bottom ])
  1573 "/         and: [ (iRect bottom) ~= self bottom ])
  1574 "/         and: [ (iRect left) ~= self left ])
  1574 "/         and: [ (iRect left) ~= self left ])
  1575 "/         and: [ (iRect right) ~= self right ] )
  1575 "/         and: [ (iRect right) ~= self right ] )
  1576 "/        ifTrue: "entirely in the center."
  1576 "/        ifTrue: "entirely in the center."
  1577 "/            [tmp := Rectangle origin: (Point x: iRect left y: self top)
  1577 "/            [tmp := Rectangle origin: (Point x: iRect left y: self top)
  1600 "/            [tmp := Rectangle origin: iRect bottomLeft corner: self corner.
  1600 "/            [tmp := Rectangle origin: iRect bottomLeft corner: self corner.
  1601 "/                 collect add: tmp].
  1601 "/                 collect add: tmp].
  1602 "/    ^collect
  1602 "/    ^collect
  1603 !
  1603 !
  1604 
  1604 
  1605 encompass:aPoint 
  1605 encompass:aPoint
  1606     "return a Rectangle that contains both the receiver and aPoint."
  1606     "return a Rectangle that contains both the receiver and aPoint."
  1607 
  1607 
  1608     ^ Rectangle 
  1608     ^ Rectangle
  1609         origin: (self origin min: aPoint)
  1609 	origin: (self origin min: aPoint)
  1610         corner: (self corner max: aPoint)
  1610 	corner: (self corner max: aPoint)
  1611 
  1611 
  1612 !
  1612 !
  1613 
  1613 
  1614 expandedBy:delta
  1614 expandedBy:delta
  1615     "return a new rectangle which is expanded in all directions
  1615     "return a new rectangle which is expanded in all directions
  1618     ^ self copy expandBy:delta
  1618     ^ self copy expandBy:delta
  1619 
  1619 
  1620     "
  1620     "
  1621      |r|
  1621      |r|
  1622      r := Rectangle origin:10@10 corner:100@100.
  1622      r := Rectangle origin:10@10 corner:100@100.
  1623      r expandedBy:5.   
  1623      r expandedBy:5.
  1624      r expandedBy:(5 @ 0).  
  1624      r expandedBy:(5 @ 0).
  1625      r expandedBy:(10 @ 10).  
  1625      r expandedBy:(10 @ 10).
  1626      r expandedBy:( 10@10 corner:20@20 )  
  1626      r expandedBy:( 10@10 corner:20@20 )
  1627     "
  1627     "
  1628 !
  1628 !
  1629 
  1629 
  1630 insetBy: delta
  1630 insetBy: delta
  1631     "return a new rectangle which is inset in all directions
  1631     "return a new rectangle which is inset in all directions
  1664      r insetBy:( 10@10 corner:20@20 )
  1664      r insetBy:( 10@10 corner:20@20 )
  1665     "
  1665     "
  1666 !
  1666 !
  1667 
  1667 
  1668 insetOriginBy:originDelta cornerBy:cornerDelta
  1668 insetOriginBy:originDelta cornerBy:cornerDelta
  1669     "return a new rectangle which is inset by originDelta 
  1669     "return a new rectangle which is inset by originDelta
  1670      and cornerDelta; both may be instances of Point or Number"
  1670      and cornerDelta; both may be instances of Point or Number"
  1671 
  1671 
  1672     ^ Rectangle
  1672     ^ Rectangle
  1673 	origin:(left @ top) + originDelta asPoint
  1673 	origin:(left @ top) + originDelta asPoint
  1674 	corner:(self corner - cornerDelta asPoint)
  1674 	corner:(self corner - cornerDelta asPoint)
  1675     "
  1675     "
  1676      |r|
  1676      |r|
  1677      r := Rectangle origin:10@10 corner:100@100.
  1677      r := Rectangle origin:10@10 corner:100@100.
  1678      r insetOriginBy:5 cornerBy:10. 
  1678      r insetOriginBy:5 cornerBy:10.
  1679      r insetOriginBy:10@5 cornerBy:10.
  1679      r insetOriginBy:10@5 cornerBy:10.
  1680      r insetOriginBy:10 cornerBy:10@5. 
  1680      r insetOriginBy:10 cornerBy:10@5.
  1681      r insetOriginBy:10@10 cornerBy:20@20.
  1681      r insetOriginBy:10@10 cornerBy:20@20.
  1682     "
  1682     "
  1683 !
  1683 !
  1684 
  1684 
  1685 intersect:aRectangle
  1685 intersect:aRectangle
  1686     "return a new rectangle covering the intersection of the receiver
  1686     "return a new rectangle covering the intersection of the receiver
  1687      and the argument, aRectangle (i.e. the area covered by both).
  1687      and the argument, aRectangle (i.e. the area covered by both).
  1688      the rectangles must intersect for a valid return"
  1688      the rectangles must intersect for a valid return"
  1689 
  1689 
  1690     ^ Rectangle left:(left max:(aRectangle left))
  1690     ^ Rectangle left:(left max:(aRectangle left))
  1691                right:((left + width) min:(aRectangle right))
  1691 	       right:((left + width) min:(aRectangle right))
  1692                  top:(top max:(aRectangle top))
  1692 		 top:(top max:(aRectangle top))
  1693               bottom:((top + height) min:(aRectangle bottom))
  1693 	      bottom:((top + height) min:(aRectangle bottom))
  1694 
  1694 
  1695     "
  1695     "
  1696      |r1 r2|
  1696      |r1 r2|
  1697 
  1697 
  1698      r1 := Rectangle origin:10@10 corner:100@100.
  1698      r1 := Rectangle origin:10@10 corner:100@100.
  1700      r1 intersect:r2
  1700      r1 intersect:r2
  1701     "
  1701     "
  1702 !
  1702 !
  1703 
  1703 
  1704 merge:aRectangle
  1704 merge:aRectangle
  1705     "return a new rectangle covering both the receiver 
  1705     "return a new rectangle covering both the receiver
  1706      and the argument, aRectangle"
  1706      and the argument, aRectangle"
  1707 
  1707 
  1708     ^ Rectangle left:(left min:(aRectangle left))
  1708     ^ Rectangle left:(left min:(aRectangle left))
  1709                right:((left + width) max:(aRectangle right))
  1709 	       right:((left + width) max:(aRectangle right))
  1710                  top:(top min:(aRectangle top))
  1710 		 top:(top min:(aRectangle top))
  1711               bottom:((top + height) max:(aRectangle bottom))
  1711 	      bottom:((top + height) max:(aRectangle bottom))
  1712 
  1712 
  1713     "
  1713     "
  1714      (Rectangle origin:10@10 corner:100@100)
  1714      (Rectangle origin:10@10 corner:100@100)
  1715          merge:(Rectangle origin:20@20 corner:110@110)
  1715 	 merge:(Rectangle origin:20@20 corner:110@110)
  1716 
  1716 
  1717      (Rectangle origin:10@10 corner:100@100)
  1717      (Rectangle origin:10@10 corner:100@100)
  1718          merge:(Rectangle origin:20@20 corner:100@100)
  1718 	 merge:(Rectangle origin:20@20 corner:100@100)
  1719     "
  1719     "
  1720 !
  1720 !
  1721 
  1721 
  1722 nonIntersections:aRectangle
  1722 nonIntersections:aRectangle
  1723     "this is the same as areasOutside: - for ST/V compatibility only"
  1723     "this is the same as areasOutside: - for ST/V compatibility only"
  1724 
  1724 
  1725     ^ self areasOutside:aRectangle
  1725     ^ self areasOutside:aRectangle
  1726 !
  1726 !
  1727 
  1727 
  1728 quickMerge: aRectangle 
  1728 quickMerge: aRectangle
  1729     "return the receiver if it encloses the given rectangle,
  1729     "return the receiver if it encloses the given rectangle,
  1730      or the merge of the two rectangles if it doesn't. 
  1730      or the merge of the two rectangles if it doesn't.
  1731      This method is an optimized version of merge: to reduce extra rectangle creations."
  1731      This method is an optimized version of merge: to reduce extra rectangle creations."
  1732 
  1732 
  1733     | useRcvr rLeft rTop rRight rBottom minX maxX minY maxY |
  1733     | useRcvr rLeft rTop rRight rBottom minX maxX minY maxY |
  1734 
  1734 
  1735     useRcvr := true.
  1735     useRcvr := true.
  1747     rTop < minY ifTrue: [useRcvr := false. minY := rTop].
  1747     rTop < minY ifTrue: [useRcvr := false. minY := rTop].
  1748     maxY := self bottom.
  1748     maxY := self bottom.
  1749     rBottom > maxY ifTrue: [useRcvr := false. maxY := rBottom].
  1749     rBottom > maxY ifTrue: [useRcvr := false. maxY := rBottom].
  1750 
  1750 
  1751     useRcvr ifTrue: [
  1751     useRcvr ifTrue: [
  1752         ^ self
  1752 	^ self
  1753     ].
  1753     ].
  1754 
  1754 
  1755     minX = rLeft ifTrue:[
  1755     minX = rLeft ifTrue:[
  1756         maxX = rRight ifTrue:[
  1756 	maxX = rRight ifTrue:[
  1757             minY = rTop ifTrue:[
  1757 	    minY = rTop ifTrue:[
  1758                 maxY = rBottom ifTrue:[
  1758 		maxY = rBottom ifTrue:[
  1759                     ^ aRectangle
  1759 		    ^ aRectangle
  1760                 ].
  1760 		].
  1761             ].
  1761 	    ].
  1762         ].
  1762 	].
  1763     ].
  1763     ].
  1764 
  1764 
  1765     ^ Rectangle left:minX top:minY right:maxX bottom:maxY.
  1765     ^ Rectangle left:minX top:minY right:maxX bottom:maxY.
  1766 
  1766 
  1767     "
  1767     "
  1768      (Rectangle origin:10@10 corner:100@100)  
       
  1769          quickMerge:(Rectangle origin:20@20 corner:110@110)   
       
  1770 
       
  1771      (Rectangle origin:10@10 corner:100@100)
  1768      (Rectangle origin:10@10 corner:100@100)
  1772          quickMerge:(Rectangle origin:20@20 corner:100@100)
  1769 	 quickMerge:(Rectangle origin:20@20 corner:110@110)
       
  1770 
       
  1771      (Rectangle origin:10@10 corner:100@100)
       
  1772 	 quickMerge:(Rectangle origin:20@20 corner:100@100)
  1773     "
  1773     "
  1774 !
  1774 !
  1775 
  1775 
  1776 scaledBy:scale
  1776 scaledBy:scale
  1777     "return a new rectangle which is the receiver
  1777     "return a new rectangle which is the receiver
  1778      scaled by scale"
  1778      scaled by scale"
  1779 
  1779 
  1780     |scalePoint sx sy|
  1780     |scalePoint sx sy|
  1781 
  1781 
  1782     (scale isMemberOf:SmallInteger) ifTrue:[
  1782     (scale isMemberOf:SmallInteger) ifTrue:[
  1783         "/ this is an stc optimization
  1783 	"/ this is an stc optimization
  1784         ^ Rectangle left:left * scale
  1784 	^ Rectangle left:left * scale
  1785                      top:top * scale
  1785 		     top:top * scale
  1786                    width:width * scale
  1786 		   width:width * scale
  1787                   height:height * scale
  1787 		  height:height * scale
  1788     ].
  1788     ].
  1789 
  1789 
  1790     scalePoint := scale asPoint.
  1790     scalePoint := scale asPoint.
  1791     sx := scalePoint x.
  1791     sx := scalePoint x.
  1792     sy := scalePoint y.
  1792     sy := scalePoint y.
  1793     ^ Rectangle left:left * sx
  1793     ^ Rectangle left:left * sx
  1794                  top:top * sy
  1794 		 top:top * sy
  1795                width:width * sx
  1795 	       width:width * sx
  1796               height:height * sy
  1796 	      height:height * sy
  1797     "
  1797     "
  1798      (Rectangle origin:10@10 corner:50@50) scaledBy:2   
  1798      (Rectangle origin:10@10 corner:50@50) scaledBy:2
  1799     "
  1799     "
  1800 
  1800 
  1801     "it is NOT destructive:"
  1801     "it is NOT destructive:"
  1802     "
  1802     "
  1803      |r1 r2|
  1803      |r1 r2|
  1804 
  1804 
  1805      r1 := Rectangle origin:10@10 corner:50@50.
  1805      r1 := Rectangle origin:10@10 corner:50@50.
  1806      r2 := r1 scaledBy:2.    
  1806      r2 := r1 scaledBy:2.
  1807      r1  
  1807      r1
  1808     "
  1808     "
  1809 !
  1809 !
  1810 
  1810 
  1811 scaledBy:scale translatedBy:translation 
  1811 scaledBy:scale translatedBy:translation
  1812     "return a new rectangle which is translated (i.e. moved)
  1812     "return a new rectangle which is translated (i.e. moved)
  1813      by translation, aPoint or Number and scaled by scale, aPoint or number."
  1813      by translation, aPoint or Number and scaled by scale, aPoint or number."
  1814 
  1814 
  1815     |x y w h translationPoint scalePoint sx sy|
  1815     |x y w h translationPoint scalePoint sx sy|
  1816 
  1816 
  1817     (translation isNil and:[scale isNil]) ifTrue:[
  1817     (translation isNil and:[scale isNil]) ifTrue:[
  1818         ^ self.
  1818 	^ self.
  1819     ].
  1819     ].
  1820 
  1820 
  1821     x := left.
  1821     x := left.
  1822     y := top.
  1822     y := top.
  1823     w := width.
  1823     w := width.
  1824     h := height.
  1824     h := height.
  1825 
  1825 
  1826     scale notNil ifTrue:[
  1826     scale notNil ifTrue:[
  1827         (scale isMemberOf:SmallInteger) ifTrue:[
  1827 	(scale isMemberOf:SmallInteger) ifTrue:[
  1828             "/ this is an stc optimization
  1828 	    "/ this is an stc optimization
  1829             x := x * scale.
  1829 	    x := x * scale.
  1830             y := y * scale.
  1830 	    y := y * scale.
  1831             w := w * scale.
  1831 	    w := w * scale.
  1832             h := h * scale.
  1832 	    h := h * scale.
  1833         ] ifFalse:[
  1833 	] ifFalse:[
  1834             scalePoint := scale asPoint.
  1834 	    scalePoint := scale asPoint.
  1835             sx := scalePoint x.
  1835 	    sx := scalePoint x.
  1836             sy := scalePoint y.
  1836 	    sy := scalePoint y.
  1837             x := x * sx.
  1837 	    x := x * sx.
  1838             y := y * sy.
  1838 	    y := y * sy.
  1839             w := w * sx.
  1839 	    w := w * sx.
  1840             h := h * sy.
  1840 	    h := h * sy.
  1841         ].
  1841 	].
  1842     ].
  1842     ].
  1843     translation notNil ifTrue:[
  1843     translation notNil ifTrue:[
  1844         (translation isMemberOf:SmallInteger) ifTrue:[
  1844 	(translation isMemberOf:SmallInteger) ifTrue:[
  1845             "/ this is an stc optimization
  1845 	    "/ this is an stc optimization
  1846             x := x + translation.
  1846 	    x := x + translation.
  1847             y := y + translation.
  1847 	    y := y + translation.
  1848         ] ifFalse:[
  1848 	] ifFalse:[
  1849             translationPoint := translation asPoint.
  1849 	    translationPoint := translation asPoint.
  1850             x := x + translationPoint x.
  1850 	    x := x + translationPoint x.
  1851             y := y + translationPoint y.
  1851 	    y := y + translationPoint y.
  1852         ].
  1852 	].
  1853     ].
  1853     ].
  1854 
  1854 
  1855     ^ Rectangle left:x top:y width:w height:h.
  1855     ^ Rectangle left:x top:y width:w height:h.
  1856 
  1856 
  1857     "
  1857     "
  1858      (Rectangle origin:10@10 corner:50@50) scaledBy:2 translatedBy:10 
  1858      (Rectangle origin:10@10 corner:50@50) scaledBy:2 translatedBy:10
  1859     "
  1859     "
  1860 !
  1860 !
  1861 
  1861 
  1862 translatedBy:amount
  1862 translatedBy:amount
  1863     "return a new rectangle which is translated (i.e. moved)
  1863     "return a new rectangle which is translated (i.e. moved)
  1864      by amount, aPoint or Number"
  1864      by amount, aPoint or Number"
  1865 
  1865 
  1866     |amountPoint|
  1866     |amountPoint|
  1867 
  1867 
  1868     (amount isMemberOf:SmallInteger) ifTrue:[
  1868     (amount isMemberOf:SmallInteger) ifTrue:[
  1869         "/ this is an stc optimization
  1869 	"/ this is an stc optimization
  1870         ^ Rectangle 
  1870 	^ Rectangle
  1871             left:(left + amount)
  1871 	    left:(left + amount)
  1872             top:(top + amount)
  1872 	    top:(top + amount)
  1873             width:width
  1873 	    width:width
  1874             height:height
  1874 	    height:height
  1875     ].
  1875     ].
  1876 
  1876 
  1877     amountPoint := amount asPoint.
  1877     amountPoint := amount asPoint.
  1878     ^ Rectangle left:(left + amountPoint x) 
  1878     ^ Rectangle left:(left + amountPoint x)
  1879                  top:(top + amountPoint y)
  1879 		 top:(top + amountPoint y)
  1880                width:width
  1880 	       width:width
  1881               height:height
  1881 	      height:height
  1882     "
  1882     "
  1883      (Rectangle origin:10@10 corner:50@50) translatedBy:10
  1883      (Rectangle origin:10@10 corner:50@50) translatedBy:10
  1884     "
  1884     "
  1885 
  1885 
  1886     "its NOT destructive:"
  1886     "its NOT destructive:"
  1887     "
  1887     "
  1888      |r1 r2|
  1888      |r1 r2|
  1889 
  1889 
  1890      r1 := Rectangle origin:10@10 corner:50@50.
  1890      r1 := Rectangle origin:10@10 corner:50@50.
  1891      r2 := r1 translatedBy:10.
  1891      r2 := r1 translatedBy:10.
  1892      r1 
  1892      r1
  1893     "
  1893     "
  1894 ! !
  1894 ! !
  1895 
  1895 
  1896 !Rectangle methodsFor:'testing'!
  1896 !Rectangle methodsFor:'testing'!
  1897 
  1897 
  1930 
  1930 
  1931 rounded
  1931 rounded
  1932     "return a copy of the receiver with rounded coordinates.
  1932     "return a copy of the receiver with rounded coordinates.
  1933      Return the receiver if its coordinates are already integral."
  1933      Return the receiver if its coordinates are already integral."
  1934 
  1934 
  1935     (left isInteger 
  1935     (left isInteger
  1936     and:[top isInteger 
  1936     and:[top isInteger
  1937     and:[width isInteger 
  1937     and:[width isInteger
  1938     and:[height isInteger]]])
  1938     and:[height isInteger]]])
  1939         ifTrue: [^ self].
  1939 	ifTrue: [^ self].
  1940 
  1940 
  1941     ^ Rectangle left:(left rounded) 
  1941     ^ Rectangle left:(left rounded)
  1942                  top:(top rounded)
  1942 		 top:(top rounded)
  1943                width:(width rounded) 
  1943 	       width:(width rounded)
  1944               height:(height rounded)
  1944 	      height:(height rounded)
  1945 !
  1945 !
  1946 
  1946 
  1947 truncated
  1947 truncated
  1948     "return a Rectangle whose origin and corner have any fractional parts removed.
  1948     "return a Rectangle whose origin and corner have any fractional parts removed.
  1949      Return the receiver if its coordinates are already integral."
  1949      Return the receiver if its coordinates are already integral."
  1950 
  1950 
  1951     (left isInteger 
  1951     (left isInteger
  1952     and:[top isInteger 
  1952     and:[top isInteger
  1953     and:[width isInteger 
  1953     and:[width isInteger
  1954     and:[height isInteger]]])
  1954     and:[height isInteger]]])
  1955         ifTrue: [^ self].
  1955 	ifTrue: [^ self].
  1956 
  1956 
  1957     ^ Rectangle 
  1957     ^ Rectangle
  1958         left:left truncated
  1958 	left:left truncated
  1959         top:top truncated
  1959 	top:top truncated
  1960         width:width truncated
  1960 	width:width truncated
  1961         height:height truncated.
  1961 	height:height truncated.
  1962 ! !
  1962 ! !
  1963 
  1963 
  1964 !Rectangle class methodsFor:'documentation'!
  1964 !Rectangle class methodsFor:'documentation'!
  1965 
  1965 
  1966 version
  1966 version