summaryrefslogtreecommitdiffstats
path: root/lib/widget/rect.c
blob: 8c2d46418b2ac749abee97241be566b5701701a8 (plain)
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
/* Rectangular class for Midnight Commander widgets

   Copyright (C) 2020-2024
   The Free Software Foundation, Inc.

   Written by:
   Andrew Borodin <aborodin@vmail.ru>, 2020-2022

   This file is part of the Midnight Commander.

   The Midnight Commander 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 3 of the License,
   or (at your option) any later version.

   The Midnight Commander 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.  If not, see <http://www.gnu.org/licenses/>.
 */

/** \file widget-common.c
 *  \brief Source: shared stuff of widgets
 */

#include <config.h>

#include <stdlib.h>

#include "lib/global.h"

#include "rect.h"

/*** global variables ****************************************************************************/

/*** file scope macro definitions ****************************************************************/

/*** file scope type declarations ****************************************************************/

/*** file scope variables ************************************************************************/

/*** file scope functions ************************************************************************/

/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/**
  * Create new WRect object.
  *
  * @param y y-coordinate of left-up corner
  * @param x x-coordinate of left-up corner
  * @param lines height
  * @param cols width
  *
  * @return newly allocated WRect object.
  */

WRect *
rect_new (int y, int x, int lines, int cols)
{
    WRect *r;

    r = g_try_new (WRect, 1);

    if (r != NULL)
        rect_init (r, y, x, lines, cols);

    return r;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Initialize WRect object.
  *
  * @param r WRect object
  * @param y y-coordinate of left-up corner
  * @param x x-coordinate of left-up corner
  * @param lines height
  * @param cols width
  */

void
rect_init (WRect * r, int y, int x, int lines, int cols)
{
    r->y = y;
    r->x = x;
    r->lines = lines;
    r->cols = cols;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Change position of rectangle area.
  *
  * @param r WRect object
  * @param dy y-shift of left-up corner
  * @param dx x-shift of left-up corner
  */

void
rect_move (WRect * r, int dy, int dx)
{
    r->y += dy;
    r->x += dx;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Change size of rectangle area keeping it's position.
  *
  * @param r WRect object
  * @param dl change size value of height
  * @param dc change size value of width
  */

void
rect_resize (WRect * r, int dl, int dc)
{
    r->lines += dl;
    r->cols += dc;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Change size of rectangle area keeping it's center.
  *
  * @param r WRect object
  * @param dl change size value of y-coordinate and height
  *           Positive value means move up and increase height.
  *           Negative value means move down and decrease height.
  * @param dc change size value of x-coordinate and width
  *           Positive value means move left and increase width.
  *           Negative value means move right and decrease width.
  */

void
rect_grow (WRect * r, int dl, int dc)
{
    r->y -= dl;
    r->x -= dc;
    r->lines += dl * 2;
    r->cols += dc * 2;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Calculates the intersection of two rectangle areas.
  * The resulting rectangle is the largest rectangle which contains intersection of rectangle areas.
  *
  * @param r first WRect object
  * @param r1 second WRect object
  *
  * The resulting rectangle is stored in r.
  */

void
rect_intersect (WRect * r, const WRect * r1)
{
    int y, x;
    int y1, x1;

    /* right-down corners */
    y = r->y + r->lines;
    x = r->x + r->cols;
    y1 = r1->y + r1->lines;
    x1 = r1->x + r1->cols;

    /* right-down corner of intersection */
    y = MIN (y, y1);
    x = MIN (x, x1);

    /* left-up corner of intersection */
    r->y = MAX (r->y, r1->y);
    r->x = MAX (r->x, r1->x);

    /* intersection sizes */
    r->lines = y - r->y;
    r->cols = x - r->x;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Calculates the union of two rectangle areas.
  * The resulting rectangle is the largest rectangle which contains both rectangle areas.
  *
  * @param r first WRect object
  * @param r1 second WRect object
  *
  * The resulting rectangle is stored in r.
  */

void
rect_union (WRect * r, const WRect * r1)
{
    int x, y;
    int x1, y1;

    /* right-down corners */
    y = r->y + r->lines;
    x = r->x + r->cols;
    y1 = r1->y + r1->lines;
    x1 = r1->x + r1->cols;

    /* right-down corner of union */
    y = MAX (y, y1);
    x = MAX (x, x1);

    /* left-up corner of union */
    r->y = MIN (r->y, r1->y);
    r->x = MIN (r->x, r1->x);

    /* union sizes */
    r->lines = y - r->y;
    r->cols = x - r->x;
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Check whether two rectangle areas are overlapped or not.
  *
  * @param r1 WRect object
  * @param r2 WRect object
  *
  * @return TRUE if rectangle areas are overlapped, FALSE otherwise.
  */

gboolean
rects_are_overlapped (const WRect * r1, const WRect * r2)
{
    return !((r2->x >= r1->x + r1->cols) || (r1->x >= r2->x + r2->cols)
             || (r2->y >= r1->y + r1->lines) || (r1->y >= r2->y + r2->lines));
}

/* --------------------------------------------------------------------------------------------- */
/**
  * Check whether two rectangle areas are equal or not.
  *
  * @param r1 WRect object
  * @param r2 WRect object
  *
  * @return TRUE if rectangle areas are equal, FALSE otherwise.
  */

gboolean
rects_are_equal (const WRect * r1, const WRect * r2)
{
    return (r1->y == r2->y && r1->x == r2->x && r1->lines == r2->lines && r1->cols == r2->cols);
}

/* --------------------------------------------------------------------------------------------- */