Graphviz 13.1.1~dev.20250718.1235
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 <stddef.h>
23#include <stdlib.h>
24#include <string.h>
25#include <util/unreachable.h>
26#include <util/xml.h>
27
28#include <xdot/xdot.h>
29#include "viewport.h"
30#include "topfisheyeview.h"
31#include "gui/appmouse.h"
32#include "hotkeymap.h"
33#include "polytess.h"
34#include <glcomp/glcompimage.h>
35
36
37//delta values
38static float dx = 0.0;
39static float dy = 0.0;
40#define LAYER_DIFF 0.001
41
42static void DrawBezier(xdot_point* pts, int filled, int param)
43{
44 /*copied from NEHE */
45 /*Written by: David Nikdel ( ogapo@ithink.net ) */
46 double Ax = pts[0].x;
47 double Ay = pts[0].y;
48 double Az = pts[0].z;
49 double Bx = pts[1].x;
50 double By = pts[1].y;
51 double Bz = pts[1].z;
52 double Cx = pts[2].x;
53 double Cy = pts[2].y;
54 double Cz = pts[2].z;
55 double Dx = pts[3].x;
56 double Dy = pts[3].y;
57 double Dz = pts[3].z;
58 double X;
59 double Y;
60 double Z;
61 int i = 0; //loop index
62 // Variable
63 double a = 1.0;
64 double b = 1.0 - a;
65 /* Tell OGL to start drawing a line strip */
66 glLineWidth(view->LineWidth);
67 if (!filled) {
68
69 if (param == 0)
70 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
71 view->penColor.A);
72 else if (param == 1) //selected
76 glBegin(GL_LINE_STRIP);
77 } else {
78 if (param == 0)
79 glColor4f(view->fillColor.R, view->fillColor.G,
81 else if (param == 1) //selected
85 glBegin(GL_POLYGON);
86 }
87 /* We will not actually draw a curve, but we will divide the curve into small
88 points and draw a line between each point. If the points are close enough, it
89 will appear as a curved line. 20 points are plenty, and since the variable goes
90 from 1.0 to 0.0 we must change it by 1/20 = 0.05 each time */
91 for (i = 0; i <= 20; i++) {
92 // Get a point on the curve
93 X = Ax * a * a * a + Bx * 3 * a * a * b + Cx * 3 * a * b * b +
94 Dx * b * b * b;
95 Y = Ay * a * a * a + By * 3 * a * a * b + Cy * 3 * a * b * b +
96 Dy * b * b * b;
97 Z = Az * a * a * a + Bz * 3 * a * a * b + Cz * 3 * a * b * b +
98 Dz * b * b * b;
99 // Draw the line from point to point (assuming OGL is set up properly)
100 glVertex3d(X, Y, Z + view->Topview->global_z);
101 // Change the variable
102 a -= 0.05;
103 b = 1.0 - a;
104 }
105// Tell OGL to stop drawing the line strip
106 glEnd();
107}
108
109static void set_options(int param)
110{
111
112 int a=get_mode(view);
113 if (param == 1 && a == 10 && view->mouse.down) // selected, if there is move, move it
114 {
117 } else {
118 dx = 0;
119 dy = 0;
120 }
121
122}
123
124static void DrawBeziers(xdot_op *op, int param) {
125 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
126 xdot_point* ps = op->u.bezier.pts;
128
129 const int filled = op->kind == xd_filled_bezier;
130
131 for (size_t i = 1; i < op->u.bezier.cnt; i += 3) {
132 DrawBezier(ps, filled, param);
133 ps += 3;
134 }
135}
136
137//Draws an ellipse made out of points.
138static void DrawEllipse(xdot_op *op, int param) {
139 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
140 int filled;
142 set_options(param);
143 double x = op->u.ellipse.x - dx;
144 double y = op->u.ellipse.y - dy;
145 double xradius = op->u.ellipse.w;
146 double yradius = op->u.ellipse.h;
147 if (op->kind == xd_filled_ellipse) {
148 if (param == 0)
149 glColor4f(view->fillColor.R, view->fillColor.G,
151 if (param == 1) //selected
155
156 filled = 1;
157 } else {
158 if (param == 0)
159 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
160 view->penColor.A);
161 if (param == 1) //selected
165
166 filled = 0;
167 }
168
169 if (!filled)
170 glBegin(GL_LINE_LOOP);
171 else
172 glBegin(GL_POLYGON);
173 for (int i = 0; i < 360; ++i) {
174 //convert degrees into radians
175 float degInRad = (float) (i * DEG2RAD);
176 glVertex3f((float)(x + cos(degInRad) * xradius),
177 (float)(y + sin(degInRad) * yradius), (float)view->Topview->global_z);
178 }
179 glEnd();
180}
181
182static void DrawPolygon(xdot_op *op, int param) {
183 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
185
186 set_options(param);
187
188 if (op->kind == xd_filled_polygon) {
189 if (param == 0)
190 glColor4f(view->fillColor.R, view->fillColor.G,
192 if (param == 1) //selected
196 } else {
197 if (param == 0)
198 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
199 view->penColor.A);
200 if (param == 1) //selected
204
205 }
206 glLineWidth(view->LineWidth);
208}
209
210static void DrawPolyline(xdot_op *op, int param) {
211 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
213
214 if (param == 0)
215 glColor4f(view->penColor.R, view->penColor.G, view->penColor.B,
216 view->penColor.A);
217 if (param == 1) //selected
220 set_options(param);
221 glLineWidth(view->LineWidth);
222 glBegin(GL_LINE_STRIP);
223 for (size_t i = 0; i < op->u.polyline.cnt; ++i) {
224 glVertex3f((float)op->u.polyline.pts[i].x - dx,
225 (float)op->u.polyline.pts[i].y - dy,
226 (float)(op->u.polyline.pts[i].z + view->Topview->global_z));
227 }
228 glEnd();
229}
230
231static glCompColor GetglCompColor(const char *color) {
232 gvcolor_t cl;
233 glCompColor c;
234 if (color != NULL) {
236 c.R = (float) cl.u.RGBA[0];
237 c.G = (float) cl.u.RGBA[1];
238 c.B = (float) cl.u.RGBA[2];
239 c.A = (float) cl.u.RGBA[3];
240 } else {
241 c = view->penColor;
242 }
243 return c;
244}
245
246static void SetFillColor(xdot_op *op, int param) {
247 (void)param;
249}
250
251static void SetPenColor(xdot_op *op, int param) {
252 (void)param;
254}
255
257
258static void SetFont(xdot_op *op, int param) {
259 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
260 (void)param;
261
262 font_op=o;
263}
264
265/*for now we only support png files in 2d space, no image rotation*/
266static void InsertImage(xdot_op *op, int param) {
267 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
268 (void)param;
269
270 if(!o->obj)
271 return;
272
273
274 if(!o->img) {
275 const float x = o->op.u.image.pos.x;
276 const float y = o->op.u.image.pos.y;
277 glCompImage *const i = o->img = glCompImageNewFile(x, y, o->op.u.image.name);
278 if (!o->img) {
279 fprintf (stderr, "Could not open file \"%s\" to read image.\n", o->op.u.image.name);
280 return;
281 }
282 i->width = o->op.u.image.pos.w;
283 i->height = o->op.u.image.pos.h;
285 }
286}
287
288// see usage in EmbedText
289static int put(void *buffer, const char *s) {
290 char **b = buffer;
291
292 const size_t len = strlen(s);
293 memcpy(*b, s, len);
294 *b += len;
295
296 return 0;
297}
298
299static void EmbedText(xdot_op *op, int param) {
300 sdot_op *const o = (sdot_op *)((char *)op - offsetof(sdot_op, op));
301 (void)param;
302
303 float x, y;
305 view->Topview->global_z += o->layer * LAYER_DIFF + 0.05;
306 switch (o->op.u.text.align)
307 {
308 case xd_left:
309 x=o->op.u.text.x ;
310 break;
311 case xd_center:
312 x=o->op.u.text.x - o->op.u.text.width / 2.0;
313 break;
314 case xd_right:
315 x=o->op.u.text.x - o->op.u.text.width;
316 break;
317 default:
318 UNREACHABLE();
319 }
320 y=o->op.u.text.y;
321 if (o->font.fontdesc == NULL) {
322 // allocate a buffer large enough to hold the maximum escaped version of the
323 // text
324 char *escaped = calloc(sizeof(char), strlen(o->op.u.text.text) *
325 sizeof("&#xFFFFFFFF;") + 1);
326 if (escaped == NULL)
327 return;
328
329 // XML-escape the text
330 const xml_flags_t flags = {.dash = 1, .nbsp = 1};
331 char *ptr = escaped;
332 (void)gv_xml_escape(o->op.u.text.text, flags, put, &ptr);
333
334 o->font = glNewFont(view->widgets, escaped, &view->penColor,
336 false);
337
338 free(escaped);
339 }
341 font_op->op.u.font.size);
342}
343
345{
346 if (vi->bdVisible) {
347 glColor4f(vi->borderColor.R, vi->borderColor.G,
348 vi->borderColor.B, vi->borderColor.A);
349 glLineWidth(2);
350 glBegin(GL_LINE_STRIP);
351 glVertex3d(vi->bdxLeft, vi->bdyBottom,-0.001);
352 glVertex3d(vi->bdxRight, vi->bdyBottom,-0.001);
353 glVertex3d(vi->bdxRight, vi->bdyTop,-0.001);
354 glVertex3d(vi->bdxLeft, vi->bdyTop,-0.001);
355 glVertex3d(vi->bdxLeft, vi->bdyBottom,-0.001);
356 glEnd();
357 glLineWidth(1);
358 }
359}
360
361void drawCircle(float x, float y, float radius, float zdepth)
362{
363 if (radius < 0.3)
364 radius = 0.4f;
365 glBegin(GL_POLYGON);
366 for (int i = 0; i < 360; i += 36) {
367 float degInRad = (float) (i * DEG2RAD);
368 glVertex3f(x + cosf(degInRad) * radius, y + sinf(degInRad) * radius,
369 (float)(zdepth + view->Topview->global_z));
370 }
371
372 glEnd();
373}
374
389
390void draw_selpoly(glCompPoly_t *selPoly) {
391 glColor4f(1,0,0,1);
392 glBegin(GL_LINE_STRIP);
393 for (size_t i = 0; i < glCompPoly_size(selPoly); ++i) {
394 const glCompPoint pt = glCompPoly_get(selPoly, i);
395 glVertex3f(pt.x, pt.y, pt.z);
396 }
397 glEnd();
398 if (!glCompPoly_is_empty(selPoly)) {
399 const glCompPoint last = *glCompPoly_back(selPoly);
400 glBegin(GL_LINE_STRIP);
401 glVertex3f(last.x, last.y, last.z);
402 glVertex3f(view->mouse.GLpos.x,view->mouse.GLpos.y,0);
403 glEnd();
404 }
405}
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:256
static void SetFont(xdot_op *op, int param)
Definition draw.c:258
void draw_selpoly(glCompPoly_t *selPoly)
Definition draw.c:390
static int put(void *buffer, const char *s)
Definition draw.c:289
static void DrawBezier(xdot_point *pts, int filled, int param)
Definition draw.c:42
static void EmbedText(xdot_op *op, int param)
Definition draw.c:299
static void DrawEllipse(xdot_op *op, int param)
Definition draw.c:138
static float dy
Definition draw.c:39
void drawBorders(ViewInfo *vi)
Definition draw.c:344
#define LAYER_DIFF
Definition draw.c:40
static void SetPenColor(xdot_op *op, int param)
Definition draw.c:251
static float dx
Definition draw.c:38
static glCompColor GetglCompColor(const char *color)
Definition draw.c:231
static void DrawPolyline(xdot_op *op, int param)
Definition draw.c:210
void drawCircle(float x, float y, float radius, float zdepth)
Definition draw.c:361
static void InsertImage(xdot_op *op, int param)
Definition draw.c:266
drawfunc_t OpFns[]
Definition draw.c:375
static void set_options(int param)
Definition draw.c:109
static void DrawBeziers(xdot_op *op, int param)
Definition draw.c:124
static void DrawPolygon(xdot_op *op, int param)
Definition draw.c:182
static void SetFillColor(xdot_op *op, int param)
Definition draw.c:246
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
void glCompDrawText3D(glCompFont f, float x, float y, double z, float w, float h)
Definition glcompfont.c:109
glCompFont glNewFont(glCompSet *s, const char *text, glCompColor *c, char *fontdesc, int fs, bool is2D)
Definition glcompfont.c:46
glCompImage * glCompImageNewFile(float x, float y, const char *imgfile)
Definition glcompimage.c:33
static double len(glCompPoint p)
Definition glutils.c:136
void free(void *)
node NULL
Definition grammar.y:180
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:54
float bdxLeft
Definition smyrnadefs.h:284
topview * Topview
Definition smyrnadefs.h:307
float LineWidth
Definition smyrnadefs.h:273
float bdyTop
Definition smyrnadefs.h:284
glCompSet * widgets
Definition smyrnadefs.h:326
glCompColor fillColor
Definition smyrnadefs.h:262
glCompColor borderColor
Definition smyrnadefs.h:266
glCompColor selectedNodeColor
Definition smyrnadefs.h:268
float bdxRight
Definition smyrnadefs.h:285
float bdyBottom
Definition smyrnadefs.h:285
int bdVisible
Definition smyrnadefs.h:281
glCompMouse mouse
Definition smyrnadefs.h:297
glCompColor penColor
Definition smyrnadefs.h:260
xdot_font font
Definition xdot.h:157
xdot_rect ellipse
Definition xdot.h:149
xdot_image image
Definition xdot.h:154
union _xdot_op::@134 u
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
double RGBA[4]
Definition color.h:32
union color_s::@74 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:84
glCompImage * img
Definition smyrnadefs.h:88
void * obj
Definition smyrnadefs.h:85
int layer
Definition smyrnadefs.h:87
glCompFont font
Definition smyrnadefs.h:86
double global_z
Definition smyrnadefs.h:233
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:89
#define UNREACHABLE()
Definition unreachable.h:30
parsing and deparsing of xdot operations
@ xop_polygon
Definition xdot.h:129
@ xop_font
Definition xdot.h:135
@ xop_image
Definition xdot.h:137
@ xop_bezier
Definition xdot.h:130
@ xop_fill_color
Definition xdot.h:133
@ xop_text
Definition xdot.h:132
@ xop_fontchar
Definition xdot.h:139
@ xop_style
Definition xdot.h:136
@ xop_grad_color
Definition xdot.h:138
@ xop_pen_color
Definition xdot.h:134
@ xop_ellipse
Definition xdot.h:128
@ xop_polyline
Definition xdot.h:131
@ 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:181
XML escaping functionality.