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