source: mainline/uspace/lib/gfx/src/coord.c@ b252e87

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b252e87 was fb420e48, checked in by Jiri Svoboda <jiri@…>, 6 years ago

Use window dimensions for picking window to focus

  • Property mode set to 100644
File size: 5.6 KB
RevLine 
[7b882c1f]1/*
2 * Copyright (c) 2019 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libgfx
30 * @{
31 */
32/**
33 * @file Coordinates
34 */
35
36#include <gfx/coord.h>
[8b1ce56]37#include <macros.h>
38#include <stdbool.h>
[7b882c1f]39
40/** Add two vectors.
41 *
42 * @param a First vector
43 * @param b Second vector
44 * @param d Destination
45 */
46void gfx_coord2_add(gfx_coord2_t *a, gfx_coord2_t *b, gfx_coord2_t *d)
47{
48 d->x = a->x + b->x;
49 d->y = a->y + b->y;
50}
51
52/** Subtract two vectors.
53 *
54 * @param a First vector
55 * @param b Second vector
56 * @param d Destination
57 */
58void gfx_coord2_subtract(gfx_coord2_t *a, gfx_coord2_t *b, gfx_coord2_t *d)
59{
60 d->x = a->x - b->x;
61 d->y = a->y - b->y;
62}
63
[8b1ce56]64/** Sort points of a span.
65 *
66 * Sort the begin and end points so that the begin point has the lower
67 * coordinate (i.e. if needed, the span is transposed, if not, it is simply
68 * copied).
69 *
70 * @param s0 Source span start point
71 * @param s1 Source span end point
72 * @param d0 Destination span start point
73 * @param d1 Destination span end point
74 */
75void gfx_span_points_sort(gfx_coord_t s0, gfx_coord_t s1, gfx_coord_t *d0,
76 gfx_coord_t *d1)
77{
78 if (s0 <= s1) {
79 *d0 = s0;
80 *d1 = s1;
81 } else {
82 *d0 = s1 + 1;
83 *d1 = s0 + 1;
84 }
85}
86
[7b882c1f]87/** Move (translate) rectangle.
88 *
[fdc8e40]89 * @param trans Translation offset
[7b882c1f]90 * @param src Source rectangle
91 * @param dest Destination rectangle
92 */
93void gfx_rect_translate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
94{
[fdc8e40]95 gfx_coord2_add(&src->p0, trans, &dest->p0);
96 gfx_coord2_add(&src->p1, trans, &dest->p1);
97}
98
99/** Reverse move (translate) rectangle.
100 *
101 * @param trans Translation offset
102 * @param src Source rectangle
103 * @param dest Destination rectangle
104 */
105void gfx_rect_rtranslate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
106{
107 gfx_coord2_subtract(&src->p0, trans, &dest->p0);
108 gfx_coord2_subtract(&src->p1, trans, &dest->p1);
[7b882c1f]109}
110
[8b1ce56]111/** Compute envelope of two rectangles.
112 *
113 * Envelope is the minimal rectangle covering all pixels of both rectangles.
[fdc8e40]114 *
115 * @param a First rectangle
116 * @param b Second rectangle
117 * @param dest Place to store enveloping rectangle
[8b1ce56]118 */
119void gfx_rect_envelope(gfx_rect_t *a, gfx_rect_t *b, gfx_rect_t *dest)
120{
121 gfx_rect_t sa, sb;
122
123 if (gfx_rect_is_empty(a)) {
124 *dest = *b;
125 return;
126 }
127
128 if (gfx_rect_is_empty(b)) {
129 *dest = *a;
130 return;
131 }
132
133 /* a and b are both non-empty */
134
135 gfx_rect_points_sort(a, &sa);
136 gfx_rect_points_sort(b, &sb);
137
138 dest->p0.x = min(sa.p0.x, sb.p0.x);
139 dest->p0.y = min(sa.p0.y, sb.p0.y);
140 dest->p1.x = max(sa.p1.x, sb.p1.x);
141 dest->p1.y = max(sa.p1.y, sb.p1.y);
142}
143
[fdc8e40]144/** Compute intersection of two rectangles.
145 *
146 * If the two rectangles do not intersect, the result will be an empty
[c2250702]147 * rectangle (check with gfx_rect_is_empty()). The resulting rectangle
148 * is always sorted.
[fdc8e40]149 *
150 * @param rect Source rectangle
151 * @param clip Clipping rectangle
152 * @param dest Place to store clipped rectangle
153 */
154void gfx_rect_clip(gfx_rect_t *rect, gfx_rect_t *clip, gfx_rect_t *dest)
155{
156 gfx_rect_t srect, sclip;
157
158 gfx_rect_points_sort(rect, &srect);
159 gfx_rect_points_sort(clip, &sclip);
160
161 dest->p0.x = min(max(srect.p0.x, sclip.p0.x), sclip.p1.x);
162 dest->p0.y = min(max(srect.p0.y, sclip.p0.y), sclip.p1.y);
163 dest->p1.x = max(sclip.p0.x, min(srect.p1.x, sclip.p1.x));
164 dest->p1.y = max(sclip.p0.y, min(srect.p1.y, sclip.p1.y));
165}
166
[8b1ce56]167/** Sort points of a rectangle.
168 *
169 * Shuffle around coordinates of a rectangle so that p0.x < p1.x and
170 * p0.y < p0.y.
171 *
172 * @param src Source rectangle
173 * @param dest Destination (sorted) rectangle
174 */
175void gfx_rect_points_sort(gfx_rect_t *src, gfx_rect_t *dest)
176{
177 gfx_span_points_sort(src->p0.x, src->p1.x, &dest->p0.x, &dest->p1.x);
178 gfx_span_points_sort(src->p0.y, src->p1.y, &dest->p0.y, &dest->p1.y);
179}
180
181/** Determine if rectangle contains no pixels
182 *
183 * @param rect Rectangle
184 * @return @c true iff rectangle contains no pixels
185 */
186bool gfx_rect_is_empty(gfx_rect_t *rect)
187{
188 return rect->p0.x == rect->p1.x || rect->p0.y == rect->p1.y;
189}
190
[fb420e48]191/** Return true if pixel at coordinate @a coord lies within rectangle @a rect. */
192bool gfx_pix_inside_rect(gfx_coord2_t *coord, gfx_rect_t *rect)
193{
194 gfx_rect_t sr;
195
196 gfx_rect_points_sort(rect, &sr);
197
198 if (coord->x < sr.p0.x || coord->y < sr.p0.y)
199 return false;
200
201 if (coord->x >= sr.p1.x || coord->y >= sr.p1.y)
202 return false;
203
204 return true;
205}
206
[7b882c1f]207/** @}
208 */
Note: See TracBrowser for help on using the repository browser.