@knowvah/dot-engine 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -17
- package/dist/api.js +24 -0
- package/dist/api.js.map +2 -2
- package/dist/common/arrows.d.ts.map +1 -1
- package/dist/common/edge-label-init.d.ts.map +1 -1
- package/dist/common/htmltable-emit.d.ts +0 -8
- package/dist/common/htmltable-emit.d.ts.map +1 -1
- package/dist/common/ps-fontalias.d.ts +22 -9
- package/dist/common/ps-fontalias.d.ts.map +1 -1
- package/dist/common/splines-clip.d.ts.map +1 -1
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/gvc/job.d.ts +4 -0
- package/dist/gvc/job.d.ts.map +1 -1
- package/dist/index.js +1981 -1533
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/index.d.ts +1 -1
- package/dist/layout/dot/index.d.ts.map +1 -1
- package/dist/layout/sfdp/init.d.ts.map +1 -1
- package/dist/model/graph.d.ts +24 -0
- package/dist/model/graph.d.ts.map +1 -1
- package/dist/parser/builder.d.ts +32 -0
- package/dist/parser/builder.d.ts.map +1 -1
- package/dist/render/dot/agwrite.d.ts +186 -0
- package/dist/render/dot/agwrite.d.ts.map +1 -0
- package/dist/render/dot/attrs.d.ts +220 -0
- package/dist/render/dot/attrs.d.ts.map +1 -0
- package/dist/render/dot/edge-draw.d.ts +60 -0
- package/dist/render/dot/edge-draw.d.ts.map +1 -0
- package/dist/render/dot/types.d.ts +28 -0
- package/dist/render/dot/types.d.ts.map +1 -0
- package/dist/render/dot/xdot-ops.d.ts +206 -0
- package/dist/render/dot/xdot-ops.d.ts.map +1 -0
- package/dist/render/dot.d.ts +58 -277
- package/dist/render/dot.d.ts.map +1 -1
- package/dist/render/map.d.ts +14 -1
- package/dist/render/map.d.ts.map +1 -1
- package/dist/render/svg-graph.d.ts.map +1 -1
- package/dist/render.js +1942 -1494
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/arrows.ts +17 -4
- package/src/common/edge-label-init.ts +9 -2
- package/src/common/htmltable-emit.ts +36 -8
- package/src/common/poly-gencode.ts +8 -8
- package/src/common/ps-fontalias.ts +80 -49
- package/src/common/splines-clip.ts +36 -10
- package/src/gvc/device.ts +18 -6
- package/src/gvc/job.ts +4 -0
- package/src/layout/dot/index.ts +37 -5
- package/src/layout/sfdp/init.ts +11 -0
- package/src/model/graph.ts +26 -0
- package/src/parser/builder.ts +90 -5
- package/src/render/dot/agwrite.ts +506 -0
- package/src/render/dot/attrs.ts +437 -0
- package/src/render/dot/edge-draw.ts +203 -0
- package/src/render/dot/types.ts +32 -0
- package/src/render/dot/xdot-ops.ts +432 -0
- package/src/render/dot.ts +114 -1131
- package/src/render/map.ts +18 -1
- package/src/render/svg-graph.ts +4 -0
- package/src/render/svg-helpers.ts +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Shared shapes for the dot/xdot renderer and its agwrite serializer. */
|
|
2
|
+
import type { Graph } from '../../model/graph.js';
|
|
3
|
+
import type { Node } from '../../model/node.js';
|
|
4
|
+
import type { Edge } from '../../model/edge.js';
|
|
5
|
+
/** Accumulated xdot draw strings for one model object (agset side-table). */
|
|
6
|
+
export interface XdotDraws {
|
|
7
|
+
draw?: string;
|
|
8
|
+
ldraw?: string;
|
|
9
|
+
hdraw?: string;
|
|
10
|
+
tdraw?: string;
|
|
11
|
+
hldraw?: string;
|
|
12
|
+
tldraw?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Mutable state threaded through the recursive agwrite serializer. */
|
|
15
|
+
export interface SerCtx {
|
|
16
|
+
out: string[];
|
|
17
|
+
/** subgraph → preorder number (write.c:subgdfs). */
|
|
18
|
+
preorder: Map<Graph, number>;
|
|
19
|
+
/** node → preorder of the subgraph it was last written in (node_last_written). */
|
|
20
|
+
nodeLW: Map<Node, number>;
|
|
21
|
+
/** edge → preorder of the subgraph it was last written in (edge_last_written). */
|
|
22
|
+
edgeLW: Map<Edge, number>;
|
|
23
|
+
/** objects whose attributes have already been emitted (AGATTRWF/attrs_written). */
|
|
24
|
+
attrsWritten: Set<Node | Edge>;
|
|
25
|
+
/** current indentation depth. */
|
|
26
|
+
level: number;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/render/dot/types.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAE1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uEAAuE;AACvE,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,oDAAoD;IACpD,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7B,kFAAkF;IAClF,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1B,kFAAkF;IAClF,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1B,mFAAmF;IACnF,YAAY,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC/B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xdot output primitives — number, string, colour and geometry formatting for
|
|
3
|
+
* the xdot draw-string language, plus the shared `%.5g`/`%.2f` helpers.
|
|
4
|
+
*
|
|
5
|
+
* @see plugin/core/gvrender_core_dot.c
|
|
6
|
+
*/
|
|
7
|
+
import type { Point } from '../../model/geom.js';
|
|
8
|
+
import type { GVColor } from '../../common/color.js';
|
|
9
|
+
export declare const XDOT_VERSION = "1.7";
|
|
10
|
+
/** Max magnitude cap — matches maxnegnum in C source. */
|
|
11
|
+
export declare const MAX_NEGNUM = 1000000000000000;
|
|
12
|
+
/** Near-zero suppression threshold (same as gvprintdouble). */
|
|
13
|
+
export declare const NEAR_ZERO = 0.005;
|
|
14
|
+
/** Indices 8/9 alias 1; 10/11 alias 5. NUM_XBUFS covers 0–7. */
|
|
15
|
+
export declare const NUM_XBUFS = 8;
|
|
16
|
+
/**
|
|
17
|
+
* Style tokens that never become an xdot `S` op: `filled`/`bold`/`setlinewidth`
|
|
18
|
+
* are filtered by xdot_style itself; the polygon/fill styles are consumed by the
|
|
19
|
+
* shape/fill code before gvrender_set_style, so they never reach the render
|
|
20
|
+
* style. Only line styles (solid/dashed/dotted + unknown) emit an `S` op.
|
|
21
|
+
* @see plugin/core/gvrender_core_dot.c:184 xdot_style · lib/common/shapes.c
|
|
22
|
+
*/
|
|
23
|
+
export declare const NON_LINE_STYLES: ReadonlySet<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Strip trailing zeros (and the decimal point) from a toFixed(3) string,
|
|
26
|
+
* then collapse a leading "0." or "-0." prefix.
|
|
27
|
+
*/
|
|
28
|
+
export declare function trimAndStrip(s: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Convert a double to compact string form for DOT/XDOT output.
|
|
31
|
+
*
|
|
32
|
+
* Rules (porting gvprintnum from lib/gvc/gvdevice.c):
|
|
33
|
+
* - |n| > MAX_NEGNUM → clamped to ±MAX_NEGNUM
|
|
34
|
+
* - |n| < NEAR_ZERO → "0" (suppresses -0)
|
|
35
|
+
* - 3 decimal places, trailing zeros and point stripped
|
|
36
|
+
* - Leading "0." collapsed to "." (e.g. 0.5 → ".5")
|
|
37
|
+
*
|
|
38
|
+
* Exported for json.ts (T30) and map.ts (T31).
|
|
39
|
+
*
|
|
40
|
+
* @see lib/gvc/gvdevice.c:gvprintnum
|
|
41
|
+
*/
|
|
42
|
+
export declare function printNum(n: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* Create a 12-slot xbufs array with the canonical aliasing.
|
|
45
|
+
*
|
|
46
|
+
* Indices 8–9 (NDraw, EDraw) alias index 1 (CDraw).
|
|
47
|
+
* Indices 10–11 (NLabel, ELabel) alias index 5 (CLabel).
|
|
48
|
+
*
|
|
49
|
+
* @see plugin/core/gvrender_core_dot.c:xbufs
|
|
50
|
+
*/
|
|
51
|
+
export declare function makeXbufs(): string[][];
|
|
52
|
+
/**
|
|
53
|
+
* Format one xdot draw-op number: 2 decimals, trailing zeros and point trimmed
|
|
54
|
+
* — mirroring xdot_fmt_num ("%.02f" + agxbuf_trim_zeros). Distinct from
|
|
55
|
+
* `printNum` (used for the DOT `pos`/`bb`/`width`/`height` attributes), which
|
|
56
|
+
* keeps more precision; xdot's DRAW ops are emitted at 2 dp by the C engine.
|
|
57
|
+
* @see plugin/core/gvrender_core_dot.c:126 xdot_fmt_num
|
|
58
|
+
*/
|
|
59
|
+
export declare function xdotNum(v: number): string;
|
|
60
|
+
/**
|
|
61
|
+
* Format a single xdot point "x y ". xdot is y-up: `Y_invert` defaults false, so
|
|
62
|
+
* `yDir(y, yOff)` returns `y` unchanged for xdot (only `-Ty` plain/dot invert).
|
|
63
|
+
* The layout coordinate passes through with NO inversion — unlike the SVG path.
|
|
64
|
+
* @see lib/common/output.c:36 yDir · plugin/core/gvrender_core_dot.c:132 xdot_point
|
|
65
|
+
*/
|
|
66
|
+
export declare function xdotPoint(p: Point): string;
|
|
67
|
+
/** Format N points preceded by opcode and count: "<c> <n> x0 y0 x1 y1 …". */
|
|
68
|
+
export declare function xdotPoints(c: string, pts: Point[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* UTF-8 byte length of a string — the value C's `xdot_str` writes as the length
|
|
71
|
+
* prefix (`strlen(s)` over the UTF-8 bytes), NOT the JS UTF-16 code-unit count.
|
|
72
|
+
* A label like `ÿ` (U+00FF) is 2 UTF-8 bytes, so its `T`/`F` op prefix is 2.
|
|
73
|
+
* @see plugin/core/gvrender_core_dot.c:83 xdot_str_xbuf (`%zu`, strlen)
|
|
74
|
+
*/
|
|
75
|
+
export declare function utf8Len(s: string): number;
|
|
76
|
+
/** Clamp a normalized [0,1] float channel to a 0-255 byte (round-to-nearest). */
|
|
77
|
+
export declare function chanByte(v: number): number;
|
|
78
|
+
/**
|
|
79
|
+
* Resolve a GVColor to RGBA bytes — the value the C xdot callbacks read from
|
|
80
|
+
* `job->obj->pencolor.u.rgba` (already resolved by gvrender_set_pencolor). A
|
|
81
|
+
* plain `rgba` passes through; named/hex/HSV specs run through colorxlate; a
|
|
82
|
+
* `none` color is fully transparent black (callers gate on PEN_NONE).
|
|
83
|
+
*/
|
|
84
|
+
export declare function gvColorRgba(c: GVColor): [number, number, number, number];
|
|
85
|
+
/**
|
|
86
|
+
* Bare xdot color body (no `c `/`C ` prefix): the CONSTANT length prefix
|
|
87
|
+
* (7 for `#rrggbb`, 9 for `#rrggbbaa`) plus `-#hex`, the alpha byte present only
|
|
88
|
+
* when not fully opaque. Used both by the color ops and by gradient color stops.
|
|
89
|
+
* @see plugin/core/gvrender_core_dot.c:99 xdot_str_color_xbuf
|
|
90
|
+
*/
|
|
91
|
+
export declare function xdotColorBody(rgba: [number, number, number, number]): string;
|
|
92
|
+
/**
|
|
93
|
+
* Format an xdot color op ("c "/"C ") from RGBA bytes.
|
|
94
|
+
* @see plugin/core/gvrender_core_dot.c:99 xdot_str_color_xbuf
|
|
95
|
+
*/
|
|
96
|
+
export declare function xdotColorOp(prefix: 'c ' | 'C ', rgba: [number, number, number, number]): string;
|
|
97
|
+
/**
|
|
98
|
+
* Build the linear-gradient `C len -[x0 y0 x1 y1 2 <stops>]` fill op. Endpoints
|
|
99
|
+
* come from getGradientPoints (the same geometry the SVG gradient uses); stops
|
|
100
|
+
* are (frac,fill)/(frac,stop) when frac>0, else (0,fill)/(1,stop). Shared by
|
|
101
|
+
* node/cluster gradient fills and the graph-background gradient.
|
|
102
|
+
* @see plugin/core/gvrender_core_dot.c:544-598 xdot_gradient_fillcolor
|
|
103
|
+
*/
|
|
104
|
+
export declare function linearGradientOp(pts: Point[], fillColor: GVColor, stopColor: GVColor, frac: number, angleDeg: number): string;
|
|
105
|
+
/** The `<frac> <colorbody>` stop pairs for a gradient (frac>0 vs the 0/1 form). */
|
|
106
|
+
export declare function gradientStops(fillColor: GVColor, stopColor: GVColor, frac: number): string;
|
|
107
|
+
/**
|
|
108
|
+
* Build the radial-gradient `C len -(c1x c1y r1 c2x c2y r2 2 <stops>)` fill op.
|
|
109
|
+
* Reuses getGradientPoints (radial) for the center/radii, un-negating its SVG
|
|
110
|
+
* y. r1 = outerR/4, r2 = outerR; c2 is the center, c1 the center offset by r1
|
|
111
|
+
* along the gradient angle (== center when angle 0).
|
|
112
|
+
* @see plugin/core/gvrender_core_dot.c:562-585 xdot_gradient_fillcolor (radial)
|
|
113
|
+
*/
|
|
114
|
+
export declare function radialGradientOp(pts: Point[], fillColor: GVColor, stopColor: GVColor, frac: number, angleDeg: number): string;
|
|
115
|
+
/** Pen ("c ") color op from a resolved GVColor. */
|
|
116
|
+
export declare function xdotPenColor(c: GVColor): string;
|
|
117
|
+
/** Fill ("C ") color op from a resolved GVColor. */
|
|
118
|
+
export declare function xdotFillColor(c: GVColor): string;
|
|
119
|
+
/**
|
|
120
|
+
* Build the xdot "F size len -name " font op. Mirrors xdot_textspan's `F` +
|
|
121
|
+
* `xdot_str(job, "", font->name)` — the length prefix is the byte length of the
|
|
122
|
+
* face name. @see plugin/core/gvrender_core_dot.c:498 xdot_textspan
|
|
123
|
+
*/
|
|
124
|
+
export declare function xdotFont(size: number, name: string): string;
|
|
125
|
+
/**
|
|
126
|
+
* Build an xdot length-prefixed string op ("S "/"" prefix): "<pfx><len> -<s> ".
|
|
127
|
+
* @see plugin/core/gvrender_core_dot.c:83 xdot_str_xbuf
|
|
128
|
+
*/
|
|
129
|
+
export declare function xdotStrOp(prefix: string, s: string): string;
|
|
130
|
+
/**
|
|
131
|
+
* Quote a DOT identifier unless it is a bare id or numeral, mirroring agwrite's
|
|
132
|
+
* agcanonStr so the serialized graph reparses (the comparator reparses both
|
|
133
|
+
* sides). Only `"` is escaped (→ `\"`); a `\` is left as-is — it is already the
|
|
134
|
+
* start of a stored escape like `\n`/`\l` that agcanonStr keeps verbatim, so
|
|
135
|
+
* doubling it (`\\n`) would change the name (`a\n(b\n"c")` must stay `a\n…`, not
|
|
136
|
+
* `a\\n…`). Over-quoting a value native leaves bare is harmless: both parse to
|
|
137
|
+
* the same name. @see lib/cgraph/write.c:_agstrcanon (escapes '"', keeps '\')
|
|
138
|
+
*
|
|
139
|
+
* ONE DELIBERATE DIVERGENCE from _agstrcanon: an ODD trailing backslash run is
|
|
140
|
+
* padded to even. C copies it verbatim and appends the closing quote, so a name
|
|
141
|
+
* ending in a single `\` serializes as `"a\"` — the backslash escapes the quote
|
|
142
|
+
* and the output does not reparse. The DOT lexer cannot produce such a name
|
|
143
|
+
* (source `"a\"` never terminates), so this is unreachable from any file and no
|
|
144
|
+
* corpus id changes; it is reachable only through the programmatic API, where a
|
|
145
|
+
* caller supplies the string directly. Padding costs a name that round-trips to
|
|
146
|
+
* `a\\` instead of `a\`, which beats emitting a document that cannot be parsed.
|
|
147
|
+
* @see CodeQL "Incomplete string escaping or encoding" — the alert's own remedy
|
|
148
|
+
* (escape every `\`) is wrong here and breaks `\n`/`\l` parity.
|
|
149
|
+
*/
|
|
150
|
+
export declare function xdotId(s: string): string;
|
|
151
|
+
/**
|
|
152
|
+
* Format a number as C's `%.5g` — 5 significant figures, trailing zeros and
|
|
153
|
+
* point trimmed, switching to `e±NN` (min 2 exponent digits) when the exponent
|
|
154
|
+
* is < -4 or ≥ 5. Native writes the DOT `pos`/`bb`/`width`/`height` attributes
|
|
155
|
+
* with `%.5g` (output.c:71/294/302), so large coordinates round to 5 sig figs
|
|
156
|
+
* (`2219962` → `2.2201e+06`); `printNum`'s fixed 3 dp keeps too much precision.
|
|
157
|
+
*
|
|
158
|
+
* Uses {@link printfSig} rather than `Number.prototype.toPrecision(5)` so
|
|
159
|
+
* exact-halfway values (e.g. 1399.25) round half-to-even like C's snprintf,
|
|
160
|
+
* not half-away-from-zero like `toPrecision`. @see docs proven case
|
|
161
|
+
* graphs-b786 (circo): pos coordinate 1399.25 → native "1399.2", `toPrecision`
|
|
162
|
+
* gave "1399.3".
|
|
163
|
+
* @see lib/common/output.c:71 (agxbprint "%.5g")
|
|
164
|
+
*/
|
|
165
|
+
export declare function gfmt5(v: number): string;
|
|
166
|
+
/**
|
|
167
|
+
* Format a number as C's `%.2f` — fixed 2 decimals, half-to-even on exact ties.
|
|
168
|
+
* `attach_attrs` writes the graph-label size attributes `lwidth`/`lheight` in
|
|
169
|
+
* INCHES with `%.2f`, unlike every other computed attribute (which uses `%.5g`).
|
|
170
|
+
* @see lib/common/output.c:244-247 (agxbprint "%.2f", PS2INCH)
|
|
171
|
+
*/
|
|
172
|
+
export declare function gfmt2(v: number): string;
|
|
173
|
+
/**
|
|
174
|
+
* Format a label position as the `x,y` pair every computed `*_lp` attribute
|
|
175
|
+
* uses: both coordinates at `%.5g`. C passes y through `yDir()`, which is the
|
|
176
|
+
* identity unless `Y_invert` — and `Y_invert` is only set by `-Ty` (plain/dot),
|
|
177
|
+
* never for xdot — so no inversion is applied here, exactly as the existing
|
|
178
|
+
* `pos`/`bb` emission does.
|
|
179
|
+
* @see lib/common/output.c:35 yDir · lib/common/output.c:241 (agxbprint "%.5g,%.5g")
|
|
180
|
+
*/
|
|
181
|
+
export declare function lpStr(p: Point): string;
|
|
182
|
+
/**
|
|
183
|
+
* Escape backslashes in a LABEL draw string — C's put_escaping_backslashes,
|
|
184
|
+
* applied to the `_ldraw_`/`_hldraw_`/`_tldraw_` buffers (not the shape draws)
|
|
185
|
+
* before agset. A literal `\` in a label's text (e.g. `WXYZ\nabc`) becomes `\\`
|
|
186
|
+
* so it survives the DOT string round-trip; the T-op byte-length prefix stays on
|
|
187
|
+
* the UNescaped text. @see plugin/core/gvrender_core_dot.c:218 put_escaping_backslashes
|
|
188
|
+
*/
|
|
189
|
+
export declare function escBackslash(s: string): string;
|
|
190
|
+
/** True if s[i..] starts an escape sequence agcanonStr keeps verbatim: a `\`
|
|
191
|
+
* followed by one of E G H L N T l n r \ ". @see lib/cgraph/write.c:is_escape */
|
|
192
|
+
export declare function isEscapeSeq(s: string, i: number): boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Escape a value for a DOT attribute exactly as agwrite's agcanonStr does: a `"`
|
|
195
|
+
* becomes `\"` ONLY when it is not already part of an escape sequence, so an
|
|
196
|
+
* existing `\"` or `\\` in the value is passed through verbatim rather than
|
|
197
|
+
* double-escaped. For an already-backslash-doubled value (node/edge/graph labels,
|
|
198
|
+
* post put_escaping_backslashes) this is identical to a naive `"`→`\"` — every
|
|
199
|
+
* `"` follows a doubled `\\`, so none are ever part_of_escape. For raw cluster
|
|
200
|
+
* labels (agset, no put_escaping) it preserves the source `\"`/`\\` unchanged.
|
|
201
|
+
* @see lib/cgraph/write.c:_agstrcanon (135-167)
|
|
202
|
+
*/
|
|
203
|
+
export declare function agcanonEscape(s: string): string;
|
|
204
|
+
/** Trim a "%.3f" fixed string like C's agxbuf_trim_zeros (trailing 0s + dot). */
|
|
205
|
+
export declare function trimFixed3(v: number): string;
|
|
206
|
+
//# sourceMappingURL=xdot-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xdot-ops.d.ts","sourceRoot":"","sources":["../../../src/render/dot/xdot-ops.ts"],"names":[],"mappings":"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"}
|
package/dist/render/dot.d.ts
CHANGED
|
@@ -12,171 +12,14 @@ import type { Node } from '../model/node.js';
|
|
|
12
12
|
import type { Edge } from '../model/edge.js';
|
|
13
13
|
import type { Point } from '../model/geom.js';
|
|
14
14
|
import type { TextSpan } from '../common/emit-types.js';
|
|
15
|
-
import type { GVColor } from '../common/color.js';
|
|
16
15
|
import type { RendererPlugin } from '../gvc/context.js';
|
|
16
|
+
import { EdgeDrawBase } from './dot/edge-draw.js';
|
|
17
|
+
export * from './dot/types.js';
|
|
18
|
+
export type { XdotDraws, SerCtx } from './dot/types.js';
|
|
19
|
+
import type { XdotDraws } from './dot/types.js';
|
|
17
20
|
import type { RenderJob } from '../gvc/job.js';
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* Rules (porting gvprintnum from lib/gvc/gvdevice.c):
|
|
22
|
-
* - |n| > MAX_NEGNUM → clamped to ±MAX_NEGNUM
|
|
23
|
-
* - |n| < NEAR_ZERO → "0" (suppresses -0)
|
|
24
|
-
* - 3 decimal places, trailing zeros and point stripped
|
|
25
|
-
* - Leading "0." collapsed to "." (e.g. 0.5 → ".5")
|
|
26
|
-
*
|
|
27
|
-
* Exported for json.ts (T30) and map.ts (T31).
|
|
28
|
-
*
|
|
29
|
-
* @see lib/gvc/gvdevice.c:gvprintnum
|
|
30
|
-
*/
|
|
31
|
-
export declare function printNum(n: number): string;
|
|
32
|
-
/**
|
|
33
|
-
* Create a 12-slot xbufs array with the canonical aliasing.
|
|
34
|
-
*
|
|
35
|
-
* Indices 8–9 (NDraw, EDraw) alias index 1 (CDraw).
|
|
36
|
-
* Indices 10–11 (NLabel, ELabel) alias index 5 (CLabel).
|
|
37
|
-
*
|
|
38
|
-
* @see plugin/core/gvrender_core_dot.c:xbufs
|
|
39
|
-
*/
|
|
40
|
-
export declare function makeXbufs(): string[][];
|
|
41
|
-
/**
|
|
42
|
-
* Format one xdot draw-op number: 2 decimals, trailing zeros and point trimmed
|
|
43
|
-
* — mirroring xdot_fmt_num ("%.02f" + agxbuf_trim_zeros). Distinct from
|
|
44
|
-
* `printNum` (used for the DOT `pos`/`bb`/`width`/`height` attributes), which
|
|
45
|
-
* keeps more precision; xdot's DRAW ops are emitted at 2 dp by the C engine.
|
|
46
|
-
* @see plugin/core/gvrender_core_dot.c:126 xdot_fmt_num
|
|
47
|
-
*/
|
|
48
|
-
export declare function xdotNum(v: number): string;
|
|
49
|
-
/**
|
|
50
|
-
* Format a single xdot point "x y ". xdot is y-up: `Y_invert` defaults false, so
|
|
51
|
-
* `yDir(y, yOff)` returns `y` unchanged for xdot (only `-Ty` plain/dot invert).
|
|
52
|
-
* The layout coordinate passes through with NO inversion — unlike the SVG path.
|
|
53
|
-
* @see lib/common/output.c:36 yDir · plugin/core/gvrender_core_dot.c:132 xdot_point
|
|
54
|
-
*/
|
|
55
|
-
export declare function xdotPoint(p: Point): string;
|
|
56
|
-
/** Format N points preceded by opcode and count: "<c> <n> x0 y0 x1 y1 …". */
|
|
57
|
-
export declare function xdotPoints(c: string, pts: Point[]): string;
|
|
58
|
-
/**
|
|
59
|
-
* UTF-8 byte length of a string — the value C's `xdot_str` writes as the length
|
|
60
|
-
* prefix (`strlen(s)` over the UTF-8 bytes), NOT the JS UTF-16 code-unit count.
|
|
61
|
-
* A label like `ÿ` (U+00FF) is 2 UTF-8 bytes, so its `T`/`F` op prefix is 2.
|
|
62
|
-
* @see plugin/core/gvrender_core_dot.c:83 xdot_str_xbuf (`%zu`, strlen)
|
|
63
|
-
*/
|
|
64
|
-
export declare function utf8Len(s: string): number;
|
|
65
|
-
/**
|
|
66
|
-
* Resolve a GVColor to RGBA bytes — the value the C xdot callbacks read from
|
|
67
|
-
* `job->obj->pencolor.u.rgba` (already resolved by gvrender_set_pencolor). A
|
|
68
|
-
* plain `rgba` passes through; named/hex/HSV specs run through colorxlate; a
|
|
69
|
-
* `none` color is fully transparent black (callers gate on PEN_NONE).
|
|
70
|
-
*/
|
|
71
|
-
export declare function gvColorRgba(c: GVColor): [number, number, number, number];
|
|
72
|
-
/**
|
|
73
|
-
* Bare xdot color body (no `c `/`C ` prefix): the CONSTANT length prefix
|
|
74
|
-
* (7 for `#rrggbb`, 9 for `#rrggbbaa`) plus `-#hex`, the alpha byte present only
|
|
75
|
-
* when not fully opaque. Used both by the color ops and by gradient color stops.
|
|
76
|
-
* @see plugin/core/gvrender_core_dot.c:99 xdot_str_color_xbuf
|
|
77
|
-
*/
|
|
78
|
-
export declare function xdotColorBody(rgba: [number, number, number, number]): string;
|
|
79
|
-
/**
|
|
80
|
-
* Format an xdot color op ("c "/"C ") from RGBA bytes.
|
|
81
|
-
* @see plugin/core/gvrender_core_dot.c:99 xdot_str_color_xbuf
|
|
82
|
-
*/
|
|
83
|
-
export declare function xdotColorOp(prefix: 'c ' | 'C ', rgba: [number, number, number, number]): string;
|
|
84
|
-
/**
|
|
85
|
-
* Build the linear-gradient `C len -[x0 y0 x1 y1 2 <stops>]` fill op. Endpoints
|
|
86
|
-
* come from getGradientPoints (the same geometry the SVG gradient uses); stops
|
|
87
|
-
* are (frac,fill)/(frac,stop) when frac>0, else (0,fill)/(1,stop). Shared by
|
|
88
|
-
* node/cluster gradient fills and the graph-background gradient.
|
|
89
|
-
* @see plugin/core/gvrender_core_dot.c:544-598 xdot_gradient_fillcolor
|
|
90
|
-
*/
|
|
91
|
-
export declare function linearGradientOp(pts: Point[], fillColor: GVColor, stopColor: GVColor, frac: number, angleDeg: number): string;
|
|
92
|
-
/**
|
|
93
|
-
* Build the radial-gradient `C len -(c1x c1y r1 c2x c2y r2 2 <stops>)` fill op.
|
|
94
|
-
* Reuses getGradientPoints (radial) for the center/radii, un-negating its SVG
|
|
95
|
-
* y. r1 = outerR/4, r2 = outerR; c2 is the center, c1 the center offset by r1
|
|
96
|
-
* along the gradient angle (== center when angle 0).
|
|
97
|
-
* @see plugin/core/gvrender_core_dot.c:562-585 xdot_gradient_fillcolor (radial)
|
|
98
|
-
*/
|
|
99
|
-
export declare function radialGradientOp(pts: Point[], fillColor: GVColor, stopColor: GVColor, frac: number, angleDeg: number): string;
|
|
100
|
-
/** Pen ("c ") color op from a resolved GVColor. */
|
|
101
|
-
export declare function xdotPenColor(c: GVColor): string;
|
|
102
|
-
/** Fill ("C ") color op from a resolved GVColor. */
|
|
103
|
-
export declare function xdotFillColor(c: GVColor): string;
|
|
104
|
-
/**
|
|
105
|
-
* Build the xdot "F size len -name " font op. Mirrors xdot_textspan's `F` +
|
|
106
|
-
* `xdot_str(job, "", font->name)` — the length prefix is the byte length of the
|
|
107
|
-
* face name. @see plugin/core/gvrender_core_dot.c:498 xdot_textspan
|
|
108
|
-
*/
|
|
109
|
-
export declare function xdotFont(size: number, name: string): string;
|
|
110
|
-
/**
|
|
111
|
-
* Quote a DOT identifier unless it is a bare id or numeral, mirroring agwrite's
|
|
112
|
-
* agcanonStr so the serialized graph reparses (the comparator reparses both
|
|
113
|
-
* sides). Only `"` is escaped (→ `\"`); a `\` is left as-is — it is already the
|
|
114
|
-
* start of a stored escape like `\n`/`\l` that agcanonStr keeps verbatim, so
|
|
115
|
-
* doubling it (`\\n`) would change the name (`a\n(b\n"c")` must stay `a\n…`, not
|
|
116
|
-
* `a\\n…`). Over-quoting a value native leaves bare is harmless: both parse to
|
|
117
|
-
* the same name. @see lib/cgraph/write.c:_agstrcanon (escapes '"', keeps '\')
|
|
118
|
-
*/
|
|
119
|
-
export declare function xdotId(s: string): string;
|
|
120
|
-
/**
|
|
121
|
-
* Format a number as C's `%.5g` — 5 significant figures, trailing zeros and
|
|
122
|
-
* point trimmed, switching to `e±NN` (min 2 exponent digits) when the exponent
|
|
123
|
-
* is < -4 or ≥ 5. Native writes the DOT `pos`/`bb`/`width`/`height` attributes
|
|
124
|
-
* with `%.5g` (output.c:71/294/302), so large coordinates round to 5 sig figs
|
|
125
|
-
* (`2219962` → `2.2201e+06`); `printNum`'s fixed 3 dp keeps too much precision.
|
|
126
|
-
*
|
|
127
|
-
* Uses {@link printfSig} rather than `Number.prototype.toPrecision(5)` so
|
|
128
|
-
* exact-halfway values (e.g. 1399.25) round half-to-even like C's snprintf,
|
|
129
|
-
* not half-away-from-zero like `toPrecision`. @see docs proven case
|
|
130
|
-
* graphs-b786 (circo): pos coordinate 1399.25 → native "1399.2", `toPrecision`
|
|
131
|
-
* gave "1399.3".
|
|
132
|
-
* @see lib/common/output.c:71 (agxbprint "%.5g")
|
|
133
|
-
*/
|
|
134
|
-
export declare function gfmt5(v: number): string;
|
|
135
|
-
/** Format node attributes for DOT output. */
|
|
136
|
-
export declare function formatNodeAttrs(n: Node): string;
|
|
137
|
-
/**
|
|
138
|
-
* Format edge spline points for the DOT `pos` attribute. Per bezier: the start
|
|
139
|
-
* endpoint `s,sp` when `sflag` set, then the end endpoint `e,ep` when `eflag`
|
|
140
|
-
* set, then `bez.size` control points — all at `%.5g`, exactly as native's
|
|
141
|
-
* spline serialization. @see lib/common/output.c:357-372
|
|
142
|
-
*/
|
|
143
|
-
export declare function formatEdgePos(e: Edge): string;
|
|
144
|
-
/** Return the edge connector token. */
|
|
145
|
-
export declare function edgeConnector(directed: boolean): string;
|
|
146
|
-
/** Return true if the graph is directed or strict-directed. */
|
|
147
|
-
export declare function isDirected(g: Graph): boolean;
|
|
148
|
-
/** Emit the opening digraph/graph line and bb attribute. */
|
|
149
|
-
export declare function dotBeginGraphHeader(g: Graph, job: RenderJob): void;
|
|
150
|
-
/**
|
|
151
|
-
* DOT format renderer — writes graphviz DOT language with layout attributes.
|
|
152
|
-
*
|
|
153
|
-
* @see plugin/core/gvrender_core_dot.c:dot_engine
|
|
154
|
-
*/
|
|
155
|
-
export declare class DotRenderer implements RendererPlugin {
|
|
156
|
-
readonly type = "dot";
|
|
157
|
-
/** @see plugin/core/gvplugin_core.c registration table */
|
|
158
|
-
readonly quality = 0;
|
|
159
|
-
beginGraph(g: Graph, job: RenderJob): void;
|
|
160
|
-
endGraph(_g: Graph, job: RenderJob): void;
|
|
161
|
-
beginNode(_n: Node, _job: RenderJob): void;
|
|
162
|
-
endNode(n: Node, job: RenderJob): void;
|
|
163
|
-
beginEdge(_e: Edge, _job: RenderJob): void;
|
|
164
|
-
endEdge(e: Edge, job: RenderJob): void;
|
|
165
|
-
textspan(_pos: Point, _span: TextSpan, _job: RenderJob): void;
|
|
166
|
-
ellipse(_c: Point, _rx: number, _ry: number, _f: boolean, _j: RenderJob): void;
|
|
167
|
-
polygon(_pts: Point[], _filled: boolean, _job: RenderJob): void;
|
|
168
|
-
bezier(_pts: Point[], _filled: boolean, _job: RenderJob): void;
|
|
169
|
-
polyline(_pts: Point[], _job: RenderJob): void;
|
|
170
|
-
}
|
|
171
|
-
/** Accumulated xdot draw strings for one model object (agset side-table). */
|
|
172
|
-
export interface XdotDraws {
|
|
173
|
-
draw?: string;
|
|
174
|
-
ldraw?: string;
|
|
175
|
-
hdraw?: string;
|
|
176
|
-
tdraw?: string;
|
|
177
|
-
hldraw?: string;
|
|
178
|
-
tldraw?: string;
|
|
179
|
-
}
|
|
21
|
+
export * from './dot/xdot-ops.js';
|
|
22
|
+
export * from './dot/attrs.js';
|
|
180
23
|
/**
|
|
181
24
|
* XDOT format renderer — mirrors plugin/core/gvrender_core_dot.c's xdot engine.
|
|
182
25
|
*
|
|
@@ -192,27 +35,33 @@ export interface XdotDraws {
|
|
|
192
35
|
*
|
|
193
36
|
* @see plugin/core/gvrender_core_dot.c xdot_begin_graph / xdot_end_graph
|
|
194
37
|
*/
|
|
195
|
-
export declare class XdotRenderer implements RendererPlugin {
|
|
196
|
-
readonly type
|
|
38
|
+
export declare class XdotRenderer extends EdgeDrawBase implements RendererPlugin {
|
|
39
|
+
readonly type: string;
|
|
197
40
|
/** @see plugin/core/gvplugin_core.c registration table */
|
|
198
41
|
readonly quality = 0;
|
|
42
|
+
/**
|
|
43
|
+
* Whether this format attaches the xdot draw attributes before agwrite.
|
|
44
|
+
* Mirrors C's `job->render.id` switch: FORMAT_DOT runs `attach_attrs(g)` then
|
|
45
|
+
* `agwrite`, while FORMAT_XDOT runs `attach_attrs_and_arrows` +
|
|
46
|
+
* `xdot_begin_graph`/`xdot_end_graph` and *then* the same `agwrite`. The
|
|
47
|
+
* serializer below is that shared `agwrite`; this flag is the only difference.
|
|
48
|
+
* @see plugin/core/gvrender_core_dot.c:404,418,475,482
|
|
49
|
+
*/
|
|
50
|
+
protected readonly emitDraws: boolean;
|
|
51
|
+
/** Draw strings for `obj`, or undefined in a format that emits none (`-Tdot`).
|
|
52
|
+
* Single gate so the xdot path cannot drift from the dot path. */
|
|
53
|
+
protected drawsOf(obj: Node | Edge | Graph): XdotDraws | undefined;
|
|
199
54
|
/** Per-render draw buffers. Indices 8/9 alias 1; 10/11 alias 5. */
|
|
200
55
|
private bufs;
|
|
201
|
-
/** setlinewidth state per emit_state. @see gvrender_core_dot.c penwidth[] */
|
|
202
|
-
private penwidth;
|
|
203
56
|
/** text-flag state per emit_state. @see gvrender_core_dot.c textflags[] */
|
|
204
57
|
private textflags;
|
|
205
58
|
/** Accumulated draw strings keyed by model object (C: agset on the object). */
|
|
206
59
|
private draws;
|
|
207
|
-
/** Clusters in render order — the graphs `endCluster` was actually called for
|
|
208
|
-
* (from `renderClusters`/`GD_clust`), which is NOT always reachable via
|
|
209
|
-
* `g.subgraphs`, so it is tracked here rather than re-walked. */
|
|
210
|
-
private clusters;
|
|
211
60
|
/** edge_in_box gate for the current edge: emit_edge draws nothing (spline OR
|
|
212
61
|
* label) for an edge whose content is outside job->clip. Mirrors svg.ts's
|
|
213
62
|
* edgeGroupOpen. @see lib/common/emit.c:emit_edge (3039) */
|
|
214
63
|
private edgeDrawable;
|
|
215
|
-
beginGraph(
|
|
64
|
+
beginGraph(_g: Graph, _job: RenderJob): void;
|
|
216
65
|
/** The per-object draw strings accumulated during the last render, keyed by
|
|
217
66
|
* the ORIGINAL model object. These are the pre-serialization values C's
|
|
218
67
|
* `-Tjson` reads directly (via agxget) — feeding them to parseXDot avoids the
|
|
@@ -223,6 +72,10 @@ export declare class XdotRenderer implements RendererPlugin {
|
|
|
223
72
|
/** Emit the canvas background polygon into the GDRAW buffer.
|
|
224
73
|
* @see lib/common/emit.c:1476 emit_background */
|
|
225
74
|
pageBackground(g: Graph, job: RenderJob): void;
|
|
75
|
+
/** The canvas fill op: a two-colour `bgcolor` is a gradient (emit_background →
|
|
76
|
+
* findStopColor), linear or radial per style; anything else is a flat fill.
|
|
77
|
+
* @see lib/common/emit.c:1476 emit_background */
|
|
78
|
+
private backgroundFillOp;
|
|
226
79
|
beginNode(_n: Node, _job: RenderJob): void;
|
|
227
80
|
endNode(n: Node, _job: RenderJob): void;
|
|
228
81
|
/**
|
|
@@ -240,27 +93,14 @@ export declare class XdotRenderer implements RendererPlugin {
|
|
|
240
93
|
* -tapered` (the style), a transparent pen, the edge-color fill, then the
|
|
241
94
|
* polygon vertices from `taper()` (y-up). @see lib/common/emit.c:2422
|
|
242
95
|
*/
|
|
243
|
-
private emitTaperedSpline;
|
|
244
|
-
/**
|
|
245
|
-
* Emit a split-along-length `;` multicolor edge spline: split each routed
|
|
246
|
-
* bezier along its arc length into one sub-curve per color segment, drawn
|
|
247
|
-
* under that segment's pen. Reuses the same split geometry
|
|
248
|
-
* (splitSplineByColor) as the SVG path. @see lib/common/emit.c:1975 multicolor
|
|
249
|
-
*/
|
|
250
|
-
private emitSplitSpline;
|
|
251
|
-
/**
|
|
252
|
-
* Emit the parallel-multicolor edge spline: one offset Bézier per color,
|
|
253
|
-
* offset SEP=2.0 perpendicular per pass — reusing the same offset geometry
|
|
254
|
-
* (buildOffsetLists/advanceTmpList) as the SVG parallel-edge path.
|
|
255
|
-
* @see lib/common/emit.c:2443 (parallel multicolor) / svg-parallel-edge.ts
|
|
256
|
-
*/
|
|
257
|
-
private emitParallelSpline;
|
|
258
|
-
/** Emit one arrow's primitive ops into `buf` (pen/fill from the edge color).
|
|
259
|
-
* arrow_gen sets the default line style ("solid") and the edge penwidth
|
|
260
|
-
* before each primitive, so a non-default penwidth emits `S setlinewidth(N)`
|
|
261
|
-
* once (tracked per HDRAW/TDRAW state). @see arrows.c:arrow_gen */
|
|
262
|
-
private emitArrows;
|
|
263
96
|
endEdge(e: Edge, job: RenderJob): void;
|
|
97
|
+
/** Flush the six edge buffers and attach the non-empty ones. Label buffers get
|
|
98
|
+
* put_escaping_backslashes; shape buffers do not.
|
|
99
|
+
* @see plugin/core/gvrender_core_dot.c:218 */
|
|
100
|
+
private attachEdgeDraws;
|
|
101
|
+
/** Per-edge emit-state reset, run on both the drawable and the early-return
|
|
102
|
+
* path — identical in C, so it is one helper here rather than two copies. */
|
|
103
|
+
private resetEdgeState;
|
|
264
104
|
beginCluster(_sg: Graph, _job: RenderJob): void;
|
|
265
105
|
endCluster(sg: Graph, _job: RenderJob): void;
|
|
266
106
|
textspan(pos: Point, span: TextSpan, job: RenderJob): void;
|
|
@@ -269,7 +109,7 @@ export declare class XdotRenderer implements RendererPlugin {
|
|
|
269
109
|
bezier(pts: Point[], filled: boolean, job: RenderJob): void;
|
|
270
110
|
polyline(pts: Point[], job: RenderJob): void;
|
|
271
111
|
/** Pen color op from the resolved graphics state (default black). */
|
|
272
|
-
|
|
112
|
+
protected penOp(job: RenderJob): string;
|
|
273
113
|
/**
|
|
274
114
|
* Fill op from the resolved graphics state. A linear gradient emits the
|
|
275
115
|
* bracketed `C len -[G0 G1 2 <stops>]` form (xdot_gradient_fillcolor); a plain
|
|
@@ -280,7 +120,7 @@ export declare class XdotRenderer implements RendererPlugin {
|
|
|
280
120
|
private fillOp;
|
|
281
121
|
/** Style ops (`S`): setlinewidth on a penwidth change, plus dash/dot pen.
|
|
282
122
|
* @see gvrender_core_dot.c:161 xdot_style */
|
|
283
|
-
|
|
123
|
+
protected styleOp(job: RenderJob): string;
|
|
284
124
|
/** Active xdot buffer for the current emit state. */
|
|
285
125
|
private getBuf;
|
|
286
126
|
/** Join and clear the buffer for `state`; returns '' when empty. */
|
|
@@ -288,89 +128,30 @@ export declare class XdotRenderer implements RendererPlugin {
|
|
|
288
128
|
/** Reset per-emit-state penwidth/textflags after an object (C's reset). */
|
|
289
129
|
private resetState;
|
|
290
130
|
private drawsFor;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
private subgdfs;
|
|
316
|
-
/** A subgraph is anonymous when its name is empty or a `%N` local name. */
|
|
317
|
-
private isAnonymous;
|
|
318
|
-
/** A graph carries a `bb` attribute when it is the root or has a layout bb
|
|
319
|
-
* (clusters, and any subgraph output.c computed a box for). Native seeds `bb`
|
|
320
|
-
* on every graph via safe_dcl, so the value differs (set vs empty "") between
|
|
321
|
-
* a boxed graph and an unboxed child — the driver that makes an anon subgraph
|
|
322
|
-
* under the root or a cluster "relevant". @see lib/common/output.c:safe_dcl */
|
|
323
|
-
private hasBb;
|
|
324
|
-
/** Anonymous subgraph with no own node/edge defaults and no graph attrs
|
|
325
|
-
* differing from its parent → inlined into the parent. Native compares every
|
|
326
|
-
* graph attr over the root attr dict; the load-bearing ones are `bb` (set on
|
|
327
|
-
* the parent, empty on the child) and `rank`. @see write.c:irrelevant_subgraph */
|
|
328
|
-
private irrelevantSubgraph;
|
|
329
|
-
/** Non-draw graph attrs a subgraph emits (rank for rank=same; clusters use
|
|
330
|
-
* clusterAttrs). Only comparator-relevant fields need be exact.
|
|
331
|
-
*
|
|
332
|
-
* `rec_attach_bb` walks the ROOT and then `GD_clust` recursively, so a
|
|
333
|
-
* subgraph the layout did not box is attached NEITHER `bb` NOR the label
|
|
334
|
-
* triple — both keep the INPUT's values, which agwrite echoes. circo and
|
|
335
|
-
* twopi lay out no clusters at all (`GD_clust` empty — mirrored here by
|
|
336
|
-
* `this.clusters`, filled from endCluster), so on a re-fed dot output their
|
|
337
|
-
* `cluster0` comes back carrying the *previous* run's `bb` and `lp`.
|
|
338
|
-
* @see lib/common/output.c:249 rec_attach_bb */
|
|
339
|
-
private subgGraphAttrs;
|
|
340
|
-
private indent;
|
|
341
|
-
/** @see write.c:write_hdr */
|
|
342
|
-
private writeHdr;
|
|
343
|
-
/** @see write.c:write_trl */
|
|
344
|
-
private writeTrl;
|
|
345
|
-
/** @see write.c:write_subgs */
|
|
346
|
-
private writeSubgs;
|
|
347
|
-
/** @see write.c:write_body — subgraphs, then this scope's nodes and edges. */
|
|
348
|
-
private writeBody;
|
|
349
|
-
/** @see write.c:write_node_test — every xdot node carries pos/size, so it is
|
|
350
|
-
* never "default"; write it in the first scope that has not yet emitted it.
|
|
351
|
-
* Cluster nodes (fdp compound proxies, ND_clustnode) are never declared —
|
|
352
|
-
* C's write_plain/writenodeandport suppress them. @see lib/common/output.c:146 */
|
|
353
|
-
private writeNodeTest;
|
|
354
|
-
/** Emitted node name: a cluster node's synthetic `__i:<cluster>` id is written
|
|
355
|
-
* as the cluster name it stands for. @see lib/common/output.c:114 */
|
|
356
|
-
private emitNodeName;
|
|
357
|
-
/** @see write.c:write_edge_test */
|
|
358
|
-
private writeEdgeTest;
|
|
359
|
-
/** @see write.c:write_node */
|
|
360
|
-
private writeNode;
|
|
361
|
-
/** @see write.c:write_edge — attrs only on first emission, bare thereafter. */
|
|
362
|
-
private writeEdge;
|
|
363
|
-
/** Root-graph attribute block: `_draw_`, `_ldraw_`, `bb`, `xdotversion`. */
|
|
364
|
-
private graphAttrs;
|
|
365
|
-
/** Cluster attribute block. C's xdot_end_cluster ALWAYS agsets `_draw_` when
|
|
366
|
-
* the graph has clusters (even empty, e.g. peripheries=0), so emit it
|
|
367
|
-
* unconditionally; `_ldraw_` only when the cluster has a label.
|
|
368
|
-
* @see plugin/core/gvrender_core_dot.c:284 xdot_end_cluster */
|
|
369
|
-
private clusterAttrs;
|
|
370
|
-
/** Node attribute block: pos/width/height plus `_draw_`/`_ldraw_`. */
|
|
371
|
-
private nodeAttrs;
|
|
372
|
-
/** The `[...]` attribute body for an edge (draw ops + spline `pos`), or ''. */
|
|
373
|
-
private edgeAttrStr;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* DOT format renderer (`-Tdot`) — the same engine as {@link XdotRenderer} with
|
|
134
|
+
* the xdot draw-attribute step switched off, mirroring C's one renderer with a
|
|
135
|
+
* `job->render.id` switch: FORMAT_DOT is `attach_attrs(g)` then `agwrite(g)`,
|
|
136
|
+
* FORMAT_XDOT is `attach_attrs_and_arrows` + the `xdot_*` draw attributes then
|
|
137
|
+
* *the same* `agwrite(g)`. Sharing the serializer is what makes `-Tdot` emit the
|
|
138
|
+
* subgraph tree, per-scope node/edge scoping, and the `node [label="\N"]`
|
|
139
|
+
* default line, none of which a streaming emitter can produce (the whole graph
|
|
140
|
+
* must be walked before the first byte).
|
|
141
|
+
*
|
|
142
|
+
* The drawing callbacks are overridden to no-ops: `-Tdot` renders no draw ops,
|
|
143
|
+
* so accumulating them would be dead work.
|
|
144
|
+
*
|
|
145
|
+
* @see plugin/core/gvrender_core_dot.c:398 dot_begin_graph / :464 dot_end_graph
|
|
146
|
+
*/
|
|
147
|
+
export declare class DotRenderer extends XdotRenderer {
|
|
148
|
+
readonly type: string;
|
|
149
|
+
protected readonly emitDraws: boolean;
|
|
150
|
+
textspan(_pos: Point, _span: TextSpan, _job: RenderJob): void;
|
|
151
|
+
ellipse(_c: Point, _rx: number, _ry: number, _f: boolean, _j: RenderJob): void;
|
|
152
|
+
polygon(_pts: Point[], _filled: boolean, _job: RenderJob): void;
|
|
153
|
+
bezier(_pts: Point[], _filled: boolean, _job: RenderJob): void;
|
|
154
|
+
polyline(_pts: Point[], _job: RenderJob): void;
|
|
374
155
|
}
|
|
375
156
|
/** @see plugin/core/gvrender_core_dot.c FORMAT_DOT */
|
|
376
157
|
export declare function createDotRenderer(): RendererPlugin;
|