]> granicus.if.org Git - graphviz/commitdiff
Added a visible border to rounded tables.
authordperry <devnull@localhost>
Tue, 19 Jul 2011 18:50:20 +0000 (18:50 +0000)
committerdperry <devnull@localhost>
Tue, 19 Jul 2011 18:50:20 +0000 (18:50 +0000)
lib/common/htmltable.c
lib/gvc/gvcproc.h
lib/gvc/gvrender.c
plugin/pango/gvrender_pango.c

index 9c15befcebf01c414f820bb239521776bf689e70..0ed47053732362c22a26ffa21bcde8404d9e3b13 100644 (file)
@@ -377,13 +377,13 @@ emit_html_rules(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, char *color)
     //Determine vertical line coordinate and length
     if ((cp->ruled & HTML_VRULE) && (cp->col + cp->cspan < cp->parent->cc)) {
        if(cp->row == 0) {  // first row
-           // extend to table border and add half cell spacing
-           base = cp->parent->data.border + cp->parent->data.space/2;
+           // extend to center of table border and add half cell spacing
+           base = cp->parent->data.border/2 + cp->parent->data.space/2;
            rule_pt.y = pts.LL.y - cp->parent->data.space/2; 
        }
        else if(cp->row + cp->rspan == cp->parent->rc){  // bottom row
-           // extend to table border and add half cell spacing
-           base = cp->parent->data.border + cp->parent->data.space/2;
+           // extend to center of table border and add half cell spacing
+           base = cp->parent->data.border/2 + cp->parent->data.space/2;
            rule_pt.y = pts.LL.y - cp->parent->data.space/2 - base;
        }
        else {
@@ -398,13 +398,13 @@ emit_html_rules(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, char *color)
     //Determine the horizontal coordinate and length
     if ((cp->ruled & HTML_HRULE) && (cp->row + cp->rspan < cp->parent->rc)) {
        if(cp->col == 0) { // first column 
-           // extend to table border and add half cell spacing
-           base = cp->parent->data.border + cp->parent->data.space/2;
-           rule_pt.x = pts.LL.x - base - cp->parent->data.space/2;
+           // extend to center of table border and add half cell spacing
+           base = cp->parent->data.border/2 + cp->parent->data.space/2;
+           rule_pt.x = pts.LL.x - base  - cp->parent->data.space/2;
        }
        else if(cp->col + cp->cspan == cp->parent->cc){  // last column
-           // extend to table border and add half cell spacing
-           base = cp->parent->data.border + cp->parent->data.space/2;
+           // extend to center of table border and add half cell spacing
+           base = cp->parent->data.border/2 + cp->parent->data.space/2;
            rule_pt.x = pts.LL.x - cp->parent->data.space/2;
        }
        else {
@@ -443,16 +443,24 @@ emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env)
        anchor = 0;
 
     if (tbl->style & ROUNDED) {
-       pointf AF[4];
-       char* color = (tbl->data.pencolor ? tbl->data.pencolor : DEFAULT_COLOR);
-       AF[0] = pts.LL;
-       AF[2] = pts.UR;
-       AF[1].x = AF[2].x;
-       AF[1].y = AF[0].y;
-       AF[3].x = AF[0].x;
-       AF[3].y = AF[2].y;
-       round_corners (job, tbl->data.bgcolor, color, AF, 4, tbl->style,
-           (tbl->data.bgcolor != NULL));
+       if(tbl->data.border == 0 ){  //no need to display border, just fill if required
+         if (tbl->data.bgcolor)
+           doFill(job, tbl->data.bgcolor, pts);
+       }
+       else {
+         pointf AF[4];
+         char* color = (tbl->data.pencolor ? tbl->data.pencolor : DEFAULT_COLOR);
+         AF[0] = pts.LL;
+         AF[2] = pts.UR;
+         AF[1].x = AF[2].x;
+         AF[1].y = AF[0].y;
+         AF[3].x = AF[0].x;
+         AF[3].y = AF[2].y;
+         gvrender_set_fillcolor(job, tbl->data.bgcolor);       /* emit fill color */
+         gvrender_set_pencolor(job,  color);
+         gvrender_rounded_box(job, AF, 4, (tbl->data.bgcolor != NULL), tbl->data.border);
+
+       }
     }
     else {
        if (tbl->data.bgcolor)
@@ -463,8 +471,8 @@ emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env)
     }
     //render table rules
     while ((cp = *cells++)){
-       if (cp->ruled) emit_html_rules(job, cp, env, tbl->data.bgcolor);
   }
+       if (cp->ruled) emit_html_rules(job, cp, env, tbl->data.pencolor);
+ }
     cells = tbl->u.n.cells;
 
     while (*cells) {
index 53d6c63c477b9273943f9bd1018cd883223ce0b5..781ac9403d49d99928002a3ebbc642ed352e4677 100644 (file)
     extern void gvrender_set_style(GVJ_t * job, char **s);
     extern void gvrender_ellipse(GVJ_t * job, pointf * AF, int n, boolean filled);
     extern void gvrender_polygon(GVJ_t * job, pointf * AF, int n, boolean filled);
+    extern void gvrender_rounded_box(GVJ_t * job, pointf * AF, int n, boolean filled, int border);
     extern void gvrender_box(GVJ_t * job, boxf BF, boolean filled);
     extern void gvrender_beziercurve(GVJ_t * job, pointf * AF, int n,
                        int arrow_at_start, int arrow_at_end, boolean filled);
index d585fa0b5aef543449d48866803f1c24f69e6fb0..7272480d0065912afbfc562192691a867f2d4e4a 100644 (file)
@@ -48,6 +48,7 @@ extern int strcasecmp(const char *s1, const char *s2);
 /* storage for temporary hacks until client API is FP */
 static pointf *AF;
 static int sizeAF;
+#define PARAM_OFFSET 1000
 /* end hack */
 
 int gvrender_select(GVJ_t * job, const char *str)
@@ -567,6 +568,30 @@ void gvrender_polygon(GVJ_t * job, pointf * af, int n, boolean filled)
     }
 }
 
