1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
22 * Copyright (C) 2009-2010 Cyril Hrubis <metan@ucw.cz> *
24 *****************************************************************************/
26 #include "core/GP_Common.h"
27 #include "core/GP_Types.h"
28 #include "gfx/GP_LineClip.h"
30 int GP_LineClip(int *px0
, int *py0
, int *px1
, int *py1
, int xmax
, int ymax
)
32 float x0
= (float) *px0
;
33 float y0
= (float) *py0
;
34 float x1
= (float) *px1
;
35 float y1
= (float) *py1
;
37 /* horizontal and vertical line are special cases */
40 /* orient the line from left to right */
46 /* check if it is not completely outside */
47 if (x1
< 0 || x0
> xmax
|| y0
< 0 || y0
> ymax
)
51 x1
= GP_MIN(x1
, xmax
);
56 /* orient the line from top to down */
62 /* check if it is not completely outside */
63 if (y1
< 0 || y0
> ymax
|| x0
< 0 || x0
> xmax
)
66 /* clip it to the valid range */
68 y1
= GP_MIN(y1
, ymax
);
72 /* orient the line from left to right */
78 if (x1
< 0 || x0
> xmax
|| (y0
< 0 && y1
< 0) || (y0
> ymax
&& y1
> ymax
)) {
80 /* the line lies completely outside the rectangle */
84 float dx
= (float)(x1
- x0
);
85 float dy
= (float)(y1
- y0
);
89 /* clip the line against the left and right side of the rectangle */
96 y1
= y0
+ (x1
-x0
)*dyx
;
102 } else if (y0
> ymax
) {
103 x0
= x0
+ (ymax
-y0
)*dxy
;
111 else if (y1
> ymax
) {
112 x1
= x1
- (y1
- ymax
)*dxy
;
116 if (x0
< 0 || x0
> xmax
|| x1
< 0 || x1
> xmax
) {
118 /* the line misses the clip rectangle around the corner */