56#define DEFAULT_BORDER 1
57#define DEFAULT_CELLPADDING 2
58#define DEFAULT_CELLSPACING 2
71static void printCell(
htmlcell_t * cp,
int ind);
113 if (savp->
size >= 0.0)
121 double center_x, left_x, right_x;
128 left_x = center_x - halfwidth_x;
129 right_x = center_x + halfwidth_x;
134 p_.
y = p.
y + (b.
UR.
y - b.
LL.
y) / 2.0;
137 for (
size_t i = 0; i < nspans; i++) {
139 switch (spans[i].just) {
144 p.
x = right_x - spans[i].
size;
148 p.
x = center_x - spans[i].
size / 2.0;
154 for (
size_t j = 0; j < spans[i].
nitems; j++) {
234 const double delta = border / 2.0;
258 unsigned short sides;
262 sptr[0] = sptr[1] =
NULL;
420 if(obj->fld != save->fld) {free(obj->fld); obj->fld = save->fld;}
485 doSide(job, rule_pt, 0, rule_length);
496 else if (nextc && nextc->
row != cp->
row) {
507 if (nextc && nextc->
row != cp->
row) {
513 doSide(job, rule_pt, rule_length, 0);
571 while ((cp = *cells++)) {
809 for (
size_t i = 0; i < t->
nspans; i++) {
811 for (
size_t j = 0; j < tl[i].
nitems; j++) {
813 if (ti[j].
layout && ti[j].free_layout)
903 while ((cp = *cells++)) {
917 assert(pname !=
NULL && !
streq(pname,
""));
939 double mxfsize = 0.0;
940 double curbline = 0.0;
945 double maxoffset, mxysize = 0.0;
947 double prev_fsize = -1;
948 char* prev_fname =
NULL;
950 for (
size_t i = 0; i < ftxt->
nspans; i++) {
974 prev_fsize = tf.
size;
975 else if (tf.
size != prev_fsize) {
979 if (prev_fname ==
NULL)
980 prev_fname = tf.
name;
981 else if (strcmp(tf.
name,prev_fname)) {
988 for (
size_t i = 0; i < ftxt->
nspans; i++) {
990 mxysize = maxoffset = mxfsize = 0;
991 for (
size_t j = 0; j < ftxt->
spans[i].
nitems; j++) {
1031 mxfsize =
MAX(tf.
size, mxfsize);
1032 mxysize =
MAX(sz.
y, mxysize);
1056 ftxt->
spans[i].
lfsize = mxfsize + ysize - curbline - maxoffset;
1059 xsize =
MAX(width, xsize);
1064 ftxt->
box.
UR.
y = mxysize;
1080 if (b.
UR.
x == -1 && b.
UR.
y == -1) {
1083 agerrorf(
"No or improper image file=\"%s\"\n", img->
src);
1109 if (
parent->cellborder >= 0)
1129 sz.
x = child_sz.
x + margin;
1130 sz.
y = child_sz.
y + margin;
1135 agwarningf(
"cell size too small for content\n");
1142 "fixed cell size with unspecified width or height\n");
1159 for (c = lastc; c >= col; c--) {
1168 for (j = col; j < col + cellp->
colspan; j++) {
1174 return (uint16_t)col;
1205 for (
size_t i = 0; i <
LIST_SIZE(&rp->rp); ++i) {
1213 n_cols =
MAX(c, n_cols);
1252 assert(
table->widths ==
NULL &&
"table widths computed twice");
1262 if (
cell.colspan > 1) {
1265 assert(
cell.col <
table->column_count &&
"out of range cell");
1275 if (
cell.colspan == 1) {
1280 double span_width = 0;
1282 "cell spans wider than containing table");
1283 for (
size_t j = 0; j <
cell.colspan; ++j) {
1284 span_width +=
table->widths[
cell.col + j];
1288 const double spacing = (
cell.colspan - 1) *
table->data.space;
1289 if (span_width + spacing <
cell.data.box.UR.x) {
1290 const double widen_by =
1291 (
cell.data.box.UR.x - spacing - span_width) /
cell.colspan;
1292 for (
size_t j = 0; j <
cell.colspan; ++j) {
1293 table->widths[
cell.col + j] += widen_by;
1303 double min_width = 0;
1305 "cell spans wider than containing table");
1306 for (
size_t j = 0; j <
cell->colspan; ++j) {
1307 min_width +=
table->widths[
cell->col + j];
1311 const double spacing = (
cell->colspan - 1) *
table->data.space;
1312 cell->data.box.UR.x = fmax(
cell->data.box.UR.x, min_width + spacing);
1323 assert(
table->heights ==
NULL &&
"table heights computed twice");
1328 if (
cell.rowspan > 1) {
1331 assert(
cell.row <
table->row_count &&
"out of range cell");
1338 if (
cell.rowspan == 1) {
1342 double span_height = 0;
1344 "cell spans higher than containing table");
1345 for (
size_t j = 0; j <
cell.rowspan; ++j) {
1346 span_height +=
table->heights[
cell.row + j];
1349 const double spacing = (
cell.rowspan - 1) *
table->data.space;
1350 if (span_height + spacing <
cell.data.box.UR.y) {
1351 const double heighten_by =
1352 (
cell.data.box.UR.y - spacing - span_height) /
cell.rowspan;
1353 for (
size_t j = 0; j <
cell.rowspan; ++j) {
1354 table->heights[
cell.row + j] += heighten_by;
1362 double min_height = 0;
1364 "cell spans higher than containing table");
1365 for (
size_t j = 0; j <
cell->rowspan; ++j) {
1366 min_height +=
table->heights[
cell->row + j];
1369 const double spacing = (
cell->rowspan - 1) *
table->data.space;
1370 cell->data.box.UR.y = fmax(
cell->data.box.UR.y, min_height + spacing);
1388 for (
size_t i = 0; i < ftxt->
nspans; i++) {
1405 delx = pos.
UR.
x - pos.
LL.
x - oldsz.
x;
1409 pos.
UR.
x = pos.
LL.
x + oldsz.
x;
1416 pos.
LL.
x += delx / 2;
1417 pos.
UR.
x -= delx / 2;
1421 dely = pos.
UR.
y - pos.
LL.
y - oldsz.
y;
1425 pos.
UR.
y = pos.
LL.
y + oldsz.
y;
1432 pos.
LL.
y += dely / 2;
1433 pos.
UR.
y -= dely / 2;
1452 delx = cbox.
UR.
x - cbox.
LL.
x - oldsz.
x;
1466 dely = cbox.
UR.
y - cbox.
LL.
y - oldsz.
y;
1485 delx = cbox.
UR.
x - cbox.
LL.
x - oldsz.
x;
1498 cbox.
LL.
x += delx / 2;
1499 cbox.
UR.
x -= delx / 2;
1504 dely = cbox.
UR.
y - cbox.
LL.
y - oldsz.
y;
1514 cbox.
LL.
y += dely / 2;
1515 cbox.
UR.
y -= dely / 2;
1553 double delx = fmax(pos.
UR.
x - pos.
LL.
x - oldsz, 0);
1555 double dely = fmax(pos.
UR.
y - pos.
LL.
y - oldsz, 0);
1562 pos.
UR.
x = pos.
LL.
x + oldsz;
1569 pos.
LL.
x += delx / 2;
1570 pos.
UR.
x -= delx / 2;
1578 pos.
UR.
y = pos.
LL.
y + oldsz;
1582 pos.
UR.
y = pos.
LL.
y + oldsz;
1585 pos.
LL.
y += dely / 2;
1586 pos.
UR.
y -= dely / 2;
1599 delx = tbl->
widths[i] + extra + ((i <= INT_MAX && (int)i < plus) ? 1 : 0);
1607 for (
size_t i = 0; i <= tbl->
row_count; i++) {
1608 dely = tbl->
heights[i] + extra + ((i <= INT_MAX && (int)i < plus) ? 1 : 0);
1613 while ((cp = *cells++)) {
1614 unsigned char mask = 0;
1668 for (
size_t i = 0; i < tbl->
row_count; i++)
1674 agwarningf(
"table size too small for content\n");
1681 "fixed table size with unspecified width or height\n");
1720 fprintf(stderr,
" ");
1723void printBox(
boxf b)
1725 fprintf(stderr,
"(%f,%f)(%f,%f)", b.
LL.
x, b.
LL.
y, b.
UR.
x, b.
UR.
y);
1731 fprintf(stderr,
"img: %s\n", ip->
src);
1738 for (
size_t i = 0; i < txt->
nspans; i++) {
1742 for (
size_t j = 0; j < txt->
spans[i].
nitems; j++) {
1744 fprintf(stderr,
"[%" PRISIZE_T "] (%f,%f) \"%s\" ",
1749 fprintf(stderr,
"font %s color %s size %f\n",
1754 fprintf(stderr,
"\n");
1778 fprintf(stderr,
"%c", c);
1790 fprintf(stderr,
"%c ", c);
1800 fputs(
"\n", stderr);
1802 printCell(*cells++, ind + 1);
1805static void printCell(
htmlcell_t * cp,
int ind)
1808 fprintf(stderr,
"cell %" PRIu16
" %" PRIu16
" %" PRIu16
" %" PRIu16
" ", cp->
colspan,
1811 fputs(
"\n", stderr);
1830 printTbl(lbl->
u.
tbl, 0);
1832 printTxt(lbl->
u.
txt, 0);
1840 if ((
str =
agget(obj,
"pencolor")) != 0 &&
str[0])
1842 else if ((
str =
agget(obj,
"color")) != 0 &&
str[0])
1909 boxf b = {{-wd2, -ht2}, {wd2, ht2}};
1917 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)
#define LIST_GET(list, index)
static 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)