File: area.h

package info (click to toggle)
xevil 2.02r2-10
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 7,992 kB
  • ctags: 8,006
  • sloc: cpp: 47,789; makefile: 228; csh: 4
file content (364 lines) | stat: -rw-r--r-- 11,598 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/* 
 * XEvil(TM) Copyright (C) 1994,2000 Steve Hardt and Michael Judge
 * http://www.xevil.com
 * satan@xevil.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program, the file "gpl.txt"; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA, or visit http://www.gnu.org.
 */

// "area.h" 

#ifndef AREA_H
#define AREA_H

#if X11
	#ifndef NO_PRAGMAS
	#pragma interface
	#endif
#endif


// Include Files
#include "utils.h"
#include "coord.h"
#include "streams.h"


// Defines
#define AR_WSQUARES_MAX 20
enum ARshape {AR_RECT,AR_UNDEFINED};
enum ARsig {AR_NO_SIG, AR_CLOSE, AR_FAILURE, AR_BAD_SHAPE};



// Data structures
struct TouchingListItem {
  Loc list[AR_WSQUARES_MAX];
  int num;
};

struct TouchingList {
  TouchingListItem r,dn,l,up; 
};


class Area;
class Avoid;



// Class Declarations
class Area {
 public:
  Size operator - (const Area &) const;
  /* EFFECTS: Subtract areas according to their upper left corners. */
  
  Boolean operator == (const Area &) const;
  
  Area operator + (const Size &) const;
  Area operator - (const Size &) const;
  /* EFFECTS: Return new Area with pos shifted by shift. */
  

  Area() {shape = AR_UNDEFINED;}
  /* EFFECTS: Create undefined area. */

  Area(const Pos &p,const Size &s) {shape = AR_RECT,pos = p,size = s;}
  Area(ARshape sh,const Pos &p,const Size &s) {assert(sh == AR_RECT);  
      shape = AR_RECT; pos = p; size = s; }
  /* REQUIRES: c is AR_RECT. */
  /* EFFECTS: Creates a rectangle area at position p of size s. */

  Area(ARshape c,const Loc &loc,const Dim &dim);
  /* REQUIRES: c is AR_RECT. */
  /* EFFECTS: Creates a rectangle area at loc and dim. */

  Area(InStreamP);
  void read(InStreamP);
  static int get_write_length()
    {return Pos::get_write_length() + Size::get_write_length();}
  void write(OutStreamP) const;

  Boolean is_defined() const {return shape != AR_UNDEFINED;}

  void get_rect(Pos &p,Size &s) const 
    {assert (shape == AR_RECT); p = pos; s = size;}

  /* MODIFIES: p,s */

  Pos get_pos() const 
    {assert(shape == AR_RECT); return pos;}
  Size get_size() const
    {assert(shape == AR_RECT); return size;}
  
  Box get_box() const;
  /* EFFECTS: Returns the box of wsquares that contains the area. */

  void set_pos(const Pos &p) 
	{assert(shape == AR_RECT); pos = p;}
  void set_size(const Size &s)
    {assert(shape == AR_RECT); size = s;}

  void wsquares(Loc list[AR_WSQUARES_MAX],int &nitems) const;
  /* MODIFIES: list, nitems */
  /* EFFECTS: After completion, the first nitems of list contain the locations
     of all the wsquares covered by the area.  The initial values of list 
     and nitems are ignored.  wsquares are not necessarily inside the world. */

  Boolean overlap(const Area &) const;
  /* EFFECTS: Returns True if *this overlaps with r, False otherwise. */

  Boolean overlap(const Loc &loc) const;
  /* EFFECTS: Returns True if loc overlaps with any of the area.  Returns 
     False otherwise. */

  Boolean overlap(const Box &box) const;
  /* EFFECTS: Returns True if box overlaps with any of the area.  Returns 
     False otherwise. */

  Boolean overlap(const Pos &pos) const;

  Loc middle_wsquare() const;
  /* EFFECTS: Returns the location of the middle wsquare in the area. */

