13 #include <X11/Xft/Xft.h>
14 #include <fontconfig/fontconfig.h>
19 char *WMFontPanelFontChangedNotification
= "WMFontPanelFontChangedNotification";
24 typedef struct W_FontPanel
{
51 #define MIN_UPPER_HEIGHT 20
52 #define MIN_LOWER_HEIGHT 140
55 #define MAX_FONTS_TO_RETRIEVE 2000
57 #define BUTTON_SPACE_HEIGHT 40
60 #define MIN_HEIGHT (MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)
62 #define DEF_UPPER_HEIGHT 60
63 #define DEF_LOWER_HEIGHT 310
66 #define DEF_HEIGHT (DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)
71 static int scalableFontSizes
[] = {
89 static void setFontPanelFontName(FontPanel
*panel
, FcChar8
*family
, FcChar8
*style
, double size
);
92 static int isXLFD(char *font
, int *length_ret
);
94 static void arrangeLowerFrame(FontPanel
*panel
);
96 static void familyClick(WMWidget
*, void *);
97 static void typefaceClick(WMWidget
*, void *);
98 static void sizeClick(WMWidget
*, void *);
101 static void listFamilies(WMScreen
*scr
, WMFontPanel
*panel
);
105 splitViewConstrainCallback(WMSplitView
*sPtr
, int indView
, int *min
, int *max
)
108 *min
= MIN_UPPER_HEIGHT
;
110 *min
= MIN_LOWER_HEIGHT
;
114 notificationObserver(void *self
, WMNotification
*notif
)
116 WMFontPanel
*panel
= (WMFontPanel
*)self
;
117 void *object
= WMGetNotificationObject(notif
);
119 if (WMGetNotificationName(notif
) == WMViewSizeDidChangeNotification
) {
120 if (object
== WMWidgetView(panel
->win
)) {
121 int h
= WMWidgetHeight(panel
->win
);
122 int w
= WMWidgetWidth(panel
->win
);
124 WMResizeWidget(panel
->split
, w
, h
-BUTTON_SPACE_HEIGHT
);
126 WMMoveWidget(panel
->setB
, w
-80, h
-(BUTTON_SPACE_HEIGHT
-5));
128 WMMoveWidget(panel
->revertB
, w
-240, h
-(BUTTON_SPACE_HEIGHT
-5));
130 } else if (object
== WMWidgetView(panel
->upperF
)) {
132 if (WMWidgetHeight(panel
->upperF
) < MIN_UPPER_HEIGHT
) {
133 WMResizeWidget(panel
->upperF
, WMWidgetWidth(panel
->upperF
),
136 WMResizeWidget(panel
->sampleT
, WMWidgetWidth(panel
->upperF
)-20,
137 WMWidgetHeight(panel
->upperF
)-10);
140 } else if (object
== WMWidgetView(panel
->lowerF
)) {
142 if (WMWidgetHeight(panel
->lowerF
) < MIN_LOWER_HEIGHT
) {
143 WMResizeWidget(panel
->upperF
, WMWidgetWidth(panel
->upperF
),
146 WMMoveWidget(panel
->lowerF
, 0, WMWidgetHeight(panel
->upperF
)
147 + WMGetSplitViewDividerThickness(panel
->split
));
149 WMResizeWidget(panel
->lowerF
, WMWidgetWidth(panel
->lowerF
),
150 WMWidgetWidth(panel
->split
) - MIN_UPPER_HEIGHT
151 - WMGetSplitViewDividerThickness(panel
->split
));
153 arrangeLowerFrame(panel
);
161 closeWindow(WMWidget
*w
, void *data
)
163 FontPanel
*panel
= (FontPanel
*)data
;
165 WMHideFontPanel(panel
);
172 setClickedAction(WMWidget
*w
, void *data
)
174 FontPanel
*panel
= (FontPanel
*)data
;
177 (*panel
->action
)(panel
, panel
->data
);
182 revertClickedAction(WMWidget
*w
, void *data
)
184 /*FontPanel *panel = (FontPanel*)data;*/
191 WMGetFontPanel(WMScreen
*scr
)
194 WMColor
*dark
, *white
;
198 if (scr
->sharedFontPanel
)
199 return scr
->sharedFontPanel
;
202 panel
= wmalloc(sizeof(FontPanel
));
203 memset(panel
, 0, sizeof(FontPanel
));
205 panel
->win
= WMCreateWindow(scr
, "fontPanel");
206 /* WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr));*/
207 WMSetWindowTitle(panel
->win
, _("Font Panel"));
208 WMResizeWidget(panel
->win
, DEF_WIDTH
, DEF_HEIGHT
);
209 WMSetWindowMinSize(panel
->win
, MIN_WIDTH
, MIN_HEIGHT
);
210 WMSetViewNotifySizeChanges(WMWidgetView(panel
->win
), True
);
212 WMSetWindowCloseAction(panel
->win
, closeWindow
, panel
);
214 panel
->split
= WMCreateSplitView(panel
->win
);
215 WMResizeWidget(panel
->split
, DEF_WIDTH
, DEF_HEIGHT
- BUTTON_SPACE_HEIGHT
);
216 WMSetSplitViewConstrainProc(panel
->split
, splitViewConstrainCallback
);
218 divThickness
= WMGetSplitViewDividerThickness(panel
->split
);
220 panel
->upperF
= WMCreateFrame(panel
->win
);
221 WMSetFrameRelief(panel
->upperF
, WRFlat
);
222 WMSetViewNotifySizeChanges(WMWidgetView(panel
->upperF
), True
);
223 panel
->lowerF
= WMCreateFrame(panel
->win
);
224 /* WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr));*/
225 WMSetFrameRelief(panel
->lowerF
, WRFlat
);
226 WMSetViewNotifySizeChanges(WMWidgetView(panel
->lowerF
), True
);
228 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->upperF
));
229 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->lowerF
));
231 WMResizeWidget(panel
->upperF
, DEF_WIDTH
, DEF_UPPER_HEIGHT
);
233 WMResizeWidget(panel
->lowerF
, DEF_WIDTH
, DEF_LOWER_HEIGHT
);
235 WMMoveWidget(panel
->lowerF
, 0, 60+divThickness
);
237 white
= WMWhiteColor(scr
);
238 dark
= WMDarkGrayColor(scr
);
240 panel
->sampleT
= WMCreateTextField(panel
->upperF
);
241 WMResizeWidget(panel
->sampleT
, DEF_WIDTH
- 20, 50);
242 WMMoveWidget(panel
->sampleT
, 10, 10);
243 WMSetTextFieldText(panel
->sampleT
, _("The quick brown fox jumps over the lazy dog"));
245 font
= WMBoldSystemFontOfSize(scr
, 12);
247 panel
->famL
= WMCreateLabel(panel
->lowerF
);
248 WMSetWidgetBackgroundColor(panel
->famL
, dark
);
249 WMSetLabelText(panel
->famL
, _("Family"));
250 WMSetLabelFont(panel
->famL
, font
);
251 WMSetLabelTextColor(panel
->famL
, white
);
252 WMSetLabelRelief(panel
->famL
, WRSunken
);
253 WMSetLabelTextAlignment(panel
->famL
, WACenter
);
255 panel
->famLs
= WMCreateList(panel
->lowerF
);
256 WMSetListAction(panel
->famLs
, familyClick
, panel
);
258 panel
->typL
= WMCreateLabel(panel
->lowerF
);
259 WMSetWidgetBackgroundColor(panel
->typL
, dark
);
260 WMSetLabelText(panel
->typL
, _("Typeface"));
261 WMSetLabelFont(panel
->typL
, font
);
262 WMSetLabelTextColor(panel
->typL
, white
);
263 WMSetLabelRelief(panel
->typL
, WRSunken
);
264 WMSetLabelTextAlignment(panel
->typL
, WACenter
);
266 panel
->typLs
= WMCreateList(panel
->lowerF
);
267 WMSetListAction(panel
->typLs
, typefaceClick
, panel
);
269 panel
->sizL
= WMCreateLabel(panel
->lowerF
);
270 WMSetWidgetBackgroundColor(panel
->sizL
, dark
);
271 WMSetLabelText(panel
->sizL
, _("Size"));
272 WMSetLabelFont(panel
->sizL
, font
);
273 WMSetLabelTextColor(panel
->sizL
, white
);
274 WMSetLabelRelief(panel
->sizL
, WRSunken
);
275 WMSetLabelTextAlignment(panel
->sizL
, WACenter
);
277 panel
->sizT
= WMCreateTextField(panel
->lowerF
);
278 /* WMSetTextFieldAlignment(panel->sizT, WARight);*/
280 panel
->sizLs
= WMCreateList(panel
->lowerF
);
281 WMSetListAction(panel
->sizLs
, sizeClick
, panel
);
284 WMReleaseColor(white
);
285 WMReleaseColor(dark
);
287 panel
->setB
= WMCreateCommandButton(panel
->win
);
288 WMResizeWidget(panel
->setB
, 70, 24);
289 WMMoveWidget(panel
->setB
, 240, DEF_HEIGHT
- (BUTTON_SPACE_HEIGHT
-5));
290 WMSetButtonText(panel
->setB
, _("Set"));
291 WMSetButtonAction(panel
->setB
, setClickedAction
, panel
);
293 panel
->revertB
= WMCreateCommandButton(panel
->win
);
294 WMResizeWidget(panel
->revertB
, 70, 24);
295 WMMoveWidget(panel
->revertB
, 80, DEF_HEIGHT
- (BUTTON_SPACE_HEIGHT
-5));
296 WMSetButtonText(panel
->revertB
, _("Revert"));
297 WMSetButtonAction(panel
->revertB
, revertClickedAction
, panel
);
300 WMRealizeWidget(panel
->win
);
302 WMMapSubwidgets(panel
->upperF
);
303 WMMapSubwidgets(panel
->lowerF
);
304 WMMapSubwidgets(panel
->split
);
305 WMMapSubwidgets(panel
->win
);
307 WMUnmapWidget(panel
->revertB
);
309 arrangeLowerFrame(panel
);
311 scr
->sharedFontPanel
= panel
;
314 /* register notification observers */
315 WMAddNotificationObserver(notificationObserver
, panel
,
316 WMViewSizeDidChangeNotification
,
317 WMWidgetView(panel
->win
));
318 WMAddNotificationObserver(notificationObserver
, panel
,
319 WMViewSizeDidChangeNotification
,
320 WMWidgetView(panel
->upperF
));
321 WMAddNotificationObserver(notificationObserver
, panel
,
322 WMViewSizeDidChangeNotification
,
323 WMWidgetView(panel
->lowerF
));
326 listFamilies(scr
, panel
);
334 WMFreeFontPanel(WMFontPanel
*panel
)
336 if (panel
== WMWidgetScreen(panel
->win
)->sharedFontPanel
) {
337 WMWidgetScreen(panel
->win
)->sharedFontPanel
= NULL
;
339 WMRemoveNotificationObserver(panel
);
340 WMUnmapWidget(panel
->win
);
341 WMDestroyWidget(panel
->win
);
347 WMShowFontPanel(WMFontPanel
*panel
)
349 WMMapWidget(panel
->win
);
354 WMHideFontPanel(WMFontPanel
*panel
)
356 WMUnmapWidget(panel
->win
);
361 WMGetFontPanelFont(WMFontPanel
*panel
)
363 return WMGetTextFieldFont(panel
->sampleT
);
368 WMSetFontPanelFont(WMFontPanel
*panel
, char *fontName
)
373 FcChar8
*family
, *style
;
376 if (!isXLFD(fontName
, &fname_len
)) {
377 /* maybe its proper fontconfig and we can parse it */
378 pattern
= FcNameParse(fontName
);
380 /* maybe its proper xlfd and we can convert it to an FcPattern */
381 pattern
= XftXlfdParse(fontName
, False
, False
);
382 //FcPatternPrint(pattern);
388 if (FcPatternGetString(pattern
, FC_FAMILY
, 0, &family
)==FcResultMatch
)
389 if (FcPatternGetString(pattern
, FC_STYLE
, 0, &style
)==FcResultMatch
)
390 if (FcPatternGetDouble(pattern
, "pixelsize", 0, &size
)==FcResultMatch
)
391 setFontPanelFontName(panel
, family
, style
, size
);
393 FcPatternDestroy(pattern
);
399 WMSetFontPanelAction(WMFontPanel
*panel
, WMAction2
*action
, void *data
)
401 panel
->action
= action
;
410 arrangeLowerFrame(FontPanel
*panel
)
412 int width
= WMWidgetWidth(panel
->lowerF
) - 55 - 30;
413 int height
= WMWidgetHeight(panel
->split
) - WMWidgetHeight(panel
->upperF
);
416 #define LABEL_HEIGHT 20
418 height
-= WMGetSplitViewDividerThickness(panel
->split
);
421 height
-= LABEL_HEIGHT
+ 8;
423 fw
= (125*width
) / 235;
424 tw
= (110*width
) / 235;
427 WMMoveWidget(panel
->famL
, 10, 0);
428 WMResizeWidget(panel
->famL
, fw
, LABEL_HEIGHT
);
430 WMMoveWidget(panel
->famLs
, 10, 23);
431 WMResizeWidget(panel
->famLs
, fw
, height
);
433 WMMoveWidget(panel
->typL
, 10+fw
+3, 0);
434 WMResizeWidget(panel
->typL
, tw
, LABEL_HEIGHT
);
436 WMMoveWidget(panel
->typLs
, 10+fw
+3, 23);
437 WMResizeWidget(panel
->typLs
, tw
, height
);
439 WMMoveWidget(panel
->sizL
, 10+fw
+3+tw
+3, 0);
440 WMResizeWidget(panel
->sizL
, sw
+4, LABEL_HEIGHT
);
442 WMMoveWidget(panel
->sizT
, 10+fw
+3+tw
+3, 23);
443 WMResizeWidget(panel
->sizT
, sw
+4, 20);
445 WMMoveWidget(panel
->sizLs
, 10+fw
+3+tw
+3, 46);
446 WMResizeWidget(panel
->sizLs
, sw
+4, height
-23);
452 #define ALL_FONTS_MASK "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
469 #define NUM_FIELDS 14
474 isXLFD(char *font
, int *length_ret
)
485 return c
==NUM_FIELDS
;
490 parseFont(char *font
, char values
[NUM_FIELDS
][256])
494 char buffer
[256], *bptr
;
498 ptr
++; /* skip first - */
503 strcpy(values
[part
], buffer
);
512 strcpy(values
[part
], buffer
);
528 char showSetWidth
; /* when duplicated */
529 char showAddStyle
; /* when duplicated */
539 char *registry
, *encoding
;
541 char showFoundry
; /* when duplicated */
542 char showRegistry
; /* when duplicated */
554 char *name
; /* gotta love simplicity */
563 compare_int(const void *a
, const void *b
)
579 addSizeToTypeface(Xft_Typeface
*face
, int size
)
581 addSizeToTypeface(Typeface
*face
, int size
)
587 for (j
= 0; j
< sizeof(scalableFontSizes
)/sizeof(int); j
++) {
588 size
= scalableFontSizes
[j
];
590 if (!WMCountInArray(face
->sizes
, (void*)size
)) {
591 WMAddToArray(face
->sizes
, (void*)size
);
594 WMSortArray(face
->sizes
, compare_int
);
596 if (!WMCountInArray(face
->sizes
, (void*)size
)) {
597 WMAddToArray(face
->sizes
, (void*)size
);
598 WMSortArray(face
->sizes
, compare_int
);
605 addTypefaceToXftFamily(Xft_Family
*fam
, char *style
)
611 WM_ITERATE_ARRAY(fam
->typefaces
, face
, i
) {
612 if(strcmp(face
->typeface
, style
) != 0)
613 continue; /* go to next interation */
614 addSizeToTypeface(face
, 0);
618 fam
->typefaces
= WMCreateArray(4);
621 face
= wmalloc(sizeof(Xft_Typeface
));
622 memset(face
, 0 , sizeof(Xft_Typeface
));
624 face
->typeface
= wstrdup(style
);
625 face
->sizes
= WMCreateArray(4);
626 addSizeToTypeface(face
, 0);
628 WMAddToArray(fam
->typefaces
, face
);
634 addTypefaceToFamily(Family
*family
, char fontFields
[NUM_FIELDS
][256])
639 if (family
->typefaces
) {
640 WM_ITERATE_ARRAY(family
->typefaces
, face
, i
) {
643 if (strcmp(face
->weight
, fontFields
[WEIGHT
]) != 0) {
646 if (strcmp(face
->slant
, fontFields
[SLANT
]) != 0) {
650 size
= atoi(fontFields
[PIXEL_SIZE
]);
652 addSizeToTypeface(face
, size
);
657 family
->typefaces
= WMCreateArray(4);
660 face
= wmalloc(sizeof(Typeface
));
661 memset(face
, 0, sizeof(Typeface
));
663 face
->weight
= wstrdup(fontFields
[WEIGHT
]);
664 face
->slant
= wstrdup(fontFields
[SLANT
]);
665 face
->setWidth
= wstrdup(fontFields
[SETWIDTH
]);
666 face
->addStyle
= wstrdup(fontFields
[ADD_STYLE
]);
668 face
->sizes
= WMCreateArray(4);
669 addSizeToTypeface(face
, atoi(fontFields
[PIXEL_SIZE
]));
671 WMAddToArray(family
->typefaces
, face
);
676 * families (same family name) (Hashtable of family -> array)
677 * registries (same family but different registries)
683 addFontToXftFamily(WMHashTable
*families
, char *name
, char *style
)
689 array
= WMHashGet(families
, name
);
691 WM_ITERATE_ARRAY(array
, fam
, i
) {
692 if(strcmp(fam
->name
, name
) == 0 )
693 addTypefaceToXftFamily(fam
, style
);
698 array
= WMCreateArray(8);
700 fam
= wmalloc(sizeof(Xft_Family
));
701 memset(fam
, 0, sizeof(Xft_Family
));
703 fam
->name
= wstrdup(name
);
705 addTypefaceToXftFamily(fam
, style
);
707 WMAddToArray(array
, fam
);
709 WMHashInsert(families
, fam
->name
, array
);
715 addFontToFamily(WMHashTable
*families
, char fontFields
[NUM_FIELDS
][256])
722 family
= WMHashGet(families
, fontFields
[FAMILY
]);
725 /* look for same encoding/registry and foundry */
726 WM_ITERATE_ARRAY(family
, fam
, i
) {
729 enc
= (strcmp(fam
->encoding
, fontFields
[ENCODING
]) == 0);
730 reg
= (strcmp(fam
->registry
, fontFields
[REGISTRY
]) == 0);
731 found
= (strcmp(fam
->foundry
, fontFields
[FOUNDRY
]) == 0);
733 if (enc
&& reg
&& found
) {
734 addTypefaceToFamily(fam
, fontFields
);
738 /* look for same encoding/registry */
739 WM_ITERATE_ARRAY(family
, fam
, i
) {
742 enc
= (strcmp(fam
->encoding
, fontFields
[ENCODING
]) == 0);
743 reg
= (strcmp(fam
->registry
, fontFields
[REGISTRY
]) == 0);
746 /* has the same encoding, but the foundry is different */
747 fam
->showFoundry
= 1;
749 fam
= wmalloc(sizeof(Family
));
750 memset(fam
, 0, sizeof(Family
));
752 fam
->name
= wstrdup(fontFields
[FAMILY
]);
753 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
754 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
755 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
756 fam
->showFoundry
= 1;
758 addTypefaceToFamily(fam
, fontFields
);
760 WMAddToArray(family
, fam
);
764 /* look for same foundry */
765 WM_ITERATE_ARRAY(family
, fam
, i
) {
768 found
= (strcmp(fam
->foundry
, fontFields
[FOUNDRY
]) == 0);
771 /* has the same foundry, but encoding is different */
772 fam
->showRegistry
= 1;
774 fam
= wmalloc(sizeof(Family
));
775 memset(fam
, 0, sizeof(Family
));
777 fam
->name
= wstrdup(fontFields
[FAMILY
]);
778 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
779 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
780 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
781 fam
->showRegistry
= 1;
783 addTypefaceToFamily(fam
, fontFields
);
785 WMAddToArray(family
, fam
);
789 /* foundry and encoding do not match anything known */
790 fam
= wmalloc(sizeof(Family
));
791 memset(fam
, 0, sizeof(Family
));
793 fam
->name
= wstrdup(fontFields
[FAMILY
]);
794 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
795 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
796 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
797 fam
->showFoundry
= 1;
798 fam
->showRegistry
= 1;
800 addTypefaceToFamily(fam
, fontFields
);
802 WMAddToArray(family
, fam
);
806 family
= WMCreateArray(8);
808 fam
= wmalloc(sizeof(Family
));
809 memset(fam
, 0, sizeof(Family
));
811 fam
->name
= wstrdup(fontFields
[FAMILY
]);
812 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
813 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
814 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
816 addTypefaceToFamily(fam
, fontFields
);
818 WMAddToArray(family
, fam
);
820 WMHashInsert(families
, fam
->name
, family
);
827 listFamilies(WMScreen
*scr
, WMFontPanel
*panel
)
835 char fields
[NUM_FIELDS
][256];
838 WMHashTable
*families
;
839 WMHashEnumerator enumer
;
844 pat
= FcPatternCreate();
845 os
= FcObjectSetBuild(FC_FAMILY
, FC_STYLE
, 0);
846 fs
= FcFontList(0, pat
, os
);
848 WMRunAlertPanel(scr
, panel
->win
, _("Error"),
849 _("Could not init font config library\n"), _("OK"), NULL
, NULL
);
853 FcPatternDestroy (pat
);
855 fontList
= XListFonts(scr
->display
, ALL_FONTS_MASK
, MAX_FONTS_TO_RETRIEVE
,
858 WMRunAlertPanel(scr
, panel
->win
, _("Error"),
859 _("Could not retrieve font list"), _("OK"), NULL
, NULL
);
864 families
= WMCreateHashTable(WMStringPointerHashCallbacks
);
868 for (i
= 0; i
< fs
->nfont
; i
++) {
872 if (FcPatternGetString(fs
->fonts
[i
],FC_FAMILY
,0,&family
)==FcResultMatch
)
873 if (FcPatternGetString(fs
->fonts
[i
],FC_STYLE
,0,&style
)==FcResultMatch
)
874 addFontToXftFamily(families
, family
, style
);
876 FcFontSetDestroy(fs
);
879 for (i
= 0; i
< count
; i
++) {
882 if (!isXLFD(fontList
[i
], &fname_len
)) {
886 if (fname_len
> 255) {
887 wwarning(_("font name %s is longer than 256, which is invalid."),
892 if (!parseFont(fontList
[i
], fields
)) {
896 addFontToFamily(families
, fields
);
900 enumer
= WMEnumerateHashTable(families
);
903 while ((array
= WMNextHashEnumeratorItem(&enumer
))) {
909 WM_ITERATE_ARRAY(array
, fam
, i
) {
910 strcpy(buffer
, fam
->name
);
911 item
= WMAddListItem(panel
->famLs
, buffer
);
913 item
->clientData
= fam
;
919 while ((array
= WMNextHashEnumeratorItem(&enumer
))) {
925 WM_ITERATE_ARRAY(array
, fam
, i
) {
926 strcpy(buffer
, fam
->name
);
928 if (fam
->showFoundry
) {
930 strcat(buffer
, fam
->foundry
);
933 if (fam
->showRegistry
) {
934 strcat(buffer
, " (");
935 strcat(buffer
, fam
->registry
);
937 strcat(buffer
, fam
->encoding
);
940 item
= WMAddListItem(panel
->famLs
, buffer
);
942 item
->clientData
= fam
;
947 WMSortListItems(panel
->famLs
);
949 WMFreeHashTable(families
);
954 getSelectedFont(FontPanel
*panel
, char buffer
[], int bufsize
)
967 item
= WMGetListSelectedItem(panel
->famLs
);
971 family
= (Xft_Family
*)item
->clientData
;
973 family
= (Family
*)item
->clientData
;
976 item
= WMGetListSelectedItem(panel
->typLs
);
980 face
= (Xft_Typeface
*)item
->clientData
;
982 face
= (Typeface
*)item
->clientData
;
985 size
= WMGetTextFieldText(panel
->sizT
);
988 snprintf(buffer
, bufsize
, "%s:style=%s:pixelsize=%s",
993 snprintf(buffer
, bufsize
, "-%s-%s-%s-%s-%s-%s-%s-*-*-*-*-*-%s-%s",
1010 preview(FontPanel
*panel
)
1015 getSelectedFont(panel
, buffer
, sizeof(buffer
));
1016 font
= WMCreateFont(WMWidgetScreen(panel
->win
), buffer
);
1018 WMSetTextFieldFont(panel
->sampleT
, font
);
1019 WMReleaseFont(font
);
1026 familyClick(WMWidget
*w
, void *data
)
1028 WMList
*lPtr
= (WMList
*)w
;
1037 FontPanel
*panel
= (FontPanel
*)data
;
1039 /* current typeface and size */
1045 /* must try to keep the same typeface and size for the new family */
1046 item
= WMGetListSelectedItem(panel
->typLs
);
1048 oface
= wstrdup(item
->text
);
1050 osize
= WMGetTextFieldText(panel
->sizT
);
1053 item
= WMGetListSelectedItem(lPtr
);
1055 family
= (Xft_Family
*)item
->clientData
;
1057 family
= (Family
*)item
->clientData
;
1060 WMClearList(panel
->typLs
);
1063 WM_ITERATE_ARRAY(family
->typefaces
, face
, i
) {
1069 strcpy(buffer
, face
->typeface
);
1070 if(strcasecmp(face
->typeface
, "Roman") == 0)
1072 if(strcasecmp(face
->typeface
, "Regular") == 0)
1075 if (strcmp(face
->weight
, "medium") == 0) {
1078 if (*face
->weight
) {
1079 strcpy(buffer
, face
->weight
);
1080 buffer
[0] = toupper(buffer
[0]);
1081 strcat(buffer
, " ");
1087 if (strcmp(face
->slant
, "r") == 0) {
1088 strcat(buffer
, _("Roman"));
1090 } else if (strcmp(face
->slant
, "i") == 0) {
1091 strcat(buffer
, _("Italic"));
1092 } else if (strcmp(face
->slant
, "o") == 0) {
1093 strcat(buffer
, _("Oblique"));
1094 } else if (strcmp(face
->slant
, "ri") == 0) {
1095 strcat(buffer
, _("Rev Italic"));
1096 } else if (strcmp(face
->slant
, "ro") == 0) {
1097 strcat(buffer
, _("Rev Oblique"));
1099 strcat(buffer
, face
->slant
);
1102 if (buffer
[0] == 0) {
1103 strcpy(buffer
, _("Normal"));
1107 fitem
= WMInsertListItem(panel
->typLs
, 0, buffer
);
1109 fitem
= WMAddListItem(panel
->typLs
, buffer
);
1110 fitem
->clientData
= face
;
1114 facei
= WMFindRowOfListItemWithTitle(panel
->typLs
, oface
);
1120 WMSelectListItem(panel
->typLs
, facei
);
1121 typefaceClick(panel
->typLs
, panel
);
1124 sizei
= WMFindRowOfListItemWithTitle(panel
->sizLs
, osize
);
1127 WMSelectListItem(panel
->sizLs
, sizei
);
1128 sizeClick(panel
->sizLs
, panel
);
1140 typefaceClick(WMWidget
*w
, void *data
)
1142 FontPanel
*panel
= (FontPanel
*)data
;
1156 osize
= WMGetTextFieldText(panel
->sizT
);
1159 item
= WMGetListSelectedItem(panel
->typLs
);
1161 face
= (Xft_Typeface
*)item
->clientData
;
1163 face
= (Typeface
*)item
->clientData
;
1166 WMClearList(panel
->sizLs
);
1168 WM_ITERATE_ARRAY(face
->sizes
, size
, i
) {
1169 if ((int)size
!= 0) {
1170 sprintf(buffer
, "%i", (int)size
);
1172 WMAddListItem(panel
->sizLs
, buffer
);
1177 sizei
= WMFindRowOfListItemWithTitle(panel
->sizLs
, osize
);
1180 sizei
= WMFindRowOfListItemWithTitle(panel
->sizLs
, "12");
1185 WMSelectListItem(panel
->sizLs
, sizei
);
1186 WMSetListPosition(panel
->sizLs
, sizei
);
1187 sizeClick(panel
->sizLs
, panel
);
1196 sizeClick(WMWidget
*w
, void *data
)
1198 FontPanel
*panel
= (FontPanel
*)data
;
1201 item
= WMGetListSelectedItem(panel
->sizLs
);
1202 WMSetTextFieldText(panel
->sizT
, item
->text
);
1204 WMSelectTextFieldRange(panel
->sizT
, wmkrange(0, strlen(item
->text
)));
1212 setFontPanelFontName(FontPanel
*panel
, FcChar8
*family
, FcChar8
*style
, double size
)
1224 famrow
= WMFindRowOfListItemWithTitle(panel
->famLs
, family
);
1229 WMSelectListItem(panel
->famLs
, famrow
);
1230 WMSetListPosition(panel
->famLs
, famrow
);
1232 WMClearList(panel
->typLs
);
1234 item
= WMGetListSelectedItem(panel
->famLs
);
1236 fam
= (Xft_Family
*)item
->clientData
;
1237 WM_ITERATE_ARRAY(fam
->typefaces
, face
, i
) {
1242 strcpy(buffer
, face
->typeface
);
1243 if(strcasecmp(face
->typeface
, "Roman") == 0)
1246 fitem
= WMInsertListItem(panel
->typLs
, 0, buffer
);
1248 fitem
= WMAddListItem(panel
->typLs
, buffer
);
1249 fitem
->clientData
= face
;
1253 stlrow
= WMFindRowOfListItemWithTitle(panel
->typLs
, style
);
1260 WMSelectListItem(panel
->typLs
, stlrow
);
1262 item
= WMGetListSelectedItem(panel
->typLs
);
1264 face
= (Xft_Typeface
*)item
->clientData
;
1266 WMClearList(panel
->sizLs
);
1269 WM_ITERATE_ARRAY(face
->sizes
, vsize
, i
) {
1271 if ((int)vsize
!= 0) {
1272 sprintf(buffer
, "%i", (int)vsize
);
1274 WMAddListItem(panel
->sizLs
, buffer
);
1278 snprintf(asize
, sizeof(asize
)-1, "%d",(int)(size
+0.5));
1280 sz
= WMFindRowOfListItemWithTitle(panel
->sizLs
, asize
);
1287 WMSelectListItem(panel
->sizLs
, sz
);
1288 sizeClick(panel
->sizLs
, panel
);