]> granicus.if.org Git - graphviz/commitdiff
Allow cells and tables to specify which borders should be drawn in
authorEmden R. Gansner <erg@alum.mit.edu>
Sun, 9 Feb 2014 01:05:55 +0000 (20:05 -0500)
committerEmden R. Gansner <erg@alum.mit.edu>
Sun, 9 Feb 2014 01:05:55 +0000 (20:05 -0500)
the non-curved case.

doc/info/shapes.html
doc/infosrc/html.2
lib/common/htmllex.c
lib/common/htmltable.c
lib/common/htmltable.h

index fb78c4ef3a186f76d47ee1f6cce9e22d5bd7419f..3e7d26853a431929d6d34fc940fd4a4be6c2e021 100644 (file)
@@ -652,6 +652,7 @@ Attribute values must appear in double quotes.
   ID="<I>value</I>"
   PORT="<I>portName</I>"
   ROWS="<I>value</I>"
+  SIDES="<I>value</I>"
   STYLE="<I>value</I>"
   TARGET="<I>value</I>"
   TITLE="<I>value</I>"
@@ -684,6 +685,7 @@ Attribute values must appear in double quotes.
   ID="<I>value</I>"
   PORT="<I>portName</I>"
   ROWSPAN="<I>value</I>"
+  SIDES="<I>value</I>"
   STYLE="<I>value</I>"
   TARGET="<I>value</I>"
   TITLE="<I>value</I>"
@@ -986,6 +988,17 @@ and <B><I>VALIGN</I></B> attributes override
 an image's <B><I>SCALE</I></B> attribute.
 </BLOCKQUOTE>
 
+<B><I><FONT SIZE=-1>SIDES="value"</FONT></I></B>
+<BLOCKQUOTE>
+specifies which sides of a border in a cell or table should be drawn, if
+a border is drawn. By default, all sides are drawn. The <TT>"value"</TT>
+string can contain any collection of the (case-insensitive) 
+characters <TT>'L'</TT>, <TT>'T'</TT>, <TT>'R'</TT>, or <TT>'B'</TT>,
+corresponding to the left, top, right and, bottom sides of the border,
+respectively. For example, <TT>SIDES="LB"</TT> would indicate only the
+left and bottom segments of the  border should be drawn.
+</BLOCKQUOTE>
+
 <B><I><FONT SIZE=-1>SRC="value"</FONT></I></B>
 <BLOCKQUOTE>
 specifies the image file to be displayed in the cell.
index 307a83f23413f779d517e503e64abb28beeaa3aa..49bac1b15a061675a325ac4ddccc858b2ec69528 100644 (file)
@@ -40,6 +40,7 @@ Attribute values must appear in double quotes.
   ID="<I>value</I>"
   PORT="<I>portName</I>"
   ROWS="<I>value</I>"
+  SIDES="<I>value</I>"
   STYLE="<I>value</I>"
   TARGET="<I>value</I>"
   TITLE="<I>value</I>"
@@ -72,6 +73,7 @@ Attribute values must appear in double quotes.
   ID="<I>value</I>"
   PORT="<I>portName</I>"
   ROWSPAN="<I>value</I>"
+  SIDES="<I>value</I>"
   STYLE="<I>value</I>"
   TARGET="<I>value</I>"
   TITLE="<I>value</I>"
@@ -374,6 +376,17 @@ and <B><I>VALIGN</I></B> attributes override
 an image's <B><I>SCALE</I></B> attribute.
 </BLOCKQUOTE>
 
+<B><I><FONT SIZE=-1>SIDES="value"</FONT></I></B>
+<BLOCKQUOTE>
+specifies which sides of a border in a cell or table should be drawn, if
+a border is drawn. By default, all sides are drawn. The <TT>"value"</TT>
+string can contain any collection of the (case-insensitive) 
+characters <TT>'L'</TT>, <TT>'T'</TT>, <TT>'R'</TT>, or <TT>'B'</TT>,
+corresponding to the left, top, right and, bottom sides of the border,
+respectively. For example, <TT>SIDES="LB"</TT> would indicate only the
+left and bottom segments of the  border should be drawn.
+</BLOCKQUOTE>
+
 <B><I><FONT SIZE=-1>SRC="value"</FONT></I></B>
 <BLOCKQUOTE>
 specifies the image file to be displayed in the cell.
index 7470f6592c27aad11c7274e4ca50a6951d4dea82..067efa6c156faed74eddc1290819405e1f7a084a 100644 (file)
@@ -124,6 +124,35 @@ static int hreffn(htmldata_t * p, char *v)
     return 0;
 }
 
