1 // -*- mode: C++; indent-tabs-mode: nil; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
22 BImage::BImage(BImageControl *c, int w, int h) {
25 width = (w > 0) ? w : 1;
26 height = (h > 0) ? h : 1;
28 red = new unsigned char[width * height];
29 green = new unsigned char[width * height];
30 blue = new unsigned char[width * height];
32 xtable = ytable = (unsigned int *) 0;
34 cpc = control->getColorsPerChannel();
37 control->getColorTables(&red_table, &green_table, &blue_table,
38 &red_offset, &green_offset, &blue_offset,
39 &red_bits, &green_bits, &blue_bits);
41 if (control->getVisual()->c_class != TrueColor)
42 control->getXColorTable(&colors, &ncolors);
46 BImage::~BImage(void) {
53 Pixmap BImage::render(const BTexture &texture) {
54 if (texture.texture() & BTexture::Parent_Relative)
55 return ParentRelative;
56 else if (texture.texture() & BTexture::Solid)
57 return render_solid(texture);
58 else if (texture.texture() & BTexture::Gradient)
59 return render_gradient(texture);
64 Pixmap BImage::render_solid(const BTexture &texture) {
65 Pixmap pixmap = XCreatePixmap(OBDisplay::display,
66 control->getDrawable(), width,
67 height, control->getDepth());
69 fprintf(stderr, "BImage::render_solid: error creating pixmap\n");
73 BPen pen(texture.color());
74 BPen penlight(texture.lightColor());
75 BPen penshadow(texture.shadowColor());
77 XFillRectangle(OBDisplay::display, pixmap, pen.gc(), 0, 0, width, height);
79 if (texture.texture() & BTexture::Interlaced) {
80 BPen peninterlace(texture.colorTo());
81 for (unsigned int i = 0; i < height; i += 2)
82 XDrawLine(OBDisplay::display, pixmap, peninterlace.gc(), 0, i, width, i);
85 int left = 0, top = 0, right = width - 1, bottom = height - 1;
87 if (texture.texture() & BTexture::Border) {
88 BPen penborder(texture.borderColor());
89 XDrawRectangle(OBDisplay::display, pixmap, penborder.gc(),
90 left, top, right, bottom);
93 if (texture.texture() & BTexture::Bevel1) {
94 if (texture.texture() & BTexture::Raised) {
95 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
96 left, bottom, right, bottom);
97 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
98 right, bottom, right, top);
100 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
101 left, top, right, top);
102 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
103 left, bottom, left, top);
104 } else if (texture.texture() & BTexture::Sunken) {
105 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
106 left, bottom, right, bottom);
107 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
108 right, bottom, right, top);
110 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
111 left, top, right, top);
112 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
113 left, bottom, left, top);
115 } else if (texture.texture() & BTexture::Bevel2) {
116 if (texture.texture() & BTexture::Raised) {
117 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
118 left + 1, bottom - 2, right - 2, bottom - 2);
119 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
120 right - 2, bottom - 2, right - 2, top + 1);
122 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
123 left + 1, top + 1, right - 2, top + 1);
124 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
125 left + 1, bottom - 2, left + 1, top + 1);
126 } else if (texture.texture() & BTexture::Sunken) {
127 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
128 left + 1, bottom - 2, right - 2, bottom - 2);
129 XDrawLine(OBDisplay::display, pixmap, penlight.gc(),
130 right - 2, bottom - 2, right - 2, top + 1);
132 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
133 left + 1, top + 1, right - 2, top + 1);
134 XDrawLine(OBDisplay::display, pixmap, penshadow.gc(),
135 left + 1, bottom - 2, left + 1, top + 1);
143 Pixmap BImage::render_gradient(const BTexture &texture) {
144 bool inverted = False;
146 interlaced = texture.texture() & BTexture::Interlaced;
148 if (texture.texture() & BTexture::Sunken) {
149 from = texture.colorTo();
150 to = texture.color();
152 if (! (texture.texture() & BTexture::Invert)) inverted = True;
154 from = texture.color();
155 to = texture.colorTo();
157 if (texture.texture() & BTexture::Invert) inverted = True;
160 control->getGradientBuffers(width, height, &xtable, &ytable);
162 if (texture.texture() & BTexture::Diagonal) dgradient();
163 else if (texture.texture() & BTexture::Elliptic) egradient();
164 else if (texture.texture() & BTexture::Horizontal) hgradient();
165 else if (texture.texture() & BTexture::Pyramid) pgradient();
166 else if (texture.texture() & BTexture::Rectangle) rgradient();
167 else if (texture.texture() & BTexture::Vertical) vgradient();
168 else if (texture.texture() & BTexture::CrossDiagonal) cdgradient();
169 else if (texture.texture() & BTexture::PipeCross) pcgradient();
171 if (texture.texture() & BTexture::Bevel1) bevel1();
172 else if (texture.texture() & BTexture::Bevel2) bevel2();
174 if (texture.texture() & BTexture::Border) border(texture);
176 if (inverted) invert();
178 return renderPixmap();
183 static const unsigned char dither4[4][4] = {
192 * Helper function for TrueColorDither and renderXImage
194 * This handles the proper setting of the image data based on the image depth
195 * and the machine's byte ordering
198 void assignPixelData(unsigned int bit_depth, unsigned char **data,
199 unsigned long pixel) {
200 unsigned char *pixel_data = *data;
203 *pixel_data++ = pixel;
206 case 16: // 16bpp LSB
207 *pixel_data++ = pixel;
208 *pixel_data++ = pixel >> 8;
211 case 17: // 16bpp MSB
212 *pixel_data++ = pixel >> 8;
213 *pixel_data++ = pixel;
216 case 24: // 24bpp LSB
217 *pixel_data++ = pixel;
218 *pixel_data++ = pixel >> 8;
219 *pixel_data++ = pixel >> 16;
222 case 25: // 24bpp MSB
223 *pixel_data++ = pixel >> 16;
224 *pixel_data++ = pixel >> 8;
225 *pixel_data++ = pixel;
228 case 32: // 32bpp LSB
229 *pixel_data++ = pixel;
230 *pixel_data++ = pixel >> 8;
231 *pixel_data++ = pixel >> 16;
232 *pixel_data++ = pixel >> 24;
235 case 33: // 32bpp MSB
236 *pixel_data++ = pixel >> 24;
237 *pixel_data++ = pixel >> 16;
238 *pixel_data++ = pixel >> 8;
239 *pixel_data++ = pixel;
242 *data = pixel_data; // assign back so we don't lose our place
246 // algorithm: ordered dithering... many many thanks to rasterman
247 // (raster@rasterman.com) for telling me about this... portions of this
248 // code is based off of his code in Imlib
249 void BImage::TrueColorDither(unsigned int bit_depth, int bytes_per_line,
250 unsigned char *pixel_data) {
251 unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset;
252 unsigned char *ppixel_data = pixel_data;
255 for (y = 0, offset = 0; y < height; y++) {
258 for (x = 0; x < width; x++, offset++) {
264 er = r & (red_bits - 1);
265 eg = g & (green_bits - 1);
266 eb = b & (blue_bits - 1);
272 if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++;
273 if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++;
274 if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++;
276 pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
277 assignPixelData(bit_depth, &pixel_data, pixel);
280 pixel_data = (ppixel_data += bytes_per_line);
285 const static unsigned char dither8[8][8] = {
286 { 0, 32, 8, 40, 2, 34, 10, 42},
287 { 48, 16, 56, 24, 50, 18, 58, 26},
288 { 12, 44, 4, 36, 14, 46, 6, 38},
289 { 60, 28, 52, 20, 62, 30, 54, 22},
290 { 3, 35, 11, 43, 1, 33, 9, 41},
291 { 51, 19, 59, 27, 49, 17, 57, 25},
292 { 15, 47, 7, 39, 13, 45, 5, 37},
293 { 63, 31, 55, 23, 61, 29, 53, 21}
296 void BImage::OrderedPseudoColorDither(int bytes_per_line,
297 unsigned char *pixel_data) {
298 unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset;
300 unsigned char *ppixel_data = pixel_data;
302 for (y = 0, offset = 0; y < height; y++) {
305 for (x = 0; x < width; x++, offset++) {
312 er = r & (red_bits - 1);
313 eg = g & (green_bits - 1);
314 eb = b & (blue_bits - 1);
320 if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++;
321 if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++;
322 if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++;
324 pixel = (r * cpccpc) + (g * cpc) + b;
325 *(pixel_data++) = colors[pixel].pixel;
328 pixel_data = (ppixel_data += bytes_per_line);
333 void BImage::PseudoColorDither(int bytes_per_line, unsigned char *pixel_data) {
335 *rerr = new short[width + 2],
336 *gerr = new short[width + 2],
337 *berr = new short[width + 2],
338 *nrerr = new short[width + 2],
339 *ngerr = new short[width + 2],
340 *nberr = new short[width + 2];
342 int rr, gg, bb, rer, ger, ber;
343 int dd = 255 / control->getColorsPerChannel();
344 unsigned int x, y, r, g, b, offset;
346 unsigned char *ppixel_data = pixel_data;
348 for (x = 0; x < width; x++) {
349 *(rerr + x) = *(red + x);
350 *(gerr + x) = *(green + x);
351 *(berr + x) = *(blue + x);
354 *(rerr + x) = *(gerr + x) = *(berr + x) = 0;
356 for (y = 0, offset = 0; y < height; y++) {
357 if (y < (height - 1)) {
358 int i = offset + width;
359 for (x = 0; x < width; x++, i++) {
360 *(nrerr + x) = *(red + i);
361 *(ngerr + x) = *(green + i);
362 *(nberr + x) = *(blue + i);
365 *(nrerr + x) = *(red + (--i));
366 *(ngerr + x) = *(green + i);
367 *(nberr + x) = *(blue + i);
370 for (x = 0; x < width; x++) {
375 if (rr > 255) rr = 255; else if (rr < 0) rr = 0;
376 if (gg > 255) gg = 255; else if (gg < 0) gg = 0;
377 if (bb > 255) bb = 255; else if (bb < 0) bb = 0;
383 rer = rerr[x] - r*dd;
384 ger = gerr[x] - g*dd;
385 ber = berr[x] - b*dd;
387 pixel = (r * cpccpc) + (g * cpc) + b;
388 *pixel_data++ = colors[pixel].pixel;
403 pixel_data = (ppixel_data += bytes_per_line);
426 XImage *BImage::renderXImage(void) {
428 XCreateImage(OBDisplay::display,
429 control->getVisual(), control->getDepth(), ZPixmap, 0, 0,
430 width, height, 32, 0);
433 fprintf(stderr, "BImage::renderXImage: error creating XImage\n");
438 image->data = (char *) 0;
440 unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)];
442 unsigned int o = image->bits_per_pixel +
443 ((image->byte_order == MSBFirst) ? 1 : 0);
445 bool unsupported = False;
447 if (control->doDither() && width > 1 && height > 1) {
448 switch (control->getVisual()->c_class) {
450 TrueColorDither(o, image->bytes_per_line, d);
456 OrderedPseudoColorDither(image->bytes_per_line, d);
458 PseudoColorDither(image->bytes_per_line, d);
467 unsigned int x, y, r, g, b, offset;
468 unsigned char *pixel_data = d, *ppixel_data = d;
471 switch (control->getVisual()->c_class) {
474 for (y = 0, offset = 0; y < height; ++y) {
475 for (x = 0; x < width; ++x, ++offset) {
476 r = red_table[red[offset]];
477 g = green_table[green[offset]];
478 b = blue_table[blue[offset]];
480 pixel = (r * cpccpc) + (g * cpc) + b;
481 *pixel_data++ = colors[pixel].pixel;
484 pixel_data = (ppixel_data += image->bytes_per_line);
490 for (y = 0, offset = 0; y < height; y++) {
491 for (x = 0; x < width; x++, offset++) {
492 r = red_table[red[offset]];
493 g = green_table[green[offset]];
494 b = blue_table[blue[offset]];
496 pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
497 assignPixelData(o, &pixel_data, pixel);
500 pixel_data = (ppixel_data += image->bytes_per_line);
507 for (y = 0, offset = 0; y < height; y++) {
508 for (x = 0; x < width; x++, offset++) {
509 r = *(red_table + *(red + offset));
510 g = *(green_table + *(green + offset));
511 b = *(blue_table + *(blue + offset));
513 g = ((r * 30) + (g * 59) + (b * 11)) / 100;
514 *pixel_data++ = colors[g].pixel;
517 pixel_data = (ppixel_data += image->bytes_per_line);
528 fprintf(stderr, "BImage::renderXImage: unsupported visual\n");
530 XDestroyImage(image);
534 image->data = (char *) d;
540 Pixmap BImage::renderPixmap(void) {
542 XCreatePixmap(OBDisplay::display,
543 control->getDrawable(), width, height, control->getDepth());
545 if (pixmap == None) {
546 fprintf(stderr, "BImage::renderPixmap: error creating pixmap\n");
550 XImage *image = renderXImage();
553 XFreePixmap(OBDisplay::display, pixmap);
558 XDestroyImage(image);
559 XFreePixmap(OBDisplay::display, pixmap);
563 XPutImage(OBDisplay::display, pixmap,
564 DefaultGC(OBDisplay::display,
565 control->getScreenInfo()->getScreenNumber()),
566 image, 0, 0, 0, 0, width, height);
569 delete [] image->data;
573 XDestroyImage(image);
579 void BImage::bevel1(void) {
580 if (width > 2 && height > 2) {
581 unsigned char *pr = red, *pg = green, *pb = blue;
583 register unsigned char r, g, b, rr ,gg ,bb;
584 register unsigned int w = width, h = height - 1, wh = w * h;
602 rr = (r >> 2) + (r >> 1);
605 gg = (g >> 2) + (g >> 1);
608 bb = (b >> 2) + (b >> 1);
631 rr = (r >> 2) + (r >> 1);
634 gg = (g >> 2) + (g >> 1);
637 bb = (b >> 2) + (b >> 1);
668 rr = (r >> 2) + (r >> 1);
671 gg = (g >> 2) + (g >> 1);
674 bb = (b >> 2) + (b >> 1);
701 rr = (r >> 2) + (r >> 1);
704 gg = (g >> 2) + (g >> 1);
707 bb = (b >> 2) + (b >> 1);
717 void BImage::bevel2(void) {
718 if (width > 4 && height > 4) {
719 unsigned char r, g, b, rr ,gg ,bb, *pr = red + width + 1,
720 *pg = green + width + 1, *pb = blue + width + 1;
721 unsigned int w = width - 2, h = height - 1, wh = width * (height - 3);
739 rr = (r >> 2) + (r >> 1);
742 gg = (g >> 2) + (g >> 1);
745 bb = (b >> 2) + (b >> 1);
777 rr = (r >> 2) + (r >> 1);
780 gg = (g >> 2) + (g >> 1);
783 bb = (b >> 2) + (b >> 1);
796 void BImage::border(const BTexture &texture) {
797 if (width < 2 || height < 2) return;
799 register unsigned int i;
800 int r = texture.borderColor().red(),
801 g = texture.borderColor().green(),
802 b = texture.borderColor().blue();
804 unsigned char *pr, *pg, *pb;
810 for (i = 0; i < width; ++i) {
817 // left and right lines (pr,pg,pb are already lined up)
818 for (i = 1; i < height - 1; ++i) {
831 // bottom line (pr,pg,pb are already lined up)
832 for (i = 0; i < width; ++i) {
840 void BImage::invert(void) {
841 register unsigned int i, j, wh = (width * height) - 1;
844 for (i = 0, j = wh; j > i; j--, i++) {
846 *(red + j) = *(red + i);
850 *(green + j) = *(green + i);
854 *(blue + j) = *(blue + i);
860 void BImage::dgradient(void) {
861 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
862 // modified for interlacing by Brad Hughes
864 float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
865 xr = (float) from.red(),
866 xg = (float) from.green(),
867 xb = (float) from.blue();
868 unsigned char *pr = red, *pg = green, *pb = blue;
869 unsigned int w = width * 2, h = height * 2, *xt = xtable, *yt = ytable;
871 register unsigned int x, y;
873 dry = drx = (float) (to.red() - from.red());
874 dgy = dgx = (float) (to.green() - from.green());
875 dby = dbx = (float) (to.blue() - from.blue());
882 for (x = 0; x < width; x++) {
883 *(xt++) = (unsigned char) (xr);
884 *(xt++) = (unsigned char) (xg);
885 *(xt++) = (unsigned char) (xb);
897 for (y = 0; y < height; y++) {
898 *(yt++) = ((unsigned char) yr);
899 *(yt++) = ((unsigned char) yg);
900 *(yt++) = ((unsigned char) yb);
907 // Combine tables to create gradient
911 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
912 for (xt = xtable, x = 0; x < width; x++) {
913 *(pr++) = *(xt++) + *(yt);
914 *(pg++) = *(xt++) + *(yt + 1);
915 *(pb++) = *(xt++) + *(yt + 2);
919 // faked interlacing effect
920 unsigned char channel, channel2;
922 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
923 for (xt = xtable, x = 0; x < width; x++) {
925 channel = *(xt++) + *(yt);
926 channel2 = (channel >> 1) + (channel >> 2);
927 if (channel2 > channel) channel2 = 0;
930 channel = *(xt++) + *(yt + 1);
931 channel2 = (channel >> 1) + (channel >> 2);
932 if (channel2 > channel) channel2 = 0;
935 channel = *(xt++) + *(yt + 2);
936 channel2 = (channel >> 1) + (channel >> 2);
937 if (channel2 > channel) channel2 = 0;
940 channel = *(xt++) + *(yt);
941 channel2 = channel + (channel >> 3);
942 if (channel2 < channel) channel2 = ~0;
945 channel = *(xt++) + *(yt + 1);
946 channel2 = channel + (channel >> 3);
947 if (channel2 < channel) channel2 = ~0;
950 channel = *(xt++) + *(yt + 2);
951 channel2 = channel + (channel >> 3);
952 if (channel2 < channel) channel2 = ~0;
961 void BImage::hgradient(void) {
963 xr = (float) from.red(),
964 xg = (float) from.green(),
965 xb = (float) from.blue();
966 unsigned char *pr = red, *pg = green, *pb = blue;
968 register unsigned int x, y;
970 drx = (float) (to.red() - from.red());
971 dgx = (float) (to.green() - from.green());
972 dbx = (float) (to.blue() - from.blue());
978 if (interlaced && height > 2) {
979 // faked interlacing effect
980 unsigned char channel, channel2;
982 for (x = 0; x < width; x++, pr++, pg++, pb++) {
983 channel = (unsigned char) xr;
984 channel2 = (channel >> 1) + (channel >> 2);
985 if (channel2 > channel) channel2 = 0;
988 channel = (unsigned char) xg;
989 channel2 = (channel >> 1) + (channel >> 2);
990 if (channel2 > channel) channel2 = 0;
993 channel = (unsigned char) xb;
994 channel2 = (channel >> 1) + (channel >> 2);
995 if (channel2 > channel) channel2 = 0;
999 channel = (unsigned char) xr;
1000 channel2 = channel + (channel >> 3);
1001 if (channel2 < channel) channel2 = ~0;
1002 *(pr + width) = channel2;
1004 channel = (unsigned char) xg;
1005 channel2 = channel + (channel >> 3);
1006 if (channel2 < channel) channel2 = ~0;
1007 *(pg + width) = channel2;
1009 channel = (unsigned char) xb;
1010 channel2 = channel + (channel >> 3);
1011 if (channel2 < channel) channel2 = ~0;
1012 *(pb + width) = channel2;
1025 for (y = 2; y < height; y++, pr += width, pg += width, pb += width) {
1026 if (y & 1) offset = width; else offset = 0;
1028 memcpy(pr, (red + offset), width);
1029 memcpy(pg, (green + offset), width);
1030 memcpy(pb, (blue + offset), width);
1034 for (x = 0; x < width; x++) {
1035 *(pr++) = (unsigned char) (xr);
1036 *(pg++) = (unsigned char) (xg);
1037 *(pb++) = (unsigned char) (xb);
1044 for (y = 1; y < height; y++, pr += width, pg += width, pb += width) {
1045 memcpy(pr, red, width);
1046 memcpy(pg, green, width);
1047 memcpy(pb, blue, width);
1053 void BImage::vgradient(void) {
1054 float dry, dgy, dby,
1055 yr = (float) from.red(),
1056 yg = (float) from.green(),
1057 yb = (float) from.blue();
1058 unsigned char *pr = red, *pg = green, *pb = blue;
1060 register unsigned int y;
1062 dry = (float) (to.red() - from.red());
1063 dgy = (float) (to.green() - from.green());
1064 dby = (float) (to.blue() - from.blue());
1071 // faked interlacing effect
1072 unsigned char channel, channel2;
1074 for (y = 0; y < height; y++, pr += width, pg += width, pb += width) {
1076 channel = (unsigned char) yr;
1077 channel2 = (channel >> 1) + (channel >> 2);
1078 if (channel2 > channel) channel2 = 0;
1079 memset(pr, channel2, width);
1081 channel = (unsigned char) yg;
1082 channel2 = (channel >> 1) + (channel >> 2);
1083 if (channel2 > channel) channel2 = 0;
1084 memset(pg, channel2, width);
1086 channel = (unsigned char) yb;
1087 channel2 = (channel >> 1) + (channel >> 2);
1088 if (channel2 > channel) channel2 = 0;
1089 memset(pb, channel2, width);
1091 channel = (unsigned char) yr;
1092 channel2 = channel + (channel >> 3);
1093 if (channel2 < channel) channel2 = ~0;
1094 memset(pr, channel2, width);
1096 channel = (unsigned char) yg;
1097 channel2 = channel + (channel >> 3);
1098 if (channel2 < channel) channel2 = ~0;
1099 memset(pg, channel2, width);
1101 channel = (unsigned char) yb;
1102 channel2 = channel + (channel >> 3);
1103 if (channel2 < channel) channel2 = ~0;
1104 memset(pb, channel2, width);
1113 for (y = 0; y < height; y++, pr += width, pg += width, pb += width) {
1114 memset(pr, (unsigned char) yr, width);
1115 memset(pg, (unsigned char) yg, width);
1116 memset(pb, (unsigned char) yb, width);
1126 void BImage::pgradient(void) {
1127 // pyramid gradient - based on original dgradient, written by
1128 // Mosfet (mosfet@kde.org)
1129 // adapted from kde sources for Blackbox by Brad Hughes
1131 float yr, yg, yb, drx, dgx, dbx, dry, dgy, dby,
1133 int rsign, gsign, bsign;
1134 unsigned char *pr = red, *pg = green, *pb = blue;
1135 unsigned int tr = to.red(), tg = to.green(), tb = to.blue(),
1136 *xt = xtable, *yt = ytable;
1138 register unsigned int x, y;
1140 dry = drx = (float) (to.red() - from.red());
1141 dgy = dgx = (float) (to.green() - from.green());
1142 dby = dbx = (float) (to.blue() - from.blue());
1144 rsign = (drx < 0) ? -1 : 1;
1145 gsign = (dgx < 0) ? -1 : 1;
1146 bsign = (dbx < 0) ? -1 : 1;
1148 xr = yr = (drx / 2);
1149 xg = yg = (dgx / 2);
1150 xb = yb = (dbx / 2);
1157 for (x = 0; x < width; x++) {
1158 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
1159 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
1160 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
1172 for (y = 0; y < height; y++) {
1173 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
1174 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
1175 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
1182 // Combine tables to create gradient
1186 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1187 for (xt = xtable, x = 0; x < width; x++) {
1188 *(pr++) = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
1189 *(pg++) = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
1190 *(pb++) = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
1194 // faked interlacing effect
1195 unsigned char channel, channel2;
1197 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1198 for (xt = xtable, x = 0; x < width; x++) {
1200 channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
1201 channel2 = (channel >> 1) + (channel >> 2);
1202 if (channel2 > channel) channel2 = 0;
1205 channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
1206 channel2 = (channel >> 1) + (channel >> 2);
1207 if (channel2 > channel) channel2 = 0;
1210 channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
1211 channel2 = (channel >> 1) + (channel >> 2);
1212 if (channel2 > channel) channel2 = 0;
1215 channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
1216 channel2 = channel + (channel >> 3);
1217 if (channel2 < channel) channel2 = ~0;
1220 channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
1221 channel2 = channel + (channel >> 3);
1222 if (channel2 < channel) channel2 = ~0;
1225 channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
1226 channel2 = channel + (channel >> 3);
1227 if (channel2 < channel) channel2 = ~0;
1236 void BImage::rgradient(void) {
1237 // rectangle gradient - based on original dgradient, written by
1238 // Mosfet (mosfet@kde.org)
1239 // adapted from kde sources for Blackbox by Brad Hughes
1241 float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
1242 int rsign, gsign, bsign;
1243 unsigned char *pr = red, *pg = green, *pb = blue;
1244 unsigned int tr = to.red(), tg = to.green(), tb = to.blue(),
1245 *xt = xtable, *yt = ytable;
1247 register unsigned int x, y;
1249 dry = drx = (float) (to.red() - from.red());
1250 dgy = dgx = (float) (to.green() - from.green());
1251 dby = dbx = (float) (to.blue() - from.blue());
1253 rsign = (drx < 0) ? -2 : 2;
1254 gsign = (dgx < 0) ? -2 : 2;
1255 bsign = (dbx < 0) ? -2 : 2;
1257 xr = yr = (drx / 2);
1258 xg = yg = (dgx / 2);
1259 xb = yb = (dbx / 2);
1266 for (x = 0; x < width; x++) {
1267 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
1268 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
1269 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
1281 for (y = 0; y < height; y++) {
1282 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
1283 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
1284 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
1291 // Combine tables to create gradient
1295 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1296 for (xt = xtable, x = 0; x < width; x++) {
1297 *(pr++) = (unsigned char) (tr - (rsign * max(*(xt++), *(yt))));
1298 *(pg++) = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1))));
1299 *(pb++) = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2))));
1303 // faked interlacing effect
1304 unsigned char channel, channel2;
1306 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1307 for (xt = xtable, x = 0; x < width; x++) {
1309 channel = (unsigned char) (tr - (rsign * max(*(xt++), *(yt))));
1310 channel2 = (channel >> 1) + (channel >> 2);
1311 if (channel2 > channel) channel2 = 0;
1314 channel = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1))));
1315 channel2 = (channel >> 1) + (channel >> 2);
1316 if (channel2 > channel) channel2 = 0;
1319 channel = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2))));
1320 channel2 = (channel >> 1) + (channel >> 2);
1321 if (channel2 > channel) channel2 = 0;
1324 channel = (unsigned char) (tr - (rsign * max(*(xt++), *(yt))));
1325 channel2 = channel + (channel >> 3);
1326 if (channel2 < channel) channel2 = ~0;
1329 channel = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1))));
1330 channel2 = channel + (channel >> 3);
1331 if (channel2 < channel) channel2 = ~0;
1334 channel = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2))));
1335 channel2 = channel + (channel >> 3);
1336 if (channel2 < channel) channel2 = ~0;
1345 void BImage::egradient(void) {
1346 // elliptic gradient - based on original dgradient, written by
1347 // Mosfet (mosfet@kde.org)
1348 // adapted from kde sources for Blackbox by Brad Hughes
1350 float drx, dgx, dbx, dry, dgy, dby, yr, yg, yb, xr, xg, xb;
1351 int rsign, gsign, bsign;
1352 unsigned char *pr = red, *pg = green, *pb = blue;
1353 unsigned int *xt = xtable, *yt = ytable,
1354 tr = (unsigned long) to.red(),
1355 tg = (unsigned long) to.green(),
1356 tb = (unsigned long) to.blue();
1358 register unsigned int x, y;
1360 dry = drx = (float) (to.red() - from.red());
1361 dgy = dgx = (float) (to.green() - from.green());
1362 dby = dbx = (float) (to.blue() - from.blue());
1364 rsign = (drx < 0) ? -1 : 1;
1365 gsign = (dgx < 0) ? -1 : 1;
1366 bsign = (dbx < 0) ? -1 : 1;
1368 xr = yr = (drx / 2);
1369 xg = yg = (dgx / 2);
1370 xb = yb = (dbx / 2);
1377 for (x = 0; x < width; x++) {
1378 *(xt++) = (unsigned long) (xr * xr);
1379 *(xt++) = (unsigned long) (xg * xg);
1380 *(xt++) = (unsigned long) (xb * xb);
1392 for (y = 0; y < height; y++) {
1393 *(yt++) = (unsigned long) (yr * yr);
1394 *(yt++) = (unsigned long) (yg * yg);
1395 *(yt++) = (unsigned long) (yb * yb);
1402 // Combine tables to create gradient
1406 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1407 for (xt = xtable, x = 0; x < width; x++) {
1408 *(pr++) = (unsigned char)
1409 (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
1410 *(pg++) = (unsigned char)
1411 (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
1412 *(pb++) = (unsigned char)
1413 (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
1417 // faked interlacing effect
1418 unsigned char channel, channel2;
1420 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1421 for (xt = xtable, x = 0; x < width; x++) {
1423 channel = (unsigned char)
1424 (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
1425 channel2 = (channel >> 1) + (channel >> 2);
1426 if (channel2 > channel) channel2 = 0;
1429 channel = (unsigned char)
1430 (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
1431 channel2 = (channel >> 1) + (channel >> 2);
1432 if (channel2 > channel) channel2 = 0;
1435 channel = (unsigned char)
1436 (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
1437 channel2 = (channel >> 1) + (channel >> 2);
1438 if (channel2 > channel) channel2 = 0;
1441 channel = (unsigned char)
1442 (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
1443 channel2 = channel + (channel >> 3);
1444 if (channel2 < channel) channel2 = ~0;
1447 channel = (unsigned char)
1448 (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
1449 channel2 = channel + (channel >> 3);
1450 if (channel2 < channel) channel2 = ~0;
1453 channel = (unsigned char)
1454 (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
1455 channel2 = channel + (channel >> 3);
1456 if (channel2 < channel) channel2 = ~0;
1465 void BImage::pcgradient(void) {
1466 // pipe cross gradient - based on original dgradient, written by
1467 // Mosfet (mosfet@kde.org)
1468 // adapted from kde sources for Blackbox by Brad Hughes
1470 float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
1471 int rsign, gsign, bsign;
1472 unsigned char *pr = red, *pg = green, *pb = blue;
1473 unsigned int *xt = xtable, *yt = ytable,
1478 register unsigned int x, y;
1480 dry = drx = (float) (to.red() - from.red());
1481 dgy = dgx = (float) (to.green() - from.green());
1482 dby = dbx = (float) (to.blue() - from.blue());
1484 rsign = (drx < 0) ? -2 : 2;
1485 gsign = (dgx < 0) ? -2 : 2;
1486 bsign = (dbx < 0) ? -2 : 2;
1488 xr = yr = (drx / 2);
1489 xg = yg = (dgx / 2);
1490 xb = yb = (dbx / 2);
1497 for (x = 0; x < width; x++) {
1498 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
1499 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
1500 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
1512 for (y = 0; y < height; y++) {
1513 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
1514 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
1515 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
1522 // Combine tables to create gradient
1525 // normal pcgradient
1526 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1527 for (xt = xtable, x = 0; x < width; x++) {
1528 *(pr++) = (unsigned char) (tr - (rsign * min(*(xt++), *(yt))));
1529 *(pg++) = (unsigned char) (tg - (gsign * min(*(xt++), *(yt + 1))));
1530 *(pb++) = (unsigned char) (tb - (bsign * min(*(xt++), *(yt + 2))));
1534 // faked interlacing effect
1535 unsigned char channel, channel2;
1537 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1538 for (xt = xtable, x = 0; x < width; x++) {
1540 channel = (unsigned char) (tr - (rsign * min(*(xt++), *(yt))));
1541 channel2 = (channel >> 1) + (channel >> 2);
1542 if (channel2 > channel) channel2 = 0;
1545 channel = (unsigned char) (tg - (bsign * min(*(xt++), *(yt + 1))));
1546 channel2 = (channel >> 1) + (channel >> 2);
1547 if (channel2 > channel) channel2 = 0;
1550 channel = (unsigned char) (tb - (gsign * min(*(xt++), *(yt + 2))));
1551 channel2 = (channel >> 1) + (channel >> 2);
1552 if (channel2 > channel) channel2 = 0;
1555 channel = (unsigned char) (tr - (rsign * min(*(xt++), *(yt))));
1556 channel2 = channel + (channel >> 3);
1557 if (channel2 < channel) channel2 = ~0;
1560 channel = (unsigned char) (tg - (gsign * min(*(xt++), *(yt + 1))));
1561 channel2 = channel + (channel >> 3);
1562 if (channel2 < channel) channel2 = ~0;
1565 channel = (unsigned char) (tb - (bsign * min(*(xt++), *(yt + 2))));
1566 channel2 = channel + (channel >> 3);
1567 if (channel2 < channel) channel2 = ~0;
1576 void BImage::cdgradient(void) {
1577 // cross diagonal gradient - based on original dgradient, written by
1578 // Mosfet (mosfet@kde.org)
1579 // adapted from kde sources for Blackbox by Brad Hughes
1581 float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
1582 xr = (float) from.red(),
1583 xg = (float) from.green(),
1584 xb = (float) from.blue();
1585 unsigned char *pr = red, *pg = green, *pb = blue;
1586 unsigned int w = width * 2, h = height * 2, *xt, *yt;
1588 register unsigned int x, y;
1590 dry = drx = (float) (to.red() - from.red());
1591 dgy = dgx = (float) (to.green() - from.green());
1592 dby = dbx = (float) (to.blue() - from.blue());
1599 for (xt = (xtable + (width * 3) - 1), x = 0; x < width; x++) {
1600 *(xt--) = (unsigned char) xb;
1601 *(xt--) = (unsigned char) xg;
1602 *(xt--) = (unsigned char) xr;
1614 for (yt = ytable, y = 0; y < height; y++) {
1615 *(yt++) = (unsigned char) yr;
1616 *(yt++) = (unsigned char) yg;
1617 *(yt++) = (unsigned char) yb;
1624 // Combine tables to create gradient
1627 // normal cdgradient
1628 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1629 for (xt = xtable, x = 0; x < width; x++) {
1630 *(pr++) = *(xt++) + *(yt);
1631 *(pg++) = *(xt++) + *(yt + 1);
1632 *(pb++) = *(xt++) + *(yt + 2);
1636 // faked interlacing effect
1637 unsigned char channel, channel2;
1639 for (yt = ytable, y = 0; y < height; y++, yt += 3) {
1640 for (xt = xtable, x = 0; x < width; x++) {
1642 channel = *(xt++) + *(yt);
1643 channel2 = (channel >> 1) + (channel >> 2);
1644 if (channel2 > channel) channel2 = 0;
1647 channel = *(xt++) + *(yt + 1);
1648 channel2 = (channel >> 1) + (channel >> 2);
1649 if (channel2 > channel) channel2 = 0;
1652 channel = *(xt++) + *(yt + 2);
1653 channel2 = (channel >> 1) + (channel >> 2);
1654 if (channel2 > channel) channel2 = 0;
1657 channel = *(xt++) + *(yt);
1658 channel2 = channel + (channel >> 3);
1659 if (channel2 < channel) channel2 = ~0;
1662 channel = *(xt++) + *(yt + 1);
1663 channel2 = channel + (channel >> 3);
1664 if (channel2 < channel) channel2 = ~0;
1667 channel = *(xt++) + *(yt + 2);
1668 channel2 = channel + (channel >> 3);
1669 if (channel2 < channel) channel2 = ~0;