]>
Commit | Line | Data |
---|---|---|
3970628f JB |
1 | --- gd-2.0.33/gd.c.orig 2006-12-23 02:27:25.723423857 +0100 |
2 | +++ gd-2.0.33/gd.c 2006-12-23 02:31:59.599031139 +0100 | |
3 | @@ -65,6 +65,10 @@ | |
4 | ||
5 | static void gdImageBrushApply (gdImagePtr im, int x, int y); | |
6 | static void gdImageTileApply (gdImagePtr im, int x, int y); | |
7 | +/* from php */ | |
8 | +static int gdLayerOverlay(int dst, int src); | |
9 | +static int gdAlphaOverlayColor(int src, int dst, int max); | |
10 | +/* end from php */ | |
11 | BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y); | |
12 | ||
13 | BGD_DECLARE(gdImagePtr) gdImageCreate (int sx, int sy) | |
14 | @@ -761,16 +765,22 @@ | |
1e268c02 PG |
15 | default: |
16 | if (gdImageBoundsSafeMacro (im, x, y)) | |
17 | { | |
18 | - if (im->trueColor) | |
19 | - { | |
20 | - if (im->alphaBlendingFlag) | |
21 | - { | |
22 | - im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color); | |
23 | - } | |
24 | - else | |
25 | - { | |
3970628f JB |
26 | - im->tpixels[y][x] = color; |
27 | - } | |
1e268c02 | 28 | + if (im->trueColor) { |
1e268c02 PG |
29 | + switch (im->alphaBlendingFlag) { |
30 | + default: | |
1e268c02 PG |
31 | + case gdEffectReplace: |
32 | + im->tpixels[y][x] = color; | |
33 | + break; | |
3970628f | 34 | + case gdEffectAlphaBlend: |
1e268c02 PG |
35 | + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); |
36 | + break; | |
37 | + case gdEffectNormal: | |
3970628f | 38 | + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); |
1e268c02 PG |
39 | + break; |
40 | + case gdEffectOverlay : | |
41 | + im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color); | |
3970628f | 42 | + break; |
1e268c02 | 43 | + } |
1e268c02 | 44 | } |
3970628f JB |
45 | else |
46 | { | |
47 | @@ -2287,6 +2297,564 @@ | |
1e268c02 PG |
48 | } |
49 | } | |
50 | ||
3970628f | 51 | +/* Taken from php */ |
1e268c02 | 52 | +/* |
3970628f | 53 | + * Rotate function Added on 2003/12 |
1e268c02 PG |
54 | + * by Pierre-Alain Joye (pajoye@pearfr.org) |
55 | + **/ | |
56 | +/* Begin rotate function */ | |
57 | +#ifdef ROTATE_PI | |
58 | +#undef ROTATE_PI | |
59 | +#endif /* ROTATE_PI */ | |
60 | + | |
61 | +#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180 | |
3970628f | 62 | +BGD_DECLARE(void) gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent) |
1e268c02 | 63 | +{ |
3970628f JB |
64 | + typedef int (*FuncPtr)(gdImagePtr, int, int); |
65 | + int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA; | |
66 | + FuncPtr f; | |
67 | + | |
68 | + int pxlOldLeft, pxlLeft=0, pxlSrc; | |
69 | + | |
70 | + /* Keep clrBack as color index if required */ | |
71 | + if (src->trueColor) { | |
72 | + pxlOldLeft = clrBack; | |
73 | + f = gdImageGetTrueColorPixel; | |
74 | + } else { | |
75 | + pxlOldLeft = clrBack; | |
76 | + clrBackR = gdImageRed(src, clrBack); | |
77 | + clrBackG = gdImageGreen(src, clrBack); | |
78 | + clrBackB = gdImageBlue(src, clrBack); | |
79 | + clrBackA = gdImageAlpha(src, clrBack); | |
80 | + clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA); | |
81 | + f = gdImageGetPixel; | |
82 | + } | |
83 | + | |
84 | + for (i = 0; i < iOffset; i++) { | |
85 | + gdImageSetPixel (dst, i, uRow, clrBack); | |
86 | + } | |
87 | + | |
88 | + if (i < dst->sx) { | |
89 | + gdImageSetPixel (dst, i, uRow, clrBack); | |
90 | + } | |
91 | + | |
92 | + for (i = 0; i < src->sx; i++) { | |
93 | + pxlSrc = f (src,i,uRow); | |
94 | + | |
95 | + r = (int)(gdImageRed(src,pxlSrc) * dWeight); | |
96 | + g = (int)(gdImageGreen(src,pxlSrc) * dWeight); | |
97 | + b = (int)(gdImageBlue(src,pxlSrc) * dWeight); | |
98 | + a = (int)(gdImageAlpha(src,pxlSrc) * dWeight); | |
99 | + | |
100 | + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); | |
101 | + | |
102 | + if (pxlLeft == -1) { | |
103 | + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); | |
104 | + } | |
105 | + | |
106 | + r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft)); | |
107 | + g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft)); | |
108 | + b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft)); | |
109 | + a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft)); | |
110 | + | |
111 | + if (r>255) { | |
112 | + r = 255; | |
113 | + } | |
114 | + | |
115 | + if (g>255) { | |
116 | + g = 255; | |
117 | + } | |
118 | + | |
119 | + if (b>255) { | |
120 | + b = 255; | |
121 | + } | |
122 | + | |
123 | + if (a>127) { | |
124 | + a = 127; | |
125 | + } | |
126 | + | |
127 | + if (ignoretransparent && pxlSrc == dst->transparent) { | |
128 | + pxlSrc = dst->transparent; | |
129 | + } else { | |
130 | + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); | |
131 | + | |
132 | + if (pxlSrc == -1) { | |
133 | + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); | |
134 | + } | |
135 | + } | |
136 | + | |
137 | + if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) { | |
138 | + gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc); | |
139 | + } | |
140 | + | |
141 | + pxlOldLeft = pxlLeft; | |
142 | + } | |
143 | + | |
144 | + i += iOffset; | |
145 | + | |
146 | + if (i < dst->sx) { | |
147 | + gdImageSetPixel (dst, i, uRow, pxlLeft); | |
148 | + } | |
149 | + | |
150 | + gdImageSetPixel (dst, iOffset, uRow, clrBack); | |
151 | + | |
152 | + i--; | |
153 | + | |
154 | + while (++i < dst->sx) { | |
155 | + gdImageSetPixel (dst, i, uRow, clrBack); | |
156 | + } | |
1e268c02 PG |
157 | +} |
158 | + | |
3970628f | 159 | +void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent) |
1e268c02 | 160 | +{ |
3970628f JB |
161 | + typedef int (*FuncPtr)(gdImagePtr, int, int); |
162 | + int i, iYPos=0, r, g, b, a; | |
163 | + FuncPtr f; | |
164 | + int pxlOldLeft, pxlLeft=0, pxlSrc; | |
165 | + | |
166 | + if (src->trueColor) { | |
167 | + f = gdImageGetTrueColorPixel; | |
168 | + } else { | |
169 | + f = gdImageGetPixel; | |
170 | + } | |
171 | + | |
172 | + for (i = 0; i<=iOffset; i++) { | |
173 | + gdImageSetPixel (dst, uCol, i, clrBack); | |
174 | + } | |
175 | + r = (int)((double)gdImageRed(src,clrBack) * dWeight); | |
176 | + g = (int)((double)gdImageGreen(src,clrBack) * dWeight); | |
177 | + b = (int)((double)gdImageBlue(src,clrBack) * dWeight); | |
178 | + a = (int)((double)gdImageAlpha(src,clrBack) * dWeight); | |
179 | + | |
180 | + pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a); | |
181 | + | |
182 | + for (i = 0; i < src->sy; i++) { | |
183 | + pxlSrc = f (src, uCol, i); | |
184 | + iYPos = i + iOffset; | |
185 | + | |
186 | + r = (int)((double)gdImageRed(src,pxlSrc) * dWeight); | |
187 | + g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight); | |
188 | + b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight); | |
189 | + a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight); | |
190 | + | |
191 | + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); | |
192 | + | |
193 | + if (pxlLeft == -1) { | |
194 | + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); | |
195 | + } | |
196 | + | |
197 | + r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft)); | |
198 | + g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft)); | |
199 | + b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft)); | |
200 | + a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft)); | |
201 | + | |
202 | + if (r>255) { | |
203 | + r = 255; | |
204 | + } | |
205 | + | |
206 | + if (g>255) { | |
207 | + g = 255; | |
208 | + } | |
209 | + | |
210 | + if (b>255) { | |
211 | + b = 255; | |
212 | + } | |
213 | + | |
214 | + if (a>127) { | |
215 | + a = 127; | |
216 | + } | |
217 | + | |
218 | + if (ignoretransparent && pxlSrc == dst->transparent) { | |
219 | + pxlSrc = dst->transparent; | |
220 | + } else { | |
221 | + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); | |
222 | + | |
223 | + if (pxlSrc == -1) { | |
224 | + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); | |
225 | + } | |
226 | + } | |
227 | + | |
228 | + if ((iYPos >= 0) && (iYPos < dst->sy)) { | |
229 | + gdImageSetPixel (dst, uCol, iYPos, pxlSrc); | |
230 | + } | |
231 | + | |
232 | + pxlOldLeft = pxlLeft; | |
233 | + } | |
234 | + | |
235 | + i = iYPos; | |
236 | + if (i < dst->sy) { | |
237 | + gdImageSetPixel (dst, uCol, i, pxlLeft); | |
238 | + } | |
239 | + | |
240 | + i--; | |
241 | + while (++i < dst->sy) { | |
242 | + gdImageSetPixel (dst, uCol, i, clrBack); | |
243 | + } | |
1e268c02 PG |
244 | +} |
245 | + | |
246 | +/* Rotates an image by 90 degrees (counter clockwise) */ | |
3970628f | 247 | +BGD_DECLARE(gdImagePtr) gdImageRotate90 (gdImagePtr src, int ignoretransparent) |
1e268c02 | 248 | +{ |
3970628f JB |
249 | + int uY, uX; |
250 | + int c,r,g,b,a; | |
251 | + gdImagePtr dst; | |
252 | + typedef int (*FuncPtr)(gdImagePtr, int, int); | |
253 | + FuncPtr f; | |
254 | + | |
255 | + if (src->trueColor) { | |
256 | + f = gdImageGetTrueColorPixel; | |
257 | + } else { | |
258 | + f = gdImageGetPixel; | |
259 | + } | |
260 | + dst = gdImageCreateTrueColor(src->sy, src->sx); | |
261 | + dst->transparent = src->transparent; | |
262 | + | |
263 | + if (dst != NULL) { | |
264 | + gdImagePaletteCopy (dst, src); | |
265 | + | |
266 | + for (uY = 0; uY<src->sy; uY++) { | |
267 | + for (uX = 0; uX<src->sx; uX++) { | |
268 | + c = f (src, uX, uY); | |
269 | + if (!src->trueColor) { | |
270 | + r = gdImageRed(src,c); | |
271 | + g = gdImageGreen(src,c); | |
272 | + b = gdImageBlue(src,c); | |
273 | + a = gdImageAlpha(src,c); | |
274 | + c = gdTrueColorAlpha(r, g, b, a); | |
275 | + } | |
276 | + if (ignoretransparent && c == dst->transparent) { | |
277 | + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent); | |
278 | + } else { | |
279 | + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c); | |
280 | + } | |
281 | + } | |
282 | + } | |
283 | + } | |
284 | + | |
285 | + return dst; | |
1e268c02 PG |
286 | +} |
287 | + | |
288 | +/* Rotates an image by 180 degrees (counter clockwise) */ | |
3970628f | 289 | +BGD_DECLARE(gdImagePtr) gdImageRotate180 (gdImagePtr src, int ignoretransparent) |
1e268c02 | 290 | +{ |
3970628f JB |
291 | + int uY, uX; |
292 | + int c,r,g,b,a; | |
293 | + gdImagePtr dst; | |
294 | + typedef int (*FuncPtr)(gdImagePtr, int, int); | |
295 | + FuncPtr f; | |
296 | + | |
297 | + if (src->trueColor) { | |
298 | + f = gdImageGetTrueColorPixel; | |
299 | + } else { | |
300 | + f = gdImageGetPixel; | |
301 | + } | |
302 | + dst = gdImageCreateTrueColor(src->sx, src->sy); | |
303 | + dst->transparent = src->transparent; | |
304 | + | |
305 | + if (dst != NULL) { | |
306 | + gdImagePaletteCopy (dst, src); | |
307 | + | |
308 | + for (uY = 0; uY<src->sy; uY++) { | |
309 | + for (uX = 0; uX<src->sx; uX++) { | |
310 | + c = f (src, uX, uY); | |
311 | + if (!src->trueColor) { | |
312 | + r = gdImageRed(src,c); | |
313 | + g = gdImageGreen(src,c); | |
314 | + b = gdImageBlue(src,c); | |
315 | + a = gdImageAlpha(src,c); | |
316 | + c = gdTrueColorAlpha(r, g, b, a); | |
317 | + } | |
318 | + | |
319 | + if (ignoretransparent && c == dst->transparent) { | |
320 | + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent); | |
321 | + } else { | |
322 | + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c); | |
323 | + } | |
324 | + } | |
325 | + } | |
326 | + } | |
327 | + | |
328 | + return dst; | |
1e268c02 PG |
329 | +} |
330 | + | |
331 | +/* Rotates an image by 270 degrees (counter clockwise) */ | |
3970628f | 332 | +BGD_DECLARE(gdImagePtr) gdImageRotate270 (gdImagePtr src, int ignoretransparent) |
1e268c02 | 333 | +{ |
3970628f JB |
334 | + int uY, uX; |
335 | + int c,r,g,b,a; | |
336 | + gdImagePtr dst; | |
337 | + typedef int (*FuncPtr)(gdImagePtr, int, int); | |
338 | + FuncPtr f; | |
339 | + | |
340 | + if (src->trueColor) { | |
341 | + f = gdImageGetTrueColorPixel; | |
342 | + } else { | |
343 | + f = gdImageGetPixel; | |
344 | + } | |
345 | + dst = gdImageCreateTrueColor (src->sy, src->sx); | |
346 | + dst->transparent = src->transparent; | |
347 | + | |
348 | + if (dst != NULL) { | |
349 | + gdImagePaletteCopy (dst, src); | |
350 | + | |
351 | + for (uY = 0; uY<src->sy; uY++) { | |
352 | + for (uX = 0; uX<src->sx; uX++) { | |
353 | + c = f (src, uX, uY); | |
354 | + if (!src->trueColor) { | |
355 | + r = gdImageRed(src,c); | |
356 | + g = gdImageGreen(src,c); | |
357 | + b = gdImageBlue(src,c); | |
358 | + a = gdImageAlpha(src,c); | |
359 | + c = gdTrueColorAlpha(r, g, b, a); | |
360 | + } | |
361 | + | |
362 | + if (ignoretransparent && c == dst->transparent) { | |
363 | + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent); | |
364 | + } else { | |
365 | + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c); | |
366 | + } | |
367 | + } | |
368 | + } | |
369 | + } | |
370 | + | |
371 | + return dst; | |
1e268c02 PG |
372 | +} |
373 | + | |
3970628f | 374 | +BGD_DECLARE(gdImagePtr) gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent) |
1e268c02 | 375 | +{ |
3970628f JB |
376 | + typedef int (*FuncPtr)(gdImagePtr, int, int); |
377 | + gdImagePtr dst1,dst2,dst3; | |
378 | + FuncPtr f; | |
379 | + double dRadAngle, dSinE, dTan, dShear; | |
380 | + double dOffset; /* Variable skew offset */ | |
381 | + int u, iShear, newx, newy; | |
382 | + int clrBackR, clrBackG, clrBackB, clrBackA; | |
383 | + | |
384 | + /* See GEMS I for the algorithm details */ | |
385 | + dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */ | |
386 | + dSinE = sin (dRadAngle); | |
387 | + dTan = tan (dRadAngle / 2.0); | |
388 | + | |
389 | + newx = (int)(src->sx + src->sy * fabs(dTan)); | |
390 | + newy = src->sy; | |
391 | + | |
392 | + /* 1st shear */ | |
393 | + if (src->trueColor) { | |
394 | + f = gdImageGetTrueColorPixel; | |
395 | + } else { | |
396 | + f = gdImageGetPixel; | |
397 | + } | |
398 | + | |
399 | + dst1 = gdImageCreateTrueColor(newx, newy); | |
400 | + /******* Perform 1st shear (horizontal) ******/ | |
401 | + if (dst1 == NULL) { | |
402 | + return NULL; | |
403 | + } | |
404 | + dst1->alphaBlendingFlag = gdEffectReplace; | |
405 | + | |
406 | + if (dAngle == 0.0) { | |
407 | + /* Returns copy of src */ | |
408 | + gdImageCopy (dst1, src,0,0,0,0,src->sx,src->sy); | |
409 | + return dst1; | |
410 | + } | |
411 | + | |
412 | + gdImagePaletteCopy (dst1, src); | |
413 | + | |
414 | + if (ignoretransparent) { | |
415 | + if (gdImageTrueColor(src)) { | |
416 | + dst1->transparent = src->transparent; | |
417 | + } else { | |
418 | + | |
419 | + dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127); | |
420 | + } | |
421 | + } | |
422 | + | |
423 | + dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */ | |
424 | + dSinE = sin (dRadAngle); | |
425 | + dTan = tan (dRadAngle / 2.0); | |
426 | + | |
427 | + for (u = 0; u < dst1->sy; u++) { | |
428 | + if (dTan >= 0.0) { | |
429 | + dShear = ((double)(u + 0.5)) * dTan; | |
430 | + } else { | |
431 | + dShear = ((double)(u - dst1->sy) + 0.5) * dTan; | |
432 | + } | |
433 | + | |
434 | + iShear = (int)floor(dShear); | |
435 | + gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent); | |
436 | + } | |
437 | + | |
438 | + /* | |
439 | + The 1st shear may use the original clrBack as color index | |
440 | + Convert it once here | |
441 | + */ | |
442 | + if(!src->trueColor) { | |
443 | + clrBackR = gdImageRed(src, clrBack); | |
444 | + clrBackG = gdImageGreen(src, clrBack); | |
445 | + clrBackB = gdImageBlue(src, clrBack); | |
446 | + clrBackA = gdImageAlpha(src, clrBack); | |
447 | + clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA); | |
448 | + } | |
449 | + /* 2nd shear */ | |
450 | + newx = dst1->sx; | |
451 | + | |
452 | + if (dSinE > 0.0) { | |
453 | + dOffset = (src->sx-1) * dSinE; | |
454 | + } else { | |
455 | + dOffset = -dSinE * (src->sx - newx); | |
456 | + } | |
457 | + | |
458 | + newy = (int) ((double) src->sx * fabs( dSinE ) + (double) src->sy * cos (dRadAngle))+1; | |
459 | + | |
460 | + if (src->trueColor) { | |
461 | + f = gdImageGetTrueColorPixel; | |
462 | + } else { | |
463 | + f = gdImageGetPixel; | |
464 | + } | |
465 | + dst2 = gdImageCreateTrueColor(newx, newy); | |
466 | + if (dst2 == NULL) { | |
467 | + gdImageDestroy(dst1); | |
468 | + return NULL; | |
469 | + } | |
470 | + dst2->alphaBlendingFlag = gdEffectReplace; | |
471 | + if (ignoretransparent) { | |
472 | + dst2->transparent = dst1->transparent; | |
473 | + } | |
474 | + | |
475 | + for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) { | |
476 | + iShear = (int)floor (dOffset); | |
477 | + gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent); | |
478 | + } | |
479 | + | |
480 | + /* 3rd shear */ | |
481 | + gdImageDestroy(dst1); | |
482 | + | |
483 | + newx = (int) ((double)src->sy * fabs (dSinE) + (double)src->sx * cos (dRadAngle)) + 1; | |
484 | + newy = dst2->sy; | |
485 | + | |
486 | + if (src->trueColor) { | |
487 | + f = gdImageGetTrueColorPixel; | |
488 | + } else { | |
489 | + f = gdImageGetPixel; | |
490 | + } | |
491 | + dst3 = gdImageCreateTrueColor(newx, newy); | |
492 | + if (dst3 == NULL) { | |
493 | + gdImageDestroy(dst2); | |
494 | + return NULL; | |
495 | + } | |
496 | + | |
497 | + dst3->alphaBlendingFlag = gdEffectReplace; | |
498 | + if (ignoretransparent) { | |
499 | + dst3->transparent = dst2->transparent; | |
500 | + } | |
501 | + | |
502 | + if (dSinE >= 0.0) { | |
503 | + dOffset = (double)(src->sx - 1) * dSinE * -dTan; | |
504 | + } else { | |
505 | + dOffset = dTan * ((double)(src->sx - 1) * -dSinE + (double)(1 - newy)); | |
506 | + } | |
507 | + | |
508 | + for (u = 0; u < dst3->sy; u++, dOffset += dTan) { | |
509 | + int iShear = (int)floor(dOffset); | |
510 | + gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent); | |
511 | + } | |
512 | + | |
513 | + gdImageDestroy(dst2); | |
514 | + | |
515 | + return dst3; | |
1e268c02 PG |
516 | +} |
517 | + | |
3970628f | 518 | +BGD_DECLARE(gdImagePtr) gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent) |
1e268c02 | 519 | +{ |
3970628f JB |
520 | + gdImagePtr pMidImg; |
521 | + gdImagePtr rotatedImg; | |
522 | + | |
523 | + if (src == NULL) { | |
524 | + return NULL; | |
525 | + } | |
526 | + | |
527 | + if (!gdImageTrueColor(src) && clrBack>=gdImageColorsTotal(src)) { | |
528 | + return NULL; | |
529 | + } | |
530 | + | |
531 | + while (dAngle >= 360.0) { | |
532 | + dAngle -= 360.0; | |
533 | + } | |
534 | + | |
535 | + while (dAngle < 0) { | |
536 | + dAngle += 360.0; | |
537 | + } | |
538 | + | |
539 | + if (dAngle == 90.00) { | |
540 | + return gdImageRotate90(src, ignoretransparent); | |
541 | + } | |
542 | + if (dAngle == 180.00) { | |
543 | + return gdImageRotate180(src, ignoretransparent); | |
544 | + } | |
545 | + if(dAngle == 270.00) { | |
546 | + return gdImageRotate270 (src, ignoretransparent); | |
547 | + } | |
548 | + | |
549 | + if ((dAngle > 45.0) && (dAngle <= 135.0)) { | |
550 | + pMidImg = gdImageRotate90 (src, ignoretransparent); | |
551 | + dAngle -= 90.0; | |
552 | + } else if ((dAngle > 135.0) && (dAngle <= 225.0)) { | |
553 | + pMidImg = gdImageRotate180 (src, ignoretransparent); | |
554 | + dAngle -= 180.0; | |
555 | + } else if ((dAngle > 225.0) && (dAngle <= 315.0)) { | |
556 | + pMidImg = gdImageRotate270 (src, ignoretransparent); | |
557 | + dAngle -= 270.0; | |
558 | + } else { | |
559 | + return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent); | |
560 | + } | |
561 | + | |
562 | + if (pMidImg == NULL) { | |
563 | + return NULL; | |
564 | + } | |
565 | + | |
566 | + rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent); | |
567 | + gdImageDestroy(pMidImg); | |
568 | + | |
569 | + return rotatedImg; | |
1e268c02 PG |
570 | +} |
571 | +/* End Rotate function */ | |
572 | + | |
3970628f JB |
573 | +static int gdLayerOverlay (int dst, int src) |
574 | +{ | |
575 | + int a1, a2; | |
576 | + a1 = gdAlphaMax - gdTrueColorGetAlpha(dst); | |
577 | + a2 = gdAlphaMax - gdTrueColorGetAlpha(src); | |
578 | + return ( ((gdAlphaMax - a1*a2/gdAlphaMax) << 24) + | |
579 | + (gdAlphaOverlayColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax ) << 16) + | |
580 | + (gdAlphaOverlayColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax ) << 8) + | |
581 | + (gdAlphaOverlayColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax )) | |
582 | + ); | |
583 | +} | |
584 | + | |
585 | +static int gdAlphaOverlayColor (int src, int dst, int max ) | |
586 | +{ | |
587 | + /* this function implements the algorithm | |
588 | + * | |
589 | + * for dst[rgb] < 0.5, | |
590 | + * c[rgb] = 2.src[rgb].dst[rgb] | |
591 | + * and for dst[rgb] > 0.5, | |
592 | + * c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1 | |
593 | + * | |
594 | + */ | |
595 | + | |
596 | + dst = dst << 1; | |
597 | + if( dst > max ) { | |
598 | + /* in the "light" zone */ | |
599 | + return dst + (src << 1) - (dst * src / max) - max; | |
600 | + } else { | |
601 | + /* in the "dark" zone */ | |
602 | + return dst * src / max; | |
603 | + } | |
604 | +} | |
605 | + | |
1e268c02 | 606 | + |
3970628f | 607 | +/* End of part code from php */ |
1e268c02 PG |
608 | + |
609 | /* When gd 1.x was first created, floating point was to be avoided. | |
610 | These days it is often faster than table lookups or integer | |
611 | arithmetic. The routine below is shamelessly, gloriously | |
3970628f JB |
612 | --- gd-2.0.33/gd.h.orig 2006-12-23 01:06:10.281588261 +0100 |
613 | +++ gd-2.0.33/gd.h 2006-12-23 01:48:20.989805102 +0100 | |
614 | @@ -117,6 +117,10 @@ | |
1e268c02 PG |
615 | #define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16) |
616 | #define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8) | |
617 | #define gdTrueColorGetBlue(c) ((c) & 0x0000FF) | |
618 | +#define gdEffectReplace 0 | |
619 | +#define gdEffectAlphaBlend 1 | |
620 | +#define gdEffectNormal 2 | |
621 | +#define gdEffectOverlay 3 | |
622 | ||
623 | /* This function accepts truecolor pixel values only. The | |
624 | source color is composited with the destination color | |
3970628f | 625 | @@ -691,6 +695,12 @@ |
1e268c02 PG |
626 | int srcX, int srcY, |
627 | int srcWidth, int srcHeight, int angle); | |
628 | ||
3970628f JB |
629 | +gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent); |
630 | +gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent); | |
631 | +gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent); | |
632 | +gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); | |
633 | +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); | |
1e268c02 PG |
634 | + |
635 | BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush); | |
636 | BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile); | |
637 | BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c); |