Working on new canvas item...



 Folks,

   I've recently written a simple GnomeCanvasItem for use in a 
financial charting application I'm writing.  The item is meant to
display a simple open-high-low-close pricebar, which looks a bit
like this:

   |
   |-
   |
   |
  -|
   |
   |

   The opening price of the equity is represented by the small
tic on the left side of the bar.  The bottom of the vertical bar
is the low price, the top is the high price, and the small tic
on the right side of the bar represents the closing price.  Now,
I've implemented all of the necessary methods for doing this,
but the visual results that are coming out just refuse to do
what's expected.

   I've written this item to work *only* with antialiased canvas
items, as I expect to place a lot of points on these charts and
don't want the extra server communication overhead associated
with Gdk rendering.  The update method, as a result, is quite
straightforward (I think).  Here is the pertinent code (I've
stripped out a bunch of debugging I/O):


static void
gnome_canvas_pricebar_update( GnomeCanvasItem *item,
	double affine[6], ArtSVP *clip_path, gint flags )
    {
    GnomeCanvasPricebar *pbar;
    ArtVpath vpath[7];
    ArtVpath *vpath2;

    pbar = GNOME_CANVAS_PRICEBAR(item);

    if( parent_class->update ) 
	(* parent_class->update) (item, affine, clip_path, flags);

    g_assert( item->canvas->aa );

    gnome_canvas_item_reset_bounds( item );
   
    vpath[0].code = ART_MOVETO;
    vpath[0].x = pbar->time - pbar->tic_length;
    vpath[0].y = pbar->open;
    vpath[1].code = ART_LINETO;
    vpath[1].x = pbar->time;
    vpath[1].y = pbar->open;
    vpath[2].code = ART_LINETO;
    vpath[2].x = pbar->time;
    vpath[2].y = pbar->low;
    vpath[3].code = ART_LINETO;
    vpath[3].x = pbar->time;
    vpath[3].y = pbar->high;
    vpath[4].code = ART_LINETO;
    vpath[4].x = pbar->time;
    vpath[4].y = pbar->close;
    vpath[5].code = ART_LINETO;
    vpath[5].x = pbar->time + pbar->tic_length;
    vpath[5].y = pbar->close;

    vpath[6].code = ART_END;
    vpath[6].x = 0;
    vpath[6].y = 0;

    /* Transform the vector path with the affine passed to the routine. */

    vpath2 = art_vpath_affine_transform( vpath, affine );

    /* Place the new stroked vector path in place. */

    gnome_canvas_item_update_svp_clip( item, &pbar->svp,
	art_svp_from_vpath(vpath2), clip_path );

    /* Free the temporary path. */

    art_free(vpath2);
    }

   And here is the actual render method:


static void
gnome_canvas_pricebar_render( GnomeCanvasItem *item, GnomeCanvasBuf *buf )
    {
    GnomeCanvasPricebar *pbar;

    pbar = GNOME_CANVAS_PRICEBAR(item);

    if( pbar->svp != NULL )
	gnome_canvas_render_svp( buf, pbar->svp, pbar->color );
    }


   To me, this code seems pretty straightforward.  What I get on the
canvas, of course, is nothing like what it should be.  I get a bunch
of fat rectangles, whose only relationship to the proper appearance
is that they appear to be getting placed roughly where they are
supposed to on the canvas.  The only thing I can think of is that
somehow the "width" of the line that the libart routines are drawing
is somehow being set to some huge value, so that the lines are so
thick they *look* like boxes.

   Can anyone see *anything* offhand here that might be leading to 
the problem?  The canvas/world coordinates are identical at the
moment, save for a translation in the y dimension.  I have not been
messing around with the affines to scale the thing to fit my window
yet, so I doubt that that is the cause.  The value of the tic_length
is on the order of 1.0, and I have tried fiddling it back and forth
a little.  No effect that I can see.

   How do we set the "width" of the strokes that libart uses when
rendering its vector paths?

thanks,
Jim Wiggs
wiggs wiggs net





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]