From: trelane@digitasaru.net Date: Thu, 24 Jul 2008 22:03:47 +0000 (-0500) Subject: * Compiles but segfaults. X-Git-Url: http://vcs.maemo.org/git/?p=scdataviz;a=commitdiff_plain;h=d6cbaf19e985004c55770b7408f9ac91429f40ea * Compiles but segfaults. * Fix the bug!! --- diff --git a/graph.c b/graph.c index 66b7e6c..4c75464 100644 --- a/graph.c +++ b/graph.c @@ -6,20 +6,20 @@ ** - Copyright (C) 2008 Joseph Pingenot +Copyright (C) 2008 Joseph Pingenot - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . **Many thanks to Davyd Madeley for the excellent Cairo Tutorial @@ -53,7 +53,7 @@ Graph *graph_new(void) { int graph_add_graph_point(Graph* graph, struct graph_point *pt) { if(pt == NULL) return 1; g_ptr_array_add(graph->points, pt); - if(graph->points->len == 1) { + if((graph->points->len == 1) && ((graph->lines == NULL) || (graph->lines->len == 0))) { graph->maxx = graph->minx = pt->x; graph->maxy = graph->miny = pt->y; }else{ @@ -76,9 +76,62 @@ int graph_add_point(Graph* graph, double x, double y, const GString *label) { pt->x = x; pt->y = y; pt->label = (label)?g_string_new(label->str):NULL; - /*Easiest way to do a line: the control points are the same as this point*/ - pt->bezier_from_x = pt->bezier_to_x = x; - pt->bezier_from_y = pt->bezier_to_y = y; graph_add_graph_point(graph, pt); return 0; } + +int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y) { + if(graph->lines == NULL) { + if((graph->points = g_ptr_array_new()) == NULL) return 1; + } + struct graph_line *l; + if((l=(struct graph_line*)malloc(sizeof(struct graph_line))) == NULL) return 2; + l->p0_x=p0_x; + l->p0_y=p0_y; + l->p1_x=p1_x; + l->p1_y=p1_y; + l->p2_x=p2_x; + l->p2_y=p2_y; + l->p3_x=p3_x; + l->p3_y=p3_y; + g_ptr_array_add(graph->lines, l); + if((graph->points->len == 0) && (graph->lines->len == 1)) { + graph->maxx = graph->minx = p0_x; + graph->maxy = graph->miny = p0_y; + }else{ + if(p0_x > graph->maxx) graph->maxx = p0_x; + if(p0_x < graph->minx) graph->minx = p0_x; + if(p0_y > graph->maxy) graph->maxy = p0_y; + if(p0_y < graph->miny) graph->miny = p0_y; + } + if(p3_x > graph->maxx) graph->maxx = p3_x; + if(p3_x < graph->minx) graph->minx = p3_x; + if(p3_y > graph->maxy) graph->maxy = p3_y; + if(p3_y < graph->miny) graph->miny = p3_y; + return 0; +} + +struct cxt { + Graph *graph; + struct graph_point *p0; +}; + +static void linear_interpolate(gpointer data, gpointer user_data) { + struct cxt *cxt = user_data; + struct graph_point *p3 = data; + if(cxt->p0 != NULL) { + double p1_x = (p3->x - cxt->p0->x)/3.0; + double p1_y = (p3->y - cxt->p0->y)/3.0; + double p2_x = (p3->x + 2*cxt->p0->x)/3.0; + double p2_y = (p3->y + 2*cxt->p0->y)/3.0; + graph_add_line(cxt->graph, cxt->p0->x, cxt->p0->y, p1_x, p1_y, p2_x, p2_y, p3->x, p3->y); + } + cxt->p0 = p3; +} + +void graph_add_linear_connectors(Graph* graph) { + struct cxt cxt; + cxt.graph = graph; + cxt.p0 = NULL; + g_ptr_array_foreach(graph->points, &linear_interpolate, &cxt); +} diff --git a/graph.h b/graph.h index 3015d30..e140057 100644 --- a/graph.h +++ b/graph.h @@ -35,19 +35,27 @@ struct graph_point { double x; double y; GString *label; - /*the Bezier control point FROM HERE to the next point (P1)*/ - double bezier_from_x; - double bezier_from_y; - /*the Bezier control point from previous point TO HERE (P2)*/ - double bezier_to_x; - double bezier_to_y; +}; + +/*Bezier line*/ +struct graph_line { + /*First point*/ + double p0_x; + double p0_y; + double p1_x; + double p1_y; + double p2_x; + double p2_y; + /*End point*/ + double p3_x; + double p3_y; }; typedef struct _Graph { GObject parent_instance; /*Array of n_points sets of x,y coords*/ GPtrArray *points; - /*If you want to, this will override the lines between the points.*/ + /*This draws all of the lines (generally between points)*/ GPtrArray *lines; double maxx; double minx; @@ -70,5 +78,7 @@ typedef struct _GraphClass { Graph *graph_new(void); int graph_add_point(Graph* graph, double x, double y, const GString *label); int graph_add_graph_point(Graph* graph, struct graph_point *pt); +int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y); +void graph_add_linear_connectors(Graph* graph); #endif /* !GRAPHCLASS_H_ */ diff --git a/graphwidget.c b/graphwidget.c index fe209ca..7dbfbbd 100644 --- a/graphwidget.c +++ b/graphwidget.c @@ -44,12 +44,6 @@ struct drawing_context { double yoffset; double xscaling; double yscaling; - double bezier_p0_x; - double bezier_p0_y; - double bezier_p1_x; - double bezier_p1_y; - int draw_line; - int not_first_point; }; static void draw_point(gpointer data, gpointer user_data) { @@ -57,37 +51,29 @@ static void draw_point(gpointer data, gpointer user_data) { struct graph_point *pt = data; double x = (pt->x + cxt->xoffset)*cxt->xscaling; double y = (pt->y + cxt->yoffset)*cxt->yscaling; - double bezier_p2_x = (pt->bezier_to_x + cxt->xoffset)*cxt->xscaling; - double bezier_p2_y = (pt->bezier_to_y + cxt->yoffset)*cxt->yscaling; - #ifdef DEBUG - fprintf(stderr, "\tcxt=(cr=%x, rad=%g, xoffset=%g, yoffset=%g, xscaling=%g, yscaling=%g, p0_x=%g, p0_y=%g, p1_x=%g, p1_y=%g, draw_line=%d, not_first_point=%d)\n", (unsigned int)cxt->cr, cxt->radius, cxt->xoffset, cxt->yoffset, cxt->xscaling, cxt->yscaling, cxt->bezier_p0_x, cxt->bezier_p0_y, cxt->bezier_p1_x, cxt->bezier_p1_y, cxt->draw_line, cxt->not_first_point); - #endif - /*Draw line to here if we need to.*/ - if(cxt->draw_line && cxt->not_first_point) { - /*Note that the cxt points are already normalized*/ - //cairo_move_to(cxt->cr, cxt->bezier_p0_x, cxt->bezier_p0_y); - cairo_curve_to(cxt->cr, cxt->bezier_p1_x, cxt->bezier_p1_y, bezier_p2_x, bezier_p2_y, x, y); - }else{ - cairo_move_to(cxt->cr, x, y); - } - #ifdef DEBUG - fprintf(stderr, "\t\tpt=(x=%g, y=%g, label=%s, from_x=%g, from_y=%g, to_x=%g, to_y=%g)\n", pt->x, pt->y, pt->label->str, pt->bezier_from_x, pt->bezier_from_y, pt->bezier_to_x, pt->bezier_to_y); - fprintf(stderr, "\t\tx=%g, y=%g, p2_x=%g, p2_y=%g\n", x, y, bezier_p2_x, bezier_p2_y); - #endif + cairo_move_to(cxt->cr, x, y); cairo_arc(cxt->cr, x, y, cxt->radius, 0, 2*M_PI); if(pt->label != NULL) { cairo_save(cxt->cr); - cairo_translate(cxt->cr, 0, 1); cairo_scale(cxt->cr, 1, -1); cairo_show_text(cxt->cr, pt->label->str); cairo_restore(cxt->cr); } - /*Set up the context for the next point*/ - cxt->bezier_p0_x = x; - cxt->bezier_p0_y = y; - cxt->bezier_p1_x = (pt->bezier_from_x + cxt->xoffset)*cxt->xscaling; - cxt->bezier_p1_y = (pt->bezier_from_y + cxt->yoffset)*cxt->yscaling; - cxt->not_first_point=1; +} + +static void draw_lines(gpointer data, gpointer user_data) { + struct drawing_context *cxt = user_data; + struct graph_line *l = data; + double p0_x = (l->p0_x + cxt->xoffset)*cxt->xscaling; + double p0_y = (l->p0_y + cxt->yoffset)*cxt->yscaling; + double p1_x = (l->p1_x + cxt->xoffset)*cxt->xscaling; + double p1_y = (l->p1_y + cxt->yoffset)*cxt->yscaling; + double p2_x = (l->p2_x + cxt->xoffset)*cxt->xscaling; + double p2_y = (l->p2_y + cxt->yoffset)*cxt->yscaling; + double p3_x = (l->p3_x + cxt->xoffset)*cxt->xscaling; + double p3_y = (l->p3_y + cxt->yoffset)*cxt->yscaling; + cairo_move_to(cxt->cr, p0_x, p0_y); + cairo_curve_to(cxt->cr, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y); } static void draw(GtkWidget *graph, cairo_t *cr) { @@ -108,9 +94,6 @@ static void draw(GtkWidget *graph, cairo_t *cr) { cxt.yscaling = (gw->graph->points->len == 1)? 1 : (1/(gw->graph->maxy - gw->graph->miny)); cxt.xoffset = (gw->graph->points->len == 1)? (-gw->graph->minx/2) : (-gw->graph->minx); cxt.yoffset = (gw->graph->points->len == 1)? (-gw->graph->miny/2) : (-gw->graph->miny); - /*Signal that the point is the first point.*/ - cxt.draw_line=0; - cxt.not_first_point=0; #ifdef DEBUG fprintf(stderr, "minx=%g, maxx=%g, miny=%g, maxy=%g, xscaling=%g, yscaling=%g, xoffset=%g, yoffset=%g\n", gw->graph->minx, gw->graph->maxx, gw->graph->miny, gw->graph->maxy, cxt.xscaling, cxt.yscaling, cxt.xoffset, cxt.yoffset); fprintf(stderr, "x0=%g, y0=%g, width=%g, height=%g\n", x0, y0, height, width); diff --git a/scdataviz.c b/scdataviz.c index c51f21d..4171631 100644 --- a/scdataviz.c +++ b/scdataviz.c @@ -39,6 +39,7 @@ struct xy_properties { Graph *graph; }; + static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) { struct xy_properties *propmap = user_data; struct matdb_material *mat = value; @@ -62,7 +63,6 @@ static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) { int main(int argc, char *argv[]) { GtkWidget *window; - GtkWidget *button; GtkWidget *graph; GString *file = g_string_new("../matdb"); int err=0; @@ -72,10 +72,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "err=%d\n", err); //print_matdb(mdb); - gtk_init (&argc, &argv); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); graph = graph_widget_new(); @@ -85,6 +82,7 @@ int main(int argc, char *argv[]) propmap.yprop = g_string_new("E_g_Gamma"); propmap.graph = graph_widget_get_graph(GRAPH_WIDGET(graph)); g_hash_table_foreach(mdb->materials, &put_mat_in_graph, &propmap); + graph_add_linear_connectors(propmap.graph); //Connect signals