1 /*
2  * FIG : Facility for Interactive Generation of figures
3  * Copyright (c) 1989-2007 by Brian V. Smith
4  *
5  * Any party obtaining a copy of these files is granted, free of charge, a
6  * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
7  * nonexclusive right and license to deal in this software and documentation
8  * files (the "Software"), including without limitation the rights to use,
9  * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
10  * the Software, and to permit persons who receive copies from any such
11  * party to do so, with the only requirement being that the above copyright
12  * and this permission notice remain intact.
13  *
14  */
15 
16 #include "fig.h"
17 #include "figx.h"
18 #include "resources.h"
19 #include "u_fonts.h"		/* printer font names */
20 #include "w_fontbits.h"
21 #include "w_indpanel.h"
22 #include "w_msgpanel.h"
23 #include "w_fontpanel.h"
24 #include "w_setup.h"
25 #include "w_util.h"
26 #include "w_color.h"
27 
28 /********************  local variables	***************************/
29 
30 static int     *font_ps_sel;	/* ptr to store selected ps font in */
31 static int     *font_latex_sel; /* ptr to store selected latex font */
32 static int     *flag_sel;	/* pointer to store ps/latex flag */
33 static Widget	font_widget;	/* widget adr to store font image in */
34 static void	(*font_setimage) ();
35 
36 static MenuItemRec ps_fontmenu_items[NUM_FONTS + 1];
37 static MenuItemRec latex_fontmenu_items[NUM_LATEX_FONTS];
38 
39 static void	fontpane_select(Widget w, XtPointer closure, XtPointer call_data);
40 static void	fontpane_cancel(void);
41 static void	fontpane_swap(void);
42 
43 static XtCallbackRec pane_callbacks[] =
44 {
45     {fontpane_select, NULL},
46     {NULL, NULL},
47 };
48 
49 static String	fontpane_translations =
50 	"<Message>WM_PROTOCOLS: FontPaneCancel()\n\
51 	 <Key>Escape: FontPaneCancel()\n";
52 static XtActionsRec	fontpane_actions[] =
53 {
54     {"FontPaneCancel", (XtActionProc) fontpane_cancel},
55 };
56 
57 static Widget	ps_fontpanes, ps_form;
58 static Widget	latex_fontpanes, latex_form;
59 static Widget	ps_fontpane[NUM_FONTS+1];
60 static Widget	latex_fontpane[NUM_LATEX_FONTS];
61 static Boolean	first_fontmenu;
62 
63 
64 
65 void
init_fontmenu(Widget tool)66 init_fontmenu(Widget tool)
67 {
68     Widget	    tmp_but, ps_cancel, latex_cancel;
69     register intptr_t i;
70     register MenuItemRec *mi;
71     XtTranslations  pane_actions;
72 
73     DeclareArgs(8);
74 
75     first_fontmenu = True;
76 
77     FirstArg(XtNborderWidth, POPUP_BW);
78     NextArg(XtNmappedWhenManaged, False);
79     NextArg(XtNtitle, "Xfig: Font menu");
80 
81     ps_fontmenu = XtCreatePopupShell("ps_font_menu",
82 				     transientShellWidgetClass, tool,
83 				     Args, ArgCount);
84     XtOverrideTranslations(ps_fontmenu,
85 			XtParseTranslationTable(fontpane_translations));
86     latex_fontmenu = XtCreatePopupShell("latex_font_menu",
87 					transientShellWidgetClass, tool,
88 					Args, ArgCount);
89     XtOverrideTranslations(latex_fontmenu,
90 			XtParseTranslationTable(fontpane_translations));
91     XtAppAddActions(tool_app, fontpane_actions, XtNumber(fontpane_actions));
92 
93     FirstArg(XtNwidth, PS_FONTPANE_WD*2);
94     NextArg(XtNdefaultDistance, INTERNAL_BW);
95     NextArg(XtNborderWidth, 0);
96     NextArg(XtNtop, XtChainTop);
97     NextArg(XtNbottom, XtChainTop);
98     NextArg(XtNleft, XtChainLeft);
99     NextArg(XtNright, XtChainLeft);
100     ps_form = XtCreateManagedWidget("ps_form", formWidgetClass,
101 				       ps_fontmenu, Args, ArgCount);
102     XtOverrideTranslations(ps_form,
103 			XtParseTranslationTable(fontpane_translations));
104 
105     FirstArg(XtNwidth, LATEX_FONTPANE_WD*2);
106     NextArg(XtNdefaultDistance, INTERNAL_BW);
107     NextArg(XtNborderWidth, 0);
108     NextArg(XtNtop, XtChainTop);
109     NextArg(XtNbottom, XtChainTop);
110     NextArg(XtNleft, XtChainLeft);
111     NextArg(XtNright, XtChainLeft);
112     latex_form = XtCreateManagedWidget("latex_form", formWidgetClass,
113 					  latex_fontmenu, Args, ArgCount);
114     XtOverrideTranslations(latex_fontmenu,
115 			XtParseTranslationTable(fontpane_translations));
116 
117     /* box with PostScript font image buttons */
118     FirstArg(XtNvSpace, -INTERNAL_BW);
119     NextArg (XtNhSpace, -INTERNAL_BW);
120     NextArg (XtNwidth, PS_FONTPANE_WD*2 + INTERNAL_BW*4);	/* two across */
121     NextArg (XtNhSpace, 0);
122     NextArg(XtNtop, XtChainTop);
123     NextArg(XtNbottom, XtChainTop);
124     NextArg(XtNleft, XtChainLeft);
125     NextArg(XtNright, XtChainLeft);
126     ps_fontpanes = XtCreateManagedWidget("menu", boxWidgetClass,
127 					 ps_form, Args, ArgCount);
128 
129     /* box with LaTeX font image buttons */
130     FirstArg(XtNvSpace, -INTERNAL_BW);
131     NextArg (XtNhSpace, -INTERNAL_BW);
132     NextArg (XtNwidth, LATEX_FONTPANE_WD*2 + INTERNAL_BW*4);	/* two across */
133     NextArg (XtNhSpace, 0);
134     NextArg(XtNtop, XtChainTop);
135     NextArg(XtNbottom, XtChainTop);
136     NextArg(XtNleft, XtChainLeft);
137     NextArg(XtNright, XtChainLeft);
138     latex_fontpanes = XtCreateManagedWidget("menu", boxWidgetClass,
139 					    latex_form, Args, ArgCount);
140 
141     for (i = 0; i < NUM_FONTS + 1; i++) {
142 	ps_fontmenu_items[i].type = MENU_IMAGESTRING;		/* put the fontnames in
143 								 * menu */
144 	ps_fontmenu_items[i].label = ps_fontinfo[i].name;
145 	ps_fontmenu_items[i].info = (caddr_t) (i - 1);		/* index for font # */
146     }
147 
148     for (i = 0; i < NUM_LATEX_FONTS; i++) {
149 	latex_fontmenu_items[i].type = MENU_IMAGESTRING;	/* put the fontnames in
150 								 * menu */
151 	latex_fontmenu_items[i].label = latex_fontinfo[i].name;
152 	latex_fontmenu_items[i].info = (caddr_t) i;		/* index for font # */
153     }
154 
155     pane_actions = XtParseTranslationTable("<EnterWindow>:set()\n\
156 		<Btn1Up>:notify()unset()\n");
157 
158     /* make the PostScript font image buttons */
159     FirstArg(XtNwidth, PS_FONTPANE_WD);
160     NextArg(XtNheight, PS_FONTPANE_HT+4);
161     NextArg(XtNcallback, pane_callbacks);
162     NextArg(XtNbitmap, NULL);
163     NextArg(XtNinternalWidth, 0);	/* space between pixmap and edge */
164     NextArg(XtNinternalHeight, 0);
165     NextArg(XtNborderWidth, INTERNAL_BW);
166     NextArg(XtNresize, False);	/* don't allow resize */
167 
168     for (i = 0; i < NUM_FONTS + 1; ++i) {
169 	mi = &ps_fontmenu_items[i];
170 	pane_callbacks[0].closure = (caddr_t) mi;
171 	ps_fontpane[i] = XtCreateManagedWidget("pane", commandWidgetClass,
172 					       ps_fontpanes, Args, ArgCount);
173 	XtOverrideTranslations(ps_fontpane[i], pane_actions);
174     }
175     /* Cancel */
176     FirstArg(XtNlabel, "Cancel");
177     NextArg(XtNfromVert, ps_fontpanes);
178     NextArg(XtNhorizDistance, 4);
179     NextArg(XtNtop, XtChainTop);
180     NextArg(XtNbottom, XtChainTop);
181     NextArg(XtNleft, XtChainLeft);
182     NextArg(XtNright, XtChainLeft);
183     ps_cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
184 				    ps_form, Args, ArgCount);
185     XtAddEventHandler(ps_cancel, ButtonReleaseMask, False,
186 		      (XtEventHandler)fontpane_cancel, (XtPointer) NULL);
187 
188     /* button to switch to the LaTeX fonts */
189     FirstArg(XtNlabel, " Use LaTex Fonts ");
190     NextArg(XtNfromVert, ps_fontpanes);
191     NextArg(XtNfromHoriz, ps_cancel);
192     NextArg(XtNhorizDistance, 10);
193     NextArg(XtNtop, XtChainTop);
194     NextArg(XtNbottom, XtChainTop);
195     NextArg(XtNleft, XtChainLeft);
196     NextArg(XtNright, XtChainLeft);
197     tmp_but = XtCreateManagedWidget("use_latex_fonts", commandWidgetClass,
198 				    ps_form, Args, ArgCount);
199     XtAddEventHandler(tmp_but, ButtonReleaseMask, False,
200 		      (XtEventHandler)fontpane_swap, (XtPointer) NULL);
201 
202     /* now make the LaTeX font image buttons */
203     FirstArg(XtNwidth, LATEX_FONTPANE_WD);
204     NextArg(XtNheight, LATEX_FONTPANE_HT+4);
205     NextArg(XtNcallback, pane_callbacks);
206     NextArg(XtNbitmap, NULL);
207     NextArg(XtNinternalWidth, 0);	/* space between pixmap and edge */
208     NextArg(XtNinternalHeight, 0);
209     NextArg(XtNborderWidth, INTERNAL_BW);
210     NextArg(XtNresize, False);	/* don't allow resize */
211 
212     for (i = 0; i < NUM_LATEX_FONTS; ++i) {
213 	mi = &latex_fontmenu_items[i];
214 	pane_callbacks[0].closure = (caddr_t) mi;
215 	latex_fontpane[i] = XtCreateManagedWidget("pane", commandWidgetClass,
216 					   latex_fontpanes, Args, ArgCount);
217 	XtOverrideTranslations(latex_fontpane[i], pane_actions);
218     }
219     /* Cancel */
220     FirstArg(XtNlabel, "Cancel");
221     NextArg(XtNfromVert, latex_fontpanes);
222     NextArg(XtNhorizDistance, 4);
223     NextArg(XtNtop, XtChainTop);
224     NextArg(XtNbottom, XtChainTop);
225     NextArg(XtNleft, XtChainLeft);
226     NextArg(XtNright, XtChainLeft);
227     latex_cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
228 				    latex_form, Args, ArgCount);
229     XtAddEventHandler(latex_cancel, ButtonReleaseMask, False,
230 		      (XtEventHandler)fontpane_cancel, (XtPointer) NULL);
231 
232     /* button to switch to the PostScript fonts */
233     FirstArg(XtNlabel, " Use PostScript Fonts ");
234     NextArg(XtNfromVert, latex_fontpanes);
235     NextArg(XtNfromHoriz, latex_cancel);
236     NextArg(XtNhorizDistance, 10);
237     NextArg(XtNtop, XtChainTop);
238     NextArg(XtNbottom, XtChainTop);
239     NextArg(XtNleft, XtChainLeft);
240     NextArg(XtNright, XtChainLeft);
241     tmp_but = XtCreateManagedWidget("use_postscript_fonts", commandWidgetClass,
242 				    latex_form, Args, ArgCount);
243     XtAddEventHandler(tmp_but, ButtonReleaseMask, False,
244 		      (XtEventHandler)fontpane_swap, (XtPointer) NULL);
245 
246     XtInstallAccelerators(ps_form, ps_cancel);
247     XtInstallAccelerators(latex_form, latex_cancel);
248 }
249 
250 /* create the bitmaps for the font menu */
251 
252 void
setup_fontmenu(void)253 setup_fontmenu(void)
254 {
255     register int    i;
256 
257     DeclareArgs(2);
258 
259     Pixel	    bg, fg;
260 
261     /* get the foreground/background of the widget */
262     FirstArg(XtNforeground, &fg);
263     NextArg(XtNbackground, &bg);
264     GetValues(ps_fontpane[0]);
265 
266     /* Create the bitmaps */
267 
268 #ifdef I18N
269     if (appres.international) {
270       char *lang;
271       lang = appres.font_menu_language;
272       if (lang[0] == '\0') lang = setlocale(LC_CTYPE, NULL);
273       if (strncasecmp(lang, "japanese", 2) == 0) {
274 	extern unsigned char Japanese_Times_Roman_bits[], Japanese_Roman_bits[];
275 	extern unsigned char Japanese_Times_Bold_bits[], Japanese_Bold_bits[];
276 	psfont_menu_bits[1] = Japanese_Times_Roman_bits;
277 	latexfont_menu_bits[1] = Japanese_Roman_bits;
278 	psfont_menu_bits[3] = Japanese_Times_Bold_bits;
279 	latexfont_menu_bits[2] = Japanese_Bold_bits;
280       } else if (strncasecmp(lang, "korean", 2) == 0) {
281 	extern unsigned char Korean_Times_Roman_bits[], Korean_Roman_bits[];
282 	extern unsigned char Korean_Times_Bold_bits[], Korean_Bold_bits[];
283 	psfont_menu_bits[1] = Korean_Times_Roman_bits;
284 	latexfont_menu_bits[1] = Korean_Roman_bits;
285 	psfont_menu_bits[3] = Korean_Times_Bold_bits;
286 	latexfont_menu_bits[2] = Korean_Bold_bits;
287       }
288     }
289 #endif  /* I18N */
290     for (i = 0; i < NUM_FONTS + 1; i++)
291 	psfont_menu_bitmaps[i] = XCreatePixmapFromBitmapData(tool_d,
292 				   XtWindow(ind_panel), (char *) psfont_menu_bits[i],
293 				     PS_FONTPANE_WD, PS_FONTPANE_HT, fg, bg,
294 				      tool_dpth);
295 
296     for (i = 0; i < NUM_LATEX_FONTS; i++)
297 	latexfont_menu_bitmaps[i] = XCreatePixmapFromBitmapData(tool_d,
298 				     XtWindow(ind_panel), (char *) latexfont_menu_bits[i],
299 				      LATEX_FONTPANE_WD, LATEX_FONTPANE_HT, fg, bg,
300 				       tool_dpth);
301 
302     /* Store the bitmaps in the menu panes */
303     for (i = 0; i < NUM_FONTS + 1; i++) {
304 	FirstArg(XtNbitmap, psfont_menu_bitmaps[i]);
305 	SetValues(ps_fontpane[i]);
306     }
307     for (i = 0; i < NUM_LATEX_FONTS; i++) {
308 	FirstArg(XtNbitmap, latexfont_menu_bitmaps[i]);
309 	SetValues(latex_fontpane[i]);
310     }
311 
312     XtRealizeWidget(ps_fontmenu);
313     XtRealizeWidget(latex_fontmenu);
314     /* at this point the windows are realized but not drawn */
315     XDefineCursor(tool_d, XtWindow(ps_fontpanes), arrow_cursor);
316     XDefineCursor(tool_d, XtWindow(latex_fontpanes), arrow_cursor);
317 }
318 
319 void
fontpane_popup(int * psfont_adr,int * latexfont_adr,int * psflag_adr,void (* showfont_fn)(),Widget show_widget)320 fontpane_popup(int *psfont_adr, int *latexfont_adr, int *psflag_adr, void (*showfont_fn) (/* ??? */), Widget show_widget)
321 {
322     DeclareArgs(2);
323     Position	    xposn, yposn;
324     Widget	    widg;
325 
326     font_ps_sel = psfont_adr;
327     font_latex_sel = latexfont_adr;
328     flag_sel = psflag_adr;
329     font_setimage = showfont_fn;
330     font_widget = show_widget;
331     if (first_fontmenu) {
332 	first_fontmenu = False;	/* don't reposition it if user has already popped it */
333 	XtTranslateCoords(tool, CANVAS_WD/4, CANVAS_HT/4, &xposn, &yposn);
334 	FirstArg(XtNx, xposn);	/* position about 1/4 from upper-left corner of canvas */
335 	NextArg(XtNy, yposn);
336 	SetValues(ps_fontmenu);
337 	SetValues(latex_fontmenu);
338     }
339     widg = *flag_sel ? ps_fontmenu : latex_fontmenu;
340     XtPopup(widg, XtGrabExclusive);
341     /* if the file message window is up add it to the grab */
342     file_msg_add_grab();
343     /* insure that the most recent colormap is installed */
344     set_cmap(XtWindow(widg));
345     XSetWMProtocols(tool_d, XtWindow(widg), &wm_delete_window, 1);
346 }
347 
348 static void
fontpane_select(Widget w,XtPointer closure,XtPointer call_data)349 fontpane_select(Widget w, XtPointer closure, XtPointer call_data)
350 {
351     MenuItemRec	   *mi = (MenuItemRec *) closure;
352     char	   *font_name = mi->label;
353     ptr_int	data = {mi->info};
354 
355     if (*flag_sel)
356 	*font_ps_sel = data.val;
357     else
358 	*font_latex_sel = data.val;
359 
360     put_msg("Font: %s", font_name);
361     /* put image of font in indicator window */
362     (*font_setimage) (font_widget);
363     XtPopdown(*flag_sel ? ps_fontmenu : latex_fontmenu);
364 }
365 
366 static void
fontpane_cancel(void)367 fontpane_cancel(void)
368 {
369     XtPopdown(*flag_sel ? ps_fontmenu : latex_fontmenu);
370 }
371 
372 static void
fontpane_swap(void)373 fontpane_swap(void)
374 {
375     Widget widg;
376 
377     XtPopdown(*flag_sel ? ps_fontmenu : latex_fontmenu);
378     *flag_sel = 1 - *flag_sel;
379     /* put image of font in indicator window */
380     (*font_setimage) (font_widget);
381     widg = *flag_sel ? ps_fontmenu : latex_fontmenu;
382     XtPopup(widg, XtGrabExclusive);
383     /* if the file message window is up add it to the grab */
384     file_msg_add_grab();
385     /* insure that the most recent colormap is installed */
386     set_cmap(XtWindow(widg));
387     XSetWMProtocols(tool_d, XtWindow(widg), &wm_delete_window, 1);
388 }
389