Rename GP_Context -> GP_Pixmap
[gfxprim.git] / libs / core / GP_Blit.c
blob039f20ea2147b4ef55b7b6017fb0fbc18b4fac08
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
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. *
8 * *
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. *
13 * *
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 *
18 * *
19 * Copyright (C) 2011 Tomas Gavenciak <gavento@ucw.cz> *
20 * Copyright (C) 2011-2013 Cyril Hrubis <metan@ucw.cz> *
21 * *
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 */
45 if (x1 < x0)
46 GP_SWAP(x0, x1);
48 if (y1 < y0)
49 GP_SWAP(y0, y1);
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 */
69 if (x1 < x0)
70 GP_SWAP(x0, x1);
72 if (y1 < y0)
73 GP_SWAP(y0, y1);
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))
81 return;
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.
89 * (>= 0 and < w, < h)
91 if (x2 < 0) {
92 x0 -= x2;
93 x2 = 0;
96 if (y2 < 0) {
97 y0 -= y2;
98 y2 = 0;
101 /* Make sure souce coordinates are inside of the src */
102 x0 = GP_MAX(x0, 0);
103 y0 = GP_MAX(y0, 0);
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);
117 if (src_w > dst_w)
118 x1 -= src_w - dst_w;
120 if (src_h > dst_h)
121 y1 -= src_h - 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)
135 return;
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)
145 return;
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 */
155 if (x1 < x0)
156 GP_SWAP(x0, x1);
158 if (y1 < y0)
159 GP_SWAP(y0, y1);
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)
179 return;
181 GP_BlitXYXY_Raw(src, x0, y0, x0 + w0 - 1, y0 + h0 - 1, dst, x2, y2);