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) 2011 Tomas Gavenciak <gavento@ucw.cz> *
20 * Copyright (C) 2011-2013 Cyril Hrubis <metan@ucw.cz> *
22 *****************************************************************************/
24 #include "core/GP_Pixel.h"
25 #include "core/GP_GetPutPixel.h"
26 #include "core/GP_Pixmap.h"
27 #include "core/GP_Convert.h"
28 #include "core/GP_Debug.h"
29 #include "core/GP_Blit.h"
31 /* Generated functions */
32 void GP_BlitXYXY_Raw_Fast(const GP_Pixmap
*src
,
33 GP_Coord x0
, GP_Coord y0
, GP_Coord x1
, GP_Coord y1
,
34 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
);
36 void GP_BlitXYXY_Fast(const GP_Pixmap
*src
,
37 GP_Coord x0
, GP_Coord y0
, GP_Coord x1
, GP_Coord y1
,
38 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
);
40 void GP_BlitXYXY(const GP_Pixmap
*src
,
41 GP_Coord x0
, GP_Coord y0
, GP_Coord x1
, GP_Coord y1
,
42 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
)
44 /* Normalize source rectangle */
51 /* All coordinates are inside of src the pixmap */
52 GP_CHECK(x0
< (GP_Coord
)GP_PixmapW(src
));
53 GP_CHECK(y0
< (GP_Coord
)GP_PixmapH(src
));
54 GP_CHECK(x1
< (GP_Coord
)GP_PixmapW(src
));
55 GP_CHECK(y1
< (GP_Coord
)GP_PixmapH(src
));
57 /* Destination is big enough */
58 GP_CHECK(x2
+ (x1
- x0
) < (GP_Coord
)GP_PixmapW(dst
));
59 GP_CHECK(y2
+ (y1
- y0
) < (GP_Coord
)GP_PixmapH(dst
));
61 GP_BlitXYXY_Fast(src
, x0
, y0
, x1
, y1
, dst
, x2
, y2
);
64 void GP_BlitXYXY_Clipped(const GP_Pixmap
*src
,
65 GP_Coord x0
, GP_Coord y0
, GP_Coord x1
, GP_Coord y1
,
66 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
)
68 /* Normalize source rectangle */
76 * Handle all cases where at least one of dest coordinates are out of
77 * the dest in positive direction -> src is out of dst completly.
79 if (x2
>= (GP_Coord
)GP_PixmapW(dst
) ||
80 y2
>= (GP_Coord
)GP_PixmapH(dst
))
84 * The coordinates in dest are negative.
86 * We need to clip the source upper left corner accordingly.
88 * Notice that x2 and y2 are inside the dst rectangle now.
101 /* Make sure souce coordinates are inside of the src */
104 x1
= GP_MIN(x1
, (GP_Coord
)GP_PixmapW(src
) - 1);
105 y1
= GP_MIN(y1
, (GP_Coord
)GP_PixmapH(src
) - 1);
107 /* And source rectangle fits inside of the destination */
108 GP_Coord src_w
= x1
- x0
+ 1;
109 GP_Coord src_h
= y1
- y0
+ 1;
111 GP_Coord dst_w
= GP_PixmapW(dst
) - x2
;
112 GP_Coord dst_h
= GP_PixmapH(dst
) - y2
;
114 GP_DEBUG(2, "Blitting %ix%i, available %ix%i",
115 src_w
, src_h
, dst_w
, dst_h
);
123 GP_DEBUG(2, "Blitting %ix%i->%ix%i in %ux%u to %ix%i in %ux%u",
124 x0
, y0
, x1
, y1
, GP_PixmapW(src
), GP_PixmapH(src
),
125 x2
, y2
, GP_PixmapW(dst
), GP_PixmapH(dst
));
127 GP_BlitXYXY_Fast(src
, x0
, y0
, x1
, y1
, dst
, x2
, y2
);
130 void GP_BlitXYWH(const GP_Pixmap
*src
,
131 GP_Coord x0
, GP_Coord y0
, GP_Size w0
, GP_Size h0
,
132 GP_Pixmap
*dst
, GP_Coord x1
, GP_Coord y1
)
134 if (w0
== 0 || h0
== 0)
137 GP_BlitXYXY(src
, x0
, y0
, x0
+ w0
- 1, y0
+ h0
- 1, dst
, x1
, y1
);
140 void GP_BlitXYWH_Clipped(const GP_Pixmap
*src
,
141 GP_Coord x0
, GP_Coord y0
, GP_Size w0
, GP_Size h0
,
142 GP_Pixmap
*dst
, GP_Coord x1
, GP_Coord y1
)
144 if (w0
== 0 || h0
== 0)
147 GP_BlitXYXY_Clipped(src
, x0
, y0
, x0
+ w0
- 1, y0
+ h0
- 1, dst
, x1
, y1
);
150 void GP_BlitXYXY_Raw(const GP_Pixmap
*src
,
151 GP_Coord x0
, GP_Coord y0
, GP_Coord x1
, GP_Coord y1
,
152 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
)
154 /* Normalize source rectangle */
161 /* All coordinates are inside of src the pixmap */
162 GP_CHECK(x0
< (GP_Coord
)src
->w
);
163 GP_CHECK(y0
< (GP_Coord
)src
->h
);
164 GP_CHECK(x1
< (GP_Coord
)src
->w
);
165 GP_CHECK(y1
< (GP_Coord
)src
->h
);
167 /* Destination is big enough */
168 GP_CHECK(x2
+ (x1
- x0
) < (GP_Coord
)dst
->w
);
169 GP_CHECK(y2
+ (y1
- y0
) < (GP_Coord
)dst
->h
);
171 GP_BlitXYXY_Raw_Fast(src
, x0
, y0
, x1
, y1
, dst
, x2
, y2
);
174 void GP_BlitXYWH_Raw(const GP_Pixmap
*src
,
175 GP_Coord x0
, GP_Coord y0
, GP_Size w0
, GP_Size h0
,
176 GP_Pixmap
*dst
, GP_Coord x2
, GP_Coord y2
)
178 if (w0
== 0 || h0
== 0)
181 GP_BlitXYXY_Raw(src
, x0
, y0
, x0
+ w0
- 1, y0
+ h0
- 1, dst
, x2
, y2
);