1/* graphene-quad.c: Quad
2 *
3 * SPDX-License-Identifier: MIT
4 *
5 * Copyright 2014 Emmanuele Bassi
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26/**
27 * SECTION:graphene-quad
28 * @title: Quad
29 * @short_description: Four-vertex quadrilateral
30 *
31 * A #graphene_quad_t represents a coplanar, four vertex quadrilateral shape.
32 */
33
34#include "graphene-private.h"
35
36#include "graphene-quad.h"
37
38#include "graphene-line-segment-private.h"
39#include "graphene-rect.h"
40#include "graphene-simd4f.h"
41
42#include <string.h>
43
44/**
45 * graphene_quad_alloc: (constructor)
46 *
47 * Allocates a new #graphene_quad_t instance.
48 *
49 * The contents of the returned instance are undefined.
50 *
51 * Returns: (transfer full): the newly created #graphene_quad_t instance
52 *
53 * Since: 1.0
54 */
55graphene_quad_t *
56graphene_quad_alloc (void)
57{
58 return calloc (nmemb: 1, size: sizeof (graphene_quad_t));
59}
60
61/**
62 * graphene_quad_free:
63 * @q: a #graphene_quad_t
64 *
65 * Frees the resources allocated by graphene_quad_alloc()
66 *
67 * Since: 1.0
68 */
69void
70graphene_quad_free (graphene_quad_t *q)
71{
72 free (ptr: q);
73}
74
75/**
76 * graphene_quad_init:
77 * @q: the #graphene_quad_t to initialize
78 * @p1: the first point of the quadrilateral
79 * @p2: the second point of the quadrilateral
80 * @p3: the third point of the quadrilateral
81 * @p4: the fourth point of the quadrilateral
82 *
83 * Initializes a #graphene_quad_t with the given points.
84 *
85 * Returns: (transfer none): the initialized #graphene_quad_t
86 *
87 * Since: 1.0
88 */
89graphene_quad_t *
90graphene_quad_init (graphene_quad_t *q,
91 const graphene_point_t *p1,
92 const graphene_point_t *p2,
93 const graphene_point_t *p3,
94 const graphene_point_t *p4)
95{
96 q->points[0] = *p1;
97 q->points[1] = *p2;
98 q->points[2] = *p3;
99 q->points[3] = *p4;
100
101 return q;
102}
103
104/**
105 * graphene_quad_init_from_rect:
106 * @q: the #graphene_quad_t to initialize
107 * @r: a #graphene_rect_t
108 *
109 * Initializes a #graphene_quad_t using the four corners of the
110 * given #graphene_rect_t.
111 *
112 * Returns: (transfer none): the initialized #graphene_quad_t
113 *
114 * Since: 1.0
115 */
116graphene_quad_t *
117graphene_quad_init_from_rect (graphene_quad_t *q,
118 const graphene_rect_t *r)
119{
120 graphene_rect_get_top_left (r, p: &(q->points[0]));
121 graphene_rect_get_top_right (r, p: &(q->points[1]));
122 graphene_rect_get_bottom_right (r, p: &(q->points[2]));
123 graphene_rect_get_bottom_left (r, p: &(q->points[3]));
124
125 return q;
126}
127
128/**
129 * graphene_quad_init_from_points:
130 * @q: the #graphene_quad_t to initialize
131 * @points: (array fixed-size=4): an array of 4 #graphene_point_t
132 *
133 * Initializes a #graphene_quad_t using an array of points.
134 *
135 * Returns: (transfer none): the initialized #graphene_quad_t
136 *
137 * Since: 1.2
138 */
139graphene_quad_t *
140graphene_quad_init_from_points (graphene_quad_t *q,
141 const graphene_point_t points[])
142{
143 memcpy (dest: q->points, src: points, n: sizeof (graphene_point_t) * 4);
144
145 return q;
146}
147
148/**
149 * graphene_quad_contains:
150 * @q: a #graphene_quad_t
151 * @p: a #graphene_point_t
152 *
153 * Checks if the given #graphene_quad_t contains the given #graphene_point_t.
154 *
155 * Returns: `true` if the point is inside the #graphene_quad_t
156 *
157 * Since: 1.0
158 */
159bool
160graphene_quad_contains (const graphene_quad_t *q,
161 const graphene_point_t *p)
162{
163 graphene_line_segment_t l1, l2, l3, l4;
164
165 l1 = graphene_line_segment_init (start: &q->points[0], end: &q->points[1]);
166 l2 = graphene_line_segment_init (start: &q->points[1], end: &q->points[2]);
167 l3 = graphene_line_segment_init (start: &q->points[2], end: &q->points[3]);
168 l4 = graphene_line_segment_init (start: &q->points[3], end: &q->points[0]);
169
170 return graphene_line_segment_points_on_same_side (s: l1, a: p, b: &(q->points[2])) &&
171 graphene_line_segment_points_on_same_side (s: l2, a: p, b: &(q->points[3])) &&
172 graphene_line_segment_points_on_same_side (s: l3, a: p, b: &(q->points[0])) &&
173 graphene_line_segment_points_on_same_side (s: l4, a: p, b: &(q->points[1]));
174}
175
176/**
177 * graphene_quad_bounds:
178 * @q: a #graphene_quad_t
179 * @r: (out caller-allocates): return location for a #graphene_rect_t
180 *
181 * Computes the bounding rectangle of @q and places it into @r.
182 *
183 * Since: 1.0
184 */
185void
186graphene_quad_bounds (const graphene_quad_t *q,
187 graphene_rect_t *r)
188{
189 graphene_simd4f_t vx, vy;
190 float min_x, max_x;
191 float min_y, max_y;
192
193 vx = graphene_simd4f_init (q->points[0].x, q->points[1].x, q->points[2].x, q->points[3].x);
194 vy = graphene_simd4f_init (q->points[0].y, q->points[1].y, q->points[2].y, q->points[3].y);
195
196 min_x = graphene_simd4f_get_x (graphene_simd4f_min_val (vx));
197 min_y = graphene_simd4f_get_x (graphene_simd4f_min_val (vy));
198
199 max_x = graphene_simd4f_get_x (graphene_simd4f_max_val (vx));
200 max_y = graphene_simd4f_get_x (graphene_simd4f_max_val (vy));
201
202 graphene_rect_init (r, x: min_x, y: min_y, width: max_x - min_x, height: max_y - min_y);
203}
204
205/**
206 * graphene_quad_get_point:
207 * @q: a #graphene_quad_t
208 * @index_: the index of the point to retrieve
209 *
210 * Retrieves the point of a #graphene_quad_t at the given index.
211 *
212 * Returns: (transfer none): a #graphene_point_t
213 *
214 * Since: 1.0
215 */
216const graphene_point_t *
217graphene_quad_get_point (const graphene_quad_t *q,
218 unsigned int index_)
219{
220 return &q->points[index_];
221}
222

source code of gtk/subprojects/graphene/src/graphene-quad.c