Graphviz 13.0.0~dev.20250424.1043
Loading...
Searching...
No Matches
draw.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11/*
12
13XDOT DRAWING FUNCTIONS, maybe need to move them somewhere else
14 for now keep them at the bottom
15*/
16#include "draw.h"
17#include <common/colorprocs.h>
18#include "smyrna_utils.h"
19#include <glcomp/glutils.h>
20#include <math.h>
21#include <stdbool.h>
22#include <stdlib.h>
23#include <util/unreachable.h>
24#include <util/xml.h>
25
26#include <xdot/xdot.h>
27#include "viewport.h"
28#include "topfisheyeview.h"
29#include "appmouse.h"
30#include "hotkeymap.h"
31#include "polytess.h"
32#include <glcomp/glcompimage.h>
33
34
35//delta values
36static float dx = 0.0;
37static float dy = 0.0;
38#define LAYER_DIFF 0.001
39
40static void DrawBezier(xdot_point* pts, int filled, int param)
41{
42 /*copied from NEHE */
43 /*Written by: David Nikdel ( ogapo@ithink.net ) */
44 double Ax = pts[0].x;
45 double Ay = pts[0].y;
46 double Az = pts[0].z;
47 double Bx = pts[1].x;
48 double By = pts[1].y;
49 double Bz = pts[1].z;
50 double Cx = pts[2].x;
51 double Cy = pts[2].y;
52 double Cz = pts[2].z;
53 double Dx = pts[3].x;
54 double Dy = pts[3].y;
55 double Dz = pts[3].z;
56 double X;
57 double Y;
58 double Z;
59 int i = 0; //loop index
60 // Variable
61 double a = 1.0;
62 double b = 1.0 - a;
63 /* Tell OGL to start drawing a line strip */
64 glLineWidth(view->LineWidth);
65 if (!filled) {
66
67 if (param == 0)
68 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
69 view->penColor.A);
70 else if (param == 1) //selected
74 glBegin(GL_LINE_STRIP);
75 } else {
76 if (param == 0)
77 glColor4f(view->fillColor.R, view->fillColor.G,
79 else if (param == 1) //selected
83 glBegin(GL_POLYGON);
84 }
85 /* We will not actually draw a curve, but we will divide the curve into small
86 points and draw a line between each point. If the points are close enough, it
87 will appear as a curved line. 20 points are plenty, and since the variable goes
88 from 1.0 to 0.0 we must change it by 1/20 = 0.05 each time */
89 for (i = 0; i <= 20; i++) {
90 // Get a point on the curve
91 X = Ax * a * a * a + Bx * 3 * a * a * b + Cx * 3 * a * b * b +
92 Dx * b * b * b;
93 Y = Ay * a * a * a + By * 3 * a * a * b + Cy * 3 * a * b * b +
94 Dy * b * b * b;
95 Z = Az * a * a * a + Bz * 3 * a * a * b + Cz * 3 * a * b * b +
96 Dz * b * b * b;
97 // Draw the line from point to point (assuming OGL is set up properly)
98 glVertex3d(X, Y, Z + view->Topview->global_z);
99 // Change the variable
100 a -= 0.05;
101 b = 1.0 - a;
102 }
103// Tell OGL to stop drawing the line strip
104 glEnd();
105}
106
107static void set_options(int param)
108{
109
110 int a=get_mode(view);
111 if (param == 1 && a == 10 && view->mouse.down) // selected, if there is move, move it
112 {
115 } else {
116 dx = 0;
117 dy = 0;
118 }
119
120}
121
122static void DrawBeziers(sdot_op* o, int param)
123{
124 int filled;
125 xdot_op * op=&o->op;
126 xdot_point* ps = op->u.bezier.pts;
128
129 if (op->kind == xd_filled_bezier)
130 filled = 1;
131 else
132 filled = 0;
133
134 for (size_t i = 1; i < op->u.bezier.cnt; i += 3) {
135 DrawBezier(ps, filled, param);
136 ps += 3;
137 }
138}
139
140//Draws an ellipse made out of points.
141static void DrawEllipse(sdot_op* o, int param)
142{
143 int i = 0;
144 int filled;
145 xdot_op * op=&o->op;
147 set_options(param);
148 double x = op->u.ellipse.x - dx;
149 double y = op->u.ellipse.y - dy;
150 double xradius = op->u.ellipse.w;
151 double yradius = op->u.ellipse.h;
152 if (op->kind == xd_filled_ellipse) {
153 if (param == 0)
154 glColor4f(view->fillColor.R, view->fillColor.G,
156 if (param == 1) //selected
160
161 filled = 1;
162 } else {
163 if (param == 0)
164 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
165 view->penColor.A);
166 if (param == 1) //selected
170
171 filled = 0;
172 }
173
174 if (!filled)
175 glBegin(GL_LINE_LOOP);
176 else
177 glBegin(GL_POLYGON);
178 for (i = 0; i < 360; i = i + 1) {
179 //convert degrees into radians
180 float degInRad = (float) (i * DEG2RAD);
181 glVertex3f((float)(x + cos(degInRad) * xradius),
182 (float)(y + sin(degInRad) * yradius), (float)view->Topview->global_z);
183 }
184 glEnd();
185}
186
187static void DrawPolygon(sdot_op * o, int param)
188{
189 xdot_op * op=&o->op;
191
192 set_options(param);
193
194 if (op->kind == xd_filled_polygon) {
195 if (param == 0)
196 glColor4f(view->fillColor.R, view->fillColor.G,
198 if (param == 1) //selected
202 } else {
203 if (param == 0)
204 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
205 view->penColor.A);
206 if (param == 1) //selected
210
211 }
212 glLineWidth(view->LineWidth);
214}
215
216
217static void DrawPolyline(sdot_op* o, int param)
218{
219 xdot_op * op=&o->op;
221
222 if (param == 0)
223 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
224 view->penColor.A);
225 if (param == 1) //selected
228 set_options(param);
229 glLineWidth(view->LineWidth);
230 glBegin(GL_LINE_STRIP);
231 for (size_t i = 0; i < op->u.polyline.cnt; ++i) {
232 glVertex3f((float)op->u.polyline.pts[i].x - dx,
233 (float)op->u.polyline.pts[i].y - dy,
234 (float)(op->u.polyline.pts[i].z + view->Topview->global_z));
235 }
236 glEnd();
237}
238
239static glCompColor GetglCompColor(const char *color) {
240 gvcolor_t cl;
241 glCompColor c;
242 if (color != NULL) {
244 c.R = (float) cl.u.RGBA[0];
245 c.G = (float) cl.u.RGBA[1];
246 c.B = (float) cl.u.RGBA[2];
247 c.A = (float) cl.u.RGBA[3];
248 } else {
249 c = view->penColor;
250 }
251 return c;
252}
253static void SetFillColor(sdot_op* o, int param)
254{
255 (void)param;
256
257 xdot_op * op=&o->op;
259}
260static void SetPenColor(sdot_op* o, int param)
261{
262 (void)param;
263
264 xdot_op * op=&o->op;
266}
267
268static void SetStyle(sdot_op* o, int param)
269{
270 (void)o;
271 (void)param;
272}
273
275
276static void SetFont(sdot_op * o, int param)
277{
278 (void)param;
279
280 font_op=o;
281}
282
283/*for now we only support png files in 2d space, no image rotation*/
284static void InsertImage(sdot_op * o, int param)
285{
286 (void)param;
287
288 float x,y;
289 glCompImage *i;
290
291 if(!o->obj)
292 return;
293
294
295 if(!o->img) {
296 x = o->op.u.image.pos.x;
297 y = o->op.u.image.pos.y;
298 i = o->img = glCompImageNewFile(x, y, o->op.u.image.name);
299 if (!o->img) {
300 fprintf (stderr, "Could not open file \"%s\" to read image.\n", o->op.u.image.name);
301 return;
302 }
303 i->width = o->op.u.image.pos.w;
304 i->height = o->op.u.image.pos.h;
306 }
307}
308
309// see usage in EmbedText
310static int put(void *buffer, const char *s) {
311 char **b = buffer;
312
313 for (; *s != '\0'; ++s) {
314 **b = *s;
315 ++(*b);
316 }
317
318 return 0;
319}
320
321static void EmbedText(sdot_op* o, int param)
322{
323 (void)param;
324
325 float x, y;
327 view->Topview->global_z += o->layer * LAYER_DIFF + 0.05;
328 switch (o->op.u.text.align)
329 {
330 case xd_left:
331 x=o->op.u.text.x ;
332 break;
333 case xd_center:
334 x=o->op.u.text.x - o->op.u.text.width / 2.0;
335 break;
336 case xd_right:
337 x=o->op.u.text.x - o->op.u.text.width;
338 break;
339 default:
340 UNREACHABLE();
341 }
342 y=o->op.u.text.y;
343 if (o->font.fontdesc == NULL) {
344 // allocate a buffer large enough to hold the maximum escaped version of the
345 // text
346 char *escaped = calloc(sizeof(char), strlen(o->op.u.text.text) *
347 sizeof("&#xFFFFFFFF;") + 1);
348 if (escaped == NULL)
349 return;
350
351 // XML-escape the text
352 const xml_flags_t flags = {.dash = 1, .nbsp = 1};
353 char **ptr = &escaped;
354 (void)gv_xml_escape(o->op.u.text.text, flags, put, ptr);
355
356 o->font = glNewFont(view->widgets, escaped, &view->penColor,
358 false);
359
360 free(escaped);
361 }
363 font_op->op.u.font.size);
364}
365
367{
368 if (vi->bdVisible) {
369 glColor4f(vi->borderColor.R, vi->borderColor.G,
370 vi->borderColor.B, vi->borderColor.A);
371 glLineWidth(2);
372 glBegin(GL_LINE_STRIP);
373 glVertex3d(vi->bdxLeft, vi->bdyBottom,-0.001);
374 glVertex3d(vi->bdxRight, vi->bdyBottom,-0.001);
375 glVertex3d(vi->bdxRight, vi->bdyTop,-0.001);
376 glVertex3d(vi->bdxLeft, vi->bdyTop,-0.001);
377 glVertex3d(vi->bdxLeft, vi->bdyBottom,-0.001);
378 glEnd();
379 glLineWidth(1);
380 }
381}
382
383void drawCircle(float x, float y, float radius, float zdepth)
384{
385 int i;
386 if (radius < 0.3)
387 radius = 0.4f;
388 glBegin(GL_POLYGON);
389 for (i = 0; i < 360; i = i + 36) {
390 float degInRad = (float) (i * DEG2RAD);
391 glVertex3f((float)(x + cos(degInRad) * radius),
392 (float)(y + sin(degInRad) * radius),
393 (float)(zdepth + view->Topview->global_z));
394 }
395
396 glEnd();
397}
398
411
412void draw_selpoly(glCompPoly_t *selPoly) {
413 glColor4f(1,0,0,1);
414 glBegin(GL_LINE_STRIP);
415 for (size_t i = 0; i < glCompPoly_size(selPoly); ++i) {
416 const glCompPoint pt = glCompPoly_get(selPoly, i);
417 glVertex3f(pt.x, pt.y, pt.z);
418 }
419 glEnd();
420 if (!glCompPoly_is_empty(selPoly)) {
421 const glCompPoint last = *glCompPoly_back(selPoly);
422 glBegin(GL_LINE_STRIP);
423 glVertex3f(last.x, last.y, last.z);
424 glVertex3f(view->mouse.GLpos.x,view->mouse.GLpos.y,0);
425 glEnd();
426 }
427}
static agxbuf last
last message
Definition agerror.c:29
@ RGBA_DOUBLE
Definition color.h:27
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:46
static sdot_op * font_op
Definition draw.c:274
static void DrawBeziers(sdot_op *o, int param)
Definition draw.c:122
void draw_selpoly(glCompPoly_t *selPoly)
Definition draw.c:412
static int put(void *buffer, const char *s)
Definition draw.c:310
static void DrawBezier(xdot_point *pts, int filled, int param)
Definition draw.c:40
static void SetStyle(sdot_op *o, int param)
Definition draw.c:268
static void EmbedText(sdot_op *o, int param)
Definition draw.c:321
static float dy
Definition draw.c:37
void drawBorders(ViewInfo *vi)
Definition draw.c:366
static void DrawPolygon(sdot_op *o, int param)
Definition draw.c:187
#define LAYER_DIFF
Definition draw.c:38
static float dx
Definition draw.c:36
static glCompColor GetglCompColor(const char *color)
Definition draw.c:239
void drawCircle(float x, float y, float radius, float zdepth)
Definition draw.c:383
drawfunc_t OpFns[]
Definition draw.c:399
static void set_options(int param)
Definition draw.c:107
static void SetFillColor(sdot_op *o, int param)
Definition draw.c:253
static void SetPenColor(sdot_op *o, int param)
Definition draw.c:260
static void InsertImage(sdot_op *o, int param)
Definition draw.c:284
static void SetFont(sdot_op *o, int param)
Definition draw.c:276
static void DrawPolyline(sdot_op *o, int param)
Definition draw.c:217
static void DrawEllipse(sdot_op *o, int param)
Definition draw.c:141
static int flags
Definition gc.c:61
#define Y(i)
Definition gdefs.h:3
#define X(prefix, name, str, type, subtype,...)
Definition gdefs.h:14
glCompFont glNewFont(glCompSet *s, char *text, glCompColor *c, char *fontdesc, int fs, bool is2D)
Definition glcompfont.c:46
void glCompDrawText3D(glCompFont f, float x, float y, double z, float w, float h)
Definition glcompfont.c:109
glCompImage * glCompImageNewFile(float x, float y, const char *imgfile)
Definition glcompimage.c:33
void free(void *)
node NULL
Definition grammar.y:163
static void color(Agraph_t *g)
Definition gvcolor.c:129
int get_mode(ViewInfo *v)
Definition hotkeymap.c:166
static int * ps
Definition lu.c:51
void drawTessPolygon(sdot_op *p)
Definition polytess.c:109
ViewInfo * view
Definition viewport.c:37
#define DEG2RAD
Definition smyrnadefs.h:56
float bdxLeft
Definition smyrnadefs.h:289
topview * Topview
Definition smyrnadefs.h:312
float LineWidth
Definition smyrnadefs.h:278
float bdyTop
Definition smyrnadefs.h:289
glCompSet * widgets
Definition smyrnadefs.h:335
glCompColor fillColor
Definition smyrnadefs.h:267
glCompColor borderColor
Definition smyrnadefs.h:271
glCompColor selectedNodeColor
Definition smyrnadefs.h:273
float bdxRight
Definition smyrnadefs.h:290
float bdyBottom
Definition smyrnadefs.h:290
int bdVisible
Definition smyrnadefs.h:286
glCompMouse mouse
Definition smyrnadefs.h:302
glCompColor penColor
Definition smyrnadefs.h:265
xdot_font font
Definition xdot.h:157
xdot_rect ellipse
Definition xdot.h:149
xdot_image image
Definition xdot.h:154
char * color
Definition xdot.h:155
xdot_kind kind
Definition xdot.h:147
xdot_text text
Definition xdot.h:153
xdot_polyline bezier
Definition xdot.h:152
xdot_polyline polyline
Definition xdot.h:151
union _xdot_op::@127 u
double RGBA[4]
Definition color.h:32
union color_s::@72 u
glcompdrawfunc_t draw
Definition glcompdefs.h:150
glCompCallBacks functions
Definition glcompdefs.h:179
char * fontdesc
Definition glcompdefs.h:139
glCompObj base
Definition glcompdefs.h:190
glCompPoint GLfinalPos
Definition glcompdefs.h:227
glCompPoint GLpos
Definition glcompdefs.h:225
glCompPoint GLinitPos
Definition glcompdefs.h:226
glCompCommon common
Definition glcompdefs.h:185
xdot_op op
Definition smyrnadefs.h:86
glCompImage * img
Definition smyrnadefs.h:90
void * obj
Definition smyrnadefs.h:87
int layer
Definition smyrnadefs.h:89
glCompFont font
Definition smyrnadefs.h:88
double global_z
Definition smyrnadefs.h:238
double size
Definition xdot.h:104
char * name
Definition xdot.h:105
char * name
Definition xdot.h:100
xdot_rect pos
Definition xdot.h:99
double x
Definition xdot.h:79
double z
Definition xdot.h:79
double y
Definition xdot.h:79
size_t cnt
Definition xdot.h:87
xdot_point * pts
Definition xdot.h:88
double x
Definition xdot.h:83
double w
Definition xdot.h:83
double y
Definition xdot.h:83
double h
Definition xdot.h:83
double width
Definition xdot.h:94
char * text
Definition xdot.h:95
double x
Definition xdot.h:92
xdot_align align
Definition xdot.h:93
double y
Definition xdot.h:92
options to tweak the behavior of XML escaping
Definition xml.h:30
unsigned dash
escape '-'
Definition xml.h:34
Definition grammar.c:93
#define UNREACHABLE()
Definition unreachable.h:30
parsing and deparsing of xdot operations
@ xd_left
Definition xdot.h:76
@ xd_right
Definition xdot.h:76
@ xd_center
Definition xdot.h:76
void(* drawfunc_t)(xdot_op *, int)
Definition xdot.h:143
@ xd_filled_polygon
Definition xdot.h:111
@ xd_filled_ellipse
Definition xdot.h:109
@ xd_filled_bezier
Definition xdot.h:113
int gv_xml_escape(const char *s, xml_flags_t flags, int(*cb)(void *state, const char *s), void *state)
Definition xml.c:178
XML escaping functionality.