56#define DEFAULT_BORDER 1
57#define DEFAULT_CELLPADDING 2
58#define DEFAULT_CELLSPACING 2
110 if (savp->
size >= 0.0)
117 double center_x, left_x, right_x;
124 left_x = center_x - halfwidth_x;
125 right_x = center_x + halfwidth_x;
130 p_.
y = p.
y + (b.
UR.
y - b.
LL.
y) / 2.0;
133 for (
size_t i = 0; i < nspans; i++) {
135 switch (spans[i].just) {
140 p.
x = right_x - spans[i].
size;
144 p.
x = center_x - spans[i].
size / 2.0;
150 for (
size_t j = 0; j < spans[i].
nitems; j++) {
227 const double delta = border / 2.0;
250 unsigned short sides;
254 sptr[0] = sptr[1] =
NULL;
407 if (obj->fld != save->fld) { \
409 obj->fld = save->fld; \
473 doSide(job, rule_pt, 0, rule_length);
484 else if (nextc && nextc->
row != cp->
row) {
497 if (nextc && nextc->
row != cp->
row) {
504 doSide(job, rule_pt, rule_length, 0);
785 for (
size_t i = 0; i < t->
nspans; i++) {
787 for (
size_t j = 0; j < tl[i].
nitems; j++) {
789 if (ti[j].
layout && ti[j].free_layout)
873 while ((cp = *cells++)) {
887 assert(pname !=
NULL && !
streq(pname,
""));
907 double mxfsize = 0.0;
908 double curbline = 0.0;
913 double maxoffset, maxlayout, mxysize = 0.0;
915 double prev_fsize = -1;
916 char *prev_fname =
NULL;
918 for (
size_t i = 0; i < ftxt->
nspans; i++) {
941 prev_fsize = tf.
size;
942 else if (tf.
size != prev_fsize) {
946 if (prev_fname ==
NULL)
947 prev_fname = tf.
name;
948 else if (strcmp(tf.
name, prev_fname)) {
955 for (
size_t i = 0; i < ftxt->
nspans; i++) {
957 mxysize = maxoffset = maxlayout = mxfsize = 0;
958 for (
size_t j = 0; j < ftxt->
spans[i].
nitems; j++) {
996 mxfsize =
MAX(tf.
size, mxfsize);
997 mxysize =
MAX(sz.
y, mxysize);
1027 ftxt->
spans[i].
lfsize = mxfsize + ysize - curbline - maxoffset;
1030 xsize =
MAX(width, xsize);
1035 ftxt->
box.
UR.
y = mxysize;
1050 if (b.
UR.
x == -1 && b.
UR.
y == -1) {
1053 agerrorf(
"No or improper image file=\"%s\"\n", img->
src);
1077 if (
parent->cellborder >= 0)
1097 sz.
x = child_sz.
x + margin;
1098 sz.
y = child_sz.
y + margin;
1104 agwarningf(
"cell size too small for content\n");
1110 agwarningf(
"fixed cell size with unspecified width or height\n");
1127 for (c = lastc; c >= col; c--) {
1136 for (j = col; j < col + cellp->
colspan; j++) {
1142 return (uint16_t)col;
1172 for (
size_t i = 0; i <
LIST_SIZE(&rp->rp); ++i) {
1180 n_cols =
MAX(c, n_cols);
1219 assert(
table->widths ==
NULL &&
"table widths computed twice");
1229 if (
cell.colspan > 1) {
1232 assert(
cell.col <
table->column_count &&
"out of range cell");
1242 if (
cell.colspan == 1) {
1247 double span_width = 0;
1249 "cell spans wider than containing table");
1250 for (
size_t j = 0; j <
cell.colspan; ++j) {
1251 span_width +=
table->widths[
cell.col + j];
1255 const double spacing = (
cell.colspan - 1) *
table->data.space;
1256 if (span_width + spacing <
cell.data.box.UR.x) {
1257 const double widen_by =
1258 (
cell.data.box.UR.x - spacing - span_width) /
cell.colspan;
1259 for (
size_t j = 0; j <
cell.colspan; ++j) {
1260 table->widths[
cell.col + j] += widen_by;
1270 double min_width = 0;
1272 "cell spans wider than containing table");
1273 for (
size_t j = 0; j <
cell->colspan; ++j) {
1274 min_width +=
table->widths[
cell->col + j];
1278 const double spacing = (
cell->colspan - 1) *
table->data.space;
1279 cell->data.box.UR.x = fmax(
cell->data.box.UR.x, min_width + spacing);
1290 assert(
table->heights ==
NULL &&
"table heights computed twice");
1295 if (
cell.rowspan > 1) {
1298 assert(
cell.row <
table->row_count &&
"out of range cell");
1305 if (
cell.rowspan == 1) {
1309 double span_height = 0;
1311 "cell spans higher than containing table");
1312 for (
size_t j = 0; j <
cell.rowspan; ++j) {
1313 span_height +=
table->heights[
cell.row + j];
1316 const double spacing = (
cell.rowspan - 1) *
table->data.space;
1317 if (span_height + spacing <
cell.data.box.UR.y) {
1318 const double heighten_by =
1319 (
cell.data.box.UR.y - spacing - span_height) /
cell.rowspan;
1320 for (
size_t j = 0; j <
cell.rowspan; ++j) {
1321 table->heights[
cell.row + j] += heighten_by;
1329 double min_height = 0;
1331 "cell spans higher than containing table");
1332 for (
size_t j = 0; j <
cell->rowspan; ++j) {
1333 min_height +=
table->heights[
cell->row + j];
1336 const double spacing = (
cell->rowspan - 1) *
table->data.space;
1337 cell->data.box.UR.y = fmax(
cell->data.box.UR.y, min_height + spacing);
1351 for (
size_t i = 0; i < ftxt->
nspans; i++) {
1368 delx = pos.
UR.
x - pos.
LL.
x - oldsz.
x;
1372 pos.
UR.
x = pos.
LL.
x + oldsz.
x;
1379 pos.
LL.
x += delx / 2;
1380 pos.
UR.
x -= delx / 2;
1384 dely = pos.
UR.
y - pos.
LL.
y - oldsz.
y;
1388 pos.
UR.
y = pos.
LL.
y + oldsz.
y;
1395 pos.
LL.
y += dely / 2;
1396 pos.
UR.
y -= dely / 2;
1415 delx = cbox.
UR.
x - cbox.
LL.
x - oldsz.
x;
1429 dely = cbox.
UR.
y - cbox.
LL.
y - oldsz.
y;
1448 delx = cbox.
UR.
x - cbox.
LL.
x - oldsz.
x;
1461 cbox.
LL.
x += delx / 2;
1462 cbox.
UR.
x -= delx / 2;
1467 dely = cbox.
UR.
y - cbox.
LL.
y - oldsz.
y;
1477 cbox.
LL.
y += dely / 2;
1478 cbox.
UR.
y -= dely / 2;
1516 double delx = fmax(pos.
UR.
x - pos.
LL.
x - oldsz, 0);
1518 double dely = fmax(pos.
UR.
y - pos.
LL.
y - oldsz, 0);
1525 pos.
UR.
x = pos.
LL.
x + oldsz;
1532 pos.
LL.
x += delx / 2;
1533 pos.
UR.
x -= delx / 2;
1541 pos.
UR.
y = pos.
LL.
y + oldsz;
1545 pos.
UR.
y = pos.
LL.
y + oldsz;
1548 pos.
LL.
y += dely / 2;
1549 pos.
UR.
y -= dely / 2;
1562 delx = tbl->
widths[i] + extra + ((i <= INT_MAX && (int)i < plus) ? 1 : 0);
1570 for (
size_t i = 0; i <= tbl->
row_count; i++) {
1571 dely = tbl->
heights[i] + extra + ((i <= INT_MAX && (int)i < plus) ? 1 : 0);
1576 while ((cp = *cells++)) {
1577 unsigned char mask = 0;
1631 for (
size_t i = 0; i < tbl->
row_count; i++)
1637 agwarningf(
"table size too small for content\n");
1643 agwarningf(
"fixed table size with unspecified width or height\n");
1680 fprintf(stderr,
" ");
1683void printBox(
boxf b) {
1684 fprintf(stderr,
"(%f,%f)(%f,%f)", b.
LL.
x, b.
LL.
y, b.
UR.
x, b.
UR.
y);
1687void printImage(
htmlimg_t *ip,
int ind) {
1689 fprintf(stderr,
"img: %s\n", ip->
src);
1695 for (
size_t i = 0; i < txt->
nspans; i++) {
1699 for (
size_t j = 0; j < txt->
spans[i].
nitems; j++) {
1701 fprintf(stderr,
"[%" PRISIZE_T "] (%f,%f) \"%s\" ", j,
1705 fprintf(stderr,
"font %s color %s size %f\n",
1710 fprintf(stderr,
"\n");
1733 fprintf(stderr,
"%c", c);
1745 fprintf(stderr,
"%c ", c);
1755 fputs(
"\n", stderr);
1757 printCell(*cells++, ind + 1);
1760static void printCell(
htmlcell_t *cp,
int ind) {
1762 fprintf(stderr,
"cell %" PRIu16
" %" PRIu16
" %" PRIu16
" %" PRIu16
" ",
1765 fputs(
"\n", stderr);
1783 printTbl(lbl->
u.
tbl, 0);
1785 printTxt(lbl->
u.
txt, 0);
1792 if ((
str =
agget(obj,
"pencolor")) != 0 &&
str[0])
1794 else if ((
str =
agget(obj,
"color")) != 0 &&
str[0])
1860 boxf b = {{-wd2, -ht2}, {wd2, ht2}};
1868 boxf b = {{-wd2, -ht2}, {wd2, ht2}};
Dynamically expanding string buffers.
static void agxbfree(agxbuf *xb)
free any malloced resources
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
static void * gv_calloc(size_t nmemb, size_t size)
API for compacted arrays of booleans.
static bitarray_t bitarray_new(size_t size_bits)
create an array of the given element length
static bool bitarray_get(bitarray_t self, size_t index)
get the value of the given element
static void bitarray_set(bitarray_t *self, size_t index, bool value)
set or clear the value of the given element
static void bitarray_reset(bitarray_t *self)
free underlying resources and leave a bit array empty
char * latin1ToUTF8(char *s)
Converts string from Latin1 encoding to utf8. Also translates HTML entities.
char * htmlEntityUTF8(char *s, graph_t *g)
bool findStopColor(const char *colorlist, char *clrs[2], double *frac)
obj_state_t * push_obj_state(GVJ_t *job)
void emit_map_rect(GVJ_t *job, boxf b)
void pop_obj_state(GVJ_t *job)
char * getObjId(GVJ_t *job, void *obj, agxbuf *xb)
Use id of root graph if any, plus kind and internal id of object.
bool initMapData(GVJ_t *job, char *lbl, char *url, char *tooltip, char *target, char *id, void *gobj)
static WUR pointf scale(double c, pointf p)
static int cnt(Dict_t *d, Dtlink_t **set)
char * agget(void *obj, char *name)
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
int agisdirected(Agraph_t *g)
Agraph_t * agraphof(void *obj)
char * agnameof(void *)
returns a string descriptor for the object.
static void indent(int ix)
Arithmetic helper functions.
#define EMIT_CLUSTERS_LAST
static void color(Agraph_t *g)
void gvrender_end_label(GVJ_t *job)
void gvrender_usershape(GVJ_t *job, char *name, pointf *AF, size_t n, bool filled, char *imagescale, char *imagepos)
void gvrender_set_style(GVJ_t *job, char **s)
void gvrender_set_fillcolor(GVJ_t *job, char *name)
void gvrender_polyline(GVJ_t *job, pointf *AF, size_t n)
point gvusershape_size(graph_t *g, char *name)
void gvrender_box(GVJ_t *job, boxf BF, int filled)
void gvrender_set_gradient_vals(GVJ_t *job, char *stopcolor, int angle, double frac)
void gvrender_begin_anchor(GVJ_t *job, char *href, char *tooltip, char *target, char *id)
void gvrender_end_anchor(GVJ_t *job)
void gvrender_textspan(GVJ_t *job, pointf p, textspan_t *span)
void gvrender_begin_label(GVJ_t *job, label_type type)
void gvrender_set_penwidth(GVJ_t *job, double penwidth)
void gvrender_set_pencolor(GVJ_t *job, char *name)
htmllabel_t * parseHTML(char *txt, int *warn, htmlenv_t *env)
textitem scanner parser str
static void free_html_img(htmlimg_t *ip)
static void endAnchor(GVJ_t *job, htmlmap_data_t *save)
static int size_html_tbl(graph_t *g, htmltbl_t *tbl, htmlcell_t *parent, htmlenv_t *env)
static void pos_html_cell(htmlcell_t *cp, boxf pos, unsigned char sides)
static void pushFontInfo(htmlenv_t *env, textfont_t *fp, textfont_t *savp)
static void pos_html_txt(htmltxt_t *ftxt, char c)
Set default alignment.
static void set_cell_widths(htmltbl_t *table)
static char * nameOf(void *obj, agxbuf *xb)
static void allocObj(GVJ_t *job)
boxf * html_port(node_t *n, char *pname, unsigned char *sides)
static void pos_html_tbl(htmltbl_t *, boxf, unsigned char)
static double heightOfLbl(htmllabel_t *lp)
int make_html_label(void *obj, textlabel_t *lp)
Return non-zero if problem parsing HTML. In this case, use object name.
static void emit_html_img(GVJ_t *job, htmlimg_t *cp, htmlenv_t *env)
static void pos_html_img(htmlimg_t *cp, boxf pos)
#define DEFAULT_CELLSPACING
#define DEFAULT_CELLPADDING
static int size_html_cell(graph_t *g, htmlcell_t *cp, htmltbl_t *parent, htmlenv_t *env)
static void doBorder(GVJ_t *job, htmldata_t *dp, boxf b)
static void set_cell_heights(htmltbl_t *table)
static pointf * mkPts(pointf *AF, boxf b, int border)
static void freeObj(GVJ_t *job)
static int processTbl(graph_t *g, htmltbl_t *tbl, htmlenv_t *env)
static htmldata_t * portToTbl(htmltbl_t *, char *)
static void emit_html_txt(GVJ_t *job, htmltxt_t *tp, htmlenv_t *env)
static htmldata_t * portToCell(htmlcell_t *cp, char *id)
void free_html_text(htmltxt_t *t)
static void free_html_cell(htmlcell_t *cp)
static void emit_html_tbl(GVJ_t *job, htmltbl_t *tbl, htmlenv_t *env)
static void popFontInfo(htmlenv_t *env, textfont_t *savp)
static int size_html_txt(GVC_t *gvc, htmltxt_t *ftxt, htmlenv_t *env)
void free_html_label(htmllabel_t *lp, int root)
static void emit_html_cell(GVJ_t *job, htmlcell_t *cp, htmlenv_t *env)
static uint16_t findCol(PointSet *ps, int row, int col, htmlcell_t *cellp)
void emit_html_label(GVJ_t *job, htmllabel_t *lp, textlabel_t *tp)
static void emit_htextspans(GVJ_t *job, size_t nspans, htextspan_t *spans, pointf p, double halfwidth_x, textfont_t finfo, boxf b, int simple)
static int initAnchor(GVJ_t *job, htmlenv_t *env, htmldata_t *data, boxf b, htmlmap_data_t *save)
void free_html_data(htmldata_t *dp)
static int setFill(GVJ_t *job, char *color, int angle, htmlstyle_t style, char *clrs[2])
static void doSide(GVJ_t *job, pointf p, double wd, double ht)
static void emit_html_rules(GVJ_t *job, htmlcell_t *cp, htmlenv_t *env, char *color, htmlcell_t *nextc)
static void free_html_tbl(htmltbl_t *tbl)
static int size_html_img(htmlimg_t *img, htmlenv_t *env)
static char * getPenColor(void *obj)
char * strdup_and_subst_obj(char *str, void *obj)
Processes graph object escape sequences; also collapses \ to .
void make_simple_label(GVC_t *gvc, textlabel_t *lp)
static int layout(graph_t *g, layout_info *infop, size_t *counter)
#define LIST_GET(list, index)
static const int table[NTYPES][NTYPES]
void addPS(PointSet *ps, double x, double y)
void freePS(PointSet *ps)
int isInPS(PointSet *ps, double x, double y)
point containers PointSet and PointMap
static void printData(object_t *objs, size_t n_objs, xlabel_t *lbls, size_t n_lbls, label_params_t *params)
void round_corners(GVJ_t *job, pointf *AF, size_t sides, graphviz_polygon_style_t style, int filled)
Handle some special graphical cases, such as rounding the shape, adding diagonals at corners,...
pointf textspan_size(GVC_t *gvc, textspan_t *span)
Estimates size of a textspan, in points.
platform abstraction for case-insensitive string functions
static bool streq(const char *a, const char *b)
are a and b equal?
Agraph_t * root
subgraphs - ancestors
result of partitioning available space, part of maze
bool vruled
vertically ruled?
bool hruled
horizontally ruled?
size_t row_count
number of rows
double * widths
widths of the columns
double * heights
heights of the rows
size_t column_count
number of columns
unsigned explicit_tooltip
PostscriptAlias * postscript_alias
double yoffset_centerline
void(* free_layout)(void *layout)