00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <gdk/gdktypes.h>
00030 #include "test_output_device.h"
00031
00032 namespace test
00033 {
00034
00035 OutputDevice::OutputDevice()
00036 : ctx()
00037 , shared_image(0)
00038 , color_dep(MONO_COLOR_DEPTH)
00039 , xor_gc(0)
00040 {
00041 }
00042
00043 OutputDevice::~OutputDevice(void)
00044 {
00045 if (shared_image)
00046 {
00047 g_object_unref(shared_image);
00048 }
00049
00050 if (xor_gc)
00051 {
00052 g_object_unref(xor_gc);
00053 }
00054 }
00055
00056 void OutputDevice::map(OutputDeviceContext &context)
00057 {
00058 ctx.widget = context.widget;
00059 ctx.gc = context.gc;
00060
00061 if (xor_gc)
00062 {
00063 g_object_unref(xor_gc);
00064 }
00065
00066 xor_gc = gdk_gc_new(ctx.widget->window);
00067
00068 gdk_gc_set_function(xor_gc, GDK_XOR);
00069
00070 GdkColor color = {0xffffffff, 0xffff, 0xffff, 0xffff};
00071
00072 gdk_gc_set_foreground(xor_gc, &color);
00073 }
00074
00075 void OutputDevice::update_shared_image(GtkWidget * widget)
00076 {
00077 gint width = 0, height = 0;
00078
00079 ctx.widget = widget;
00080
00081
00082 gdk_drawable_get_size(widget->window, &width, &height);
00083
00084 update_shared_image(width, height);
00085 }
00086
00087 void OutputDevice::update_shared_image(int width, int height)
00088 {
00089 if (shared_image)
00090 {
00091 if (width == shared_image->width && height == shared_image->height)
00092 {
00093 return;
00094 }
00095 g_object_unref(shared_image);
00096 shared_image = 0;
00097 }
00098
00099 GdkVisual * visual = gdk_drawable_get_visual(ctx.widget->window);
00100
00101
00102 shared_image = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height);
00103
00104 }
00105
00106 void OutputDevice::clear_background(const int color, bool flush)
00107 {
00108 update_shared_image(ctx.widget);
00109
00110
00111 unsigned char *p = (unsigned char *)shared_image->mem;
00112 memset(p, color, shared_image->height * shared_image->bpl);
00113
00114
00115 if (flush)
00116 {
00117 gdk_draw_image(ctx.widget->window, ctx.gc, shared_image, 0, 0,
00118 ctx.widget->allocation.x, ctx.widget->allocation.y,
00119 ctx.widget->allocation.width, ctx.widget->allocation.height);
00120 }
00121 }
00122
00123 void OutputDevice::invalidate_rectangle(const GdkRectangle& r)
00124 {
00125 GdkRectangle rect = r;
00126 gdk_window_invalidate_rect(ctx.widget->window, &rect, TRUE);
00127 }
00128
00129 void OutputDevice::draw_line(int x1, int y1, int x2, int y2)
00130 {
00131 gdk_draw_line(ctx.widget->window, ctx.gc, x1, y1, x2, y2);
00132 }
00133
00134 void OutputDevice::draw_highlight_rectangle(const GdkRectangle &rect)
00135 {
00136 gdk_draw_rectangle(ctx.widget->window, xor_gc, TRUE, rect.x, rect.y
00137 , rect.width, rect.height);
00138 }
00139
00140
00141
00142 void OutputDevice::draw_image(const unsigned char *src,
00143 int width,
00144 int height,
00145 int row_stride,
00146 int xDest,
00147 int yDest)
00148 {
00149
00150 if (src == 0 || width <= 0 || height <= 0)
00151 {
00152 return;
00153 }
00154
00155
00156
00157 update_shared_image(width, height);
00158
00159 unsigned char *dst = (unsigned char *)shared_image->mem +
00160 (shared_image->bpl * yDest + xDest);
00161
00162 bool transform_result = false;
00163
00164 switch(shared_image->bits_per_pixel)
00165 {
00166 case RGB_COLOR_DEPTH:
00167 {
00168 switch(color_dep)
00169 {
00170 case RGB_COLOR_DEPTH:
00171
00172 transform_result = transform_bitmap_with_same_depth(src, dst,
00173 width, height, row_stride);
00174
00175 break;
00176 case ARGB_COLOR_DEPTH:
00177
00178
00179 transform_result = transform_bitmap_ARGB_to_RGB(src, dst,
00180 width, height, row_stride);
00181
00182 break;
00183 case MONO_COLOR_DEPTH:
00184
00185 transform_result = transform_bitmap_MONO_to_RGB(src, dst,
00186 width, height, row_stride);
00187
00188 break;
00189 default:
00190
00191
00192
00193 break;
00194 }
00195 break;
00196 }
00197 case ARGB_COLOR_DEPTH:
00198 {
00199 switch(color_dep)
00200 {
00201 case RGB_COLOR_DEPTH:
00202
00203 transform_result = transform_bitmap_RGB_to_ARGB(src, dst,
00204 width, height, row_stride);
00205
00206 break;
00207 case ARGB_COLOR_DEPTH:
00208
00209 transform_result = transform_bitmap_with_same_depth(src, dst,
00210 width, height, row_stride);
00211
00212 break;
00213 case MONO_COLOR_DEPTH:
00214
00215 transform_result = transform_bitmap_MONO_to_ARGB(src, dst,
00216 width, height, row_stride);
00217
00218 break;
00219 default:
00220
00221
00222
00223 break;
00224 }
00225 break;
00226 }
00227 case MONO_COLOR_DEPTH:
00228 {
00229 switch(color_dep)
00230 {
00231 case RGB_COLOR_DEPTH:
00232
00233 transform_result = transform_bitmap_RGB_to_MONO(src, dst,
00234 width, height, row_stride);
00235
00236 break;
00237 case ARGB_COLOR_DEPTH:
00238
00239 transform_result = transform_bitmap_ARGB_to_MONO(src, dst,
00240 width, height, row_stride);
00241
00242 break;
00243 case MONO_COLOR_DEPTH:
00244
00245 transform_result = transform_bitmap_with_same_depth(src, dst,
00246 width, height, row_stride);
00247
00248 break;
00249 default:
00250
00251 break;
00252 }
00253 break;
00254 }
00255 }
00256
00257
00258
00259 if (transform_result)
00260 {
00261 gdk_draw_image(ctx.widget->window, ctx.gc, shared_image, 0, 0,
00262 xDest, yDest, width, height);
00263 }
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 void OutputDevice::draw_image_with_transform(const unsigned char *src,
00273 int width,
00274 int height,
00275 int row_stride,
00276 int xDest,
00277 int yDest,
00278 int transform)
00279 {
00280
00281 if (src == 0 || width <= 0 || height <= 0)
00282 {
00283 return;
00284 }
00285
00286 unsigned char * dst = 0;
00287
00288 if (transform == PLUGIN_ORIENTATION_LANDSCAPE)
00289 {
00290 update_shared_image(height, width);
00291 }
00292 else
00293 {
00294 update_shared_image(width, height);
00295 }
00296
00297 dst = (unsigned char *)shared_image->mem +
00298 (shared_image->bpl * yDest + xDest);
00299
00300 bool transform_result = false;
00301
00302 switch(shared_image->bits_per_pixel)
00303 {
00304 case RGB_COLOR_DEPTH:
00305 {
00306 switch(color_dep)
00307 {
00308 case RGB_COLOR_DEPTH:
00309
00310 transform_result = transform_bitmap_with_same_depth(src, dst,
00311 width, height, row_stride, transform);
00312
00313 break;
00314 case ARGB_COLOR_DEPTH:
00315
00316
00317
00318 break;
00319 case MONO_COLOR_DEPTH:
00320
00321 transform_result = transform_bitmap_MONO_to_RGB(src, dst,
00322 width, height, row_stride, transform);
00323
00324 break;
00325 default:
00326
00327
00328
00329 break;
00330 }
00331 break;
00332 }
00333 case ARGB_COLOR_DEPTH:
00334 {
00335 switch(color_dep)
00336 {
00337 case RGB_COLOR_DEPTH:
00338
00339 transform_result = transform_bitmap_RGB_to_ARGB(src, dst,
00340 width, height, row_stride, transform);
00341
00342 break;
00343 case ARGB_COLOR_DEPTH:
00344
00345 transform_result = transform_bitmap_with_same_depth(src, dst,
00346 width, height, row_stride, transform);
00347
00348 break;
00349 case MONO_COLOR_DEPTH:
00350
00351 transform_result = transform_bitmap_MONO_to_ARGB(src, dst,
00352 width, height, row_stride, transform);
00353
00354 break;
00355 default:
00356
00357
00358
00359 break;
00360 }
00361 break;
00362 }
00363 case MONO_COLOR_DEPTH:
00364 {
00365 switch(color_dep)
00366 {
00367 case RGB_COLOR_DEPTH:
00368
00369 transform_result = transform_bitmap_RGB_to_MONO(src, dst,
00370 width, height, row_stride, transform);
00371
00372 break;
00373 case ARGB_COLOR_DEPTH:
00374
00375 transform_result = transform_bitmap_ARGB_to_MONO(src, dst,
00376 width, height, row_stride, transform);
00377
00378 break;
00379 case MONO_COLOR_DEPTH:
00380
00381 transform_result = transform_bitmap_with_same_depth(src, dst,
00382 width, height, row_stride, transform);
00383
00384 break;
00385 default:
00386
00387 break;
00388 }
00389 break;
00390 }
00391 }
00392
00393 if (transform_result)
00394 {
00395 gdk_draw_image(ctx.widget->window, ctx.gc, shared_image, 0, 0,
00396 xDest, yDest, height, width);
00397 }
00398 }
00399
00400
00401 bool OutputDevice::transform_bitmap_with_same_depth(const unsigned char *src,
00402 unsigned char *dst,
00403 int width,
00404 int height,
00405 int row_stride,
00406 int transform)
00407 {
00408 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00409 {
00410 for(int h = 0; h < height; ++h)
00411 {
00412 memcpy(dst, src, row_stride);
00413 dst += row_stride;
00414 src += row_stride;
00415 }
00416 }
00417 else
00418 {
00419 for(int h = 0; h < height; ++h)
00420 {
00421 const unsigned char * s = src;
00422 unsigned char * d = dst;
00423 for(int w = 0; w < width; ++w)
00424 {
00425 *d = *s++;
00426 d += height;
00427 }
00428 src += row_stride;
00429 dst += height;
00430 }
00431 }
00432 return true;
00433 }
00434
00435
00436 bool OutputDevice::transform_bitmap_RGB_to_ARGB(const unsigned char *src,
00437 unsigned char *dst,
00438 int width,
00439 int height,
00440 int row_stride,
00441 int transform)
00442 {
00443 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00444 {
00445 for(int h = 0; h < height; ++h)
00446 {
00447 unsigned char * d = dst;
00448 const unsigned char* s = src;
00449 for(int w = 0; w < width; ++w)
00450 {
00451
00452 s += 2;
00453 *d++ = *s--; *d++ = *s--; *d++ = *s;
00454 *d++ = DEFAULT_ALPHA_VALUE;
00455 s += 3;
00456
00457 }
00458 src += row_stride;
00459 dst += (width * 4);
00460 }
00461 }
00462 else
00463 {
00464 int dst_heihgt = (height-1) * 4;
00465 for(int h = 0; h < height; ++h)
00466 {
00467 const unsigned char * s = src;
00468 unsigned char * d = dst;
00469 for(int w = 0; w < width; ++w)
00470 {
00471
00472 *d++ = DEFAULT_ALPHA_VALUE;
00473
00474
00475 for(int i = 0; i < 3; ++i)
00476 {
00477 *d++ = *s++;
00478 }
00479 d += dst_heihgt;
00480 }
00481 src += row_stride;
00482 dst += 4;
00483 }
00484 }
00485
00486 return true;
00487 }
00488
00489
00490 bool OutputDevice::transform_bitmap_MONO_to_RGB(const unsigned char *src,
00491 unsigned char *dst,
00492 int width,
00493 int height,
00494 int row_stride,
00495 int transform)
00496 {
00497 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00498 {
00499 for(int h = 0; h < height; ++h)
00500 {
00501 const unsigned char* s = src;
00502 for(int w = 0; w < width; ++w)
00503 {
00504
00505 for(int i = 0; i < 3; i++)
00506 {
00507 *dst++ = *s;
00508 }
00509 s++;
00510 }
00511 src += row_stride;
00512 }
00513 }
00514 else
00515 {
00516 int dst_height = (height-1) * 3;
00517 for(int h = 0; h < height; ++h)
00518 {
00519 const unsigned char * s = src;
00520 unsigned char * d = dst;
00521 for(int w = 0; w < width; ++w)
00522 {
00523
00524 for(int i = 0; i < 3; ++i)
00525 {
00526 *d++ = *s;
00527 }
00528
00529 s++;
00530 d += dst_height;
00531 }
00532 src += row_stride;
00533 dst += 3;
00534 }
00535 }
00536 return true;
00537 }
00538
00539
00540 bool OutputDevice::transform_bitmap_MONO_to_ARGB(const unsigned char *src,
00541 unsigned char *dst,
00542 int width,
00543 int height,
00544 int row_stride,
00545 int transform)
00546 {
00547 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00548 {
00549 for(int h = 0; h < height; ++h)
00550 {
00551 const unsigned char* s = src;
00552 for(int w = 0; w < width; ++w)
00553 {
00554
00555 *dst++ = DEFAULT_ALPHA_VALUE;
00556
00557
00558 for(int i = 0; i < 3; i++)
00559 {
00560 *dst++ = *s;
00561 }
00562 s++;
00563 }
00564 src += row_stride;
00565 }
00566 }
00567 else
00568 {
00569 int dst_heihgt = (height-1) * 4;
00570 for(int h = 0; h < height; ++h)
00571 {
00572 const unsigned char * s = src;
00573 unsigned char * d = dst;
00574 for(int w = 0; w < width; ++w)
00575 {
00576
00577 *d++ = DEFAULT_ALPHA_VALUE;
00578
00579
00580 for(int i = 0; i < 3; ++i)
00581 {
00582 *d++ = *s;
00583 }
00584
00585 s++;
00586 d += dst_heihgt;
00587 }
00588 src += row_stride;
00589 dst += 4;
00590 }
00591 }
00592
00593 return true;
00594 }
00595
00596
00597 bool OutputDevice::transform_bitmap_RGB_to_MONO(const unsigned char *src,
00598 unsigned char *dst,
00599 int width,
00600 int height,
00601 int row_stride,
00602 int transform)
00603
00604 {
00605 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00606 {
00607 for(int h = 0; h < height; ++h)
00608 {
00609 const unsigned char *s = src;
00610 for(int w = 0; w < width; ++w)
00611 {
00612
00613 unsigned char red = *s++;
00614 unsigned char green = *s++;
00615 unsigned char blue = *s++;
00616 *dst++ = (red + green + blue) / 3;
00617 }
00618 src += row_stride;
00619 }
00620 }
00621 else
00622 {
00623 for(int h = 0; h < height; ++h)
00624 {
00625 const unsigned char * s = src;
00626 unsigned char * d = dst;
00627 for(int w = 0; w < width; ++w)
00628 {
00629
00630 unsigned char red = *s++;
00631 unsigned char green = *s++;
00632 unsigned char blue = *s++;
00633 *d = (red + green + blue) / 3;
00634
00635 d += height;
00636 }
00637 src += row_stride;
00638 dst ++;
00639 }
00640 }
00641
00642 return true;
00643 }
00644
00645
00646 bool OutputDevice::transform_bitmap_ARGB_to_MONO(const unsigned char *src,
00647 unsigned char *dst,
00648 int width,
00649 int height,
00650 int row_stride,
00651 int transform)
00652 {
00653 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00654 {
00655 for(int h = 0; h < height; ++h)
00656 {
00657 const unsigned char *s = src;
00658 for(int w = 0; w < width; ++w)
00659 {
00660
00661
00662
00663
00664 unsigned char red = *s++;
00665 unsigned char green = *s++;
00666 unsigned char blue = *s++;
00667 *dst++ = (red + green + blue) / 3;
00668 }
00669 src += row_stride;
00670 }
00671 }
00672 else
00673 {
00674 for(int h = 0; h < height; ++h)
00675 {
00676 const unsigned char * s = src;
00677 unsigned char * d = dst;
00678 for(int w = 0; w < width; ++w)
00679 {
00680
00681
00682
00683
00684 unsigned char red = *s++;
00685 unsigned char green = *s++;
00686 unsigned char blue = *s++;
00687 *d = (red + green + blue) / 3;
00688
00689 d += height;
00690 }
00691 src += row_stride;
00692 dst ++;
00693 }
00694 }
00695
00696 return true;
00697 }
00698
00699
00700 bool OutputDevice::transform_bitmap_ARGB_to_RGB(const unsigned char *src,
00701 unsigned char *dst,
00702 int width,
00703 int height,
00704 int row_stride,
00705 int transform)
00706 {
00707 if (transform == PLUGIN_ORIENTATION_PORTRAIT)
00708 {
00709 for(int h = 0; h < height; ++h)
00710 {
00711 const unsigned char *s = src;
00712 for(int w = 0; w < width; ++w)
00713 {
00714
00715
00716
00717
00718 for(int i=0; i < 3; ++i)
00719 {
00720 *dst++ = *s++;
00721 }
00722 }
00723 src += row_stride;
00724 }
00725 }
00726 else
00727 {
00728 int dst_height = (height - 1) * 3;
00729 for(int h = 0; h < height; ++h)
00730 {
00731 const unsigned char * s = src;
00732 unsigned char * d = dst;
00733 for(int w = 0; w < width; ++w)
00734 {
00735
00736
00737
00738
00739 for(int i=0; i < 3; ++i)
00740 {
00741 *dst++ = *s++;
00742 }
00743
00744 d += dst_height;
00745 }
00746 src += row_stride;
00747 dst += 3;
00748 }
00749 }
00750
00751 return true;
00752 }
00753
00754 }
00755