diff options
Diffstat (limited to 'src/FbTk/TextureRender.cc')
-rw-r--r-- | src/FbTk/TextureRender.cc | 276 |
1 files changed, 4 insertions, 272 deletions
diff --git a/src/FbTk/TextureRender.cc b/src/FbTk/TextureRender.cc index a4bb50c..73c1a94 100644 --- a/src/FbTk/TextureRender.cc +++ b/src/FbTk/TextureRender.cc | |||
@@ -340,280 +340,13 @@ XImage *TextureRender::renderXImage() { | |||
340 | image->data = 0; | 340 | image->data = 0; |
341 | 341 | ||
342 | unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; | 342 | unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; |
343 | register unsigned int x, y, dithx, dithy, r, g, b, o, er, eg, eb, offset; | 343 | register unsigned int x, y, r, g, b, o, offset; |
344 | 344 | ||
345 | unsigned char *pixel_data = d, *ppixel_data = d; | 345 | unsigned char *pixel_data = d, *ppixel_data = d; |
346 | unsigned long pixel; | 346 | unsigned long pixel; |
347 | 347 | ||
348 | o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); | 348 | o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); |
349 | 349 | ||
350 | if (control.doDither()) { | ||
351 | unsigned char dither4[4][4] = { | ||
352 | {0, 4, 1, 5}, | ||
353 | {6, 2, 7, 3}, | ||
354 | {1, 5, 0, 4}, | ||
355 | {7, 3, 6, 2} }; | ||
356 | |||
357 | #ifdef ORDEREDPSEUDO | ||
358 | unsigned char dither8[8][8] = { | ||
359 | { 0, 32, 8, 40, 2, 34, 10, 42 }, | ||
360 | { 48, 16, 56, 24, 50, 18, 58, 26 }, | ||
361 | { 12, 44, 4, 36, 14, 46, 6, 38 }, | ||
362 | { 60, 28, 52, 20, 62, 30, 54, 22 }, | ||
363 | { 3, 35, 11, 43, 1, 33, 9, 41 }, | ||
364 | { 51, 19, 59, 27, 49, 17, 57, 25 }, | ||
365 | { 15, 47, 7, 39, 13, 45, 5, 37 }, | ||
366 | { 63, 31, 55, 23, 61, 29, 53, 21 } }; | ||
367 | #endif // ORDEREDPSEUDO | ||
368 | |||
369 | switch (control.visual()->c_class) { | ||
370 | case TrueColor: | ||
371 | // algorithm: ordered dithering... many many thanks to rasterman | ||
372 | // (raster@rasterman.com) for telling me about this... portions of this | ||
373 | // code is based off of his code in Imlib | ||
374 | for (y = 0, offset = 0; y < height; y++) { | ||
375 | dithy = y & 0x3; | ||
376 | |||
377 | for (x = 0; x < width; x++, offset++) { | ||
378 | dithx = x & 0x3; | ||
379 | r = red[offset]; | ||
380 | g = green[offset]; | ||
381 | b = blue[offset]; | ||
382 | |||
383 | er = r & (red_bits - 1); | ||
384 | eg = g & (green_bits - 1); | ||
385 | eb = b & (blue_bits - 1); | ||
386 | |||
387 | r = red_table[r]; | ||
388 | g = green_table[g]; | ||
389 | b = blue_table[b]; | ||
390 | |||
391 | if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++; | ||
392 | if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++; | ||
393 | if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++; | ||
394 | |||
395 | pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset); | ||
396 | |||
397 | switch (o) { | ||
398 | case 8: // 8bpp | ||
399 | *pixel_data++ = pixel; | ||
400 | break; | ||
401 | |||
402 | case 16: // 16bpp LSB | ||
403 | *pixel_data++ = pixel; | ||
404 | *pixel_data++ = pixel >> 8; | ||
405 | break; | ||
406 | |||
407 | case 17: // 16bpp MSB | ||
408 | *pixel_data++ = pixel >> 8; | ||
409 | *pixel_data++ = pixel; | ||
410 | break; | ||
411 | |||
412 | case 24: // 24bpp LSB | ||
413 | *pixel_data++ = pixel; | ||
414 | *pixel_data++ = pixel >> 8; | ||
415 | *pixel_data++ = pixel >> 16; | ||
416 | break; | ||
417 | |||
418 | case 25: // 24bpp MSB | ||
419 | *pixel_data++ = pixel >> 16; | ||
420 | *pixel_data++ = pixel >> 8; | ||
421 | *pixel_data++ = pixel; | ||
422 | break; | ||
423 | |||
424 | case 32: // 32bpp LSB | ||
425 | *pixel_data++ = pixel; | ||
426 | *pixel_data++ = pixel >> 8; | ||
427 | *pixel_data++ = pixel >> 16; | ||
428 | *pixel_data++ = pixel >> 24; | ||
429 | break; | ||
430 | |||
431 | case 33: // 32bpp MSB | ||
432 | *pixel_data++ = pixel >> 24; | ||
433 | *pixel_data++ = pixel >> 16; | ||
434 | *pixel_data++ = pixel >> 8; | ||
435 | *pixel_data++ = pixel; | ||
436 | break; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
441 | } | ||
442 | |||
443 | break; | ||
444 | |||
445 | case StaticColor: | ||
446 | case PseudoColor: { | ||
447 | #ifndef ORDEREDPSEUDO | ||
448 | short *terr, | ||
449 | *rerr = new short[width + 2], | ||
450 | *gerr = new short[width + 2], | ||
451 | *berr = new short[width + 2], | ||
452 | *nrerr = new short[width + 2], | ||
453 | *ngerr = new short[width + 2], | ||
454 | *nberr = new short[width + 2]; | ||
455 | int rr, gg, bb, rer, ger, ber; | ||
456 | int dd = 255 / control.colorsPerChannel(); | ||
457 | |||
458 | for (x = 0; x < width; x++) { | ||
459 | *(rerr + x) = *(red + x); | ||
460 | *(gerr + x) = *(green + x); | ||
461 | *(berr + x) = *(blue + x); | ||
462 | } | ||
463 | |||
464 | *(rerr + x) = *(gerr + x) = *(berr + x) = 0; | ||
465 | #endif // ORDEREDPSEUDO | ||
466 | |||
467 | for (y = 0, offset = 0; y < height; y++) { | ||
468 | #ifdef ORDEREDPSEUDO | ||
469 | dithy = y & 7; | ||
470 | |||
471 | for (x = 0; x < width; x++, offset++) { | ||
472 | dithx = x & 7; | ||
473 | |||
474 | r = red[offset]; | ||
475 | g = green[offset]; | ||
476 | b = blue[offset]; | ||
477 | |||
478 | er = r & (red_bits - 1); | ||
479 | eg = g & (green_bits - 1); | ||
480 | eb = b & (blue_bits - 1); | ||
481 | |||
482 | r = red_table[r]; | ||
483 | g = green_table[g]; | ||
484 | b = blue_table[b]; | ||
485 | |||
486 | if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++; | ||
487 | if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++; | ||
488 | if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++; | ||
489 | |||
490 | pixel = (r * cpccpc) + (g * cpc) + b; | ||
491 | *(pixel_data++) = colors[pixel].pixel; | ||
492 | } | ||
493 | |||
494 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
495 | } | ||
496 | #else // !ORDEREDPSEUDO | ||
497 | if (y < (height - 1)) { | ||
498 | int i = offset + width; | ||
499 | for (x = 0; x < width; x++, i++) { | ||
500 | *(nrerr + x) = *(red + i); | ||
501 | *(ngerr + x) = *(green + i); | ||
502 | *(nberr + x) = *(blue + i); | ||
503 | } | ||
504 | |||
505 | *(nrerr + x) = *(red + (--i)); | ||
506 | *(ngerr + x) = *(green + i); | ||
507 | *(nberr + x) = *(blue + i); | ||
508 | } | ||
509 | |||
510 | for (x = 0; x < width; x++) { | ||
511 | rr = rerr[x]; | ||
512 | gg = gerr[x]; | ||
513 | bb = berr[x]; | ||
514 | |||
515 | if (rr > 255) rr = 255; else if (rr < 0) rr = 0; | ||
516 | if (gg > 255) gg = 255; else if (gg < 0) gg = 0; | ||
517 | if (bb > 255) bb = 255; else if (bb < 0) bb = 0; | ||
518 | |||
519 | r = red_table[rr]; | ||
520 | g = green_table[gg]; | ||
521 | b = blue_table[bb]; | ||
522 | |||
523 | rer = rerr[x] - r*dd; | ||
524 | ger = gerr[x] - g*dd; | ||
525 | ber = berr[x] - b*dd; | ||
526 | |||
527 | pixel = (r * cpccpc) + (g * cpc) + b; | ||
528 | *pixel_data++ = colors[pixel].pixel; | ||
529 | |||
530 | r = rer >> 1; | ||
531 | g = ger >> 1; | ||
532 | b = ber >> 1; | ||
533 | rerr[x+1] += r; | ||
534 | gerr[x+1] += g; | ||
535 | berr[x+1] += b; | ||
536 | nrerr[x] += r; | ||
537 | ngerr[x] += g; | ||
538 | nberr[x] += b; | ||
539 | } | ||
540 | |||
541 | offset += width; | ||
542 | |||
543 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
544 | |||
545 | terr = rerr; | ||
546 | rerr = nrerr; | ||
547 | nrerr = terr; | ||
548 | |||
549 | terr = gerr; | ||
550 | gerr = ngerr; | ||
551 | ngerr = terr; | ||
552 | |||
553 | terr = berr; | ||
554 | berr = nberr; | ||
555 | nberr = terr; | ||
556 | } | ||
557 | |||
558 | delete [] rerr; | ||
559 | delete [] gerr; | ||
560 | delete [] berr; | ||
561 | delete [] nrerr; | ||
562 | delete [] ngerr; | ||
563 | delete [] nberr; | ||
564 | #endif // ORDEREDPSUEDO | ||
565 | |||
566 | } break; | ||
567 | |||
568 | /* | ||
569 | case StaticGray: | ||
570 | case GrayScale: | ||
571 | for (y = 0, offset = 0; y < height; y++) { | ||
572 | dithy = y & 0x3; | ||
573 | |||
574 | for (x = 0; x < width; x++, offset++) { | ||
575 | dithx = x & 0x3; | ||
576 | |||
577 | r = *(red + offset); | ||
578 | g = *(green + offset); | ||
579 | b = *(blue + offset); | ||
580 | |||
581 | er = r & 0x7; | ||
582 | eg = g & 0x7; | ||
583 | eb = b & 0x7; | ||
584 | |||
585 | if ((dither[dithy][dithx] < er) && (r < (256 - 8))) | ||
586 | r += 8; | ||
587 | if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4))) | ||
588 | g += 4; | ||
589 | if ((dither[dithy][dithx] < eb) && (b < (256 - 8))) | ||
590 | b += 8; | ||
591 | |||
592 | r = *(red_table + r); | ||
593 | g = *(green_table + g); | ||
594 | b = *(blue_table + b); | ||
595 | |||
596 | g = ((r * 30) + (g * 59) + (b * 11)) / 100; | ||
597 | *pixel_data++ = colors[g].pixel; | ||
598 | } | ||
599 | |||
600 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
601 | } | ||
602 | |||
603 | break; | ||
604 | */ | ||
605 | |||
606 | default: | ||
607 | _FB_USES_NLS; | ||
608 | cerr << "TextureRender::renderXImage(): " << | ||
609 | _FBTK_CONSOLETEXT(Error, UnsupportedVisual, "Unsupported visual", "A visual is a technical term in X") << endl; | ||
610 | delete [] d; | ||
611 | XDestroyImage(image); | ||
612 | return (XImage *) 0; | ||
613 | } | ||
614 | } else { // end do dither | ||
615 | |||
616 | // no dither: | ||
617 | switch (control.visual()->c_class) { | 350 | switch (control.visual()->c_class) { |
618 | case StaticColor: | 351 | case StaticColor: |
619 | case PseudoColor: | 352 | case PseudoColor: |
@@ -714,10 +447,9 @@ XImage *TextureRender::renderXImage() { | |||
714 | XDestroyImage(image); | 447 | XDestroyImage(image); |
715 | return (XImage *) 0; | 448 | return (XImage *) 0; |
716 | } | 449 | } |
717 | } | ||
718 | 450 | ||
719 | image->data = (char *) d; | 451 | image->data = (char *) d; |
720 | return image; | 452 | return image; |
721 | } | 453 | } |
722 | 454 | ||
723 | 455 | ||
@@ -1840,4 +1572,4 @@ void TextureRender::cdgradient() { | |||
1840 | 1572 | ||
1841 | } | 1573 | } |
1842 | 1574 | ||
1843 | }; // end namespace FbTk | 1575 | } // end namespace FbTk |