示例#1
0
/* emit_html_label:
 */
void
emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp)
{
    htmlenv_t env;

    allocObj (job);
    env.pos = tp->pos;
    env.finfo.color = tp->fontcolor;
    env.finfo.name = tp->fontname;
    env.finfo.size = tp->fontsize;
    env.finfo.size = tp->fontsize;
    env.imgscale = agget (job->obj->u.n, "imagescale");
    env.objid = job->obj->id;
    env.objid_set = 0;
    if ((env.imgscale == NULL) || (env.imgscale[0] == '\0'))
	env.imgscale = "false";
    if (lp->kind == HTML_TBL) {
	htmltbl_t *tbl = lp->u.tbl;

	/* set basic graphics context */
	/* Need to override line style set by node. */
	gvrender_set_style(job, job->gvc->defaultlinestyle);
	if (tbl->data.pencolor)
	    gvrender_set_pencolor(job, tbl->data.pencolor);
	else
	    gvrender_set_pencolor(job, DEFAULT_COLOR);
	emit_html_tbl(job, tbl, &env);
    } else {
	emit_html_txt(job, lp->u.txt, &env);
    }
    if (env.objid_set)
	free (env.objid);
    freeObj (job);
}
示例#2
0
/* emit_html_label:
 */
void
emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp)
{
    htmlenv_t env;

    env.p = tp->p;
    env.finfo.color = tp->fontcolor;
    env.finfo.name = tp->fontname;
    env.finfo.size = tp->fontsize;
    if (lp->kind == HTML_TBL) {
	htmltbl_t *tbl = lp->u.tbl;

	/* set basic graphics context */
	gvrender_begin_context(job);
	/* Need to override line style set by node. */
	gvrender_set_style(job, job->gvc->defaultlinestyle);
	if (tbl->data.pencolor)
	    gvrender_set_pencolor(job, tbl->data.pencolor);
	else
	    gvrender_set_pencolor(job, DEFAULT_COLOR);
	emit_html_tbl(job, tbl, &env);
	gvrender_end_context(job);
    } else {
	emit_html_txt(job, lp->u.txt, &env);
    }
}
示例#3
0
文件: labels.c 项目: ellert/graphviz
void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t * lp)
{
    obj_state_t *obj = job->obj;
    int i;
    pointf p;
    emit_state_t old_emit_state;

    old_emit_state = obj->emit_state;
    obj->emit_state = emit_state;

    if (lp->html) {
	emit_html_label(job, lp->u.html, lp);
	obj->emit_state = old_emit_state;
	return;
    }

    /* make sure that there is something to do */
    if (lp->u.txt.nspans < 1)
	return;

    gvrender_begin_label(job, LABEL_PLAIN);
    gvrender_set_pencolor(job, lp->fontcolor);

    /* position for first span */
    switch (lp->valign) {
	case 't':
    	    p.y = lp->pos.y + lp->space.y / 2.0 - lp->fontsize;
	    break;
	case 'b':
    	    p.y = lp->pos.y - lp->space.y / 2.0 + lp->dimen.y - lp->fontsize;
	    break;
	case 'c':
	default:	
    	    p.y = lp->pos.y + lp->dimen.y / 2.0 - lp->fontsize;
	    break;
    }
    if (obj->labeledgealigned)
	p.y -= lp->pos.y;
    for (i = 0; i < lp->u.txt.nspans; i++) {
	switch (lp->u.txt.span[i].just) {
	case 'l':
	    p.x = lp->pos.x - lp->space.x / 2.0;
	    break;
	case 'r':
	    p.x = lp->pos.x + lp->space.x / 2.0;
	    break;
	default:
	case 'n':
	    p.x = lp->pos.x;
	    break;
	}
	gvrender_textspan(job, p, &(lp->u.txt.span[i]));

	/* UL position for next span */
	p.y -= lp->u.txt.span[i].size.y;
    }

    gvrender_end_label(job);
    obj->emit_state = old_emit_state;
}
示例#4
0
/* 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);
}
示例#5
0
/* 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);
    }
}
示例#6
0
static void doFill(GVJ_t * job, char *color, box B)
{
    boxf BF;

    gvrender_set_fillcolor(job, color);
    gvrender_set_pencolor(job, color);
    B2BF(B, BF);
    gvrender_box(job, BF, 1);
}
示例#7
0
void 
emit_textlines(GVJ_t* job, int nlines, textline_t lines[], pointf p,
              double halfwidth_x, char* fname, double fsize, char* fcolor)
{
    int i, linespacing;
    double tmp, center_x, left_x, right_x;

    center_x = p.x;
    left_x = center_x - halfwidth_x;
    right_x = center_x + halfwidth_x;

    /* set linespacing to an exact no. of pixelrows */
    linespacing = (int) (fsize * LINESPACING);

    /* position for first line */
    p.y += (linespacing * (nlines - 1) / 2)	/* cl of topline */
	-fsize / 3.0;	/* cl to baseline */

    tmp = ROUND(p.y);  /* align with interger points */
    p.y = (double)tmp;

    gvrender_begin_context(job);
    gvrender_set_pencolor(job, fcolor);
    gvrender_set_font(job, fname, fsize);

    for (i = 0; i < nlines; i++) {
	switch (lines[i].just) {
	case 'l':
	    p.x = left_x;
	    break;
	case 'r':
	    p.x = right_x;
	    break;
	default:
	case 'n':
	    p.x = center_x;
	    break;
	}
	gvrender_textline(job, p, &(lines[i]));

	/* position for next line */
	p.y -= linespacing;
    }

    gvrender_end_context(job);
}
示例#8
0
/* setFill:
 * Set up fill values from given color; make pen transparent.
 * Return type of fill required.
 */
