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