  ARsig avoid_wsquare(Avoid &avoid,const Loc &loc) const;
  /* MODIFIES: avoid */
  /* EFFECTS: Returns AR_NO_SIG if the wsquare at loc does not overlap with 
     the area.  If loc overlaps in the area, but not in a nearby area, returns
     AR_CLOSE and sets avoid to be the offsets necessary to make the area no 
     longer touch the wsquare. */

  int avoid_wsquare_dir(const Loc &loc,Dir dir) const;
  /* EFFECTS: Returns the amount *this will have to be shited in dir to avoid 
     loc. */

  int avoid_area_dir(const Area &area,Dir dir) const;
  /* EFFECTS: Returns the amount *this will have to be shited in dir to avoid 
      area. */

  Size avoid(const Area &area) const;
  /* EFFECTS: Returns the smallest offset necessary to move *this in order to
     avoid area. */

  Size avoid_no_up(const Area &) const;
  /* EFFECTS: Like avoid(), but will not avoid in the up direction. */

  Pos adjacent_rect(const Size &s,Dir dir) const;
  /* EFFECTS: Return the upper left corner of the rectangle of size s that
     touches *this such that the direction from *this to the rectangle is 
     dir. */

  Pos get_middle() const{  assert(shape == AR_RECT);
              return Pos(pos.x+(size.width>>1),pos.y+(size.height>>1));}
  /* EFFECTS: Returns the middle of the area. */

  Boolean touches(const Area &other,Touching touching) const;
  /* EFFECTS: Does other touch this on this's side specified by touching. */

  void touching_wsquares(TouchingList &list) const;
  /* MODIFIES: list */
  /* EFFECTS: Sets list.{r,dn,l,up} to be the lists of all wsquares that are exactly 
     touching the area.  The directions are set from the area to the touching 
     wsquare.  I.e. A loc listed under list.r would be touching the 
     right side of the area.  The list are ordered such that the smallest 
     row and column indexes come first.  I.e. top->bottom and left->right. */

  void edge_wsquares(TouchingList &list) const;
  /* MODIFIES: list */
  /* EFFECTS: Like touching_wsquares except squares on edge don't have to be 
      exactly touching.  They might just overlap area.  I.e. returns 
      Area::wsquares() - {all squares entirely inside the Area} */
      
  Boolean corner_offset(Size &offset,Loc list[3],Loc &inner,Dir corner) const;
 /* MODIFIES: offset, list, inner */
 /* EFFECTS: If the corner of the Area in the given direction covers 3 wsquares, set offset
	  to be the amount to shift the Area so it is touching on the corner, set list to be the 3 
	  covered wsquares, set inner to be the wsquare of the inside of the corner,
	  and return True.  Else return False.  corner is one of 
	  {CO_DN_R,CO_DN_L,CO_UP_L,CO_UP_R}. */

 void shift(const Size &offset)
    {assert(shape == AR_RECT); pos = pos + offset;}
  /* EFFECTS: Shift the area by offset. */

  void set_middle(const Pos &pos);
  /* EFFECTS: Move the area so that pos will be the middle. */

  Dir dir_to(const Pos &pos) const;
  Dir dir_to(const Area &area) const;
  /* EFFECTS: Returns the direction from this to pos or to area. 
     Will return one of {CO_R .. CO_UP_R, CO_air}.  I.e. 8 directions or 
     CO_air. */

  Area combine(const Area &a) const;
  /* EFFECTS: Returns minimum sized rectangular area that contains a and 
     this. */

  Area wsquare_allign(const Size &offset) const;
  /* EFFECTS: For each dimension of offset that is non-zero, wsquare_allign
	 makes sure that the returned Area is wsquare_alligned in that dimension.
	 I.e. the edge of the Area in that direction will be on a wsquare boundary.
	 The returned area will not cover any wsquares that weren't already 
	 covered. */
  
  Boolean wsquare_alligned() const;
  /* EFFECTS: Is the Area alligned in all four directions with wsquares? */
  
  Area grow_by(int delta) const;
  /* EFFECTS: Increase area by delta on all four sides.  I.e. size will increase by
     2*delta in both directions. */
  
  Size clip_top(int val);
  /* REQUIRES: Don't clip everything away. */
  /* EFFECTS: Clip top to be <= val.  Return offset (width,height) such that height is the
     amount that was clipped away. */
  