static int
setFill (GVJ_t* job, char* color, int angle, int style, char* clrs[2])
{
    int filled;
    if (findStopColor (color, clrs)) {
	gvrender_set_fillcolor(job, clrs[0]);
	if (clrs[1]) 
	    gvrender_set_gradient_vals(job,clrs[1],angle);
	else 
	    gvrender_set_gradient_vals(job,DEFAULT_COLOR,angle);
	if (style & RADIAL)
	    filled = RGRADIENT;
	else
	    filled = GRADIENT;
    }
    else {
	gvrender_set_fillcolor(job, color);
	filled = FILL;
    }
    gvrender_set_pencolor(job, "transparent");
    return filled;
}
示例#9
0
static void 
emit_htextparas(GVJ_t* job, int nparas, htextpara_t* paras, pointf p,
         double halfwidth_x, char* fname, double fsize, char* fcolor, box b)
{
    int i,j;
    double tmp, center_x, left_x, right_x, fsize_;
    double offset;
    char *fname_ , *fcolor_;
    textpara_t tl;
    pointf p_ = {0.0, 0.0};
    textitem_t* ti;
	
    center_x = p.x;
    left_x = center_x - halfwidth_x;
    right_x = center_x + halfwidth_x;

	/* Initial p is in center of text block; set initial baseline
 	 * to top of text block.
	 */
    p_.y = p.y + (double)(b.UR.y-b.LL.y)/2.0;
    tmp = ROUND(p_.y);  /* align with integer points */
    p_.y = (double)tmp;

    gvrender_begin_context(job);
    for(i=0; i<nparas; i++) {
	switch (paras[i].just) {
	case 'l':
	    p_.x = left_x;
	    p.x = left_x;
	    break;
	case 'r':
	    p_.x = right_x;
	    p.x = right_x;		
	    break;
	default:
	case 'n':
	    p_.x = center_x;
	    p.x = center_x;
	    break;
	}
	p_.y -= paras[i].lfsize;  /* move to current base line */

	ti = paras[i].items;
	offset = 0.0;
	for(j=0; j<paras[i].nitems; j++) {
	    if (ti->font && (ti->font->size > 0))
		fsize_ = ti->font->size;
	    else
	        fsize_ = fsize;
	    if (ti->font && ti->font->name)
		fname_ = ti->font->name;
	    else
	        fname_ = fname;
	    if (ti->font && ti->font->color)
		fcolor_ = ti->font->color;
	    else
	        fcolor_ = fcolor;

    	    gvrender_set_pencolor(job, fcolor_);
   	    gvrender_set_font(job, fname_, fsize_);

	    tl.str = ti->str;
	    tl.fontname = fname_;
	    tl.fontsize = fsize_;
	    tl.xshow = ti->xshow;
	    tl.postscript_alias = ti->postscript_alias;
	    tl.layout = ti->layout;
	    tl.width = paras[i].size;
	    tl.height = paras[i].lfsize;
	    tl.just = paras[i].just;

	    gvrender_textpara(job, p_, &tl);
	    offset += ti->size;
	    p_.x = p.x + offset;
            ti++;
	}
    }

    gvrender_end_context(job);
}
示例#10
0
static void
emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env)
{
    boxf pts = tbl->data.box;
    pointf pos = env->pos;
    htmlcell_t **cells = tbl->u.n.cells;
    htmlcell_t *cp;
    static htmlfont_t savef;
    htmlmap_data_t saved;
    int anchor; /* if true, we need to undo anchor settings. */
    int doAnchor = (tbl->data.href || tbl->data.target);
    pointf AF[4];

    if (tbl->font)
	pushFontInfo(env, tbl->font, &savef);

    pts.LL.x += pos.x;
    pts.UR.x += pos.x;
    pts.LL.y += pos.y;
    pts.UR.y += pos.y;

    if (doAnchor && !(job->flags & EMIT_CLUSTERS_LAST))
	anchor = initAnchor(job, env, &tbl->data, pts, &saved, 1);
    else
	anchor = 0;
    /* Set up rounded style */
    if (tbl->data.style & ROUNDED) {
	AF[0] = pts.LL;
	AF[2] = pts.UR;
	if (tbl->data.border) {
	    double delta = ((double)tbl->data.border)/2.0;
	    AF[0].x += delta;
	    AF[0].y += delta;
	    AF[2].x -= delta;
	    AF[2].y -= delta;
	}
	AF[1].x = AF[2].x;
	AF[1].y = AF[0].y;
	AF[3].x = AF[0].x;
	AF[3].y = AF[2].y;
    }

    /* Fill first */
    if (tbl->data.bgcolor) {
	char* clrs[2];
	int filled = setFill (job, tbl->data.bgcolor, tbl->data.gradientangle, tbl->data.style, clrs);
	if (tbl->data.style & ROUNDED){
	    round_corners (job, AF, 4, tbl->data.style, filled);
	}
	else
	    gvrender_box(job, pts, filled);
	free (clrs[0]);
    }
     
    while (*cells) {
	emit_html_cell(job, *cells, env);
	cells++;
    }

    /* Draw table rules and border.
     * Draw after cells so we can draw over any fill.
     * At present, we set the penwidth to 1 for rules until we provide the calculations to take
     * into account wider rules.
     */
    cells = tbl->u.n.cells;
    gvrender_set_penwidth(job, 1.0);
    while ((cp = *cells++)){
	if (cp->ruled) emit_html_rules(job, cp, env, tbl->data.pencolor);
    }

    if (tbl->data.border) {
	if (tbl->data.style & ROUNDED) {
	    char* color = (tbl->data.pencolor ? tbl->data.pencolor : DEFAULT_COLOR);
	    gvrender_set_penwidth(job, tbl->data.border);
	    gvrender_set_pencolor(job, color);
	    round_corners (job, AF, 4, tbl->data.style, 0);
	}
	else
	    doBorder(job, tbl->data.pencolor, tbl->data.border, pts);
    }

    if (anchor)
	endAnchor (job, &saved, 1);

    if (doAnchor && (job->flags & EMIT_CLUSTERS_LAST)) {
	if (initAnchor(job, env, &tbl->data, pts, &saved, 0))
	    endAnchor (job, &saved, 0);
    }

    if (tbl->font)
	popFontInfo(env, &savef);
}
示例#11
0
/* 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);
    }
}
示例#12
0
static void 
emit_htextparas(GVJ_t* job, int nparas, htextpara_t* paras, pointf p,
         double halfwidth_x, htmlfont_t finfo, boxf b)
{
    int i,j;
    double center_x, left_x, right_x, fsize_;
    char *fname_ , *fcolor_;
    textpara_t tl;
    pointf p_ = {0.0, 0.0};
    textpara_t* ti;
	
    center_x = p.x;
    left_x = center_x - halfwidth_x;
    right_x = center_x + halfwidth_x;

	/* Initial p is in center of text block; set initial baseline
 	 * to top of text block.
	 */
    p_.y = p.y + (b.UR.y-b.LL.y)/2.0;

    gvrender_begin_label(job, LABEL_HTML);
    for(i=0; i<nparas; i++) {
	/* set p.x to leftmost point where the line of text begins */
	switch (paras[i].just) {
	case 'l':
	    p.x = left_x;
	    break;
	case 'r':
	    p.x = right_x - paras[i].size;
	    break;
	default:
	case 'n':
	    p.x = center_x - paras[i].size/2.0;
	    break;
	}
	p_.y -= paras[i].lfsize;  /* move to current base line */

	ti = paras[i].items;
	for(j=0; j<paras[i].nitems; j++) {
	    if (ti->font && (ti->font->size > 0))
		fsize_ = ti->font->size;
	    else
	        fsize_ = finfo.size;
	    if (ti->font && ti->font->name)
		fname_ = ti->font->name;
	    else
	        fname_ = finfo.name;
	    if (ti->font && ti->font->color)
		fcolor_ = ti->font->color;
	    else
	        fcolor_ = finfo.color;

    	    gvrender_set_pencolor(job, fcolor_);

	    tl.str = ti->str;
	    tl.fontname = fname_;
	    tl.fontsize = fsize_;
	    tl.font = ti->font;
	    tl.yoffset_layout = ti->yoffset_layout;
	    /* tl.yoffset_centerline = ti->yoffset_centerline; */
	    tl.yoffset_centerline = 1;
	    tl.postscript_alias = ti->postscript_alias;
	    tl.layout = ti->layout;
	    tl.width = ti->size;
	    tl.height = paras[i].lfsize;
	    tl.just = 'l';

	    p_.x = p.x;
	    gvrender_textpara(job, p_, &tl);
	    p.x += ti->size;
            ti++;
	}
    }

    gvrender_end_label(job);
}