/* doBorder: * Draw rectangle of width border inside rectangle given * by box. If border is 1, we call use a single call to gvrender_polygon. * (We have set linewidth to 1 below.) Otherwise, we use four separate * filled rectangles. We could use a richer graphics model, as things * can go wrong when cell spacing and borders are small. * We decrement the border value by 1, as typically a filled rectangle * from x to x+border will all pixels from x to x+border, and thus have * width border+1. */ static void doBorder(GVJ_t * job, char *color, int border, box B) { pointf pt; boxf BF; double wd, ht; gvrender_begin_context(job); if (!color) color = "black"; gvrender_set_fillcolor(job, color); gvrender_set_pencolor(job, color); B2BF(B, BF); if (border == 1) { gvrender_box(job, BF, 0); } else { border--; ht = BF.UR.y - BF.LL.y; wd = BF.UR.x - BF.LL.x; doSide(job, BF.LL, border, ht); pt.x = BF.LL.x; pt.y = BF.UR.y; doSide(job, pt, wd, -border); doSide(job, BF.UR, -border, -ht); pt.x = BF.UR.x; pt.y = BF.LL.y; doSide(job, pt, -wd, border); } gvrender_end_context(job); }
/* doBorder: * Draw rectangle of width border inside rectangle given * by box. If border is 1, we call use a single call to gvrender_polygon. * (We have set linewidth to 1 below.) Otherwise, we use four separate * filled rectangles. We could use a richer graphics model, as things * can go wrong when cell spacing and borders are small. * We decrement the border value by 1, as typically a filled rectangle * from x to x+border will all pixels from x to x+border, and thus have * width border+1. */ static void doBorder(GVJ_t * job, char *color, int border, boxf BF) { pointf pt; double wd, ht; if (!color) color = DEFAULT_COLOR; gvrender_set_fillcolor(job, color); gvrender_set_pencolor(job, color); if (border == 1) { gvrender_box(job, BF, 0); } else { border--; ht = BF.UR.y - BF.LL.y; wd = BF.UR.x - BF.LL.x; doSide(job, BF.LL, border, ht); pt.x = BF.LL.x; pt.y = BF.UR.y; doSide(job, pt, wd, -border); doSide(job, BF.UR, -border, -ht); pt.x = BF.UR.x; pt.y = BF.LL.y; doSide(job, pt, -wd, border); } }
/* emit_html_rules: * place vertical and horizontal lines between adjacent cells and * extend the lines to intersect the rounded table boundary */ static void emit_html_rules(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, char *color) { pointf rule_pt; double rule_length; unsigned char base; boxf pts = cp->data.box; pointf pos = env->pos; if (!color) color = DEFAULT_COLOR; gvrender_set_fillcolor(job, color); gvrender_set_pencolor(job, color); pts = cp->data.box; pts.LL.x += pos.x; pts.UR.x += pos.x; pts.LL.y += pos.y; pts.UR.y += pos.y; //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 center of table border and add half cell spacing base = cp->parent->data.border + 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 center of table border and add half cell spacing base = cp->parent->data.border + cp->parent->data.space/2; rule_pt.y = pts.LL.y - cp->parent->data.space/2 - base; } else { base = 0; rule_pt.y = pts.LL.y - cp->parent->data.space/2; } rule_pt.x = pts.UR.x + cp->parent->data.space/2; rule_length = base + pts.UR.y - pts.LL.y + cp->parent->data.space; doSide(job,rule_pt,0,rule_length); } //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 center of 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; if(cp->col + cp->cspan == cp->parent->cc) // also last column base *= 2; } else if(cp->col + cp->cspan == cp->parent->cc){ // last column // extend to center of table border and add half cell spacing base = cp->parent->data.border + cp->parent->data.space/2; rule_pt.x = pts.LL.x - cp->parent->data.space/2; } else { base = 0; rule_pt.x = pts.LL.x - cp->parent->data.space/2; } rule_pt.y = pts.LL.y - cp->parent->data.space/2; rule_length = base + pts.UR.x - pts.LL.x + cp->parent->data.space; doSide(job,rule_pt,rule_length,0); } }