WINGs: Added 'const' attribute to function 'WMCreateHashTable'
[wmaker-crm.git] / WINGs / wfontpanel.c
blob0c1d3fdbce108bfda3ac1fb5b603e4ad27c04e45
2 #include "WINGsP.h"
3 #include "WUtil.h"
4 #include "wconfig.h"
6 #include <ctype.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <stdint.h>
11 #include <X11/Xft/Xft.h>
12 #include <fontconfig/fontconfig.h>
14 /* XXX TODO */
15 char *WMFontPanelFontChangedNotification = "WMFontPanelFontChangedNotification";
17 typedef struct W_FontPanel {
18 WMWindow *win;
20 WMFrame *upperF;
21 WMTextField *sampleT;
23 WMSplitView *split;
25 WMFrame *lowerF;
26 WMLabel *famL;
27 WMList *famLs;
28 WMLabel *typL;
29 WMList *typLs;
30 WMLabel *sizL;
31 WMTextField *sizT;
32 WMList *sizLs;
34 WMAction2 *action;
35 void *data;
37 WMButton *revertB;
38 WMButton *setB;
40 WMPropList *fdb;
41 } FontPanel;
43 #define MIN_UPPER_HEIGHT 20
44 #define MIN_LOWER_HEIGHT 140
46 #define MAX_FONTS_TO_RETRIEVE 2000
48 #define BUTTON_SPACE_HEIGHT 40
50 #define MIN_WIDTH 250
51 #define MIN_HEIGHT (MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)
53 #define DEF_UPPER_HEIGHT 60
54 #define DEF_LOWER_HEIGHT 310
56 #define DEF_WIDTH 320
57 #define DEF_HEIGHT (DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)
59 static const int scalableFontSizes[] = {
61 10,
62 11,
63 12,
64 14,
65 16,
66 18,
67 20,
68 24,
69 36,
70 48,
74 static void setFontPanelFontName(FontPanel * panel, const char *family, const char *style, double size);
76 static int isXLFD(const char *font, int *length_ret);
78 static void arrangeLowerFrame(FontPanel * panel);
80 static void familyClick(WMWidget *, void *);
81 static void typefaceClick(WMWidget *, void *);
82 static void sizeClick(WMWidget *, void *);
84 static void listFamilies(WMScreen * scr, WMFontPanel * panel);
86 static void splitViewConstrainCallback(WMSplitView * sPtr, int indView, int *min, int *max)
88 /* Parameter not used, but tell the compiler that it is ok */
89 (void) sPtr;
90 (void) max;
92 if (indView == 0)
93 *min = MIN_UPPER_HEIGHT;
94 else
95 *min = MIN_LOWER_HEIGHT;
98 static void notificationObserver(void *self, WMNotification * notif)
100 WMFontPanel *panel = (WMFontPanel *) self;
101 void *object = WMGetNotificationObject(notif);
103 if (WMGetNotificationName(notif) == WMViewSizeDidChangeNotification) {
104 if (object == WMWidgetView(panel->win)) {
105 int h = WMWidgetHeight(panel->win);
106 int w = WMWidgetWidth(panel->win);
108 WMResizeWidget(panel->split, w, h - BUTTON_SPACE_HEIGHT);
110 WMMoveWidget(panel->setB, w - 80, h - (BUTTON_SPACE_HEIGHT - 5));
112 WMMoveWidget(panel->revertB, w - 240, h - (BUTTON_SPACE_HEIGHT - 5));
114 } else if (object == WMWidgetView(panel->upperF)) {
116 if (WMWidgetHeight(panel->upperF) < MIN_UPPER_HEIGHT) {
117 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF), MIN_UPPER_HEIGHT);
118 } else {
119 WMResizeWidget(panel->sampleT, WMWidgetWidth(panel->upperF) - 20,
120 WMWidgetHeight(panel->upperF) - 10);
123 } else if (object == WMWidgetView(panel->lowerF)) {
125 if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
126 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF), MIN_UPPER_HEIGHT);
128 WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
129 + WMGetSplitViewDividerThickness(panel->split));
131 WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
132 WMWidgetWidth(panel->split) - MIN_UPPER_HEIGHT
133 - WMGetSplitViewDividerThickness(panel->split));
134 } else {
135 arrangeLowerFrame(panel);
141 static void closeWindow(WMWidget * w, void *data)
143 FontPanel *panel = (FontPanel *) data;
145 /* Parameter not used, but tell the compiler that it is ok */
146 (void) w;
148 WMHideFontPanel(panel);
151 static void setClickedAction(WMWidget * w, void *data)
153 FontPanel *panel = (FontPanel *) data;
155 /* Parameter not used, but tell the compiler that it is ok */
156 (void) w;
158 if (panel->action)
159 (*panel->action) (panel, panel->data);
162 static void revertClickedAction(WMWidget * w, void *data)
164 /* Parameter not used, but tell the compiler that it is ok */
165 (void) w;
166 (void) data;
168 /*FontPanel *panel = (FontPanel*)data; */
169 /* XXX TODO */
172 WMFontPanel *WMGetFontPanel(WMScreen * scr)
174 FontPanel *panel;
175 WMColor *dark, *white;
176 WMFont *font;
177 int divThickness;
179 if (scr->sharedFontPanel)
180 return scr->sharedFontPanel;
182 panel = wmalloc(sizeof(FontPanel));
184 panel->win = WMCreateWindow(scr, "fontPanel");
185 /* WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr)); */
186 WMSetWindowTitle(panel->win, _("Font Panel"));
187 WMResizeWidget(panel->win, DEF_WIDTH, DEF_HEIGHT);
188 WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
189 WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);
191 WMSetWindowCloseAction(panel->win, closeWindow, panel);
193 panel->split = WMCreateSplitView(panel->win);
194 WMResizeWidget(panel->split, DEF_WIDTH, DEF_HEIGHT - BUTTON_SPACE_HEIGHT);
195 WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);
197 divThickness = WMGetSplitViewDividerThickness(panel->split);
199 panel->upperF = WMCreateFrame(panel->win);
200 WMSetFrameRelief(panel->upperF, WRFlat);
201 WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
202 panel->lowerF = WMCreateFrame(panel->win);
203 /* WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr)); */
204 WMSetFrameRelief(panel->lowerF, WRFlat);
205 WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);
207 WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
208 WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));
210 WMResizeWidget(panel->upperF, DEF_WIDTH, DEF_UPPER_HEIGHT);
212 WMResizeWidget(panel->lowerF, DEF_WIDTH, DEF_LOWER_HEIGHT);
214 WMMoveWidget(panel->lowerF, 0, 60 + divThickness);
216 white = WMWhiteColor(scr);
217 dark = WMDarkGrayColor(scr);
219 panel->sampleT = WMCreateTextField(panel->upperF);
220 WMResizeWidget(panel->sampleT, DEF_WIDTH - 20, 50);
221 WMMoveWidget(panel->sampleT, 10, 10);
222 WMSetTextFieldText(panel->sampleT, _("The quick brown fox jumps over the lazy dog"));
224 font = WMBoldSystemFontOfSize(scr, 12);
226 panel->famL = WMCreateLabel(panel->lowerF);
227 WMSetWidgetBackgroundColor(panel->famL, dark);
228 WMSetLabelText(panel->famL, _("Family"));
229 WMSetLabelFont(panel->famL, font);
230 WMSetLabelTextColor(panel->famL, white);
231 WMSetLabelRelief(panel->famL, WRSunken);
232 WMSetLabelTextAlignment(panel->famL, WACenter);
234 panel->famLs = WMCreateList(panel->lowerF);
235 WMSetListAction(panel->famLs, familyClick, panel);
237 panel->typL = WMCreateLabel(panel->lowerF);
238 WMSetWidgetBackgroundColor(panel->typL, dark);
239 WMSetLabelText(panel->typL, _("Typeface"));
240 WMSetLabelFont(panel->typL, font);
241 WMSetLabelTextColor(panel->typL, white);
242 WMSetLabelRelief(panel->typL, WRSunken);
243 WMSetLabelTextAlignment(panel->typL, WACenter);
245 panel->typLs = WMCreateList(panel->lowerF);
246 WMSetListAction(panel->typLs, typefaceClick, panel);
248 panel->sizL = WMCreateLabel(panel->lowerF);
249 WMSetWidgetBackgroundColor(panel->sizL, dark);
250 WMSetLabelText(panel->sizL, _("Size"));
251 WMSetLabelFont(panel->sizL, font);
252 WMSetLabelTextColor(panel->sizL, white);
253 WMSetLabelRelief(panel->sizL, WRSunken);
254 WMSetLabelTextAlignment(panel->sizL, WACenter);
256 panel->sizT = WMCreateTextField(panel->lowerF);
257 /* WMSetTextFieldAlignment(panel->sizT, WARight); */
259 panel->sizLs = WMCreateList(panel->lowerF);
260 WMSetListAction(panel->sizLs, sizeClick, panel);
262 WMReleaseFont(font);
263 WMReleaseColor(white);
264 WMReleaseColor(dark);
266 panel->setB = WMCreateCommandButton(panel->win);
267 WMResizeWidget(panel->setB, 70, 24);
268 WMMoveWidget(panel->setB, 240, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT - 5));
269 WMSetButtonText(panel->setB, _("Set"));
270 WMSetButtonAction(panel->setB, setClickedAction, panel);
272 panel->revertB = WMCreateCommandButton(panel->win);
273 WMResizeWidget(panel->revertB, 70, 24);
274 WMMoveWidget(panel->revertB, 80, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT - 5));
275 WMSetButtonText(panel->revertB, _("Revert"));
276 WMSetButtonAction(panel->revertB, revertClickedAction, panel);
278 WMRealizeWidget(panel->win);
280 WMMapSubwidgets(panel->upperF);
281 WMMapSubwidgets(panel->lowerF);
282 WMMapSubwidgets(panel->split);
283 WMMapSubwidgets(panel->win);
285 WMUnmapWidget(panel->revertB);
287 arrangeLowerFrame(panel);
289 scr->sharedFontPanel = panel;
291 /* register notification observers */
292 WMAddNotificationObserver(notificationObserver, panel,
293 WMViewSizeDidChangeNotification, WMWidgetView(panel->win));
294 WMAddNotificationObserver(notificationObserver, panel,
295 WMViewSizeDidChangeNotification, WMWidgetView(panel->upperF));
296 WMAddNotificationObserver(notificationObserver, panel,
297 WMViewSizeDidChangeNotification, WMWidgetView(panel->lowerF));
299 listFamilies(scr, panel);
301 return panel;
304 void WMFreeFontPanel(WMFontPanel * panel)
306 if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
307 WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
309 WMRemoveNotificationObserver(panel);
310 WMUnmapWidget(panel->win);
311 WMDestroyWidget(panel->win);
312 wfree(panel);
315 void WMShowFontPanel(WMFontPanel * panel)
317 WMMapWidget(panel->win);
320 void WMHideFontPanel(WMFontPanel * panel)
322 WMUnmapWidget(panel->win);
325 WMFont *WMGetFontPanelFont(WMFontPanel * panel)
327 return WMGetTextFieldFont(panel->sampleT);
330 void WMSetFontPanelFont(WMFontPanel * panel, const char *fontName)
332 int fname_len;
333 FcPattern *pattern;
334 FcChar8 *family, *style;
335 double size;
337 if (!isXLFD(fontName, &fname_len)) {
338 /* maybe its proper fontconfig and we can parse it */
339 pattern = FcNameParse((const FcChar8 *) fontName);
340 } else {
341 /* maybe its proper xlfd and we can convert it to an FcPattern */
342 pattern = XftXlfdParse(fontName, False, False);
343 /*//FcPatternPrint(pattern); */
346 if (!pattern)
347 return;
349 if (FcPatternGetString(pattern, FC_FAMILY, 0, &family) == FcResultMatch)
350 if (FcPatternGetString(pattern, FC_STYLE, 0, &style) == FcResultMatch)
351 if (FcPatternGetDouble(pattern, "pixelsize", 0, &size) == FcResultMatch)
352 setFontPanelFontName(panel, (char *)family, (char *)style, size);
354 FcPatternDestroy(pattern);
357 void WMSetFontPanelAction(WMFontPanel * panel, WMAction2 * action, void *data)
359 panel->action = action;
360 panel->data = data;
363 static void arrangeLowerFrame(FontPanel * panel)
365 int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
366 int height = WMWidgetHeight(panel->split) - WMWidgetHeight(panel->upperF);
367 int fw, tw, sw;
369 #define LABEL_HEIGHT 20
371 height -= WMGetSplitViewDividerThickness(panel->split);
373 height -= LABEL_HEIGHT + 8;
375 fw = (125 * width) / 235;
376 tw = (110 * width) / 235;
377 sw = 55;
379 WMMoveWidget(panel->famL, 10, 0);
380 WMResizeWidget(panel->famL, fw, LABEL_HEIGHT);
382 WMMoveWidget(panel->famLs, 10, 23);
383 WMResizeWidget(panel->famLs, fw, height);
385 WMMoveWidget(panel->typL, 10 + fw + 3, 0);
386 WMResizeWidget(panel->typL, tw, LABEL_HEIGHT);
388 WMMoveWidget(panel->typLs, 10 + fw + 3, 23);
389 WMResizeWidget(panel->typLs, tw, height);
391 WMMoveWidget(panel->sizL, 10 + fw + 3 + tw + 3, 0);
392 WMResizeWidget(panel->sizL, sw + 4, LABEL_HEIGHT);
394 WMMoveWidget(panel->sizT, 10 + fw + 3 + tw + 3, 23);
395 WMResizeWidget(panel->sizT, sw + 4, 20);
397 WMMoveWidget(panel->sizLs, 10 + fw + 3 + tw + 3, 46);
398 WMResizeWidget(panel->sizLs, sw + 4, height - 23);
401 #define NUM_FIELDS 14
403 static int isXLFD(const char *font, int *length_ret)
405 int c = 0;
407 *length_ret = 0;
408 while (*font) {
409 (*length_ret)++;
410 if (*font++ == '-')
411 c++;
414 return c == NUM_FIELDS;
417 typedef struct {
418 char *typeface;
419 WMArray *sizes;
420 } Typeface;
422 typedef struct {
423 char *name; /* gotta love simplicity */
424 WMArray *typefaces;
425 } Family;
427 static int compare_int(const void *a, const void *b)
429 int i1 = *(int *)a;
430 int i2 = *(int *)b;
432 if (i1 < i2)
433 return -1;
434 else if (i1 > i2)
435 return 1;
436 else
437 return 0;
440 static void addSizeToTypeface(Typeface * face, int size)
442 if (size == 0) {
443 int j;
445 for (j = 0; j < wlengthof(scalableFontSizes); j++) {
446 size = scalableFontSizes[j];
448 if (!WMCountInArray(face->sizes, (void *)(uintptr_t) size)) {
449 WMAddToArray(face->sizes, (void *)(uintptr_t) size);
452 WMSortArray(face->sizes, compare_int);
453 } else {
454 if (!WMCountInArray(face->sizes, (void *)(uintptr_t) size)) {
455 WMAddToArray(face->sizes, (void *)(uintptr_t) size);
456 WMSortArray(face->sizes, compare_int);
461 static void addTypefaceToXftFamily(Family * fam, const char *style)
463 Typeface *face;
464 WMArrayIterator i;
466 if (fam->typefaces) {
467 WM_ITERATE_ARRAY(fam->typefaces, face, i) {
468 if (strcmp(face->typeface, style) != 0)
469 continue; /* go to next interation */
470 addSizeToTypeface(face, 0);
471 return;
473 } else {
474 fam->typefaces = WMCreateArray(4);
477 face = wmalloc(sizeof(Typeface));
479 face->typeface = wstrdup(style);
480 face->sizes = WMCreateArray(4);
481 addSizeToTypeface(face, 0);
483 WMAddToArray(fam->typefaces, face);
487 * families (same family name) (Hashtable of family -> array)
488 * registries (same family but different registries)
491 static void addFontToXftFamily(WMHashTable * families, const char *name, const char *style)
493 WMArrayIterator i;
494 WMArray *array;
495 Family *fam;
497 array = WMHashGet(families, name);
498 if (array) {
499 WM_ITERATE_ARRAY(array, fam, i) {
500 if (strcmp(fam->name, name) == 0)
501 addTypefaceToXftFamily(fam, style);
502 return;
506 array = WMCreateArray(8);
508 fam = wmalloc(sizeof(Family));
510 fam->name = wstrdup(name);
512 addTypefaceToXftFamily(fam, style);
514 WMAddToArray(array, fam);
516 WMHashInsert(families, fam->name, array);
519 static void listFamilies(WMScreen * scr, WMFontPanel * panel)
521 FcObjectSet *os = 0;
522 FcFontSet *fs;
523 FcPattern *pat;
524 WMHashTable *families;
525 WMHashEnumerator enumer;
526 WMArray *array;
527 int i;
529 pat = FcPatternCreate();
530 os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
531 fs = FcFontList(0, pat, os);
532 if (!fs) {
533 WMRunAlertPanel(scr, panel->win, _("Error"),
534 _("Could not init font config library\n"), _("OK"), NULL, NULL);
535 return;
537 if (pat)
538 FcPatternDestroy(pat);
540 families = WMCreateHashTable(WMStringPointerHashCallbacks);
542 if (fs) {
543 for (i = 0; i < fs->nfont; i++) {
544 FcChar8 *family;
545 FcChar8 *style;
547 if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch)
548 if (FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch)
549 addFontToXftFamily(families, (char *)family, (char *)style);
551 FcFontSetDestroy(fs);
554 enumer = WMEnumerateHashTable(families);
556 while ((array = WMNextHashEnumeratorItem(&enumer))) {
557 WMArrayIterator i;
558 Family *fam;
559 char buffer[256];
560 WMListItem *item;
562 WM_ITERATE_ARRAY(array, fam, i) {
563 wstrlcpy(buffer, fam->name, sizeof(buffer));
564 item = WMAddListItem(panel->famLs, buffer);
566 item->clientData = fam;
569 WMFreeArray(array);
572 WMSortListItems(panel->famLs);
574 WMFreeHashTable(families);
577 static void getSelectedFont(FontPanel * panel, char buffer[], int bufsize)
579 WMListItem *item;
580 Family *family;
581 Typeface *face;
582 char *size;
584 item = WMGetListSelectedItem(panel->famLs);
585 if (!item)
586 return;
587 family = (Family *) item->clientData;
589 item = WMGetListSelectedItem(panel->typLs);
590 if (!item)
591 return;
592 face = (Typeface *) item->clientData;
594 size = WMGetTextFieldText(panel->sizT);
596 snprintf(buffer, bufsize, "%s:style=%s:pixelsize=%s", family->name, face->typeface, size);
598 wfree(size);
601 static void preview(FontPanel * panel)
603 char buffer[512];
604 WMFont *font;
606 getSelectedFont(panel, buffer, sizeof(buffer));
607 font = WMCreateFont(WMWidgetScreen(panel->win), buffer);
608 if (font) {
609 WMSetTextFieldFont(panel->sampleT, font);
610 WMReleaseFont(font);
614 static void familyClick(WMWidget * w, void *data)
616 WMList *lPtr = (WMList *) w;
617 WMListItem *item;
618 Family *family;
619 Typeface *face;
620 FontPanel *panel = (FontPanel *) data;
621 WMArrayIterator i;
622 /* current typeface and size */
623 char *oface = NULL;
624 char *osize = NULL;
625 int facei = -1;
626 int sizei = -1;
628 /* must try to keep the same typeface and size for the new family */
629 item = WMGetListSelectedItem(panel->typLs);
630 if (item)
631 oface = wstrdup(item->text);
633 osize = WMGetTextFieldText(panel->sizT);
635 item = WMGetListSelectedItem(lPtr);
636 family = (Family *) item->clientData;
638 WMClearList(panel->typLs);
640 WM_ITERATE_ARRAY(family->typefaces, face, i) {
641 char buffer[256];
642 int top = 0;
643 WMListItem *fitem;
645 wstrlcpy(buffer, face->typeface, sizeof(buffer));
646 if (strcasecmp(face->typeface, "Roman") == 0)
647 top = 1;
648 if (strcasecmp(face->typeface, "Regular") == 0)
649 top = 1;
650 if (top)
651 fitem = WMInsertListItem(panel->typLs, 0, buffer);
652 else
653 fitem = WMAddListItem(panel->typLs, buffer);
654 fitem->clientData = face;
657 if (oface) {
658 facei = WMFindRowOfListItemWithTitle(panel->typLs, oface);
659 wfree(oface);
661 if (facei < 0) {
662 facei = 0;
664 WMSelectListItem(panel->typLs, facei);
665 typefaceClick(panel->typLs, panel);
667 if (osize) {
668 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
670 if (sizei >= 0) {
671 WMSelectListItem(panel->sizLs, sizei);
672 sizeClick(panel->sizLs, panel);
675 if (osize)
676 wfree(osize);
678 preview(panel);
681 static void typefaceClick(WMWidget * w, void *data)
683 FontPanel *panel = (FontPanel *) data;
684 WMListItem *item;
685 Typeface *face;
686 WMArrayIterator i;
687 char buffer[32];
689 char *osize = NULL;
690 int sizei = -1;
691 void *size;
693 /* Parameter not used, but tell the compiler that it is ok */
694 (void) w;
696 osize = WMGetTextFieldText(panel->sizT);
698 item = WMGetListSelectedItem(panel->typLs);
699 face = (Typeface *) item->clientData;
701 WMClearList(panel->sizLs);
703 WM_ITERATE_ARRAY(face->sizes, size, i) {
704 if ((uintptr_t)size != 0) {
705 sprintf(buffer, "%li", (uintptr_t)size);
707 WMAddListItem(panel->sizLs, buffer);
711 if (osize) {
712 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
714 if (sizei < 0) {
715 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, "12");
717 if (sizei < 0) {
718 sizei = 0;
720 WMSelectListItem(panel->sizLs, sizei);
721 WMSetListPosition(panel->sizLs, sizei);
722 sizeClick(panel->sizLs, panel);
724 if (osize)
725 wfree(osize);
727 preview(panel);
730 static void sizeClick(WMWidget * w, void *data)
732 FontPanel *panel = (FontPanel *) data;
733 WMListItem *item;
735 /* Parameter not used, but tell the compiler that it is ok */
736 (void) w;
738 item = WMGetListSelectedItem(panel->sizLs);
739 WMSetTextFieldText(panel->sizT, item->text);
741 WMSelectTextFieldRange(panel->sizT, wmkrange(0, strlen(item->text)));
743 preview(panel);
746 static void setFontPanelFontName(FontPanel * panel, const char *family, const char *style, double size)
748 int famrow;
749 int stlrow;
750 int sz;
751 char asize[64];
752 void *vsize;
753 WMListItem *item;
754 Family *fam;
755 Typeface *face;
756 WMArrayIterator i;
758 famrow = WMFindRowOfListItemWithTitle(panel->famLs, family);
759 if (famrow < 0) {
760 famrow = 0;
761 return;
763 WMSelectListItem(panel->famLs, famrow);
764 WMSetListPosition(panel->famLs, famrow);
766 WMClearList(panel->typLs);
768 item = WMGetListSelectedItem(panel->famLs);
770 fam = (Family *) item->clientData;
771 WM_ITERATE_ARRAY(fam->typefaces, face, i) {
772 char buffer[256];
773 int top = 0;
774 WMListItem *fitem;
776 wstrlcpy(buffer, face->typeface, sizeof(buffer));
777 if (strcasecmp(face->typeface, "Roman") == 0)
778 top = 1;
779 if (top)
780 fitem = WMInsertListItem(panel->typLs, 0, buffer);
781 else
782 fitem = WMAddListItem(panel->typLs, buffer);
783 fitem->clientData = face;
786 stlrow = WMFindRowOfListItemWithTitle(panel->typLs, style);
788 if (stlrow < 0) {
789 stlrow = 0;
790 return;
793 WMSelectListItem(panel->typLs, stlrow);
795 item = WMGetListSelectedItem(panel->typLs);
797 face = (Typeface *) item->clientData;
799 WMClearList(panel->sizLs);
801 WM_ITERATE_ARRAY(face->sizes, vsize, i) {
802 char buffer[32];
803 if ((uintptr_t)vsize != 0) {
804 sprintf(buffer, "%li", (uintptr_t)vsize);
806 WMAddListItem(panel->sizLs, buffer);
810 snprintf(asize, sizeof(asize) - 1, "%d", (int)(size + 0.5));
812 sz = WMFindRowOfListItemWithTitle(panel->sizLs, asize);
814 if (sz < 0) {
815 sz = 4;
816 return;
819 WMSelectListItem(panel->sizLs, sz);
820 sizeClick(panel->sizLs, panel);
822 return;