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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #include <sys/stat.h>
00074
00075 #include "gcw.h"
00076 #include "plplotcanvas-hacktext.h"
00077
00078 #ifdef HAVE_FREETYPE
00079
00080 #include "plfreetype.h"
00081 #include "plfci-truetype.h"
00082
00083
00084 extern FCI_to_FontName_Table FontLookup[N_TrueTypeLookup];
00085
00086 #endif // HAVE_FREETYPE
00087
00088
00089
00090 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_gcw = "gcw:Gnome Canvas Widget:1:gcw:10:gcw\n";
00091
00092
00093
00094 #ifdef HAVE_FREETYPE
00095 static PLINT text = 1;
00096 #else
00097 static PLINT text = 0;
00098 #endif
00099
00100 static PLINT hrshsym = 0;
00101 static PLINT replot = 1;
00102
00103 static DrvOpt gcw_options[] =
00104 {
00105 { "text", DRV_INT, &text, "Use truetype fonts (text=0|1)" },
00106 { "hrshsym", DRV_INT, &hrshsym, "Use Hershey symbol set (hrshsym=0|1)" },
00107 { "replot", DRV_INT, &replot, "Allow replotting to other devices (replot=0|1)" },
00108 { NULL, DRV_INT, NULL, NULL }
00109 };
00110
00111
00112
00113
00114
00115
00116 guint32 plcolor_to_rgba( PLColor color, guchar alpha )
00117 {
00118 return
00119 ( (int) ( color.r ) << 24 )
00120 + ( (int) ( color.g ) << 16 )
00121 + ( (int) ( color.b ) << 8 )
00122 + alpha;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 void plD_open_gcw( PLStream *pls );
00133 void plD_init_gcw( PLStream * );
00134 void plD_line_gcw( PLStream *, short, short, short, short );
00135 void plD_polyline_gcw( PLStream *, short *, short *, PLINT );
00136 void plD_eop_gcw( PLStream * );
00137 void plD_bop_gcw( PLStream * );
00138 void plD_tidy_gcw( PLStream * );
00139 void plD_state_gcw( PLStream *, PLINT );
00140 void plD_esc_gcw( PLStream *, PLINT, void * );
00141
00142 void plD_dispatch_init_gcw( PLDispatchTable *pdt )
00143 {
00144 #ifdef DEBUG_GCW_1
00145 gcw_debug( "<plD_dispatch_init_gcw>\n" );
00146 #endif
00147
00148 #ifndef ENABLE_DYNDRIVERS
00149 pdt->pl_MenuStr = "Gnome Canvas Widget";
00150 pdt->pl_DevName = "gcw";
00151 #endif
00152 pdt->pl_type = plDevType_Interactive;
00153 pdt->pl_seq = 1;
00154 pdt->pl_init = (plD_init_fp) plD_init_gcw;
00155 pdt->pl_line = (plD_line_fp) plD_line_gcw;
00156 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_gcw;
00157 pdt->pl_eop = (plD_eop_fp) plD_eop_gcw;
00158 pdt->pl_bop = (plD_bop_fp) plD_bop_gcw;
00159 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_gcw;
00160 pdt->pl_state = (plD_state_fp) plD_state_gcw;
00161 pdt->pl_esc = (plD_esc_fp) plD_esc_gcw;
00162
00163 #ifdef DEBUG_GCW_1
00164 gcw_debug( "</plD_dispatch_init_gcw>\n" );
00165 #endif
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 void plD_init_gcw( PLStream *pls )
00179 {
00180 GcwPLdev* dev;
00181
00182 PLINT width, height, tmp;
00183
00184 PLColor bgcolor = pls->cmap0[0];
00185
00186 #ifdef DEBUG_GCW_1
00187 gcw_debug( "<plD_init_gcw>\n" );
00188 #endif
00189
00190
00191 plParseDrvOpts( gcw_options );
00192
00193
00194 pls->termin = 1;
00195 pls->dev_flush = 1;
00196 pls->plbuf_write = replot;
00197 pls->width = 1;
00198 pls->dev_clear = 0;
00199 pls->dev_fill0 = 1;
00200
00201
00202 if ( ( dev = g_malloc( sizeof ( GcwPLdev ) ) ) == NULL )
00203 plexit( "GCW driver <plD_init_gcw>: Cannot create device" );
00204 pls->dev = dev;
00205
00206
00207 #ifdef HAVE_FREETYPE
00208 if ( text )
00209 {
00210 pls->dev_text = TRUE;
00211 pls->dev_unicode = TRUE;
00212 if ( hrshsym )
00213 pls->dev_hrshsym = 1;
00214
00215
00216 plD_FreeType_init( pls );
00217 }
00218 else
00219 {
00220 pls->dev_text = FALSE;
00221 pls->dev_unicode = FALSE;
00222 }
00223 #else
00224 pls->dev_text = FALSE;
00225 pls->dev_unicode = FALSE;
00226 #endif
00227
00228
00229 dev->use_pixmap = (gboolean) ( !pls->nopixmap );
00230 dev->pixmap_has_data = FALSE;
00231
00232
00233 dev->color = plcolor_to_rgba( pls->cmap0[pls->icol0], 0xFF );
00234 dev->bgcolor.red = (guint16) ( bgcolor.r / 255. * 65535 );
00235 dev->bgcolor.green = (guint16) ( bgcolor.b / 255. * 65535 );
00236 dev->bgcolor.blue = (guint16) ( bgcolor.g / 255. * 65535 );
00237
00238
00239 dev->canvas = NULL;
00240 dev->background = NULL;
00241 dev->gc = NULL;
00242 dev->colormap = NULL;
00243 dev->window = NULL;
00244 dev->notebook = NULL;
00245 dev->statusbar = NULL;
00246 dev->filew = NULL;
00247
00248
00249
00250
00251
00252
00253 dev->group_visible = NULL;
00254 dev->group_hidden = NULL;
00255 dev->group_persistent = NULL;
00256
00257
00258 dev->use_persistence = FALSE;
00259
00260
00261 dev->plstate_width = FALSE;
00262 dev->plstate_color0 = FALSE;
00263 dev->plstate_color1 = FALSE;
00264
00265
00266 gtk_init( 0, NULL );
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 if ( pls->xlength > 0 && pls->ylength > 0 )
00282 {
00283
00284
00285
00286 width = pls->xlength;
00287 height = pls->ylength;
00288 }
00289 else
00290 {
00291 width = (PLINT) ( CANVAS_WIDTH * DEVICE_PIXELS_PER_IN );
00292 height = (PLINT) ( CANVAS_HEIGHT * DEVICE_PIXELS_PER_IN );
00293 }
00294
00295
00296 if ( pls->portrait )
00297 {
00298 plsdiori( (PLFLT) ( 4 - ORIENTATION ) );
00299 pls->freeaspect = 1;
00300 }
00301
00302
00303 gcw_set_device_size( width, height );
00304
00305
00306
00307
00308
00309 if ( !pls->hack )
00310 {
00311 dev->allow_resize = FALSE;
00312 gcw_install_canvas( NULL );
00313 }
00314 else
00315 dev->allow_resize = TRUE;
00316
00317
00318
00319 #ifdef DEBUG_GCW_1
00320 gcw_debug( "</plD_init_gcw>\n" );
00321 #endif
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331 void plD_polyline_gcw( PLStream *pls, short *x, short *y, PLINT npts )
00332 {
00333 GcwPLdev * dev = pls->dev;
00334 GnomeCanvasPoints * points;
00335 GnomeCanvasPoints pts;
00336 GnomeCanvasGroup * group;
00337 GnomeCanvasItem * item;
00338 GnomeCanvas * canvas;
00339
00340 GdkPoint * gdkpoints;
00341
00342 PLINT i;
00343
00344 gdouble width;
00345 guint32 color;
00346
00347 #ifdef DEBUG_GCW_2
00348 gcw_debug( "<plD_polyline_gcw />\n" );
00349 #endif
00350
00351 if ( !GNOME_IS_CANVAS( dev->canvas ) )
00352 plexit( "GCW driver <plD_polyline_gcw>: Canvas not found" );
00353 canvas = dev->canvas;
00354
00355 if ( dev->use_persistence )
00356 group = dev->group_persistent;
00357 else
00358 group = dev->group_hidden;
00359
00360 if ( dev->use_pixmap && !dev->use_persistence )
00361
00362 {
00363 if ( ( gdkpoints = (GdkPoint *) malloc( npts * sizeof ( GdkPoint ) ) ) == NULL )
00364 {
00365 plabort( "GCW driver <plD_polyline_gcw>: Could not create gdkpoints" );
00366 return;
00367 }
00368
00369 if ( !pls->portrait )
00370 {
00371 for ( i = 0; i < npts; i++ )
00372 {
00373 gdkpoints[i].x = (gint) ( x[i] / VSCALE );
00374 gdkpoints[i].y = (gint) ( dev->height - y[i] / VSCALE );
00375 }
00376 }
00377 else
00378 {
00379 for ( i = 0; i < npts; i++ )
00380 {
00381 gdkpoints[i].x = (gint) ( dev->height - y[i] / VSCALE );
00382 gdkpoints[i].y = (gint) ( dev->width - x[i] / VSCALE );
00383 }
00384 }
00385
00386 gdk_draw_lines( dev->background, dev->gc, gdkpoints, npts );
00387
00388 dev->pixmap_has_data = TRUE;
00389
00390 free( gdkpoints );
00391 }
00392 else
00393
00394 {
00395
00396 if ( ( points = gnome_canvas_points_new( npts ) ) == NULL )
00397 {
00398 plabort( "GCW driver <plD_polyline_gcw>: Cannot create points" );
00399 return;
00400 }
00401 if ( !pls->portrait )
00402 {
00403 for ( i = 0; i < npts; i++ )
00404 {
00405 points->coords[2 * i] = (gdouble) ( x[i] / VSCALE );
00406 points->coords[2 * i + 1] = (gdouble) ( -y[i] / VSCALE );
00407 }
00408 }
00409 else
00410 {
00411 for ( i = 0; i < npts; i++ )
00412 {
00413 points->coords[2 * i] = (gdouble) ( dev->height - y[i] / VSCALE );
00414 points->coords[2 * i + 1] = (gdouble) ( -x[i] / VSCALE );
00415 }
00416 }
00417
00418
00419 width = pls->width;
00420 color = dev->color;
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 pts.num_points = 2;
00439 pts.ref_count = 1;
00440 pts.coords = points->coords;
00441
00442 for ( i = 0; i < npts - 1; i++ )
00443 {
00444 pts.coords = &( points->coords[2 * i] );
00445
00446 if ( !GNOME_IS_CANVAS_ITEM(
00447 item = gnome_canvas_item_new( group,
00448 GNOME_TYPE_CANVAS_LINE,
00449 "cap_style", GDK_CAP_ROUND,
00450 "join-style", GDK_JOIN_ROUND,
00451 "points", &pts,
00452 "fill-color-rgba", color,
00453 "width-units", width,
00454 NULL )
00455 ) )
00456 {
00457 plwarn( "GCW driver <plD_polyline_gcw>: Canvas item not created." );
00458 }
00459 }
00460
00461
00462 gnome_canvas_points_free( points );
00463 }
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 void plD_line_gcw( PLStream *pls, short x1, short y1, short x2, short y2 )
00474 {
00475 short x[2];
00476 short y[2];
00477
00478 #ifdef DEBUG_GCW_2
00479 gcw_debug( "<plD_line_gcw />\n" );
00480 #endif
00481
00482 x[0] = x1;
00483 x[1] = x2;
00484 y[0] = y1;
00485 y[1] = y2;
00486
00487 plD_polyline_gcw( pls, x, y, (PLINT) 2 );
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497 void plD_eop_gcw( PLStream *pls )
00498 {
00499 GcwPLdev * dev = pls->dev;
00500 GnomeCanvas * canvas;
00501
00502 GdkPixbuf * pixbuf;
00503 GnomeCanvasItem * item;
00504 GnomeCanvasGroup* group;
00505
00506 gdouble dx, dy;
00507
00508 gint count = 1, n;
00509
00510 void *save_state;
00511
00512 PLINT width, height;
00513
00514 if ( !GNOME_IS_CANVAS( dev->canvas ) )
00515 plexit( "GCW driver <plD_eop_gcw>: Canvas not found" );
00516 canvas = dev->canvas;
00517
00518
00519
00520
00521 if ( !GNOME_IS_CANVAS_GROUP( dev->group_hidden ) )
00522 return;
00523
00524 #ifdef DEBUG_GCW_1
00525 gcw_debug( "<plD_eop_gcw>\n" );
00526 #endif
00527
00528 if ( dev->use_persistence )
00529 group = dev->group_persistent;
00530 else
00531 group = dev->group_hidden;
00532
00533
00534 width = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-width" );
00535 height = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-height" );
00536
00537 if ( dev->pixmap_has_data )
00538 {
00539
00540 if ( !GDK_IS_PIXBUF( pixbuf = gdk_pixbuf_get_from_drawable( NULL,
00541 dev->background,
00542 dev->colormap,
00543 0, 0,
00544 0, 0,
00545 width, height ) ) )
00546 {
00547 plwarn( "GCW driver <plD_eop_gcw>: Can't draw pixmap into pixbuf." );
00548 }
00549 else
00550
00551 {
00552 if ( !GNOME_IS_CANVAS_ITEM(
00553 item = gnome_canvas_item_new( dev->group_hidden,
00554 GNOME_TYPE_CANVAS_PIXBUF,
00555 "pixbuf", pixbuf,
00556 "x", 1.,
00557 "y", (gdouble) ( -height + 1. ),
00558 "width", (gdouble) ( width ),
00559 "height", (gdouble) ( height ),
00560 NULL )
00561 ) )
00562 {
00563 plwarn( "GCW driver <plD_eop_gcw>: Canvas item not created." );
00564 }
00565
00566
00567 g_object_unref( pixbuf );
00568 }
00569 }
00570 else
00571 {
00572
00573 if ( !GNOME_IS_CANVAS_ITEM(
00574 item = gnome_canvas_item_new(
00575 dev->group_hidden,
00576 GNOME_TYPE_CANVAS_RECT,
00577 "x1", 0.,
00578 "y1", (gdouble) ( -height ),
00579 "x2", (gdouble) ( width ),
00580 "y2", 0.,
00581 "fill-color-rgba", plcolor_to_rgba( pls->cmap0[0], 0xFF ),
00582 "width-units", 0.,
00583 NULL )
00584 ) )
00585 {
00586 plabort( "GCW driver <pld_eop_gcw>: Canvas item not created" );
00587 return;
00588 }
00589 }
00590
00591
00592 gnome_canvas_item_raise_to_top( GNOME_CANVAS_ITEM( dev->group_persistent ) );
00593
00594
00595 if ( GNOME_IS_CANVAS_ITEM( item ) )
00596 gnome_canvas_item_lower_to_bottom( item );
00597
00598
00599 gnome_canvas_item_show( GNOME_CANVAS_ITEM( dev->group_hidden ) );
00600
00601
00602 if ( GNOME_IS_CANVAS_GROUP( dev->group_visible ) )
00603 {
00604 gtk_object_destroy( (GtkObject *) ( dev->group_visible ) );
00605 dev->group_visible = NULL;
00606 }
00607
00608
00609 if ( !dev->use_persistence && dev->pixmap_has_data )
00610 gcw_clear_background();
00611
00612
00613 dev->group_visible = dev->group_hidden;
00614 dev->group_hidden = NULL;
00615
00616
00617 canvas->need_update = 1;
00618 gnome_canvas_update_now( canvas );
00619
00620
00621
00622
00623
00624
00625 save_state = g_object_get_data( G_OBJECT( canvas ), "plotbuf" );
00626 save_state = (void *) plbuf_save( pls, save_state );
00627
00628
00629 g_object_set_data( G_OBJECT( canvas ), "plotbuf", (gpointer) save_state );
00630
00631
00632
00633
00634
00635
00636 if ( dev->window != NULL )
00637 {
00638 dev->canvas = NULL;
00639 dev->group_visible = NULL;
00640 dev->group_hidden = NULL;
00641 dev->group_persistent = NULL;
00642 }
00643
00644 #ifdef DEBUG_GCW_1
00645 gcw_debug( "</plD_eop_gcw>\n" );
00646 #endif
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 void plD_bop_gcw( PLStream *pls )
00658 {
00659 GcwPLdev * dev = pls->dev;
00660 GnomeCanvas* canvas;
00661
00662 if ( !GNOME_IS_CANVAS( dev->canvas ) )
00663 {
00664 if ( pls->hack )
00665 return;
00666 else
00667 gcw_install_canvas( NULL );
00668 }
00669 canvas = dev->canvas;
00670
00671 #ifdef DEBUG_GCW_1
00672 gcw_debug( "<plD_bop_gcw>\n" );
00673 #endif
00674
00675
00676
00677
00678 if ( dev->plstate_width )
00679 plD_state_gcw( pls, PLSTATE_WIDTH );
00680 if ( dev->plstate_color0 )
00681 plD_state_gcw( pls, PLSTATE_COLOR0 );
00682 if ( dev->plstate_color1 )
00683 plD_state_gcw( pls, PLSTATE_COLOR1 );
00684 dev->plstate_width = FALSE;
00685 dev->plstate_color0 = FALSE;
00686 dev->plstate_color1 = FALSE;
00687
00688
00689 if ( !GNOME_IS_CANVAS_ITEM(
00690 dev->group_hidden = GNOME_CANVAS_GROUP( gnome_canvas_item_new(
00691 gnome_canvas_root( canvas ),
00692 gnome_canvas_clipgroup_get_type(),
00693 "x", 0.,
00694 "y", 0.,
00695 NULL ) )
00696 ) )
00697 {
00698 plexit( "GCW driver <plD_bop_gcw>: Canvas group cannot be created" );
00699 }
00700
00701
00702 g_object_set( G_OBJECT( dev->group_hidden ), "path", NULL, NULL );
00703
00704
00705 gnome_canvas_item_hide( GNOME_CANVAS_ITEM( dev->group_hidden ) );
00706
00707 #ifdef DEBUG_GCW_1
00708 gcw_debug( "</plD_bop_gcw>\n" );
00709 #endif
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719 void plD_tidy_gcw( PLStream *pls )
00720 {
00721 GcwPLdev* dev = pls->dev;
00722
00723 #ifdef DEBUG_GCW_1
00724 gcw_debug( "<plD_tidy_gcw>\n" );
00725 #endif
00726
00727 #ifdef HAVE_FREETYPE
00728 if ( pls->dev_text )
00729 {
00730 FT_Data *FT = (FT_Data *) pls->FT;
00731 plscmap0n( FT->ncol0_org );
00732 plD_FreeType_Destroy( pls );
00733 }
00734 #endif
00735
00736 if ( dev->window != NULL )
00737 {
00738 gtk_main();
00739 }
00740
00741 #ifdef DEBUG_GCW_1
00742 gcw_debug( "</plD_tidy_gcw>\n" );
00743 #endif
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 void plD_state_gcw( PLStream *pls, PLINT op )
00760 {
00761 GcwPLdev* dev = pls->dev;
00762 char opname[20], msg[100];
00763
00764 #ifdef DEBUG_GCW_1
00765 if ( op == PLSTATE_WIDTH )
00766 strcpy( opname, "PLSTATE_WIDTH" );
00767 else if ( op == PLSTATE_COLOR0 )
00768 strcpy( opname, "PLSTATE_COLOR0" );
00769 else if ( op == PLSTATE_COLOR1 )
00770 strcpy( opname, "PLSTATE_COLOR1" );
00771 else if ( op == PLSTATE_FILL )
00772 strcpy( opname, "PLSTATE_FILL" );
00773 else if ( op == PLSTATE_CMAP0 )
00774 strcpy( opname, "PLSTATE_CMAP0" );
00775 else if ( op == PLSTATE_CMAP1 )
00776 strcpy( opname, "PLSTATE_CMAP1" );
00777 else
00778 strcpy( opname, "unknown" );
00779 snprintf( msg, 100, "<plD_state_gcw />: %s\n", opname );
00780 gcw_debug( msg );
00781 #endif
00782
00783 switch ( op )
00784 {
00785 case PLSTATE_WIDTH:
00786 if ( GNOME_IS_CANVAS( dev->canvas ) )
00787 {
00788 if ( dev->use_pixmap )
00789 {
00790 gdk_gc_set_line_attributes( dev->gc, pls->width,
00791 GDK_LINE_SOLID,
00792 GDK_CAP_BUTT,
00793 GDK_JOIN_MITER );
00794 }
00795 }
00796 else
00797 dev->plstate_width = TRUE;
00798 break;
00799
00800 case PLSTATE_COLOR0:
00801 if ( GNOME_IS_CANVAS( dev->canvas ) )
00802 {
00803 dev->color = plcolor_to_rgba( pls->cmap0[pls->icol0], 0xFF );
00804 if ( dev->use_pixmap )
00805 gcw_set_gdk_color();
00806 }
00807 else
00808 dev->plstate_color0 = TRUE;
00809 break;
00810
00811 case PLSTATE_COLOR1:
00812 if ( GNOME_IS_CANVAS( dev->canvas ) )
00813 {
00814 dev->color = plcolor_to_rgba( pls->cmap1[pls->icol1], 0xFF );
00815 if ( dev->use_pixmap )
00816 gcw_set_gdk_color();
00817 }
00818 else
00819 dev->plstate_color1 = TRUE;
00820 break;
00821
00822 case PLSTATE_FILL:
00823 break;
00824
00825 case PLSTATE_CMAP0:
00826 break;
00827
00828 case PLSTATE_CMAP1:
00829 break;
00830
00831 default:
00832 break;
00833 }
00834 }
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 static void fill_polygon( PLStream* pls )
00845 {
00846 GnomeCanvasPoints* points;
00847 GnomeCanvasGroup * group;
00848 GnomeCanvasItem * item;
00849 GcwPLdev * dev = pls->dev;
00850 GnomeCanvas * canvas;
00851
00852 PLINT i;
00853
00854 GdkPoint * gdkpoints;
00855
00856 PLINT tmp;
00857
00858 #ifdef DEBUG_GCW_2
00859 gcw_debug( "<fill_polygon />\n" );
00860 #endif
00861
00862 if ( !GNOME_IS_CANVAS( dev->canvas ) )
00863 plexit( "GCW driver <fill_polygon>: Canvas not found" );
00864 canvas = dev->canvas;
00865
00866 if ( dev->use_persistence )
00867 group = dev->group_persistent;
00868 else
00869 group = dev->group_hidden;
00870
00871 if ( dev->use_pixmap && !dev->use_persistence )
00872
00873 {
00874 if ( ( gdkpoints = (GdkPoint *) malloc( pls->dev_npts * sizeof ( GdkPoint ) ) ) == NULL )
00875 {
00876 plabort( "GCW driver <fill_polygon>: Could not create gdkpoints" );
00877 return;
00878 }
00879
00880 if ( !pls->portrait )
00881 {
00882 for ( i = 0; i < pls->dev_npts; i++ )
00883 {
00884 gdkpoints[i].x = (gint) ( pls->dev_x[i] / VSCALE );
00885 gdkpoints[i].y = (gint) ( dev->height - pls->dev_y[i] / VSCALE );
00886 }
00887 }
00888 else
00889 {
00890 for ( i = 0; i < pls->dev_npts; i++ )
00891 {
00892 gdkpoints[i].x = (gint) ( dev->height - pls->dev_y[i] / VSCALE );
00893 gdkpoints[i].y = (gint) ( dev->width - pls->dev_x[i] / VSCALE );
00894 }
00895 }
00896
00897 gdk_draw_polygon( dev->background, dev->gc, TRUE, gdkpoints, pls->dev_npts );
00898
00899 dev->pixmap_has_data = TRUE;
00900
00901 free( gdkpoints );
00902 }
00903 else
00904
00905 {
00906 if ( ( points = gnome_canvas_points_new( pls->dev_npts ) ) == NULL )
00907 {
00908 plabort( "GCW driver <fill_polygon>: Could not create points" );
00909 return;
00910 }
00911
00912 if ( !pls->portrait )
00913 {
00914 for ( i = 0; i < pls->dev_npts; i++ )
00915 {
00916 points->coords[2 * i] = (gdouble) ( pls->dev_x[i] / VSCALE );
00917 points->coords[2 * i + 1] = (gdouble) ( -pls->dev_y[i] / VSCALE );
00918 }
00919 }
00920 else
00921 {
00922 for ( i = 0; i < pls->dev_npts; i++ )
00923 {
00924 points->coords[2 * i] = (gdouble) ( dev->height - pls->dev_y[i] / VSCALE );
00925 points->coords[2 * i + 1] = (gdouble) ( -pls->dev_x[i] / VSCALE );
00926 }
00927 }
00928
00929 if ( !GNOME_IS_CANVAS_ITEM(
00930 item = gnome_canvas_item_new( group,
00931 GNOME_TYPE_CANVAS_POLYGON,
00932 "points", points,
00933 "fill-color-rgba", dev->color,
00934
00935 NULL )
00936 ) )
00937 {
00938 plwarn( "GCW driver <fill_polygon>: Canvas item not created." );
00939 }
00940
00941 gnome_canvas_points_free( points );
00942
00943
00944
00945
00946
00947
00948 tmp = pls->width;
00949 pls->width = 1;
00950 plD_polyline_gcw( pls, pls->dev_x, pls->dev_y, pls->dev_npts );
00951 pls->width = tmp;
00952 }
00953 }
00954
00955 #ifdef HAVE_FREETYPE
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 static void proc_str( PLStream *pls, EscText *args )
00966 {
00967 PLFLT *t = args->xform;
00968
00969 GnomeCanvasGroup* group;
00970 GcwPLdev * dev = pls->dev;
00971 GnomeCanvas * canvas;
00972
00973 PLUNICODE fci;
00974 guchar *fontname = NULL;
00975 gint font_size;
00976 GnomeFont *font;
00977 GnomeFontFace *face;
00978 GnomeGlyphList *glyphlist;
00979 guint Nglyphs;
00980
00981 gdouble affine_baseline[6] = { 0., 0., 0., 0., 0., 0. };
00982 gdouble affine_translate[6] = { 0., 0., 0., 0., 0., 0. };
00983 gdouble affine_rotate[6] = { 0., 0., 0., 0., 0., 0. };
00984 gdouble affine_plplot[6] = { 0., 0., 0., 0., 0., 0. };
00985
00986 GnomeCanvasItem * item[200];
00987 gdouble width[200], height[200];
00988 gdouble up_list[200];
00989 gdouble up = 0, scale = 1;
00990
00991 ArtDRect bbox;
00992
00993 const PLUNICODE *text;
00994 guint i = 0, Ntext;
00995
00996 char esc;
00997
00998 guint N = 0;
00999 gdouble total_width = 0, sum_width = 0;
01000
01001 guint symbol;
01002
01003
01004 #ifdef DEBUG_GCW_2
01005 gcw_debug( "<proc_str>\n" );
01006 #endif
01007
01008 if ( !GNOME_IS_CANVAS( dev->canvas ) )
01009 plexit( "GCW driver <proc_str>: Canvas not found" );
01010 canvas = dev->canvas;
01011
01012 if ( dev->use_persistence )
01013 group = dev->group_persistent;
01014 else
01015 group = dev->group_hidden;
01016
01017
01018 plgesc( &esc );
01019
01020
01021
01022
01023
01024
01025 affine_plplot[0] = t[0];
01026 affine_plplot[1] = -t[2];
01027 affine_plplot[2] = -t[1];
01028 affine_plplot[3] = t[3];
01029
01030
01031 font_size = (gint) ( pls->chrht * DEVICE_PIXELS_PER_MM * 1.5 );
01032
01033
01034 plgfci( &fci );
01035 fontname = plP_FCI2FontName( fci, FontLookup, N_TrueTypeLookup );
01036 if ( fontname == NULL )
01037 {
01038 plabort( "GCW driver <proc_str>: FCI inconsistent with TrueTypeLookup" );
01039 return;
01040 }
01041
01042
01043 face = gnome_font_face_find_from_filename( fontname, 0 );
01044
01045
01046 text = args->unicode_array;
01047 Ntext = (guint) ( args->unicode_array_len );
01048
01049
01050
01051
01052
01053
01054 while ( i < Ntext )
01055 {
01056
01057
01058 if ( text[i] & PL_FCI_MARK )
01059
01060 {
01061 fontname = plP_FCI2FontName( text[i], FontLookup, N_TrueTypeLookup );
01062 if ( fontname == NULL )
01063 {
01064 plabort( "GCW driver <proc_str>: FCI inconsistent with "
01065 "TrueTypeLookup" );
01066 return;
01067 }
01068
01069
01070 gnome_font_unref( face );
01071 face = gnome_font_face_find_from_filename( fontname, 0 );
01072
01073 i++;
01074 }
01075 else
01076 {
01077 if ( text[i] == esc )
01078
01079 {
01080 i++;
01081 if ( i >= Ntext )
01082 {
01083 plwarn( "GCW driver <proc_str>: Invalid escape sequence "
01084 "provided in text." );
01085 return;
01086 }
01087
01088 switch ( text[i] )
01089 {
01090 case '#':
01091 break;
01092
01093
01094 case 'd':
01095 case 'D':
01096 if ( up > 0. )
01097 scale *= 1.25;
01098 else
01099 scale *= 0.8;
01100 up -= font_size / 2.;
01101 break;
01102
01103
01104 case 'u':
01105 case 'U':
01106 if ( up < 0. )
01107 scale *= 1.25;
01108 else
01109 scale *= 0.8;
01110 up += font_size / 2.;
01111 break;
01112
01113
01114
01115
01116 case '+':
01117
01118
01119 case '-':
01120
01121
01122 case 'b':
01123 case 'B':
01124 plwarn( "GCW driver <proc_str>: '+', '-', and 'b' text "
01125 "escape sequences not processed." );
01126 break;
01127 }
01128
01129 if ( text[i] != '#' )
01130 i++;
01131 }
01132 }
01133
01134
01135 if ( i == Ntext )
01136 continue;
01137
01138
01139 up_list[N] = up;
01140
01141
01142 font = gnome_font_face_get_font_default( face, font_size * scale );
01143
01144
01145
01146 glyphlist = gnome_glyphlist_new();
01147 gnome_glyphlist_font( glyphlist, font );
01148 gnome_glyphlist_color( glyphlist, dev->color );
01149 gnome_glyphlist_advance( glyphlist, TRUE );
01150 gnome_glyphlist_kerning( glyphlist, 0. );
01151 gnome_glyphlist_letterspace( glyphlist, 0. );
01152
01153
01154 gnome_font_unref( font );
01155
01156
01157
01158
01159 Nglyphs = 0;
01160 while ( i < Ntext && !( text[i] & PL_FCI_MARK ) )
01161 {
01162
01163 if ( text[i] == esc )
01164 {
01165 if ( !( i > 0 && text[i - 1] == esc ) )
01166 break;
01167 }
01168
01169 gnome_glyphlist_glyph( glyphlist,
01170 gnome_font_lookup_default( font, text[i] ) );
01171 i++; Nglyphs++;
01172 }
01173
01174 if ( Nglyphs )
01175 {
01176
01177 gnome_glyphlist_bbox( glyphlist, NULL, 0, &bbox );
01178 width[N] = bbox.x1 - bbox.x0;
01179 height[N] = bbox.y1 - bbox.y0;
01180
01181
01182 total_width += width[N];
01183 if ( N != 0 )
01184 total_width += 2;
01185
01186
01187 if ( !GNOME_IS_CANVAS_ITEM(
01188 item[N] = gnome_canvas_item_new( group,
01189 PLPLOT_TYPE_CANVAS_HACKTEXT,
01190 "glyphlist", glyphlist,
01191 "fill-color-rgba", dev->color,
01192 "x", 0.,
01193 "y", 0.,
01194 NULL )
01195 ) )
01196 {
01197 plabort( "GCW driver <proc_str>: Canvas item not created" );
01198 return;
01199 }
01200
01201
01202 gnome_glyphlist_unref( glyphlist );
01203
01204
01205 N++;
01206 }
01207
01208
01209
01210 if ( N == 200 && i < Ntext )
01211 {
01212 plabort( "GCW driver <proc_str>: too many text segments" );
01213 return;
01214 }
01215 }
01216
01217
01218
01219
01220 for ( i = 0; i < N; i++ )
01221 {
01222
01223 art_affine_rotate( affine_rotate, 90. * ( pls->diorot - pls->portrait ) );
01224 if ( !pls->portrait )
01225 {
01226 art_affine_translate( affine_baseline,
01227 -total_width * args->just + sum_width,
01228 height[0] / 2.5 - up_list[i] );
01229 art_affine_translate( affine_translate,
01230 args->x / VSCALE, -args->y / VSCALE );
01231 }
01232 else
01233 {
01234 art_affine_translate( affine_baseline,
01235 -total_width * args->just + sum_width,
01236 height[0] / 2.5 - up_list[i] );
01237 art_affine_translate( affine_translate,
01238 dev->height - args->y / VSCALE, -args->x / VSCALE );
01239 }
01240 gnome_canvas_item_affine_relative( item[i], affine_translate );
01241 gnome_canvas_item_affine_relative( item[i], affine_rotate );
01242 gnome_canvas_item_affine_relative( item[i], affine_plplot );
01243 gnome_canvas_item_affine_relative( item[i], affine_baseline );
01244
01245
01246 sum_width += width[i];
01247 if ( i != N - 1 )
01248 sum_width += 2;
01249 }
01250
01251 #ifdef DEBUG_GCW_2
01252 gcw_debug( "</proc_str>\n" );
01253 #endif
01254 }
01255 #endif //HAVE_FREETYPE
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 void plD_esc_gcw( PLStream *pls, PLINT op, void *ptr )
01266 {
01267 GcwPLdev* dev = pls->dev;
01268
01269 #ifdef DEBUG_GCW_1
01270 char opname[20], msg[100];
01271 if ( op == PLESC_DEVINIT )
01272 strcpy( opname, "PLESC_DEVINIT" );
01273 else if ( op == PLESC_CLEAR )
01274 strcpy( opname, "PLESC_CLEAR" );
01275 else if ( op == PLESC_FILL )
01276 strcpy( opname, "PLESC_FILL" );
01277 else if ( op == PLESC_HAS_TEXT )
01278 strcpy( opname, "PLESC_HAS_TEXT" );
01279 else if ( op == PLESC_GRAPH )
01280 strcpy( opname, "PLESC_GRAPH" );
01281 else
01282 strcpy( opname, "unknown" );
01283 snprintf( msg, 100, "<plD_esc_gcw />: %s\n", opname );
01284 gcw_debug( msg );
01285 #endif
01286
01287 switch ( op )
01288 {
01289 case PLESC_DEVINIT:
01290 gcw_init_canvas( GNOME_CANVAS( ptr ) );
01291 pls->hack = 0;
01292 break;
01293
01294 case PLESC_CLEAR:
01295 break;
01296
01297 case PLESC_FILL:
01298 fill_polygon( pls );
01299 break;
01300
01301 #ifdef HAVE_FREETYPE
01302 case PLESC_HAS_TEXT:
01303 proc_str( pls, ptr );
01304 break;
01305 #endif
01306
01307 case PLESC_GRAPH:
01308 break;
01309
01310 default:
01311 break;
01312 }
01313 }