  Size clip_left(int val);
  /* REQUIRES: Don't clip everything away. */
  /* EFFECTS: Clip left to be <= val.  Return offset (width,height) such that width is the
     amount that was clipped away. */

  Size clip(const Size &size);
  /* REQUIRES: Don't clip everything away. */
  /* EFFECTS: Clip this to clipper.  Return False if nothing left. 
     In the second version, clipper is an area of size size with pos (0,0). */


 private:
  ARshape shape;
  Pos pos;
  Size size;
};



class Avoid {
friend class Area;

public:    
  void maximize(const Avoid &avoid);
  /* EFFECTS: Set all directions of *this to be to max of *this and avoid. */

  Size offset_rank(int rank = 0) const;
  /* REQUIRES: 0 <= rank < 4 */
  /* EFFECTS: Return the offset corresponding to the rankth minimum direction
     of *this using one dimensions.  E.g. rank = 0 gives the minimum.  rank
     = 1 gives the second minimum, etc. */
  
  Size offset_dir(Dir d) const;
  /* REQUIRES: d in {CO_R, CO_DN, CO_L, CO_UP} */
  /* EFFECTS: Return the offset corresponding to d. */

  int get_dir(Dir d) const;
  /* REQUIRES: d in {CO_R, CO_DN, CO_L, CO_UP} */
  /* EFFECTS: Returns the offset in the specified direction. */


private:
  /* Direction from area to wsquare.  All are positive.  r and dn are 
     therefore the negative of the corresponding offsets. */
  int r,dn,l,up; 
  // Note: A bit counter-intuitive.
};



// All values are world (unstretched) coordinates.
class ViewportRegion {
  friend class ViewportInfo;

public:
  ViewportRegion() {};
  /* NOTE: Make the fucking compiler happy. */

  Boolean visibleOverlap(const Area &) const;
  /* EFFECTS: Does the area overlap the visible region of the  viewport? */

  Boolean peripheralOverlap(const Area &) const;
  /* EFFECTS: Does the area overlap the peripheral region of the viewport, 
     including the visible subset of that. */     

  void grow_by(int val);
  /* EFFECTS: Grow the ViewportRegion by val, visible and peripheral. */


private:
  ViewportRegion(const Area &a); 
  /* EFFECTS: V_AREA constructor. */

  ViewportRegion(const Pos &periphCenter,int periphRadius,
                 const Area &visibleArea);
  /* EFFECTS: V_DISK constructor. */


  enum {V_AREA,V_DISK};
  char type;
  Area area;   // both, for V_DISK this gives the inner,visible area
  Pos pos;     // for V_DISK
  int radius;  // for V_DISK
};
typedef ViewportRegion *ViewportRegionP;



// A Factory for generating ViewportRegions, given a Physical to follow.
//
// All values are world (unstretched) coordinates.
class ViewportInfo {
public:
  ViewportInfo() {}
  /* EFFECTS: So we can create an uninitialized object to call
     ViewportInfo::read(). */

  ViewportInfo(int radius,const Size &visibleSize);
  /* EFFECTS: Create smooth scroll ViewportInfo. */
  
  ViewportInfo(int radius,const Size &logicalSize,const Size &extraSize);
  /* EFFECTS: Create non-smooth scroll ViewportInfo. */

  void read(InStreamP in);
  static int get_write_length();
  void write(OutStreamP out) const;

  ViewportRegion get_viewport_for(const Pos &pos) const;
  /* EFFECTS: The factory's creation method.  pos is the center of the
     Physical to follow. */

  Dim get_viewport_dim() const;
  /* REQUIRES: Viewport dimensions must be multiples of wsquares. */
  /* EFFECTS: Get the dimensions of a viewport in wsquares. */


private:
  Boolean smoothScroll; // both
  Size logicalSize;     // both
  Size extraSize;       // if !smoothScroll
  int radius;           // both
};
typedef ViewportInfo *ViewportInfoP;



// An interface to lazily provide a ViewportInfo object.
class IViewportInfo {
public:
  virtual ViewportInfo get_info() = 0;
};

#endif