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
);
73 static proplist_t
createFontDatabase(WMScreen
*scr
);
75 static void listFamilies(proplist_t fdb
, WMList
*list
);
78 splitViewConstrainCallback(WMSplitView
*sPtr
, int divIndex
, int *min
, int *max
)
80 *min
= MIN_UPPER_HEIGHT
;
81 *max
= WMWidgetHeight(sPtr
)-WMGetSplitViewDividerThickness(sPtr
)-MIN_LOWER_HEIGHT
;
86 notificationObserver(void *self
, WMNotification
*notif
)
88 WMFontPanel
*panel
= (WMFontPanel
*)self
;
89 void *object
= WMGetNotificationObject(notif
);
91 if (WMGetNotificationName(notif
) == WMViewSizeDidChangeNotification
) {
92 if (object
== WMWidgetView(panel
->win
)) {
93 int h
= WMWidgetHeight(panel
->win
);
94 int w
= WMWidgetWidth(panel
->win
);
96 WMResizeWidget(panel
->split
, w
, h
-40);
98 WMMoveWidget(panel
->setB
, w
-80, h
-35);
99 WMMoveWidget(panel
->previewB
, w
-160, h
-35);
100 WMMoveWidget(panel
->revertB
, w
-240, h
-35);
101 } else if (object
== WMWidgetView(panel
->upperF
)) {
102 WMResizeWidget(panel
->sampleL
, WMWidgetWidth(panel
->upperF
)-20,
103 WMWidgetHeight(panel
->upperF
)-10);
104 } else if (object
== WMWidgetView(panel
->lowerF
)) {
106 if (WMWidgetHeight(panel
->lowerF
) < MIN_LOWER_HEIGHT
) {
109 h
= WMWidgetHeight(panel
->split
)-MIN_LOWER_HEIGHT
110 - WMGetSplitViewDividerThickness(panel
->split
);
112 WMResizeWidget(panel
->upperF
, WMWidgetWidth(panel
->upperF
), h
);
114 WMMoveWidget(panel
->lowerF
, 0, WMWidgetHeight(panel
->upperF
)
115 + WMGetSplitViewDividerThickness(panel
->split
));
116 WMResizeWidget(panel
->lowerF
, WMWidgetWidth(panel
->lowerF
),
119 arrangeLowerFrame(panel
);
128 familyClick(WMWidget *w, void *data)
130 WMList *lPtr = (WMList*)w;
131 FontPanel *panel = (FontPanel*)data;
139 WMGetFontPanel(WMScreen
*scr
)
142 WMColor
*dark
, *white
;
146 if (scr
->sharedFontPanel
)
147 return scr
->sharedFontPanel
;
150 panel
= wmalloc(sizeof(FontPanel
));
151 memset(panel
, 0, sizeof(FontPanel
));
153 panel
->win
= WMCreateWindow(scr
, "fontPanel");
154 WMResizeWidget(panel
->win
, 320, 370);
155 WMSetWindowMinSize(panel
->win
, MIN_WIDTH
, MIN_HEIGHT
);
156 WMSetViewNotifySizeChanges(WMWidgetView(panel
->win
), True
);
158 panel
->split
= WMCreateSplitView(panel
->win
);
159 WMResizeWidget(panel
->split
, 320, 330);
160 WMSetSplitViewConstrainProc(panel
->split
, splitViewConstrainCallback
);
162 divThickness
= WMGetSplitViewDividerThickness(panel
->split
);
164 panel
->upperF
= WMCreateFrame(panel
->win
);
165 WMSetFrameRelief(panel
->upperF
, WRFlat
);
166 WMSetViewNotifySizeChanges(WMWidgetView(panel
->upperF
), True
);
167 panel
->lowerF
= WMCreateFrame(panel
->win
);
168 WMSetFrameRelief(panel
->lowerF
, WRFlat
);
169 WMSetViewNotifySizeChanges(WMWidgetView(panel
->lowerF
), True
);
171 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->upperF
));
172 WMAddSplitViewSubview(panel
->split
, W_VIEW(panel
->lowerF
));
174 WMResizeWidget(panel
->upperF
, 320, 60);
175 WMResizeWidget(panel
->lowerF
, 320, 330-60-divThickness
);
176 WMMoveWidget(panel
->lowerF
, 0, 60+divThickness
);
178 white
= WMWhiteColor(scr
);
179 dark
= WMDarkGrayColor(scr
);
181 panel
->sampleL
= WMCreateLabel(panel
->upperF
);
182 WMResizeWidget(panel
->sampleL
, 300, 50);
183 WMMoveWidget(panel
->sampleL
, 10, 10);
184 WMSetWidgetBackgroundColor(panel
->sampleL
, white
);
185 WMSetLabelRelief(panel
->sampleL
, WRSunken
);
186 WMSetLabelText(panel
->sampleL
, "It is not yet completed!!!");
188 font
= WMBoldSystemFontOfSize(scr
, 12);
190 panel
->famL
= WMCreateLabel(panel
->lowerF
);
191 WMSetWidgetBackgroundColor(panel
->famL
, dark
);
192 WMSetLabelText(panel
->famL
, "Family");
193 WMSetLabelFont(panel
->famL
, font
);
194 WMSetLabelTextColor(panel
->famL
, white
);
195 WMSetLabelRelief(panel
->famL
, WRSunken
);
196 WMSetLabelTextAlignment(panel
->famL
, WACenter
);
198 panel
->famLs
= WMCreateList(panel
->lowerF
);
200 panel
->typL
= WMCreateLabel(panel
->lowerF
);
201 WMSetWidgetBackgroundColor(panel
->typL
, dark
);
202 WMSetLabelText(panel
->typL
, "Typeface");
203 WMSetLabelFont(panel
->typL
, font
);
204 WMSetLabelTextColor(panel
->typL
, white
);
205 WMSetLabelRelief(panel
->typL
, WRSunken
);
206 WMSetLabelTextAlignment(panel
->typL
, WACenter
);
208 panel
->typLs
= WMCreateList(panel
->lowerF
);
210 panel
->sizL
= WMCreateLabel(panel
->lowerF
);
211 WMSetWidgetBackgroundColor(panel
->sizL
, dark
);
212 WMSetLabelText(panel
->sizL
, "Size");
213 WMSetLabelFont(panel
->sizL
, font
);
214 WMSetLabelTextColor(panel
->sizL
, white
);
215 WMSetLabelRelief(panel
->sizL
, WRSunken
);
216 WMSetLabelTextAlignment(panel
->sizL
, WACenter
);
218 panel
->sizT
= WMCreateTextField(panel
->lowerF
);
220 panel
->sizLs
= WMCreateList(panel
->lowerF
);
223 WMReleaseColor(white
);
224 WMReleaseColor(dark
);
226 panel
->encF
= WMCreateFrame(panel
->lowerF
);
227 WMSetFrameTitle(panel
->encF
, "Encoding");
228 WMResizeWidget(panel
->encF
, 130, 50);
230 panel
->encP
= WMCreatePopUpButton(panel
->encF
);
231 WMMoveWidget(panel
->encP
, 10, 20);
232 WMResizeWidget(panel
->encP
, 112, 20);
234 WMMapSubwidgets(panel
->encF
);
236 panel
->xlfdF
= WMCreateFrame(panel
->lowerF
);
237 WMSetFrameTitle(panel
->xlfdF
, "Xtra Long Font Description");
239 panel
->xlfdT
= WMCreateTextField(panel
->xlfdF
);
240 WMMoveWidget(panel
->xlfdT
, 10, 20);
242 WMMapSubwidgets(panel
->xlfdF
);
244 arrangeLowerFrame(panel
);
246 panel
->setB
= WMCreateCommandButton(panel
->win
);
247 WMResizeWidget(panel
->setB
, 70, 24);
248 WMMoveWidget(panel
->setB
, 240, 335);
249 WMSetButtonText(panel
->setB
, "Set");
251 panel
->previewB
= WMCreateCommandButton(panel
->win
);
252 WMResizeWidget(panel
->previewB
, 70, 24);
253 WMMoveWidget(panel
->previewB
, 160, 335);
254 WMSetButtonText(panel
->previewB
, "Preview");
256 panel
->revertB
= WMCreateCommandButton(panel
->win
);
257 WMResizeWidget(panel
->revertB
, 70, 24);
258 WMMoveWidget(panel
->revertB
, 80, 335);
259 WMSetButtonText(panel
->revertB
, "Revert");
261 WMRealizeWidget(panel
->win
);
263 WMMapSubwidgets(panel
->upperF
);
264 WMMapSubwidgets(panel
->lowerF
);
265 WMMapSubwidgets(panel
->split
);
266 WMMapSubwidgets(panel
->win
);
268 scr
->sharedFontPanel
= panel
;
271 /* register notification observers */
272 WMAddNotificationObserver(notificationObserver
, panel
,
273 WMViewSizeDidChangeNotification
,
274 WMWidgetView(panel
->win
));
275 WMAddNotificationObserver(notificationObserver
, panel
,
276 WMViewSizeDidChangeNotification
,
277 WMWidgetView(panel
->upperF
));
278 WMAddNotificationObserver(notificationObserver
, panel
,
279 WMViewSizeDidChangeNotification
,
280 WMWidgetView(panel
->lowerF
));
282 panel
->fdb
= createFontDatabase(scr
);
283 listFamilies(panel
->fdb
, panel
->famLs
);
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
408 parseFont(char *font
, char **values
)
412 char buffer
[256], *bptr
;
416 ptr
++; /* skip first - */
421 values
[part
]=wstrdup(buffer
);
430 values
[part
]=wstrdup(buffer
);
438 isXLFD(char *font
, int *length_ret
)
449 return c
==NUM_FIELDS
;
455 static proplist_t foundryKey
= NULL
;
456 static proplist_t typeKey
= NULL
;
457 static proplist_t sizeKey
, encKey
, xlfdKey
;
461 addSizeToEnc(proplist_t enc
, char **fields
)
465 sizel
= PLGetDictionaryEntry(enc
, sizeKey
);
467 sizel
= PLMakeArrayFromElements(PLMakeString(fields
[PIXEL_SIZE
]),NULL
);
468 PLInsertDictionaryEntry(enc
, sizeKey
, sizel
);
470 PLAppendArrayElement(sizel
, PLMakeString(fields
[PIXEL_SIZE
]));
476 addTypefaceToFont(proplist_t font
, char **fields
)
478 proplist_t face
, encod
, facedic
, encodic
;
481 strcpy(buffer
, fields
[WEIGHT
]);
483 if (strcasecmp(fields
[SLANT
], "R")==0)
484 strcat(buffer
, " Roman ");
485 else if (strcasecmp(fields
[SLANT
], "I")==0)
486 strcat(buffer
, " Italic ");
487 else if (strcasecmp(fields
[SLANT
], "O")==0)
488 strcat(buffer
, " Oblique ");
489 else if (strcasecmp(fields
[SLANT
], "RI")==0)
490 strcat(buffer
, " Reverse Italic ");
491 else if (strcasecmp(fields
[SLANT
], "RO")==0)
492 strcat(buffer
, " Reverse Oblique ");
493 else if (strcasecmp(fields
[SLANT
], "OT")==0)
494 strcat(buffer
, " ? ");
498 strcat(buffer
, fields
[SETWIDTH
]);
500 strcat(buffer
, fields
[ADD_STYLE
]);
502 face
= PLMakeString(buffer
);
504 facedic
= PLGetDictionaryEntry(font
, face
);
506 facedic
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
507 PLInsertDictionaryEntry(font
, face
, facedic
);
512 strcpy(buffer
, fields
[REGISTRY
]);
514 strcat(buffer
, fields
[ENCODING
]);
515 encod
= PLMakeString(buffer
);
517 encodic
= PLGetDictionaryEntry(facedic
, encod
);
520 sprintf(buffer
, "-%s-%s-%s-%s-%s-%s-%%d-0-%s-%s-%s-%s-%s-%s",
521 fields
[FOUNDRY
], fields
[FAMILY
], fields
[WEIGHT
],
522 fields
[SLANT
], fields
[SETWIDTH
], fields
[ADD_STYLE
],
523 fields
[RES_X
], fields
[RES_Y
], fields
[SPACING
],
524 fields
[AV_WIDTH
], fields
[REGISTRY
], fields
[ENCODING
]);
525 tmp
= PLMakeString(buffer
);
527 encodic
= PLMakeDictionaryFromEntries(xlfdKey
, tmp
, NULL
);
529 PLInsertDictionaryEntry(facedic
, encod
, encodic
);
532 addSizeToEnc(encodic
, fields
);
538 makeFontEntry(char **fields
)
543 value
= PLMakeString(fields
[FOUNDRY
]);
545 tmp
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
547 font
= PLMakeDictionaryFromEntries(foundryKey
, value
,
553 addTypefaceToFont(font
, fields
);
560 createFontDatabase(WMScreen
*scr
)
564 char *fields
[NUM_FIELDS
];
565 int font_name_length
;
575 foundryKey
= PLMakeString("Foundry");
576 typeKey
= PLMakeString("Typeface");
577 encKey
= PLMakeString("Encoding");
578 sizeKey
= PLMakeString("Sizes");
579 xlfdKey
= PLMakeString("XLFD");
582 /* retrieve a complete listing of the available fonts */
583 fontList
= XListFonts(scr
->display
, ALL_FONTS_MASK
, MAX_FONTS_TO_RETRIEVE
,
586 wwarning("could not retrieve font list");
590 fdb
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
592 for (i
=0; i
<count
; i
++) {
593 if (!isXLFD(fontList
[i
], &font_name_length
)) {
596 /* the XLFD specs limit the size of a font description in 255 chars */
597 assert(font_name_length
< 256);
599 if (parseFont(fontList
[i
], fields
)) {
600 family
= PLMakeString(fields
[FAMILY
]);
601 font
= PLGetDictionaryEntry(fdb
, family
);
603 foundry
= PLGetDictionaryEntry(font
, foundryKey
);
604 if (strcmp(PLGetString(foundry
), fields
[FOUNDRY
])==0) {
605 /* already a font with the same family */
606 addTypefaceToFont(font
, fields
);
608 /* same font family by different foundries */
609 sprintf(buffer
, "%s (%s)", fields
[FAMILY
],
612 family
= PLMakeString(buffer
);
614 font
= PLGetDictionaryEntry(fdb
, family
);
616 /* already a font with the same family */
617 addTypefaceToFont(font
, fields
);
619 tmp
= makeFontEntry(fields
);
620 PLInsertDictionaryEntry(fdb
, family
, tmp
);
625 tmp
= makeFontEntry(fields
);
626 PLInsertDictionaryEntry(fdb
, family
, tmp
);
632 XFreeFontNames(fontList
);
643 listFamilies(proplist_t fdb
, WMList
*list
)
649 arr
= PLGetAllDictionaryKeys(fdb
);
650 for (i
= 0; i
<PLGetNumberOfElements(arr
); i
++) {
651 fam
= PLGetArrayElement(arr
, i
);
652 WMAddSortedListItem(list
, PLGetString(fam
));