xref: /petsc/src/sys/classes/draw/interface/dtext.c (revision 0baf8eba40dbc839082666f9f7396a225d6f663c)
1 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/
2 
3 /*@
4   PetscDrawString - draws text onto a drawable.
5 
6   Not Collective
7 
8   Input Parameters:
9 + draw - the drawing context
10 . xl   - coordinate of lower left corner of text
11 . yl   - coordinate of lower left corner of text
12 . cl   - the color of the text
13 - text - the text to draw
14 
15   Level: beginner
16 
17 .seealso: `PetscDraw`, `PetscDrawStringVertical()`, `PetscDrawStringCentered()`, `PetscDrawStringBoxed()`, `PetscDrawStringSetSize()`,
18           `PetscDrawStringGetSize()`, `PetscDrawLine()`, `PetscDrawRectangle()`, `PetscDrawTriangle()`, `PetscDrawEllipse()`,
19           `PetscDrawMarker()`, `PetscDrawPoint()`
20 @*/
21 PetscErrorCode PetscDrawString(PetscDraw draw, PetscReal xl, PetscReal yl, int cl, const char text[])
22 {
23   PetscFunctionBegin;
24   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
25   PetscAssertPointer(text, 5);
26   PetscUseTypeMethod(draw, string, xl, yl, cl, text);
27   PetscFunctionReturn(PETSC_SUCCESS);
28 }
29 
30 /*@
31   PetscDrawStringVertical - draws text onto a drawable.
32 
33   Not Collective
34 
35   Input Parameters:
36 + draw - the drawing context
37 . xl   - coordinate of upper left corner of text
38 . yl   - coordinate of upper left corner of text
39 . cl   - the color of the text
40 - text - the text to draw
41 
42   Level: beginner
43 
44 .seealso: `PetscDraw`, `PetscDrawString()`, `PetscDrawStringCentered()`, `PetscDrawStringBoxed()`, `PetscDrawStringSetSize()`,
45           `PetscDrawStringGetSize()`
46 @*/
47 PetscErrorCode PetscDrawStringVertical(PetscDraw draw, PetscReal xl, PetscReal yl, int cl, const char text[])
48 {
49   char      chr[2] = {0, 0};
50   PetscReal tw, th;
51 
52   PetscFunctionBegin;
53   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
54   PetscAssertPointer(text, 5);
55 
56   if (draw->ops->stringvertical) PetscUseTypeMethod(draw, stringvertical, xl, yl, cl, text);
57   else {
58     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
59     for (int i = 0; (chr[0] = text[i]); i++) PetscCall(PetscDrawString(draw, xl, yl - th * ((PetscReal)i + 1), cl, chr));
60   }
61   PetscFunctionReturn(PETSC_SUCCESS);
62 }
63 
64 /*@
65   PetscDrawStringCentered - draws text onto a drawable centered at a point
66 
67   Not Collective
68 
69   Input Parameters:
70 + draw - the drawing context
71 . xc   - the coordinates of right-left center of text
72 . yl   - the coordinates of lower edge of text
73 . cl   - the color of the text
74 - text - the text to draw
75 
76   Level: beginner
77 
78 .seealso: `PetscDraw`, `PetscDrawStringVertical()`, `PetscDrawString()`, `PetscDrawStringBoxed()`, `PetscDrawStringSetSize()`,
79           `PetscDrawStringGetSize()`
80 @*/
81 PetscErrorCode PetscDrawStringCentered(PetscDraw draw, PetscReal xc, PetscReal yl, int cl, const char text[])
82 {
83   size_t    len;
84   PetscReal tw, th;
85 
86   PetscFunctionBegin;
87   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
88   PetscAssertPointer(text, 5);
89 
90   PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
91   PetscCall(PetscStrlen(text, &len));
92   xc = xc - ((PetscReal)len) * tw / 2;
93   PetscCall(PetscDrawString(draw, xc, yl, cl, text));
94   PetscFunctionReturn(PETSC_SUCCESS);
95 }
96 
97 /*@
98   PetscDrawStringBoxed - Draws a string with a box around it
99 
100   Not Collective
101 
102   Input Parameters:
103 + draw - the drawing context
104 . sxl  - the coordinates of center of the box
105 . syl  - the coordinates of top line of box
106 . sc   - the color of the text
107 . bc   - the color of the bounding box
108 - text - the text to draw
109 
110   Output Parameters:
111 + w - the width of the resulting box (optional)
112 - h - the height of resulting box (optional)
113 
114   Level: beginner
115 
116 .seealso: `PetscDraw`, `PetscDrawStringVertical()`, `PetscDrawString()`, `PetscDrawStringCentered()`, `PetscDrawStringSetSize()`,
117           `PetscDrawStringGetSize()`
118 @*/
119 PetscErrorCode PetscDrawStringBoxed(PetscDraw draw, PetscReal sxl, PetscReal syl, int sc, int bc, const char text[], PetscReal *w, PetscReal *h)
120 {
121   PetscReal top, left, right, bottom, tw, th;
122   size_t    len, mlen = 0;
123   char    **array;
124   int       cnt, i;
125 
126   PetscFunctionBegin;
127   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
128   PetscAssertPointer(text, 6);
129 
130   if (draw->ops->boxedstring) {
131     PetscUseTypeMethod(draw, boxedstring, sxl, syl, sc, bc, text, w, h);
132     PetscFunctionReturn(PETSC_SUCCESS);
133   }
134 
135   PetscCall(PetscStrToArray(text, '\n', &cnt, &array));
136   for (i = 0; i < cnt; i++) {
137     PetscCall(PetscStrlen(array[i], &len));
138     mlen = PetscMax(mlen, len);
139   }
140 
141   PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
142 
143   top    = syl;
144   left   = sxl - .5 * ((PetscReal)mlen + 2) * tw;
145   right  = sxl + .5 * ((PetscReal)mlen + 2) * tw;
146   bottom = syl - (1.0 + (PetscReal)cnt) * th;
147   if (w) *w = right - left;
148   if (h) *h = top - bottom;
149 
150   /* compute new bounding box */
151   draw->boundbox_xl = PetscMin(draw->boundbox_xl, left);
152   draw->boundbox_xr = PetscMax(draw->boundbox_xr, right);
153   draw->boundbox_yl = PetscMin(draw->boundbox_yl, bottom);
154   draw->boundbox_yr = PetscMax(draw->boundbox_yr, top);
155 
156   /* top, left, bottom, right lines */
157   PetscCall(PetscDrawLine(draw, left, top, right, top, bc));
158   PetscCall(PetscDrawLine(draw, left, bottom, left, top, bc));
159   PetscCall(PetscDrawLine(draw, right, bottom, right, top, bc));
160   PetscCall(PetscDrawLine(draw, left, bottom, right, bottom, bc));
161 
162   for (i = 0; i < cnt; i++) PetscCall(PetscDrawString(draw, left + tw, top - (1.5 + i) * th, sc, array[i]));
163   PetscCall(PetscStrToArrayDestroy(cnt, array));
164   PetscFunctionReturn(PETSC_SUCCESS);
165 }
166 
167 /*@
168   PetscDrawStringSetSize - Sets the size for character text.
169 
170   Not Collective
171 
172   Input Parameters:
173 + draw   - the drawing context
174 . width  - the width in user coordinates
175 - height - the character height in user coordinates
176 
177   Level: advanced
178 
179   Note:
180   Only a limited range of sizes are available.
181 
182 .seealso: `PetscDraw`, `PetscDrawStringVertical()`, `PetscDrawString()`, `PetscDrawStringCentered()`, `PetscDrawStringBoxed()`,
183           `PetscDrawStringGetSize()`
184 @*/
185 PetscErrorCode PetscDrawStringSetSize(PetscDraw draw, PetscReal width, PetscReal height)
186 {
187   PetscFunctionBegin;
188   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
189   PetscTryTypeMethod(draw, stringsetsize, width, height);
190   PetscFunctionReturn(PETSC_SUCCESS);
191 }
192 
193 /*@
194   PetscDrawStringGetSize - Gets the size for character text.  The width is
195   relative to the user coordinates of the window.
196 
197   Not Collective
198 
199   Input Parameters:
200 + draw   - the drawing context
201 . width  - the width in user coordinates
202 - height - the character height
203 
204   Level: advanced
205 
206 .seealso: `PetscDraw`, `PetscDrawStringVertical()`, `PetscDrawString()`, `PetscDrawStringCentered()`, `PetscDrawStringBoxed()`,
207           `PetscDrawStringSetSize()`
208 @*/
209 PetscErrorCode PetscDrawStringGetSize(PetscDraw draw, PetscReal *width, PetscReal *height)
210 {
211   PetscFunctionBegin;
212   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
213   PetscUseTypeMethod(draw, stringgetsize, width, height);
214   PetscFunctionReturn(PETSC_SUCCESS);
215 }
216