+static int sidesfn(htmldata_t * p, char *v)
+{
+    unsigned short flags = 0; 
+    char c;
+
+    while ((c = *v++)) {
+       switch (tolower(c)) {
+       case 'l' :
+           flags |= BORDER_LEFT;
+           break;
+       case 't' :
+           flags |= BORDER_TOP;
+           break;
+       case 'r' :
+           flags |= BORDER_RIGHT;
+           break;
+       case 'b' :
+           flags |= BORDER_BOTTOM;
+           break;
+       default :
+           agerr(AGWARN, "Unrecognized character '%c' (%d) in sides attribute\n", c, c);
+           break;
+       }
+    }
+    if (flags != BORDER_MASK)
+       p->flags |= flags;
+    return 0;
+}
+
 static int titlefn(htmldata_t * p, char *v)
 {
     p->title = strdup(v);
@@ -472,6 +501,7 @@ static attr_item tbl_items[] = {
     {"id", (attrFn) idfn},
     {"port", (attrFn) portfn},
     {"rows", (attrFn) rowsfn},
+    {"sides", (attrFn) sidesfn},
     {"style", (attrFn) stylefn},
     {"target", (attrFn) targetfn},
     {"title", (attrFn) titlefn},
@@ -496,6 +526,7 @@ static attr_item cell_items[] = {
     {"id", (attrFn) idfn},
     {"port", (attrFn) portfn},
     {"rowspan", (attrFn) rowspanfn},
+    {"sides", (attrFn) sidesfn},
     {"style", (attrFn) stylefn},
     {"target", (attrFn) targetfn},
     {"title", (attrFn) titlefn},
index 8f19b9c754b950361881be43218afee025d2a02e..88e044c2a869bbcd0e86f1858afc63b428edec57 100644 (file)
@@ -243,9 +243,10 @@ static pointf *mkPts(pointf * AF, boxf b, int border)
  */
 static void doBorder(GVJ_t * job, htmldata_t * dp, boxf b)
 {
-    pointf AF[4];
+    pointf AF[6];
     char *sptr[2];
     char *color = (dp->pencolor ? dp->pencolor : DEFAULT_COLOR);
+    unsigned short sides;
 
     gvrender_set_pencolor(job, color);
     if ((dp->style & (DASHED | DOTTED))) {
@@ -261,7 +262,61 @@ static void doBorder(GVJ_t * job, htmldata_t * dp, boxf b)
 
     if (dp->style & ROUNDED)
        round_corners(job, mkPts(AF, b, dp->border), 4, ROUNDED, 0);
-    else {
+    else if ((sides = (dp->flags & BORDER_MASK))) {
+       mkPts (AF+1, b, dp->border);  /* AF[1-4] has LL=SW,SW,UR=NE,NW */
+       switch (sides) {
+       case BORDER_BOTTOM :
+           gvrender_polyline(job, AF+1, 2);
+           break;
+       case BORDER_RIGHT :
+           gvrender_polyline(job, AF+2, 2);
+           break;
+       case BORDER_TOP :
+           gvrender_polyline(job, AF+3, 2);
+           break;
+       case BORDER_LEFT :
+           AF[0] = AF[4];
+           gvrender_polyline(job, AF, 2);
+           break;
+       case BORDER_BOTTOM|BORDER_RIGHT :
+           gvrender_polyline(job, AF+1, 3);
+           break;
+       case BORDER_RIGHT|BORDER_TOP :
+           gvrender_polyline(job, AF+2, 3);
+           break;
+       case BORDER_TOP|BORDER_LEFT :
+           AF[5] = AF[1];
+           gvrender_polyline(job, AF+3, 3);
+           break;
+       case BORDER_LEFT|BORDER_BOTTOM :
+           AF[0] = AF[4];
+           gvrender_polyline(job, AF, 3);
+           break;
+       case BORDER_BOTTOM|BORDER_RIGHT|BORDER_TOP :
+           gvrender_polyline(job, AF+1, 4);
+           break;
+       case BORDER_RIGHT|BORDER_TOP|BORDER_LEFT :
+           AF[5] = AF[1];
+           gvrender_polyline(job, AF+2, 4);
+           break;
+       case BORDER_TOP|BORDER_LEFT|BORDER_BOTTOM :
+           AF[5] = AF[1];
+           AF[6] = AF[2];
+           gvrender_polyline(job, AF+3, 4);
+           break;
+       case BORDER_LEFT|BORDER_BOTTOM|BORDER_RIGHT :
+           AF[0] = AF[4];
+           gvrender_polyline(job, AF, 4);
+           break;
+       case BORDER_TOP|BORDER_BOTTOM :
+           gvrender_polyline(job, AF+1, 2);
+           gvrender_polyline(job, AF+3, 2);
+           break;
+       case BORDER_LEFT|BORDER_RIGHT :
+           AF[0] = AF[4];
+           break;
+       }
+    } else {
        if (dp->border > 1) {
            double delta = ((double) dp->border) / 2.0;
            b.LL.x += delta;
index aaacd1d46c66a606b13fd20fddbe289ef85587ac..dec26eace209c86d5f96d3b23145089e5526a753 100644 (file)
@@ -32,6 +32,11 @@ extern "C" {
 #define BALIGN_RIGHT (1 << 8)
 #define BALIGN_LEFT (1 << 9)
 #define BALIGN_MASK (BALIGN_RIGHT | BALIGN_LEFT)
+#define BORDER_LEFT (1 << 10)
+#define BORDER_TOP (1 << 11)
+#define BORDER_RIGHT (1 << 12)
+#define BORDER_BOTTOM (1 << 13)
+#define BORDER_MASK (BORDER_LEFT|BORDER_TOP|BORDER_RIGHT|BORDER_BOTTOM)
 
 #define UNSET_ALIGN 0