+void gvrender_rounded_box(GVJ_t * job, pointf * af, int n, boolean filled, int border)
+{
+    gvrender_engine_t *gvre = job->render.engine;
+    int n_border;
+    
+    //encode the border size within the point count parameter
+    //it has to be passed through polygon() to cairogen_rounded_rectangle()
+    n_border = border * PARAM_OFFSET + n;
+    if (gvre) {
+       if (gvre->polygon && job->obj->pen != PEN_NONE) {
+           if (job->flags & GVRENDER_DOES_TRANSFORM)
+               gvre->polygon(job, af, n_border, filled);
+           else {
+               if (sizeAF < n) {
+                   sizeAF = n+10;
+                   AF = grealloc(AF, sizeAF * sizeof(pointf));
+               }
+               gvrender_ptf_A(job, af, AF, n);
+               gvre->polygon(job, AF, n_border, filled);
+           }
+       }
+    }
+}
+
 void gvrender_box(GVJ_t * job, boxf B, boolean filled)
 {
     pointf A[4];
index c3630d5711bd73fad19e914acafb8a8b747366bd..482aef2b1c7a97b9f923afae9cc3c4a0e1e8bf3c 100644 (file)
@@ -40,7 +40,8 @@ typedef enum {
     } format_type;
 
 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
-
+#define RBCONST 12
+#define PARAM_OFFSET 1000
 static double dashed[] = {6.};
 static int dashed_len = ARRAY_SIZE(dashed);
 
@@ -286,10 +287,75 @@ if (ry < RMIN) ry = RMIN;
     cairo_stroke(cr);
 }
 
+//create a rounded path and implement border width by setting line width
 static void
-cairogen_polygon(GVJ_t * job, pointf * A, int n, int filled)
+cairogen_rounded_rectangle(GVJ_t * job, pointf * AF, int n, int filled, int border)
 {
     obj_state_t *obj = job->obj;
+    cairo_t *cr = (cairo_t *) job->context;
+    pointf p0, p1;
+    double d, dx, dy, radius;
+    double x,y,height,width;
+    int seg, sides;
+    double degrees = -(M_PI / 180.0); //sign inversion required due to y-coordinate inversion
+
+    radius = RBCONST;
+    sides = n;
+    for (seg = 0; seg < sides; seg++) {
+       p0 = AF[seg];
+       if (seg < sides - 1)
+           p1 = AF[seg + 1];
+       else
+           p1 = AF[0];
+       dx = p1.x - p0.x;
+       dy = p1.y - p0.y;
+       d = sqrt(dx * dx + dy * dy);
+       radius = MIN(radius, d / 3.0);
+    }
+
+
+    x = AF[0].x + border/2;
+    y = -AF[0].y - border/2;
+    width = AF[2].x - AF[0].x - border;
+    height = AF[2].y - AF[0].y - border;
+    
+    cairogen_set_penstyle(job, cr);
+    cairogen_set_color(cr, &(obj->pencolor));
+
+    cairo_new_sub_path (cr);
+    cairo_arc (cr, x + width - radius, y - radius, radius,0 * degrees, -90 * degrees); //lower right
+    cairo_arc (cr, x + radius, y - radius, radius, -90 * degrees, 180 * degrees); //lower left
+    cairo_arc (cr, x + radius, y - height + radius, radius, 180 * degrees, 90 * degrees); //upper left
+    cairo_arc (cr, x + width - radius, y - height + radius, radius, 90 * degrees, 0 * degrees); //upper right
+    cairo_close_path (cr);
+
+
+     if (filled) {
+       cairogen_set_color(cr, &(obj->fillcolor));
+       cairo_fill_preserve(cr);
+    }
+
+    cairogen_set_color(cr, &(obj->pencolor));
+    cairo_set_line_width (cr, border);
+    cairo_stroke(cr);
+
+  
+}
+
+static void
+cairogen_polygon(GVJ_t * job, pointf * A, int n, int filled)
+{
+//if a rounded rectangle is being rendered, extract the border
+//value that is encoded in the point count parameter
+if( n > PARAM_OFFSET){
+    int border = n/PARAM_OFFSET;
+    n = n%PARAM_OFFSET;
+    cairogen_rounded_rectangle(job, A, n, filled, border);
+    return;
+  }
+
+obj_state_t *obj = job->obj;
     cairo_t *cr = (cairo_t *) job->context;
     int i;