PageRenderTime 87ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/nx-3.5.0/nx-X11/lib/dpstk/FontSample.c

#
C | 1814 lines | 1437 code | 287 blank | 90 comment | 310 complexity | c61e34124b704cff9bde4f3a2398f23e MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * FontSample.c
  3. *
  4. * (c) Copyright 1991-1994 Adobe Systems Incorporated.
  5. * All rights reserved.
  6. *
  7. * Permission to use, copy, modify, distribute, and sublicense this software
  8. * and its documentation for any purpose and without fee is hereby granted,
  9. * provided that the above copyright notices appear in all copies and that
  10. * both those copyright notices and this permission notice appear in
  11. * supporting documentation and that the name of Adobe Systems Incorporated
  12. * not be used in advertising or publicity pertaining to distribution of the
  13. * software without specific, written prior permission. No trademark license
  14. * to use the Adobe trademarks is hereby granted. If the Adobe trademark
  15. * "Display PostScript"(tm) is used to describe this software, its
  16. * functionality or for any other purpose, such use shall be limited to a
  17. * statement that this software works in conjunction with the Display
  18. * PostScript system. Proper trademark attribution to reflect Adobe's
  19. * ownership of the trademark shall be given whenever any such reference to
  20. * the Display PostScript system is made.
  21. *
  22. * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
  23. * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
  24. * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
  27. * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
  28. * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
  29. * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
  30. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
  31. * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
  32. *
  33. * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
  34. * Incorporated which may be registered in certain jurisdictions
  35. *
  36. * Author: Adobe Systems Incorporated
  37. */
  38. /* $XFree86$ */
  39. #include <ctype.h>
  40. #include <stdio.h>
  41. #include <X11/Xos.h>
  42. #include <stdlib.h>
  43. #include <math.h>
  44. #include <X11/IntrinsicP.h>
  45. #include <X11/StringDefs.h>
  46. #include <Xm/Xm.h>
  47. /* There are no words to describe how I feel about having to do this */
  48. #if XmVersion > 1001
  49. #include <Xm/ManagerP.h>
  50. #else
  51. #include <Xm/XmP.h>
  52. #endif
  53. #include <Xm/Form.h>
  54. #include <Xm/List.h>
  55. #include <Xm/Label.h>
  56. #include <Xm/LabelG.h>
  57. #include <Xm/PushB.h>
  58. #include <Xm/PanedW.h>
  59. #include <Xm/PushBG.h>
  60. #include <Xm/SeparatoG.h>
  61. #include <Xm/TextF.h>
  62. #include <Xm/RowColumn.h>
  63. #include <Xm/DrawingA.h>
  64. #include <Xm/ScrolledW.h>
  65. #include <Xm/ToggleBG.h>
  66. #include <Xm/Frame.h>
  67. #include <Xm/RowColumn.h>
  68. #include <DPS/dpsXclient.h>
  69. #include <DPS/dpsops.h>
  70. #include <DPS/dpsXcommon.h>
  71. #include <DPS/dpsXshare.h>
  72. #include <DPS/FontSBP.h>
  73. #include "FSBwraps.h"
  74. #include "FontSBI.h"
  75. #include <DPS/FontSamplP.h>
  76. #if 0
  77. /* This is not in Xos.h for some reason */
  78. char *strstr();
  79. #endif
  80. #undef MAX
  81. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  82. #define UnsharedCS(str) XmStringCreate(str, XmSTRING_DEFAULT_CHARSET)
  83. static float defaultSizeList[] = {
  84. #ifndef SAMPLER_DEFAULT_SIZE_LIST
  85. 8, 10, 12, 14, 16, 18, 24, 36, 48, 72
  86. #else
  87. SAMPLER_DEFAULT_SIZE_LIST
  88. #endif /* DEFAULT_SIZE_LIST */
  89. };
  90. #ifndef SAMPLER_DEFAULT_SIZE_LIST_COUNT
  91. #define SAMPLER_DEFAULT_SIZE_LIST_COUNT 10
  92. #endif /* DEFAULT_SIZE_LIST_COUNT */
  93. #ifndef SAMPLER_DEFAULT_SIZE
  94. #define SAMPLER_DEFAULT_SIZE 24.0
  95. #endif /* SAMPLER_DEFAULT_SIZE */
  96. static Boolean DisplayAllWorkProc(XtPointer client_data);
  97. static Boolean DisplaySelectedWorkProc(XtPointer client_data);
  98. static Boolean DisplaySelectedFamilyWorkProc(XtPointer client_data);
  99. static Boolean DisplayFilteredWorkProc(XtPointer client_data);
  100. #define Offset(field) XtOffsetOf(FontSamplerRec, sampler.field)
  101. static XtResource resources[] = {
  102. {XtNsizes, XtCSizes, XtRFloatList, sizeof(float*),
  103. Offset(sizes), XtRImmediate, (XtPointer) defaultSizeList},
  104. {XtNsizeCount, XtCSizeCount, XtRInt, sizeof(int),
  105. Offset(size_count), XtRImmediate,
  106. (XtPointer) SAMPLER_DEFAULT_SIZE_LIST_COUNT},
  107. {XtNdismissCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
  108. Offset(dismiss_callback), XtRCallback, (XtPointer) NULL},
  109. {XtNfontSelectionBox, XtCReadOnly, XtRWidget, sizeof(Widget),
  110. Offset(fsb), XtRWidget, (XtPointer) NULL},
  111. {XtNminimumWidth, XtCMinimumWidth, XtRDimension, sizeof(Dimension),
  112. Offset(minimum_width), XtRImmediate, (XtPointer) 100},
  113. {XtNminimumHeight, XtCMinimumHeight, XtRDimension, sizeof(Dimension),
  114. Offset(minimum_height), XtRImmediate, (XtPointer) 100},
  115. {XtNnoRoomMessage, XtCMessage, XmRXmString, sizeof(XmString),
  116. Offset(no_room_message), XtRString,
  117. "Current size is too large or panel is too small"},
  118. {XtNnoFontMessage, XtCMessage, XmRXmString, sizeof(XmString),
  119. Offset(no_font_message), XtRString,
  120. "There are no fonts!"},
  121. {XtNnoSelectedFontMessage, XtCMessage, XmRXmString, sizeof(XmString),
  122. Offset(no_selected_font_message), XtRString,
  123. "No font is currently selected"},
  124. {XtNnoSelectedFamilyMessage, XtCMessage, XmRXmString, sizeof(XmString),
  125. Offset(no_selected_family_message), XtRString,
  126. "No family is currently selected"},
  127. {XtNnoFamilyFontMessage, XtCMessage, XmRXmString, sizeof(XmString),
  128. Offset(no_family_font_message), XtRString,
  129. "Selected family has no fonts!"},
  130. {XtNnoMatchMessage, XtCMessage, XmRXmString, sizeof(XmString),
  131. Offset(no_match_message), XtRString,
  132. "No fonts match filters"},
  133. {XtNpanelChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  134. Offset(panel_child), XtRImmediate, (XtPointer) NULL},
  135. {XtNareaChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  136. Offset(area_child), XtRImmediate, (XtPointer) NULL},
  137. {XtNtextChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  138. Offset(text_child), XtRImmediate, (XtPointer) NULL},
  139. {XtNfontLabelChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  140. Offset(font_label_child), XtRImmediate, (XtPointer) NULL},
  141. {XtNscrolledWindowChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  142. Offset(scrolled_window_child), XtRImmediate, (XtPointer) NULL},
  143. {XtNdisplayButtonChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  144. Offset(display_button_child), XtRImmediate, (XtPointer) NULL},
  145. {XtNdismissButtonChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  146. Offset(dismiss_button_child), XtRImmediate, (XtPointer) NULL},
  147. {XtNstopButtonChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  148. Offset(stop_button_child), XtRImmediate, (XtPointer) NULL},
  149. {XtNclearButtonChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  150. Offset(clear_button_child), XtRImmediate, (XtPointer) NULL},
  151. {XtNradioFrameChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  152. Offset(radio_frame_child), XtRImmediate, (XtPointer) NULL},
  153. {XtNradioBoxChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  154. Offset(radio_box_child), XtRImmediate, (XtPointer) NULL},
  155. {XtNallToggleChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  156. Offset(all_toggle_child), XtRImmediate, (XtPointer) NULL},
  157. {XtNselectedToggleChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  158. Offset(selected_toggle_child), XtRImmediate, (XtPointer) NULL},
  159. {XtNselectedFamilyToggleChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  160. Offset(selected_family_toggle_child), XtRImmediate, (XtPointer) NULL},
  161. {XtNfilterToggleChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  162. Offset(filter_toggle_child), XtRImmediate, (XtPointer) NULL},
  163. {XtNfilterTextChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  164. Offset(filter_text_child), XtRImmediate, (XtPointer) NULL},
  165. {XtNfilterBoxChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  166. Offset(filter_box_child), XtRImmediate, (XtPointer) NULL},
  167. {XtNfilterFrameChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  168. Offset(filter_frame_child), XtRImmediate, (XtPointer) NULL},
  169. {XtNsizeLabelChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  170. Offset(size_label_child), XtRWidget, (XtPointer) NULL},
  171. {XtNsizeTextFieldChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  172. Offset(size_text_field_child), XtRWidget, (XtPointer) NULL},
  173. {XtNsizeOptionMenuChild, XtCReadOnly, XtRWidget, sizeof(Widget),
  174. Offset(size_option_menu_child), XtRWidget, (XtPointer) NULL},
  175. };
  176. /* Forward declarations */
  177. static Boolean SetValues(Widget old, Widget req, Widget new, ArgList args, Cardinal *num_args);
  178. static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *desired, XtWidgetGeometry *allowed);
  179. static void Cancel(Widget w);
  180. static void ChangeManaged(Widget w);
  181. static void ClassInitialize(void);
  182. static void ClassPartInitialize(WidgetClass widget_class);
  183. static void ClickAction(Widget widget, XEvent *event, String *params, Cardinal *num_params);
  184. static void Destroy(Widget widget);
  185. static void Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args);
  186. static void Resize(Widget widget);
  187. static XtActionsRec actions[] = {
  188. {"FSBClickAction", ClickAction}
  189. };
  190. FontSamplerClassRec fontSamplerClassRec = {
  191. /* Core class part */
  192. {
  193. /* superclass */ (WidgetClass) &xmManagerClassRec,
  194. /* class_name */ "FontSampler",
  195. /* widget_size */ sizeof(FontSamplerRec),
  196. /* class_initialize */ ClassInitialize,
  197. /* class_part_initialize */ ClassPartInitialize,
  198. /* class_inited */ False,
  199. /* initialize */ Initialize,
  200. /* initialize_hook */ NULL,
  201. /* realize */ XtInheritRealize,
  202. /* actions */ actions,
  203. /* num_actions */ XtNumber(actions),
  204. /* resources */ resources,
  205. /* num_resources */ XtNumber(resources),
  206. /* xrm_class */ NULLQUARK,
  207. /* compress_motion */ True,
  208. /* compress_exposure */ XtExposeCompressMultiple,
  209. /* compress_enterleave */ True,
  210. /* visible_interest */ False,
  211. /* destroy */ Destroy,
  212. /* resize */ Resize,
  213. /* expose */ NULL,
  214. /* set_values */ SetValues,
  215. /* set_values_hook */ NULL,
  216. /* set_values_almost */ XtInheritSetValuesAlmost,
  217. /* get_values_hook */ NULL,
  218. /* accept_focus */ NULL,
  219. /* version */ XtVersion,
  220. /* callback offsets */ NULL,
  221. /* tm_table */ NULL,
  222. /* query_geometry */ XtInheritQueryGeometry,
  223. /* display_accelerator */ NULL,
  224. /* extension */ NULL,
  225. },
  226. /* Composite class part */
  227. {
  228. /* geometry_manager */ GeometryManager,
  229. /* change_managed */ ChangeManaged,
  230. /* insert_child */ XtInheritInsertChild,
  231. /* delete_child */ XtInheritDeleteChild,
  232. /* extension */ NULL,
  233. },
  234. /* Constraint class part */
  235. {
  236. /* resources */ NULL,
  237. /* num_resources */ 0,
  238. /* constraint_size */ 0,
  239. /* initialize */ NULL,
  240. /* destroy */ NULL,
  241. /* set_values */ NULL,
  242. /* extension */ NULL,
  243. },
  244. /* Manager class part */
  245. {
  246. /* translations */ XtInheritTranslations,
  247. /* syn_resources */ NULL,
  248. /* num_syn_resources */ 0,
  249. /* syn_constraint_resources */ NULL,
  250. /* num_syn_constraint_resources */ 0,
  251. /* parent_process */ XmInheritParentProcess,
  252. /* extension */ NULL,
  253. },
  254. /* FontSampler class part */
  255. {
  256. /* cancel */ Cancel,
  257. /* extension */ NULL,
  258. }
  259. };
  260. WidgetClass fontSamplerWidgetClass =
  261. (WidgetClass) &fontSamplerClassRec;
  262. struct _FilterRec;
  263. typedef Boolean (*MatchProc)(String name, struct _FilterRec *filter);
  264. typedef struct _FilterRec {
  265. char *name;
  266. char *particles[9];
  267. MatchProc special;
  268. } FilterRec;
  269. static Boolean MatchRoman(String name, FilterRec *filter);
  270. static Boolean MatchMedium(String name, FilterRec *filter);
  271. static Boolean MatchBlack(String name, FilterRec *filter);
  272. FilterRec filters[] = {
  273. {"roman", {"Roman", NULL}, MatchRoman},
  274. {"italic", {"Italic", "Kursiv", "Oblique", "Slanted", NULL}},
  275. {"symbol", {"Pi", "Symbol", "Logo", "Math", "Ornaments",
  276. "Carta", "Sonata", "Dingbats", NULL}},
  277. {"display", {"Display", "Titling", NULL}},
  278. {"alternate", {"Alternate", NULL}},
  279. {"expert", {"Expert", NULL}},
  280. {"oldstyle", {"Oldstyle Figures", "Old Style Figures",
  281. "Expert", NULL}},
  282. {"smallcaps", {"Small Caps", NULL}},
  283. {"swash", {"Swash", NULL}},
  284. {"script", {"Script", NULL}},
  285. {"separator1", { NULL}},
  286. {"condensed", {"Condensed", "Compressed", "Narrow", NULL}},
  287. {"extended", {"Extended", NULL}},
  288. {"separator2", { NULL}},
  289. {"light", {"Light", "Thin", NULL}},
  290. {"book", {"Book", NULL}},
  291. {"medium", {"Medium", "Normal", "Regular",
  292. "Roman", NULL}, MatchMedium},
  293. {"demi", {"Demi", "Semi", "Demibold", "Semibold", NULL}},
  294. {"bold", {"Bold", NULL}},
  295. {"black", {"Black", "Heavy", "Poster", "Scal",
  296. "Ultra", NULL}, MatchBlack},
  297. {"separator3", { NULL}},
  298. { NULL, { NULL}}
  299. };
  300. #define ITALIC_FILTER 1
  301. #define SYMBOL_FILTER 2
  302. #define TYPE_FILTERS 0
  303. #define WIDTH_FILTERS 11
  304. #define WEIGHT_FILTERS 14
  305. static int class_indices[] = {TYPE_FILTERS, WIDTH_FILTERS, WEIGHT_FILTERS, -1};
  306. static void ShowLabel(FontSamplerWidget s, XmString string)
  307. {
  308. XtVaSetValues(s->sampler.font_label_child, XmNlabelString, string, NULL);
  309. }
  310. static void UnhighlightFont(FontSamplerWidget s)
  311. {
  312. DisplayedFontRec *d = s->sampler.highlighted_font;
  313. XCopyArea(XtDisplay(s->sampler.area_child), s->sampler.pixmap,
  314. XtWindow(s->sampler.area_child),
  315. s->sampler.gc, d->l-1, d->t-1, d->r - d->l + 2, d->b - d->t + 2,
  316. d->l-1, d->t-1);
  317. }
  318. static void HighlightFont(FontSamplerWidget s)
  319. {
  320. DisplayedFontRec *d = s->sampler.highlighted_font;
  321. FontRec *f = d->font;
  322. BlendRec *b = d->blend;
  323. String fontName;
  324. int bogusFont;
  325. if (b == NULL) fontName = f->font_name;
  326. else fontName = b->font_name;
  327. (void) _FSBDownloadFontIfNecessary(d->font, s->sampler.fsb);
  328. XDPSSetContextGState(s->sampler.fsb->fsb.context, s->sampler.gstate);
  329. DPSsetrgbcolor(s->sampler.fsb->fsb.context, 1.0, 0.0, 0.0);
  330. _DPSFShowText(s->sampler.fsb->fsb.context, d->text->str,
  331. fontName, d->text->size, d->x, d->y, &bogusFont);
  332. }
  333. /* ARGSUSED */
  334. static void ClickAction(
  335. Widget widget,
  336. XEvent *event,
  337. String *params,
  338. Cardinal *num_params)
  339. {
  340. XButtonEvent *b = (XButtonEvent *) event;
  341. DisplayedFontRec *f;
  342. FontSamplerWidget s =
  343. (FontSamplerWidget) XtParent(XtParent(XtParent(XtParent(widget))));
  344. XmString CSname;
  345. char buf[512];
  346. if (event->type != ButtonPress) return;
  347. if (s->sampler.current_display_info == NULL) return;
  348. f = s->sampler.current_display_info->shown_fonts;
  349. while (f != NULL &&
  350. (b->x < f->l || b->y < f->t || b->x > f->r || b->y > f->b)) {
  351. f = f->next;
  352. }
  353. if (f != NULL) {
  354. if (s->sampler.highlighted_font == f) return;
  355. if (s->sampler.highlighted_font != NULL) UnhighlightFont(s);
  356. s->sampler.highlighted_font = f;
  357. HighlightFont(s);
  358. if (f->blend == NULL) CSname = UnsharedCS(f->font->full_name);
  359. else {
  360. sprintf(buf, "%s %s", f->font->full_name, f->blend->blend_name);
  361. CSname = UnsharedCS(buf);
  362. }
  363. ShowLabel(s, CSname);
  364. XmStringFree(CSname);
  365. if (f->blend == NULL) {
  366. _FSBSetCurrentFont(s->sampler.fsb, f->font->font_name);
  367. } else {
  368. _FSBSetCurrentFont(s->sampler.fsb, f->blend->font_name);
  369. }
  370. }
  371. }
  372. static void UpdateDisplayedFontRecs(
  373. DisplayRecord *info,
  374. Position newHeight,
  375. Position oldHeight,
  376. Position newWidth)
  377. {
  378. float *m = info->sampler->sampler.invctm;
  379. float h, w;
  380. Position oldInfoHeight = info->height;
  381. DisplayedFontRec *f;
  382. info->window_height = newHeight;
  383. h = newHeight;
  384. w = newWidth;
  385. info->width = (int) (m[0] * w - m[2] * h + m[4]);
  386. info->height = (int) (m[1] * w - m[3] * h + m[5]);
  387. info->y += info->height - oldInfoHeight;
  388. for (f = info->shown_fonts; f != NULL; f = f->next) {
  389. f->y += info->height - oldInfoHeight;
  390. }
  391. }
  392. /* ARGSUSED */
  393. static void ResizeEventHandler(
  394. Widget widget,
  395. XtPointer clientData,
  396. XEvent *event,
  397. Boolean *continueToDispatch)
  398. {
  399. Dimension clip_width, clip_height, new_width, new_height,
  400. area_width, area_height;
  401. int depth;
  402. FontSamplerWidget s = (FontSamplerWidget) clientData;
  403. Pixmap p;
  404. if (event->type != ConfigureNotify) return;
  405. XtVaGetValues(s->sampler.clip_widget, XtNwidth, &clip_width,
  406. XtNheight, &clip_height, NULL);
  407. XtVaGetValues(s->sampler.area_child, XtNwidth, &area_width,
  408. XtNheight, &area_height, XtNdepth, &depth, NULL);
  409. /* Trying to make it fit exactly causes looooping... */
  410. new_width = clip_width-2;
  411. new_height = clip_height-2;
  412. if (clip_width < s->sampler.minimum_width) {
  413. new_width = s->sampler.minimum_width;
  414. }
  415. if (clip_height < s->sampler.minimum_height) {
  416. new_height = s->sampler.minimum_height;
  417. }
  418. if (new_height != area_height || new_width != area_width) {
  419. XtVaSetValues(s->sampler.area_child, XtNwidth, new_width,
  420. XtNheight, new_height, NULL);
  421. p = XCreatePixmap(XtDisplay(s->sampler.area_child),
  422. RootWindowOfScreen(XtScreen(s->sampler.area_child)),
  423. new_width, new_height, depth);
  424. if (s->sampler.gstate != 0) {
  425. XDPSSetContextGState(s->sampler.fsb->fsb.context,
  426. s->sampler.gstate);
  427. XDPSSetContextParameters(s->sampler.fsb->fsb.context,
  428. XtScreen(s->sampler.area_child), depth,
  429. XtWindow(s->sampler.area_child),
  430. new_height,
  431. (XDPSStandardColormap *) NULL,
  432. (XDPSStandardColormap *) NULL,
  433. XDPSContextScreenDepth | XDPSContextDrawable |
  434. XDPSContextRGBMap | XDPSContextGrayMap);
  435. _DPSFReclip(s->sampler.fsb->fsb.context);
  436. _DPSFGetCTM(s->sampler.fsb->fsb.context,
  437. s->sampler.ctm, s->sampler.invctm);
  438. XDPSUpdateContextGState(s->sampler.fsb->fsb.context,
  439. s->sampler.gstate);
  440. XDPSSetContextGState(s->sampler.fsb->fsb.context,
  441. s->sampler.pixmap_gstate);
  442. XDPSSetContextParameters(s->sampler.fsb->fsb.context,
  443. (Screen *) NULL, 0,
  444. p, new_height,
  445. (XDPSStandardColormap *) NULL,
  446. (XDPSStandardColormap *) NULL,
  447. XDPSContextDrawable);
  448. XDPSUpdateContextGState(s->sampler.fsb->fsb.context,
  449. s->sampler.pixmap_gstate);
  450. _DPSFClearWindow(s->sampler.fsb->fsb.context);
  451. /* La di dah */
  452. DPSWaitContext(s->sampler.fsb->fsb.context);
  453. XCopyArea(XtDisplay(s), s->sampler.pixmap, p,
  454. s->sampler.gc, 0, 0, new_width, new_height, 0, 0);
  455. }
  456. XFreePixmap(XtDisplay(s), s->sampler.pixmap);
  457. s->sampler.pixmap = p;
  458. UpdateDisplayedFontRecs(s->sampler.current_display_info,
  459. new_height, area_height, new_width);
  460. }
  461. }
  462. static void ClassInitialize(void)
  463. {
  464. XtInitializeWidgetClass(fontSelectionBoxWidgetClass);
  465. }
  466. static void ClassPartInitialize(WidgetClass widget_class)
  467. {
  468. register FontSamplerWidgetClass wc =
  469. (FontSamplerWidgetClass) widget_class;
  470. FontSamplerWidgetClass super =
  471. (FontSamplerWidgetClass) wc->core_class.superclass;
  472. if (wc->sampler_class.cancel == InheritCancel) {
  473. wc->sampler_class.cancel = super->sampler_class.cancel;
  474. }
  475. }
  476. static void FreeDisplayInfo(DisplayRecord *info)
  477. {
  478. DisplayedFontRec *f;
  479. DisplayedTextRec *t;
  480. if (info == NULL) return;
  481. XtVaSetValues(info->sampler->sampler.font_label_child,
  482. XtVaTypedArg, XmNlabelString, XtRString,
  483. " ", 2, NULL);
  484. while ((f = info->shown_fonts) != NULL) {
  485. info->shown_fonts = f->next;
  486. XtFree((char *) f);
  487. }
  488. while ((t = info->text_list) != NULL) {
  489. info->text_list = t->next;
  490. XtFree((char *) t->str);
  491. XtFree((char *) t);
  492. }
  493. XtFree((char *) info);
  494. }
  495. static Boolean IsSet(Widget widget)
  496. {
  497. return XmToggleButtonGadgetGetState(widget);
  498. }
  499. /* ARGSUSED */
  500. static void DisplayCallback(Widget widget, XtPointer clientData, XtPointer callData)
  501. {
  502. XtAppContext app;
  503. float h, w;
  504. DisplayRecord *info;
  505. FontSamplerWidget s = (FontSamplerWidget) clientData;
  506. float *m;
  507. char *value;
  508. DisplayedTextRec *t;
  509. if (s->sampler.current_display_proc != None) {
  510. XtRemoveWorkProc(s->sampler.current_display_proc);
  511. }
  512. FreeDisplayInfo(s->sampler.current_display_info);
  513. s->sampler.highlighted_font = NULL;
  514. app = XtDisplayToApplicationContext(XtDisplay(widget));
  515. info = s->sampler.current_display_info =
  516. (DisplayRecord *) XtNew(DisplayRecord);
  517. XtVaGetValues(s->sampler.area_child,
  518. XtNwidth, &info->width,
  519. XtNheight, &info->window_height,
  520. XtNdepth, &info->depth,
  521. NULL);
  522. if (s->sampler.gstate == 0) {
  523. XDPSSetContextParameters(s->sampler.fsb->fsb.context,
  524. XtScreen(s->sampler.area_child), info->depth,
  525. XtWindow(s->sampler.area_child),
  526. info->window_height,
  527. (XDPSStandardColormap *) NULL,
  528. (XDPSStandardColormap *) NULL,
  529. XDPSContextScreenDepth | XDPSContextDrawable |
  530. XDPSContextRGBMap | XDPSContextGrayMap);
  531. DPSsetgray(s->sampler.fsb->fsb.context, 0.0);
  532. XDPSCaptureContextGState(s->sampler.fsb->fsb.context,
  533. &s->sampler.gstate);
  534. _DPSFGetCTM(s->sampler.fsb->fsb.context,
  535. s->sampler.ctm, s->sampler.invctm);
  536. XDPSSetContextParameters(s->sampler.fsb->fsb.context,
  537. (Screen *) NULL, 0,
  538. s->sampler.pixmap, info->window_height,
  539. (XDPSStandardColormap *) NULL,
  540. (XDPSStandardColormap *) NULL,
  541. XDPSContextDrawable);
  542. DPSsetgray(s->sampler.fsb->fsb.context, 0.0);
  543. XDPSCaptureContextGState(s->sampler.fsb->fsb.context,
  544. &s->sampler.pixmap_gstate);
  545. }
  546. h = info->window_height;
  547. w = info->width;
  548. m = s->sampler.invctm;
  549. info->width = (int) (m[0] * w - m[2] * h + m[4]);
  550. info->height = (int) (m[1] * w - m[3] * h + m[5]);
  551. info->sampler = s;
  552. info->inited = info->any_shown = False;
  553. info->column_width = 0;
  554. info->x = 5;
  555. info->y = info->height;
  556. info->shown_fonts = NULL;
  557. t = info->text_list = XtNew(DisplayedTextRec);
  558. t->next = NULL;
  559. value = XmTextFieldGetString(s->sampler.text_child);
  560. t->str = XtNewString(value);
  561. value = XmTextFieldGetString(s->sampler.size_text_field_child);
  562. if (value == NULL || *value == '\0') t->size = SAMPLER_DEFAULT_SIZE;
  563. else {
  564. t->size = atof(value);
  565. if (t->size <= 0) t->size = SAMPLER_DEFAULT_SIZE;
  566. }
  567. s->sampler.displaying = True;
  568. XDPSSetContextGState(s->sampler.fsb->fsb.context, s->sampler.gstate);
  569. _DPSFClearWindow(s->sampler.fsb->fsb.context);
  570. XDPSSetContextGState(s->sampler.fsb->fsb.context,
  571. s->sampler.pixmap_gstate);
  572. _DPSFClearWindow(s->sampler.fsb->fsb.context);
  573. XtSetSensitive(s->sampler.stop_button_child, True);
  574. if (IsSet(s->sampler.all_toggle_child)) {
  575. s->sampler.current_display_proc =
  576. XtAppAddWorkProc(app, DisplayAllWorkProc,
  577. (XtPointer) info);
  578. } else if (IsSet(s->sampler.selected_toggle_child)) {
  579. s->sampler.current_display_proc =
  580. XtAppAddWorkProc(app, DisplaySelectedWorkProc,
  581. (XtPointer) info);
  582. } else if (IsSet(s->sampler.selected_family_toggle_child)) {
  583. s->sampler.current_display_proc =
  584. XtAppAddWorkProc(app, DisplaySelectedFamilyWorkProc,
  585. (XtPointer) info);
  586. } else if (IsSet(s->sampler.filter_toggle_child)) {
  587. s->sampler.current_display_proc =
  588. XtAppAddWorkProc(app, DisplayFilteredWorkProc,
  589. (XtPointer) info);
  590. }
  591. }
  592. static void FinishUpDisplaying(FontSamplerWidget s)
  593. {
  594. XtSetSensitive(s->sampler.stop_button_child, False);
  595. s->sampler.current_display_proc = None;
  596. }
  597. /* ARGSUSED */
  598. static void FilterCallback(Widget widget, XtPointer clientData, XtPointer callData)
  599. {
  600. FontSamplerWidget s = (FontSamplerWidget) clientData;
  601. s->sampler.filters_changed = True;
  602. if (IsSet(s->sampler.filter_toggle_child)) return;
  603. XmToggleButtonGadgetSetState(s->sampler.filter_toggle_child, True, True);
  604. XmToggleButtonGadgetSetState(s->sampler.all_toggle_child, False, False);
  605. XmToggleButtonGadgetSetState(s->sampler.selected_toggle_child,
  606. False, False);
  607. XmToggleButtonGadgetSetState(s->sampler.selected_family_toggle_child,
  608. False, False);
  609. }
  610. /* ARGSUSED */
  611. static void TextCallback(Widget widget, XtPointer clientData, XtPointer callData)
  612. {
  613. FontSamplerWidget s = (FontSamplerWidget) clientData;
  614. DisplayedTextRec *t;
  615. char *value;
  616. if (!s->sampler.displaying) return;
  617. t = XtNew(DisplayedTextRec);
  618. value = XmTextFieldGetString(s->sampler.text_child);
  619. t->str = XtNewString(value);
  620. t->size = s->sampler.current_display_info->text_list->size;
  621. t->next = s->sampler.current_display_info->text_list;
  622. s->sampler.current_display_info->text_list = t;
  623. }
  624. /* ARGSUSED */
  625. static void StopCallback(Widget widget, XtPointer clientData, XtPointer callData)
  626. {
  627. FontSamplerWidget s = (FontSamplerWidget) clientData;
  628. if (s->sampler.current_display_proc == None) return;
  629. XtRemoveWorkProc(s->sampler.current_display_proc);
  630. FinishUpDisplaying(s);
  631. }
  632. /* ARGSUSED */
  633. static void DismissCallback(Widget widget, XtPointer clientData, XtPointer callData)
  634. {
  635. FontSamplerWidget s = (FontSamplerWidget) clientData;
  636. if (XtIsShell(XtParent(s))) XtPopdown(XtParent(s));
  637. if (s->sampler.current_display_proc != None) {
  638. XtRemoveWorkProc(s->sampler.current_display_proc);
  639. }
  640. FinishUpDisplaying(s);
  641. XtCallCallbackList(widget, s->sampler.dismiss_callback, (XtPointer) NULL);
  642. }
  643. /* ARGSUSED */
  644. static void PopdownCallback(Widget widget, XtPointer clientData, XtPointer callData)
  645. {
  646. FontSamplerWidget s =
  647. (FontSamplerWidget)
  648. (((CompositeWidget) widget)->composite.children[0]);
  649. if (s->sampler.current_display_proc != None) {
  650. XtRemoveWorkProc(s->sampler.current_display_proc);
  651. }
  652. }
  653. /* ARGSUSED */
  654. static void ExposeCallback(Widget widget, XtPointer clientData, XtPointer callData)
  655. {
  656. XmDrawingAreaCallbackStruct *da = (XmDrawingAreaCallbackStruct *) callData;
  657. XExposeEvent *ev = (XExposeEvent *) da->event;
  658. FontSamplerWidget s = (FontSamplerWidget) clientData;
  659. if (ev->type != Expose || !s->sampler.displaying) return;
  660. XCopyArea(XtDisplay(widget), s->sampler.pixmap, XtWindow(widget),
  661. s->sampler.gc, ev->x, ev->y, ev->width, ev->height,
  662. ev->x, ev->y);
  663. if (s->sampler.highlighted_font != NULL) HighlightFont(s);
  664. }
  665. /* ARGSUSED */
  666. static void ClearCallback(Widget widget, XtPointer clientData, XtPointer callData)
  667. {
  668. int j;
  669. FontSamplerWidget s = (FontSamplerWidget) clientData;
  670. for (j = 0; filters[j].name != NULL; j++) {
  671. if (filters[j].particles[0] != NULL) {
  672. XmToggleButtonGadgetSetState(s->sampler.filter_widgets[j],
  673. False, False);
  674. }
  675. }
  676. XmTextFieldSetString(s->sampler.filter_text_child, "");
  677. }
  678. /* ARGSUSED */
  679. static void SizeSelect(Widget widget, XtPointer clientData, XtPointer callData)
  680. {
  681. FontSamplerWidget s = (FontSamplerWidget) clientData;
  682. String value;
  683. Widget option;
  684. char *ch;
  685. DisplayedTextRec *t;
  686. value = XmTextFieldGetString(widget);
  687. if (value == NULL) option = s->sampler.other_size;
  688. else {
  689. for (ch = value; *ch != '\0'; ch++) if (*ch == '.') *ch = '-';
  690. option = XtNameToWidget(s->sampler.size_menu, value);
  691. if (option == NULL) option = s->sampler.other_size;
  692. }
  693. XtVaSetValues(s->sampler.size_option_menu_child,
  694. XmNmenuHistory, option, NULL);
  695. if (!s->sampler.displaying) return;
  696. t = XtNew(DisplayedTextRec);
  697. t->str = XtNewString(s->sampler.current_display_info->text_list->str);
  698. if (value == NULL || *value == '\0') t->size = SAMPLER_DEFAULT_SIZE;
  699. else {
  700. t->size = atof(value);
  701. if (t->size <= 0) t->size = SAMPLER_DEFAULT_SIZE;
  702. }
  703. t->next = s->sampler.current_display_info->text_list;
  704. s->sampler.current_display_info->text_list = t;
  705. }
  706. /* There's a problem; sometimes the change has already been made in the field,
  707. and sometimes it hasn't. The times when it has seem to correspond to
  708. making changes with the size option menu, so we use this disgusting
  709. global flag to notice when this happens. */
  710. static Boolean changingSize = False;
  711. /* ARGSUSED */
  712. static void TextVerify(Widget widget, XtPointer clientData, XtPointer callData)
  713. {
  714. int i;
  715. XmTextVerifyPtr v = (XmTextVerifyPtr) callData;
  716. char ch, *cp;
  717. int decimalPoints = 0;
  718. if (changingSize) return; /* We know what we're doing; allow it */
  719. /* Should probably look at format field, but seems to contain garbage */
  720. if (v->text->length == 0) return;
  721. for (i = 0; i < v->text->length; i++) {
  722. ch = v->text->ptr[i];
  723. if (ch == '.') decimalPoints++;
  724. else if (!isdigit(ch)) {
  725. v->doit = False;
  726. return;
  727. }
  728. }
  729. if (decimalPoints > 1) {
  730. v->doit = False;
  731. return;
  732. }
  733. cp = XmTextFieldGetString(widget);
  734. for (/**/; *cp != '\0'; cp++) {
  735. if (*cp == '.') decimalPoints++;
  736. }
  737. if (decimalPoints > 1) v->doit = False;
  738. }
  739. /* ARGSUSED */
  740. static void SetSize(Widget widget, XtPointer clientData, XtPointer callData)
  741. {
  742. char buf[20], *ch;
  743. FontSamplerWidget s = (FontSamplerWidget) clientData;
  744. strcpy(buf, XtName(widget));
  745. for (ch = buf; *ch != '\0'; ch++) if (*ch == '-') *ch++ = '.';
  746. changingSize = True;
  747. XmTextFieldSetString(s->sampler.size_text_field_child, buf);
  748. changingSize = False;
  749. }
  750. static void CreateSizeMenu(FontSamplerWidget s, Boolean destroyOldChildren)
  751. {
  752. Arg args[20];
  753. int i, j;
  754. Widget *sizes;
  755. char buf[20];
  756. Widget *children;
  757. Cardinal num_children;
  758. XmString csName;
  759. char *ch;
  760. if (destroyOldChildren) {
  761. XtVaGetValues(s->sampler.size_menu, XtNchildren, &children,
  762. XtNnumChildren, &num_children, NULL);
  763. /* Don't destroy first child ("other") */
  764. for (j = 1; (Cardinal)j < num_children; j++) XtDestroyWidget(children[j]);
  765. sizes = (Widget *) XtMalloc((s->sampler.size_count+1) *
  766. sizeof(Widget));
  767. sizes[0] = children[0];
  768. } else {
  769. i = 0;
  770. sizes = (Widget *) XtMalloc((s->sampler.size_count+1) *
  771. sizeof(Widget));
  772. s->sampler.other_size = sizes[0] =
  773. XtCreateManagedWidget("other", xmPushButtonGadgetClass,
  774. s->sampler.size_menu, args, i);
  775. }
  776. for (j = 0; j < s->sampler.size_count; j++) {
  777. (void) sprintf(buf, "%g", s->sampler.sizes[j]);
  778. csName = UnsharedCS(buf);
  779. for (ch = buf; *ch != '\0'; ch++) if (*ch == '.') *ch = '-';
  780. i = 0;
  781. XtSetArg(args[i], XmNlabelString, csName); i++;
  782. sizes[j+1] =
  783. XmCreatePushButtonGadget(s->sampler.size_menu, buf, args, i);
  784. XmStringFree(csName);
  785. XtAddCallback(sizes[j+1], XmNactivateCallback, SetSize, (XtPointer) s);
  786. }
  787. XtManageChildren(sizes, j+1);
  788. XtFree((char *) sizes);
  789. }
  790. static void CreateFilters(FontSamplerWidget s)
  791. {
  792. FilterRec *f;
  793. int i;
  794. s->sampler.filter_widgets =
  795. (Widget *) XtCalloc(XtNumber(filters)-1, sizeof(Widget));
  796. s->sampler.filter_flags =
  797. (Boolean *) XtCalloc(XtNumber(filters)-1, sizeof(Boolean));
  798. for (i = 0; filters[i].name != NULL; i++) {
  799. f = filters+i;
  800. if (f->particles[0] == NULL) {
  801. s->sampler.filter_widgets[i] =
  802. XtCreateManagedWidget(f->name, xmSeparatorGadgetClass,
  803. s->sampler.filter_box_child,
  804. (ArgList) NULL, 0);
  805. } else {
  806. s->sampler.filter_widgets[i] =
  807. XtCreateManagedWidget(f->name, xmToggleButtonGadgetClass,
  808. s->sampler.filter_box_child,
  809. (ArgList) NULL, 0);
  810. XtAddCallback(s->sampler.filter_widgets[i],
  811. XmNvalueChangedCallback,
  812. FilterCallback, (XtPointer) s);
  813. }
  814. }
  815. }
  816. static void CreateChildren(FontSamplerWidget s)
  817. {
  818. Arg args[20];
  819. int i;
  820. Widget form;
  821. Dimension area_width, area_height;
  822. int depth;
  823. Widget w, rowcol;
  824. form = s->sampler.panel_child =
  825. XtCreateManagedWidget("panel", xmFormWidgetClass,
  826. (Widget) s, (ArgList) NULL, 0);
  827. i = 0;
  828. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  829. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  830. s->sampler.display_button_child =
  831. XtCreateManagedWidget("displayButton", xmPushButtonWidgetClass,
  832. form, args, i);
  833. XtAddCallback(s->sampler.display_button_child, XmNactivateCallback,
  834. DisplayCallback, (XtPointer) s);
  835. i = 0;
  836. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  837. XtSetArg(args[i], XmNleftWidget, s->sampler.display_button_child); i++;
  838. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  839. XtSetArg(args[i], XtNsensitive, False); i++;
  840. s->sampler.stop_button_child =
  841. XtCreateManagedWidget("stopButton", xmPushButtonWidgetClass,
  842. form, args, i);
  843. XtAddCallback(s->sampler.stop_button_child, XmNactivateCallback,
  844. StopCallback, (XtPointer) s);
  845. i = 0;
  846. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  847. XtSetArg(args[i], XmNleftWidget, s->sampler.stop_button_child); i++;
  848. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  849. s->sampler.dismiss_button_child =
  850. XtCreateManagedWidget("dismissButton", xmPushButtonWidgetClass,
  851. form, args, i);
  852. XtAddCallback(s->sampler.dismiss_button_child, XmNactivateCallback,
  853. DismissCallback, (XtPointer) s);
  854. i = 0;
  855. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  856. XtSetArg(args[i], XmNleftWidget, s->sampler.dismiss_button_child); i++;
  857. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  858. s->sampler.size_label_child =
  859. XtCreateManagedWidget("sizeLabel", xmLabelWidgetClass,
  860. form, args, i);
  861. i = 0;
  862. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  863. XtSetArg(args[i], XmNleftWidget, s->sampler.size_label_child); i++;
  864. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  865. XtSetArg(args[i], XmNbottomWidget, s->sampler.size_label_child); i++;
  866. s->sampler.size_text_field_child =
  867. XtCreateManagedWidget("sizeTextField",
  868. xmTextFieldWidgetClass,
  869. form, args, i);
  870. XtAddCallback(s->sampler.size_text_field_child, XmNvalueChangedCallback,
  871. SizeSelect, (XtPointer) s);
  872. XtAddCallback(s->sampler.size_text_field_child, XmNmodifyVerifyCallback,
  873. TextVerify, (XtPointer) NULL);
  874. i = 0;
  875. s->sampler.size_menu = XmCreatePulldownMenu(form, "sizeMenu", args, i);
  876. CreateSizeMenu(s, False);
  877. i = 0;
  878. XtSetArg(args[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
  879. XtSetArg(args[i], XmNleftWidget, s->sampler.size_text_field_child); i++;
  880. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  881. XtSetArg(args[i], XmNbottomWidget, s->sampler.size_label_child); i++;
  882. XtSetArg(args[i], XmNsubMenuId, s->sampler.size_menu); i++;
  883. s->sampler.size_option_menu_child =
  884. XmCreateOptionMenu(form, "sizeOptionMenu", args, i);
  885. XtManageChild(s->sampler.size_option_menu_child);
  886. SizeSelect(s->sampler.size_text_field_child, (XtPointer) s,
  887. (XtPointer) NULL);
  888. i = 0;
  889. XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
  890. XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
  891. rowcol = XtCreateManagedWidget("rowColumn", xmRowColumnWidgetClass,
  892. form, args, i);
  893. i = 0;
  894. s->sampler.radio_frame_child =
  895. XtCreateManagedWidget("radioFrame", xmFrameWidgetClass,
  896. rowcol, args, i);
  897. i = 0;
  898. s->sampler.radio_box_child = XmCreateRadioBox(s->sampler.radio_frame_child,
  899. "radioBox", args, i);
  900. XtManageChild(s->sampler.radio_box_child);
  901. i = 0;
  902. s->sampler.all_toggle_child =
  903. XtCreateManagedWidget("allToggle", xmToggleButtonGadgetClass,
  904. s->sampler.radio_box_child, args, i);
  905. i = 0;
  906. s->sampler.selected_toggle_child =
  907. XtCreateManagedWidget("selectedToggle", xmToggleButtonGadgetClass,
  908. s->sampler.radio_box_child, args, i);
  909. i = 0;
  910. s->sampler.selected_family_toggle_child =
  911. XtCreateManagedWidget("selectedFamilyToggle",
  912. xmToggleButtonGadgetClass,
  913. s->sampler.radio_box_child, args, i);
  914. i = 0;
  915. s->sampler.filter_toggle_child =
  916. XtCreateManagedWidget("filterToggle",
  917. xmToggleButtonGadgetClass,
  918. s->sampler.radio_box_child, args, i);
  919. i = 0;
  920. s->sampler.filter_frame_child =
  921. XtCreateManagedWidget("filterFrame", xmFrameWidgetClass,
  922. rowcol, args, i);
  923. i = 0;
  924. s->sampler.filter_box_child =
  925. XtCreateManagedWidget("filterBox", xmRowColumnWidgetClass,
  926. s->sampler.filter_frame_child, args, i);
  927. CreateFilters(s);
  928. i = 0;
  929. s->sampler.filter_text_child =
  930. XtCreateManagedWidget("filterText", xmTextFieldWidgetClass,
  931. s->sampler.filter_box_child, args, i);
  932. XtAddCallback(s->sampler.filter_text_child,
  933. XmNvalueChangedCallback,
  934. FilterCallback, (XtPointer) s);
  935. i = 0;
  936. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  937. XtSetArg(args[i], XmNleftWidget, rowcol); i++;
  938. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_FORM); i++;
  939. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  940. XtSetArg(args[i], XmNrightWidget, rowcol); i++;
  941. s->sampler.clear_button_child =
  942. XtCreateManagedWidget("clearButton", xmPushButtonWidgetClass,
  943. form, args, i);
  944. XtAddCallback(s->sampler.clear_button_child, XmNactivateCallback,
  945. ClearCallback, (XtPointer) s);
  946. i = 0;
  947. XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
  948. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  949. XtSetArg(args[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
  950. XtSetArg(args[i], XmNrightWidget, rowcol); i++;
  951. s->sampler.text_child =
  952. XtCreateManagedWidget("text", xmTextFieldWidgetClass,
  953. form, args, i);
  954. XtAddCallback(s->sampler.text_child,
  955. XmNvalueChangedCallback,
  956. TextCallback, (XtPointer) s);
  957. i = 0;
  958. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  959. XtSetArg(args[i], XmNtopWidget, s->sampler.text_child); i++;
  960. XtSetArg(args[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  961. XtSetArg(args[i], XmNleftWidget, s->sampler.text_child); i++;
  962. XtSetArg(args[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
  963. XtSetArg(args[i], XmNrightWidget, s->sampler.text_child); i++;
  964. s->sampler.font_label_child =
  965. XtCreateManagedWidget("fontLabel", xmLabelGadgetClass,
  966. form, args, i);
  967. i = 0;
  968. XtSetArg(args[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
  969. XtSetArg(args[i], XmNtopWidget, s->sampler.font_label_child); i++;
  970. XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
  971. XtSetArg(args[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
  972. XtSetArg(args[i], XmNrightWidget, rowcol); i++;
  973. XtSetArg(args[i], XmNbottomAttachment, XmATTACH_WIDGET); i++;
  974. XtSetArg(args[i], XmNbottomWidget, s->sampler.display_button_child);i++;
  975. XtSetArg(args[i], XmNscrollingPolicy, XmAUTOMATIC); i++;
  976. s->sampler.scrolled_window_child =
  977. XtCreateManagedWidget("scrolledWindow",
  978. xmScrolledWindowWidgetClass,
  979. form, args, i);
  980. i = 0;
  981. s->sampler.area_child =
  982. XtCreateManagedWidget("area", xmDrawingAreaWidgetClass,
  983. s->sampler.scrolled_window_child, args, i);
  984. XtAddCallback(s->sampler.area_child, XmNexposeCallback,
  985. ExposeCallback, (XtPointer) s);
  986. XtVaGetValues(s->sampler.scrolled_window_child,
  987. XmNclipWindow, &s->sampler.clip_widget,
  988. NULL);
  989. /* I would like to use translations for this, but Motif overwrites the
  990. clip window's translation. Grr... */
  991. XtAddEventHandler(s->sampler.clip_widget, StructureNotifyMask, False,
  992. ResizeEventHandler, (XtPointer) s);
  993. XtVaSetValues(s->sampler.scrolled_window_child,
  994. XmNworkWindow, s->sampler.area_child, NULL);
  995. XtVaGetValues(s->sampler.area_child,
  996. XtNheight, &area_height,
  997. XtNwidth, &area_width,
  998. XtNdepth, &depth,
  999. NULL);
  1000. if (area_height < s->sampler.minimum_height ||
  1001. area_width < s->sampler.minimum_width) {
  1002. area_height = MAX(area_height, s->sampler.minimum_height);
  1003. area_width = MAX(area_width, s->sampler.minimum_width);
  1004. XtVaSetValues(s->sampler.area_child, XtNwidth, area_width,
  1005. XtNheight, area_height, NULL);
  1006. }
  1007. s->sampler.pixmap =
  1008. XCreatePixmap(XtDisplay(s->sampler.area_child),
  1009. RootWindowOfScreen(XtScreen(s->sampler.area_child)),
  1010. area_width, area_height, depth);
  1011. XtVaSetValues(form, XmNdefaultButton, s->sampler.display_button_child,
  1012. NULL);
  1013. s->sampler.gc = XtGetGC(s->sampler.area_child, 0, (XGCValues *) NULL);
  1014. for (w = XtParent(s); !XtIsShell(w); w = XtParent(w)) {}
  1015. XtAddCallback(w, XtNpopdownCallback, PopdownCallback, (XtPointer) NULL);
  1016. }
  1017. /* ARGSUSED */
  1018. static void Initialize(
  1019. Widget request, Widget new,
  1020. ArgList args,
  1021. Cardinal *num_args)
  1022. {
  1023. FontSamplerWidget sampler = (FontSamplerWidget) new;
  1024. /* Must have a fsb */
  1025. if (sampler->sampler.fsb == NULL) {
  1026. XtAppErrorMsg(XtWidgetToApplicationContext(new),
  1027. "initializeFontSampler", "noFontSelectionBox",
  1028. "FontSelectionBoxError",
  1029. "No font selection box given to font sampler",
  1030. (String *) NULL, (Cardinal *) NULL);
  1031. }
  1032. /* Verify size list */
  1033. if (sampler->sampler.size_count > 0 && sampler->sampler.sizes == NULL) {
  1034. XtAppWarningMsg(XtWidgetToApplicationContext(new),
  1035. "initializeFontSampler", "sizeMismatch",
  1036. "FontSelectionBoxError",
  1037. "Size count specified but no sizes present",
  1038. (String *) NULL, (Cardinal *) NULL);
  1039. sampler->sampler.size_count = 0;
  1040. }
  1041. if (sampler->sampler.size_count < 0) {
  1042. XtAppWarningMsg(XtWidgetToApplicationContext(new),
  1043. "initializeFontSampler", "negativeSize",
  1044. "FontSelectionBoxError",
  1045. "Size count should not be negative",
  1046. (String *) NULL, (Cardinal *) NULL);
  1047. sampler->sampler.size_count = 0;
  1048. }
  1049. /* Initialize non-resource fields */
  1050. sampler->sampler.displaying = False;
  1051. sampler->sampler.current_display_proc = None;
  1052. sampler->sampler.current_display_info = NULL;
  1053. sampler->sampler.gstate = sampler->sampler.pixmap_gstate = 0;
  1054. CreateChildren(sampler);
  1055. }
  1056. static void AdvanceInfoToNextFont(DisplayRecord *info)
  1057. {
  1058. if (info->current_font->blend_data != NULL) {
  1059. if (info->current_blend == NULL) {
  1060. info->current_blend = info->current_font->blend_data->blends;
  1061. } else info->current_blend = info->current_blend->next;
  1062. if (info->current_blend == NULL) {
  1063. info->current_font = info->current_font->next;
  1064. }
  1065. } else info->current_font = info->current_font->next;
  1066. if (info->current_font == NULL) {
  1067. info->current_family = info->current_family->next;
  1068. if (info->current_family != NULL) {
  1069. info->current_font = info->current_family->fonts;
  1070. }
  1071. }
  1072. }
  1073. static Boolean ShowFont(DisplayRecord *info)
  1074. {
  1075. float width, left, right, top, bottom;
  1076. FontRec *f = info->current_font;
  1077. BlendRec *b = info->current_blend;
  1078. DisplayedFontRec *d;
  1079. FontSamplerWidget s = info->sampler;
  1080. float *m;
  1081. DisplayedTextRec *t = info->text_list;
  1082. String fontName;
  1083. int bogusFont;
  1084. int oldx, oldy;
  1085. if (f == NULL) return True;
  1086. oldx = info->x;
  1087. oldy = info->y;
  1088. info->y -= t->size * 5 / 4;
  1089. if (info->y < 0) {
  1090. if (info->column_width == 0) return False;
  1091. info->y = info->height - (t->size * 5 / 4);
  1092. info->x += info->column_width + (t->size / 4);
  1093. if (info->x > (int) info->width) return False;
  1094. info->column_width = 0;
  1095. }
  1096. if (!_FSBDownloadFontIfNecessary(f, s->sampler.fsb)) {
  1097. AdvanceInfoToNextFont(info);
  1098. return True;
  1099. }
  1100. if (b == NULL) fontName = f->font_name;
  1101. else fontName = b->font_name;
  1102. /* Do ...AndGetDimensions on the pixmap to make sure that it's synced.
  1103. That way we can reliably do an XCopyArea without first doing a
  1104. WaitContext. */
  1105. XDPSSetContextGState(s->sampler.fsb->fsb.context, s->sampler.gstate);
  1106. _DPSFShowText(s->sampler.fsb->fsb.context, t->str, fontName,
  1107. t->size, info->x, info->y, &bogusFont);
  1108. AdvanceInfoToNextFont(info);
  1109. if (bogusFont) {
  1110. info->x = oldx;
  1111. info->y = oldy;
  1112. XCopyArea(XtDisplay(s), s->sampler.pixmap,
  1113. XtWindow(s->sampler.area_child),
  1114. s->sampler.gc, 0, 0, info->width, info->height, 0, 0);
  1115. if (info->current_font == f) {
  1116. /* Must be the same font, different blend */
  1117. info->current_font = info->current_font->next;
  1118. if (info->current_font == NULL) {
  1119. info->current_family = info->current_family->next;
  1120. if (info->current_family != NULL) {
  1121. info->current_font = info->current_family->fonts;
  1122. }
  1123. }
  1124. }
  1125. _FSBFlushFont(s->sampler.fsb, f);
  1126. return True;
  1127. }
  1128. XDPSSetContextGState(s->sampler.fsb->fsb.context,
  1129. s->sampler.pixmap_gstate);
  1130. _DPSFShowTextAndGetDimensions(s->sampler.fsb->fsb.context,
  1131. t->str, fontName,
  1132. t->size, info->x, info->y,
  1133. &width, &left, &right, &top, &bottom);
  1134. width = ceil(width);
  1135. if (width > (int) info->column_width) info->column_width = (int) width;
  1136. d = XtNew(DisplayedFontRec);
  1137. m = s->sampler.ctm;
  1138. d->l = (int) (m[0] * left + m[2] * top + m[4]);
  1139. d->r = (int) ceil(m[0] * right + m[2] * bottom + m[4]);
  1140. d->t = (int) ceil(m[1] * left + m[3] * top + m[5] + info->window_height);
  1141. d->b = (int) (m[1] * right + m[3] * bottom + m[5] + info->window_height);
  1142. d->x = info->x;
  1143. d->y = info->y;
  1144. d->font = f;
  1145. d->blend = b;
  1146. d->text = info->text_list;
  1147. d->next = info->shown_fonts;
  1148. info->shown_fonts = d;
  1149. return True;
  1150. }
  1151. static Boolean DisplayAllWorkProc(XtPointer client_data)
  1152. {
  1153. DisplayRecord *info = (DisplayRecord *) client_data;
  1154. FontSamplerWidget s = info->sampler;
  1155. if (!info->inited) {
  1156. info->inited = True;
  1157. info->current_family = s->sampler.fsb->fsb.known_families;
  1158. info->current_font = info->current_family->fonts;
  1159. info->current_blend = NULL;
  1160. }
  1161. if (!ShowFont(info)) {
  1162. if (!info->any_shown) ShowLabel(s, s->sampler.no_room_message);
  1163. FinishUpDisplaying(s);
  1164. return True;
  1165. }
  1166. info->any_shown = True;
  1167. if (info->current_family == NULL) {
  1168. if (!info->any_shown) ShowLabel(s, s->sampler.no_font_message);
  1169. FinishUpDisplaying(s);
  1170. return True;
  1171. }
  1172. return False;
  1173. }
  1174. static Boolean DisplaySelectedWorkProc(XtPointer client_data)
  1175. {
  1176. DisplayRecord *info = (DisplayRecord *) client_data;
  1177. FontSamplerWidget s = info->sampler;
  1178. info->current_family = s->sampler.fsb->fsb.currently_selected_family;
  1179. info->current_font = s->sampler.fsb->fsb.currently_selected_face;
  1180. info->current_blend = s->sampler.fsb->fsb.currently_selected_blend;
  1181. if (info->current_font != NULL) {
  1182. if (!ShowFont(info)) ShowLabel(s, s->sampler.no_room_message);
  1183. } else ShowLabel(s, s->sampler.no_selected_font_message);
  1184. FinishUpDisplaying(s);
  1185. return True;
  1186. }
  1187. static Boolean DisplaySelectedFamilyWorkProc(XtPointer client_data)
  1188. {
  1189. DisplayRecord *info = (DisplayRecord *) client_data;
  1190. FontSamplerWidget s = info->sampler;
  1191. FontFamilyRec *currentFamily;
  1192. if (!info->inited) {
  1193. info->inited = True;
  1194. info->current_family = s->sampler.fsb->fsb.currently_selected_family;
  1195. if (info->current_family != NULL) {
  1196. info->current_font = info->current_family->fonts;
  1197. info->current_blend = NULL;
  1198. } else {
  1199. ShowLabel(s, s->sampler.no_selected_family_message);
  1200. FinishUpDisplaying(s);
  1201. return True;
  1202. }
  1203. }
  1204. currentFamily = info->current_family;
  1205. if (!ShowFont(info)) {
  1206. if (!info->any_shown) ShowLabel(s, s->sampler.no_room_message);
  1207. FinishUpDisplaying(s);
  1208. return True;
  1209. }
  1210. info->any_shown = True;
  1211. if (info->current_family != currentFamily) {
  1212. if (!info->any_shown) ShowLabel(s, s->sampler.no_family_font_message);
  1213. FinishUpDisplaying(s);
  1214. return True;
  1215. }
  1216. return False;
  1217. }
  1218. /* ARGSUSED */
  1219. static Boolean MatchRoman(String name, FilterRec *filter)
  1220. {
  1221. FilterRec *f;
  1222. char *ch, **search, *start;
  1223. int len;
  1224. /* Roman means not italic and not symbol */
  1225. for (f = filters + ITALIC_FILTER; f <= filters + SYMBOL_FILTER; f++) {
  1226. for (search = f->particles; *search != NULL; search++) {
  1227. start = name;
  1228. do {
  1229. ch = strstr(start, *search);
  1230. if (ch != NULL) {
  1231. len = strlen(*search);
  1232. if (ch[len] == ' ' || ch[len] == '\0') return False;
  1233. else start = ch+1;
  1234. }
  1235. } while (ch != NULL);
  1236. }
  1237. }
  1238. return True;
  1239. }
  1240. static Boolean MatchMedium(String name, FilterRec *filter)
  1241. {
  1242. FilterRec *f;
  1243. char *ch, **search, *start;
  1244. int len;
  1245. for (search = filter->particles; *search != NULL; search++) {
  1246. start = name;
  1247. do {
  1248. ch = strstr(start, *search);
  1249. if (ch != NULL) {
  1250. len = strlen(*search);
  1251. if (ch[len] == ' ' || ch[len] == '\0') return True;
  1252. else start = ch+1;
  1253. }
  1254. } while (ch != NULL);
  1255. }
  1256. /* Also match anything that has none of the other weight particles */
  1257. for (f = filters + WEIGHT_FILTERS; f->name != NULL; f++) {
  1258. if (f == filter) continue;
  1259. for (search = f->particles; *search != NULL; search++) {
  1260. start = name;
  1261. do {
  1262. ch = strstr(start, *search);
  1263. if (ch != NULL) {
  1264. len = strlen(*search);
  1265. if (ch[len] == ' ' || ch[len] == '\0') return False;
  1266. else start = ch+1;
  1267. }
  1268. } while (ch != NULL);
  1269. }
  1270. }
  1271. return True;
  1272. }
  1273. static Boolean MatchBlack(String name, FilterRec *filter)
  1274. {
  1275. char *ch, **search, *start;
  1276. int len;
  1277. Boolean ultra;
  1278. for (search = filter->particles; *search != NULL; search++) {
  1279. ultra = (strcmp(*search, "Ultra") == 0);
  1280. start = name;
  1281. do {
  1282. ch = strstr(start, *search);
  1283. if (ch != NULL) {
  1284. len = strlen(*search);
  1285. if (ch[len] == '\0') return True;
  1286. if (ch[len] == ' ') {
  1287. if (!ultra) return True;
  1288. /* Only match "Ultra" if not followed by "Compressed" or
  1289. "Light". We'd also like to add "Condensed" to this
  1290. list, but some fonts use "Ultra Condensed" to mean
  1291. "Ultra & Condensed" while others use it to mean "Very
  1292. much Condensed". Sigh... */
  1293. start = ch+len+1;
  1294. if (strncmp(start, "Compressed", 10) != 0 &&
  1295. strncmp(start, "Light", 5) != 0) return True;
  1296. else start = ch+1;
  1297. }
  1298. else start = ch+1;
  1299. }
  1300. } while (ch != NULL);
  1301. }
  1302. return False;
  1303. }
  1304. static void UpdateFilters(FontSamplerWidget s)
  1305. {
  1306. int i;
  1307. for (i = 0; filters[i].name != NULL; i++) {
  1308. if (filters[i].particles[0] != NULL) {
  1309. s->sampler.filter_flags[i] = IsSet(s->sampler.filter_widgets[i]);
  1310. }
  1311. }
  1312. s->sampler.filter_text =
  1313. XmTextFieldGetString(s->sampler.filter_text_child);
  1314. }
  1315. static Boolean FontMatchesFilters(
  1316. F

Large files files are truncated, but you can click here to view the full file