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

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

Get display resolution by querying display device

  • Property mode set to 100644
File size: 5.8 KB
Line 
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>
37#include <macros.h>
38#include <stdbool.h>
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
64void gfx_coord2_clip(gfx_coord2_t *a, gfx_rect_t *clip, gfx_coord2_t *d)
65{
66 gfx_rect_t sclip;
67 gfx_coord2_t t;
68
69 gfx_rect_points_sort(clip, &sclip);
70
71 t.x = min(a->x, clip->p1.x - 1);
72 t.y = min(a->y, clip->p1.y - 1);
73
74 d->x = max(clip->p0.x, t.x);
75 d->y = max(clip->p0.y, t.y);
76}
77
78/** Sort points of a span.
79 *
80 * Sort the begin and end points so that the begin point has the lower
81 * coordinate (i.e. if needed, the span is transposed, if not, it is simply
82 * copied).
83 *
84 * @param s0 Source span start point
85 * @param s1 Source span end point
86 * @param d0 Destination span start point
87 * @param d1 Destination span end point
88 */
89void gfx_span_points_sort(gfx_coord_t s0, gfx_coord_t s1, gfx_coord_t *d0,
90 gfx_coord_t *d1)
91{
92 if (s0 <= s1) {
93 *d0 = s0;
94 *d1 = s1;
95 } else {
96 *d0 = s1 + 1;
97 *d1 = s0 + 1;
98 }
99}
100
101/** Move (translate) rectangle.
102 *
103 * @param trans Translation offset
104 * @param src Source rectangle
105 * @param dest Destination rectangle
106 */
107void gfx_rect_translate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
108{
109 gfx_coord2_add(&src->p0, trans, &dest->p0);
110 gfx_coord2_add(&src->p1, trans, &dest->p1);
111}
112
113/** Reverse move (translate) rectangle.
114 *
115 * @param trans Translation offset
116 * @param src Source rectangle
117 * @param dest Destination rectangle
118 */
119void gfx_rect_rtranslate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
120{
121 gfx_coord2_subtract(&src->p0, trans, &dest->p0);
122 gfx_coord2_subtract(&src->p1, trans, &dest->p1);
123}
124
125/** Compute envelope of two rectangles.
126 *
127 * Envelope is the minimal rectangle covering all pixels of both rectangles.
128 *
129 * @param a First rectangle
130 * @param b Second rectangle
131 * @param dest Place to store enveloping rectangle
132 */
133void gfx_rect_envelope(gfx_rect_t *a, gfx_rect_t *b, gfx_rect_t *dest)
134{
135 gfx_rect_t sa, sb;
136
137 if (gfx_rect_is_empty(a)) {
138 *dest = *b;
139 return;
140 }
141
142 if (gfx_rect_is_empty(b)) {
143 *dest = *a;
144 return;
145 }
146
147 /* a and b are both non-empty */
148
149 gfx_rect_points_sort(a, &sa);
150 gfx_rect_points_sort(b, &sb);
151
152 dest->p0.x = min(sa.p0.x, sb.p0.x);
153 dest->p0.y = min(sa.p0.y, sb.p0.y);
154 dest->p1.x = max(sa.p1.x, sb.p1.x);
155 dest->p1.y = max(sa.p1.y, sb.p1.y);
156}
157
158/** Compute intersection of two rectangles.
159 *
160 * If the two rectangles do not intersect, the result will be an empty
161 * rectangle (check with gfx_rect_is_empty()). The resulting rectangle
162 * is always sorted.
163 *
164 * @param rect Source rectangle
165 * @param clip Clipping rectangle
166 * @param dest Place to store clipped rectangle
167 */
168void gfx_rect_clip(gfx_rect_t *rect, gfx_rect_t *clip, gfx_rect_t *dest)
169{
170 gfx_rect_t srect, sclip;
171
172 gfx_rect_points_sort(rect, &srect);
173 gfx_rect_points_sort(clip, &sclip);
174
175 dest->p0.x = min(max(srect.p0.x, sclip.p0.x), sclip.p1.x);
176 dest->p0.y = min(max(srect.p0.y, sclip.p0.y), sclip.p1.y);
177 dest->p1.x = max(sclip.p0.x, min(srect.p1.x, sclip.p1.x));
178 dest->p1.y = max(sclip.p0.y, min(srect.p1.y, sclip.p1.y));
179}
180
181/** Sort points of a rectangle.
182 *
183 * Shuffle around coordinates of a rectangle so that p0.x < p1.x and
184 * p0.y < p0.y.
185 *
186 * @param src Source rectangle
187 * @param dest Destination (sorted) rectangle
188 */
189void gfx_rect_points_sort(gfx_rect_t *src, gfx_rect_t *dest)
190{
191 gfx_span_points_sort(src->p0.x, src->p1.x, &dest->p0.x, &dest->p1.x);
192 gfx_span_points_sort(src->p0.y, src->p1.y, &dest->p0.y, &dest->p1.y);
193}
194
195/** Determine if rectangle contains no pixels
196 *
197 * @param rect Rectangle
198 * @return @c true iff rectangle contains no pixels
199 */
200bool gfx_rect_is_empty(gfx_rect_t *rect)
201{
202 return rect->p0.x == rect->p1.x || rect->p0.y == rect->p1.y;
203}
204
205/** Return true if pixel at coordinate @a coord lies within rectangle @a rect. */
206bool gfx_pix_inside_rect(gfx_coord2_t *coord, gfx_rect_t *rect)
207{
208 gfx_rect_t sr;
209
210 gfx_rect_points_sort(rect, &sr);
211
212 if (coord->x < sr.p0.x || coord->y < sr.p0.y)
213 return false;
214
215 if (coord->x >= sr.p1.x || coord->y >= sr.p1.y)
216 return false;
217
218 return true;
219}
220
221/** @}
222 */
Note: See TracBrowser for help on using the repository browser.