10 typedef struct W_FontPanel
{
41 #define MIN_UPPER_HEIGHT 20
42 #define MIN_LOWER_HEIGHT 140
45 #define MAX_FONTS_TO_RETRIEVE 2000
49 #define MIN_HEIGHT MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+70
52 static char *scalableFontSizes[] = {
71 static void arrangeLowerFrame(FontPanel
*panel
);
74 static void listFamilies(WMScreen
*scr
, WMFontPanel
*panel
);
77 splitViewConstrainCallback(WMSplitView
*sPtr
, int divIndex
, int *min
, int *max
)
79 *min
= MIN_UPPER_HEIGHT
;
80 *max
= WMWidgetHeight(sPtr
)-WMGetSplitViewDividerThickness(sPtr
)-MIN_LOWER_HEIGHT
;
85 notificationObserver(void *self
, WMNotification
*notif
)
87 WMFontPanel
*panel
= (WMFontPanel
*)self
;
88 void *object
= WMGetNotificationObject(notif
);
90 if (WMGetNotificationName(notif
) == WMViewSizeDidChangeNotification
) {
91 if (object
== WMWidgetView(panel
->win
)) {
92 int h
= WMWidgetHeight(panel
->win
);
93 int w
= WMWidgetWidth(panel
->win
);
95 WMResizeWidget(panel
->split
, w
, h
-40);
97 WMMoveWidget(panel
->setB
, w
-80, h
-35);
98 WMMoveWidget(panel
->previewB
, w
-160, h
-35);
99 WMMoveWidget(panel
->revertB
, w
-240, h
-35);
100 } else if (object
== WMWidgetView(panel
->upperF
)) {
101 WMResizeWidget(panel
->sampleL
, WMWidgetWidth(panel
->upperF
)-20,
102 WMWidgetHeight(panel
->upperF
)-10);
103 } else if (object
== WMWidgetView(panel
->lowerF
)) {
105 if (WMWidgetHeight(panel
->lowerF
) < MIN_LOWER_HEIGHT
) {
108 h
= WMWidgetHeight(panel
->split
)-MIN_LOWER_HEIGHT
109 - WMGetSplitViewDividerThickness(panel
->split
);
111 WMResizeWidget(panel
->upperF
, WMWidgetWidth(panel
->upperF
), h
);
113 WMMoveWidget(panel
->lowerF
, 0, WMWidgetHeight(panel
->upperF
)
114 + WMGetSplitViewDividerThickness(panel
->split
));
115 WMResizeWidget(panel
->lowerF
, WMWidgetWidth(panel
->lowerF
),
118 arrangeLowerFrame(panel
);
127 familyClick(WMWidget *w, void *data)
129 WMList *lPtr = (WMList*)w;
130 FontPanel *panel = (FontPanel*)data;
138 WMGetFontPanel(WMScreen
*scr
)
141 WMColor
*dark
, *white
;
145 if (scr
->sharedFontPanel
)
146 return scr
->sharedFontPanel
;
149 panel
= wmalloc(sizeof(FontPanel
));
150 memset(panel
, 0, sizeof(FontPanel
));
152 panel
->win
= WMCreateWindow(scr
, "fontPanel");
153 WMResizeWidget(panel
->win
, 320, 370);
154 WMSetWindowMinSize(panel
->win
, MIN_WIDTH
, MIN_HEIGHT
);
155 WMSetViewNotifySizeChanges(WMWidgetView(panel
->win
), True
);
157 panel
->split
= WMCreateSplitView(panel
->win
);
158 WMResizeWidget(panel
->split
, 320, 330);
159 WMSetSplitViewConstrainProc(panel
->split
, splitViewConstrainCallback
);
161 divThickness
= WMGetSplitViewDividerThickness(panel
->split
);
163 panel
->upperF
= WMCreateFrame(panel
->win
);
164 WMSetFrameRelief(panel
->upperF
, WRFlat
);
165 WMSetViewNotifySizeChanges(WMWidgetView(panel
->upperF
), True
);
166 panel
->lowerF
= WMCreateFrame(panel
->win
);
167 WMSetFrameRelief(panel
->lowerF
, WRFlat
);
168 WMSetViewNotifySizeChanges(WMWidgetView(panel
->lowerF
), True
);
170 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->upperF
));
171 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->lowerF
));
173 WMResizeWidget(panel
->upperF
, 320, 60);
174 WMResizeWidget(panel
->lowerF
, 320, 330-60-divThickness
);
175 WMMoveWidget(panel
->lowerF
, 0, 60+divThickness
);
177 white
= WMWhiteColor(scr
);
178 dark
= WMDarkGrayColor(scr
);
180 panel
->sampleL
= WMCreateLabel(panel
->upperF
);
181 WMResizeWidget(panel
->sampleL
, 300, 50);
182 WMMoveWidget(panel
->sampleL
, 10, 10);
183 WMSetWidgetBackgroundColor(panel
->sampleL
, white
);
184 WMSetLabelRelief(panel
->sampleL
, WRSunken
);
185 WMSetLabelText(panel
->sampleL
, "It is not yet completed!!!");
187 font
= WMBoldSystemFontOfSize(scr
, 12);
189 panel
->famL
= WMCreateLabel(panel
->lowerF
);
190 WMSetWidgetBackgroundColor(panel
->famL
, dark
);
191 WMSetLabelText(panel
->famL
, "Family");
192 WMSetLabelFont(panel
->famL
, font
);
193 WMSetLabelTextColor(panel
->famL
, white
);
194 WMSetLabelRelief(panel
->famL
, WRSunken
);
195 WMSetLabelTextAlignment(panel
->famL
, WACenter
);
197 panel
->famLs
= WMCreateList(panel
->lowerF
);
199 panel
->typL
= WMCreateLabel(panel
->lowerF
);
200 WMSetWidgetBackgroundColor(panel
->typL
, dark
);
201 WMSetLabelText(panel
->typL
, "Typeface");
202 WMSetLabelFont(panel
->typL
, font
);
203 WMSetLabelTextColor(panel
->typL
, white
);
204 WMSetLabelRelief(panel
->typL
, WRSunken
);
205 WMSetLabelTextAlignment(panel
->typL
, WACenter
);
207 panel
->typLs
= WMCreateList(panel
->lowerF
);
209 panel
->sizL
= WMCreateLabel(panel
->lowerF
);
210 WMSetWidgetBackgroundColor(panel
->sizL
, dark
);
211 WMSetLabelText(panel
->sizL
, "Size");
212 WMSetLabelFont(panel
->sizL
, font
);
213 WMSetLabelTextColor(panel
->sizL
, white
);
214 WMSetLabelRelief(panel
->sizL
, WRSunken
);
215 WMSetLabelTextAlignment(panel
->sizL
, WACenter
);
217 panel
->sizT
= WMCreateTextField(panel
->lowerF
);
219 panel
->sizLs
= WMCreateList(panel
->lowerF
);
222 WMReleaseColor(white
);
223 WMReleaseColor(dark
);
225 panel
->encF
= WMCreateFrame(panel
->lowerF
);
226 WMSetFrameTitle(panel
->encF
, "Encoding");
227 WMResizeWidget(panel
->encF
, 130, 50);
229 panel
->encP
= WMCreatePopUpButton(panel
->encF
);
230 WMMoveWidget(panel
->encP
, 10, 20);
231 WMResizeWidget(panel
->encP
, 112, 20);
233 WMMapSubwidgets(panel
->encF
);
235 panel
->xlfdF
= WMCreateFrame(panel
->lowerF
);
236 WMSetFrameTitle(panel
->xlfdF
, "Xtra Long Font Description");
238 panel
->xlfdT
= WMCreateTextField(panel
->xlfdF
);
239 WMMoveWidget(panel
->xlfdT
, 10, 20);
241 WMMapSubwidgets(panel
->xlfdF
);
243 arrangeLowerFrame(panel
);
245 panel
->setB
= WMCreateCommandButton(panel
->win
);
246 WMResizeWidget(panel
->setB
, 70, 24);
247 WMMoveWidget(panel
->setB
, 240, 335);
248 WMSetButtonText(panel
->setB
, "Set");
250 panel
->previewB
= WMCreateCommandButton(panel
->win
);
251 WMResizeWidget(panel
->previewB
, 70, 24);
252 WMMoveWidget(panel
->previewB
, 160, 335);
253 WMSetButtonText(panel
->previewB
, "Preview");
255 panel
->revertB
= WMCreateCommandButton(panel
->win
);
256 WMResizeWidget(panel
->revertB
, 70, 24);
257 WMMoveWidget(panel
->revertB
, 80, 335);
258 WMSetButtonText(panel
->revertB
, "Revert");
260 WMRealizeWidget(panel
->win
);
262 WMMapSubwidgets(panel
->upperF
);
263 WMMapSubwidgets(panel
->lowerF
);
264 WMMapSubwidgets(panel
->split
);
265 WMMapSubwidgets(panel
->win
);
267 scr
->sharedFontPanel
= panel
;
270 /* register notification observers */
271 WMAddNotificationObserver(notificationObserver
, panel
,
272 WMViewSizeDidChangeNotification
,
273 WMWidgetView(panel
->win
));
274 WMAddNotificationObserver(notificationObserver
, panel
,
275 WMViewSizeDidChangeNotification
,
276 WMWidgetView(panel
->upperF
));
277 WMAddNotificationObserver(notificationObserver
, panel
,
278 WMViewSizeDidChangeNotification
,
279 WMWidgetView(panel
->lowerF
));
282 listFamilies(scr
, panel
);
290 WMFreeFontPanel(WMFontPanel
*panel
)
292 if (panel
== WMWidgetScreen(panel
->win
)->sharedFontPanel
) {
293 WMWidgetScreen(panel
->win
)->sharedFontPanel
= NULL
;
295 WMRemoveNotificationObserver(panel
);
296 WMUnmapWidget(panel
->win
);
297 WMDestroyWidget(panel
->win
);
303 WMShowFontPanel(WMFontPanel
*panel
)
305 WMMapWidget(panel
->win
);
309 WMHideFontPanel(WMFontPanel
*panel
)
311 WMUnmapWidget(panel
->win
);
316 WMSetFontPanelFont(WMFontPanel
*panel
, WMFont
*font
)
322 WMGetFontPanelFont(WMFontPanel
*panel
)
329 WMGetFontPanelFontName(WMFontPanel
*panel
)
338 arrangeLowerFrame(FontPanel
*panel
)
340 int width
= WMWidgetWidth(panel
->lowerF
) - 55 - 30;
341 int height
= WMWidgetHeight(panel
->lowerF
);
342 int oheight
= 330-60-WMGetSplitViewDividerThickness(panel
->split
);
346 height
-= 20 + 3 + 10 + 50;
347 oheight
-= 20 + 3 + 10 + 50;
349 fw
= (125*width
) / 235;
350 tw
= (110*width
) / 235;
353 h
= (174*height
) / oheight
;
355 WMMoveWidget(panel
->famL
, 10, 0);
356 WMResizeWidget(panel
->famL
, fw
, 20);
358 WMMoveWidget(panel
->famLs
, 10, 23);
359 WMResizeWidget(panel
->famLs
, fw
, h
);
361 WMMoveWidget(panel
->typL
, 10+fw
+3, 0);
362 WMResizeWidget(panel
->typL
, tw
, 20);
364 WMMoveWidget(panel
->typLs
, 10+fw
+3, 23);
365 WMResizeWidget(panel
->typLs
, tw
, h
);
367 WMMoveWidget(panel
->sizL
, 10+fw
+3+tw
+3, 0);
368 WMResizeWidget(panel
->sizL
, sw
+4, 20);
370 WMMoveWidget(panel
->sizT
, 10+fw
+3+tw
+3, 23);
371 WMResizeWidget(panel
->sizT
, sw
+4, 20);
373 WMMoveWidget(panel
->sizLs
, 10+fw
+3+tw
+3, 46);
374 WMResizeWidget(panel
->sizLs
, sw
+4, h
-22);
376 WMMoveWidget(panel
->encF
, 10, WMWidgetHeight(panel
->lowerF
)-55);
378 WMMoveWidget(panel
->xlfdF
, 145, WMWidgetHeight(panel
->lowerF
)-55);
379 WMResizeWidget(panel
->xlfdF
, WMWidgetWidth(panel
->lowerF
)-155, 50);
381 WMResizeWidget(panel
->xlfdT
, WMWidgetWidth(panel
->lowerF
)-155-20, 20);
387 #define ALL_FONTS_MASK "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
404 #define NUM_FIELDS 14
410 parseFont(char *font
, char values
[NUM_FIELDS
][256])
414 char buffer
[256], *bptr
;
418 ptr
++; /* skip first - */
423 strcpy(values
[part
], buffer
);
432 strcpy(values
[part
], buffer
);
440 isXLFD(char *font
, int *length_ret
)
451 return c
==NUM_FIELDS
;
464 char showWeight
; /* not Medium */
465 char showSlant
; /* not R */
466 char showSetWidth
; /* when duplicated */
467 char showAddStyle
; /* when duplicated */
475 char *registry
, *encoding
;
477 char showFoundry
; /* when duplicated */
478 char showRegistry
; /* when duplicated */
486 addTypefaceToFamily(Family
*family
, char fontFields
[NUM_FIELDS
][256])
494 * families (same family name) (Hashtable of family -> bag)
495 * registries (same family but different registries)
500 addFontToFamily(WMHashTable
*families
, char fontFields
[NUM_FIELDS
][256])
506 family
= WMHashGet(families
, fontFields
[FAMILY
]);
509 /* look for same encoding/registry and foundry */
510 for (i
= 0; i
< WMGetBagItemCount(family
); i
++) {
513 fam
= WMGetFromBag(family
, i
);
515 enc
= (strcmp(fam
->encoding
, fontFields
[ENCODING
]) == 0);
516 reg
= (strcmp(fam
->registry
, fontFields
[REGISTRY
]) == 0);
517 found
= (strcmp(fam
->foundry
, fontFields
[FOUNDRY
]) == 0);
519 if (enc
&& reg
&& found
) {
520 addTypefaceToFamily(fam
, fontFields
);
524 /* look for same encoding/registry */
525 for (i
= 0; i
< WMGetBagItemCount(family
); i
++) {
528 fam
= WMGetFromBag(family
, i
);
530 enc
= (strcmp(fam
->encoding
, fontFields
[ENCODING
]) == 0);
531 reg
= (strcmp(fam
->registry
, fontFields
[REGISTRY
]) == 0);
534 /* has the same encoding, but the foundry is different */
535 fam
->showRegistry
= 1;
537 fam
= wmalloc(sizeof(Family
));
538 memset(fam
, 0, sizeof(Family
));
540 fam
->name
= wstrdup(fontFields
[FAMILY
]);
541 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
542 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
543 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
544 fam
->showRegistry
= 1;
546 addTypefaceToFamily(fam
, fontFields
);
548 WMPutInBag(family
, fam
);
553 /* look for same foundry */
554 for (i
= 0; i
< WMGetBagItemCount(family
); i
++) {
557 fam
= WMGetFromBag(family
, i
);
559 found
= (strcmp(fam
->foundry
, fontFields
[FOUNDRY
]) == 0);
562 /* has the same foundry, but encoding is different */
563 fam
->showFoundry
= 1;
565 fam
= wmalloc(sizeof(Family
));
566 memset(fam
, 0, sizeof(Family
));
568 fam
->name
= wstrdup(fontFields
[FAMILY
]);
569 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
570 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
571 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
572 fam
->showFoundry
= 1;
574 addTypefaceToFamily(fam
, fontFields
);
576 WMPutInBag(family
, fam
);
581 /* foundry and encoding do not match anything known */
582 fam
= wmalloc(sizeof(Family
));
583 memset(fam
, 0, sizeof(Family
));
585 fam
->name
= wstrdup(fontFields
[FAMILY
]);
586 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
587 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
588 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
590 addTypefaceToFamily(fam
, fontFields
);
592 WMPutInBag(family
, fam
);
597 family
= WMCreateBag(8);
599 fam
= wmalloc(sizeof(Family
));
600 memset(fam
, 0, sizeof(Family
));
602 fam
->name
= wstrdup(fontFields
[FAMILY
]);
603 fam
->foundry
= wstrdup(fontFields
[FOUNDRY
]);
604 fam
->registry
= wstrdup(fontFields
[REGISTRY
]);
605 fam
->encoding
= wstrdup(fontFields
[ENCODING
]);
607 addTypefaceToFamily(fam
, fontFields
);
609 WMPutInBag(family
, fam
);
611 WMHashInsert(families
, fam
->name
, family
);
617 listFamilies(WMScreen
*scr
, WMFontPanel
*panel
)
622 WMHashTable
*families
= WMCreateHashTable(WMStringHashCallbacks
);
623 char fields
[NUM_FIELDS
][256];
625 fontList
= XListFonts(scr
->display
, ALL_FONTS_MASK
, MAX_FONTS_TO_RETRIEVE
,
628 WMRunAlertPanel(scr
, panel
->win
, "Error",
629 "Could not retrieve font list", "OK", NULL
, NULL
);
633 for (i
= 0; i
< count
; i
++) {
636 if (!isXLFD(fontList
[i
], &fname_len
)) {
640 if (fname_len
> 255) {
641 wwarning("font name %s is longer than 256, which is invalid.",
646 if (!parseFont(fontList
[i
], fields
)) {
650 addFontToFamily(families
, (char**)fields
);