1 | /*
|
---|
2 | * SWT005_02.java
|
---|
3 | */
|
---|
4 |
|
---|
5 | /*
|
---|
6 | * Copyright (c) 2002, 2004 EclipseOS2 Team.
|
---|
7 | * This file is made available under the terms of the Common Public License v1.0
|
---|
8 | * which accompanies this distribution, and is available at
|
---|
9 | * http://www.eclipse.org/legal/cpl-v10.html
|
---|
10 | */
|
---|
11 |
|
---|
12 | import org.eclipse.swt.*;
|
---|
13 | import org.eclipse.swt.widgets.*;
|
---|
14 | import org.eclipse.swt.events.*;
|
---|
15 | import org.eclipse.swt.graphics.*;
|
---|
16 | import org.eclipse.swt.layout.*;
|
---|
17 |
|
---|
18 | import java.util.ArrayList;
|
---|
19 | import java.util.Iterator;
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * This testcase demonstrates all fonts installed in the system. The
|
---|
23 | * testcase uses a number of pages to be able to draw all existing fonts
|
---|
24 | * without scrolling (which is not yet ready).
|
---|
25 | *
|
---|
26 | * For every font, its height, family name, style and additional internal
|
---|
27 | * info are drawn as described in the comments to the SWT005_01 testcase.
|
---|
28 | *
|
---|
29 | * Buttons at the bottom of the screen are used to change the behavior of
|
---|
30 | * the list:
|
---|
31 | * - Checkers -- when checked the checkboard is drawn;
|
---|
32 | * - Metrics -- when checked font metrics are visualized;
|
---|
33 | * - Scalable -- when checked scalable fonts are listed, otherwise
|
---|
34 | * bitmap fonts are listed;
|
---|
35 | * - Arial only -- when checked only fonts from the Arial family are drawn
|
---|
36 | * - National -- when checked three sequences of national characters are
|
---|
37 | * drawn: cyrillic, latin and japanese to test the locale support:
|
---|
38 | * * for cyrillic locale chars 0xA0 - 0xA7 of IBM-866 codepage are drawn;
|
---|
39 | * * for latin locale chars 0xD0 - 0xD7 of IBM-850 codepage are drawn;
|
---|
40 | * * for japanese locale chars 0xB0 - 0xB7 of IBM-942 codepage are drawn.
|
---|
41 | *
|
---|
42 | * Note that currently there is no locale support in OS/2 version of SWT due
|
---|
43 | * to some system limitations and bugs. It will be added later when all
|
---|
44 | * problems are deeply explored. So at this time question marks are drawn
|
---|
45 | * instead of national characters for all three locales unless one of them
|
---|
46 | * is the default locale of the system the testcase runs on, in which case
|
---|
47 | * characters for that locale should be drawn correctly (according to
|
---|
48 | * codepages mentioned above).
|
---|
49 | *
|
---|
50 | * Also note that output of to many different TrueType fonts is quite
|
---|
51 | * slow -- again, this is the limitation of the standard OS/2 TrueType
|
---|
52 | * font rasterizer. (It works a bit better with freetype.dll, an alternative
|
---|
53 | * TTF rasterizer; however, the latter has its own bugs).
|
---|
54 | *
|
---|
55 | */
|
---|
56 |
|
---|
57 | public class SWT005_02 extends SWTTestCase {
|
---|
58 |
|
---|
59 | static {
|
---|
60 | STEP= "005";
|
---|
61 | TEST = "02";
|
---|
62 | DESC = "Font List";
|
---|
63 | }
|
---|
64 |
|
---|
65 | public static void main (String [] args) {
|
---|
66 | go (new SWT005_02 ());
|
---|
67 | }
|
---|
68 |
|
---|
69 | int page = 1;
|
---|
70 | int lastPage = 1;
|
---|
71 |
|
---|
72 | Button next, prev;
|
---|
73 |
|
---|
74 | boolean drawCheckers = false;
|
---|
75 | boolean drawMetrics = false;
|
---|
76 | boolean drawScalable = true;
|
---|
77 | boolean drawArialOnly = false;
|
---|
78 | boolean drawNational = false;
|
---|
79 |
|
---|
80 | Image background = null;
|
---|
81 |
|
---|
82 | Canvas canvas;
|
---|
83 |
|
---|
84 | Font[] fonts = new Font [0];
|
---|
85 | Font[] fonts_ru_RU = new Font [0];
|
---|
86 | Font[] fonts_en_GB = new Font [0];
|
---|
87 | Font[] fonts_ja_JP = new Font [0];
|
---|
88 | int[] fontHeights;
|
---|
89 | Integer[] fontPages = new Integer[] {new Integer (0)};
|
---|
90 |
|
---|
91 | Class fmHndCls;
|
---|
92 | String platform;
|
---|
93 |
|
---|
94 | final String strCYR = "[CYR \u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437]";
|
---|
95 | final String strLAT = "[LAT \u00F0\u00D0\u00CA\u00CB\u00C8\u20AC\u00CD\u00CE]";
|
---|
96 | final String strJPN = "[JPN \uFF70\uFF71\uFF72\uFF73\uFF74\uFF75\uFF76\uFF77]";
|
---|
97 |
|
---|
98 | Shell createTopShell (Display display) {
|
---|
99 | Shell sh = new Shell (display,
|
---|
100 | SWT.DIALOG_TRIM | SWT.NO_REDRAW_RESIZE);
|
---|
101 | return sh;
|
---|
102 | }
|
---|
103 |
|
---|
104 | void initComponents () {
|
---|
105 | shell.addDisposeListener (new DisposeListener () {
|
---|
106 | public void widgetDisposed (DisposeEvent e) {
|
---|
107 | destroyFonts (fonts);
|
---|
108 | destroyFonts (fonts_ja_JP);
|
---|
109 | if (background != null) background.dispose();
|
---|
110 | }
|
---|
111 | });
|
---|
112 |
|
---|
113 | canvas = new Canvas (shell, 0);
|
---|
114 | canvas.addPaintListener(new PaintListener () {
|
---|
115 | public void paintControl(PaintEvent event) {
|
---|
116 | GC gc = event.gc;
|
---|
117 |
|
---|
118 | Rectangle r = new Rectangle (event.x, event.y, event.width, event.height);
|
---|
119 | gc.setClipping (r);
|
---|
120 |
|
---|
121 | drawGrid (gc,
|
---|
122 | (r.x / 20) * 20, (r.y / 20) * 20,
|
---|
123 | r.width + 20, r.height + 20, 10);
|
---|
124 |
|
---|
125 | int y = 0;
|
---|
126 | for (
|
---|
127 | int fi = fontPages [page - 1].intValue();
|
---|
128 | fi < (page < lastPage ? fontPages [page].intValue() : fonts.length);
|
---|
129 | fi++
|
---|
130 | ) {
|
---|
131 | y += drawFont (gc, fi, 0, y) + 2;
|
---|
132 | }
|
---|
133 | }
|
---|
134 | });
|
---|
135 |
|
---|
136 | Composite bottom = new Composite (shell, 0);
|
---|
137 |
|
---|
138 | Composite group1 = new Composite (bottom, SWT.NO_BACKGROUND);
|
---|
139 | group1.setLayout (new FillLayout (SWT.HORIZONTAL));
|
---|
140 |
|
---|
141 | prev = new Button (group1, SWT.PUSH);
|
---|
142 | prev.setText ("< Previous");
|
---|
143 | prev.addSelectionListener (new SelectionAdapter () {
|
---|
144 | public void widgetSelected (SelectionEvent e) {
|
---|
145 | if (page > 1) {
|
---|
146 | page --;
|
---|
147 | updateTitle();
|
---|
148 | }
|
---|
149 | if (page == 1) prev.setEnabled (false);
|
---|
150 | if (page == lastPage - 1) next.setEnabled (true);
|
---|
151 | }
|
---|
152 | });
|
---|
153 | next = new Button (group1, SWT.PUSH);
|
---|
154 | next.setText ("Next >");
|
---|
155 | next.addSelectionListener (new SelectionAdapter () {
|
---|
156 | public void widgetSelected (SelectionEvent e) {
|
---|
157 | if (page < lastPage) {
|
---|
158 | page ++;
|
---|
159 | updateTitle();
|
---|
160 | }
|
---|
161 | if (page == lastPage) next.setEnabled (false);
|
---|
162 | if (page == 2) prev.setEnabled (true);
|
---|
163 | }
|
---|
164 | });
|
---|
165 | updateTitle();
|
---|
166 |
|
---|
167 | Composite group2 = new Composite (bottom, SWT.NO_BACKGROUND);
|
---|
168 | group2.setLayout (new FillLayout (SWT.HORIZONTAL));
|
---|
169 |
|
---|
170 | Button checks = new Button (group2, SWT.CHECK);
|
---|
171 | checks.setText ("Checkers");
|
---|
172 | checks.setSelection (drawCheckers);
|
---|
173 | checks.addSelectionListener (new SelectionAdapter() {
|
---|
174 | public void widgetSelected (SelectionEvent e) {
|
---|
175 | drawCheckers = ((Button)e.widget).getSelection();
|
---|
176 | canvas.redraw();
|
---|
177 | }
|
---|
178 | });
|
---|
179 | Button metrics = new Button (group2, SWT.CHECK);
|
---|
180 | metrics.setText ("Metrics");
|
---|
181 | metrics.setSelection (drawMetrics);
|
---|
182 | metrics.addSelectionListener (new SelectionAdapter() {
|
---|
183 | public void widgetSelected (SelectionEvent e) {
|
---|
184 | drawMetrics = ((Button)e.widget).getSelection();
|
---|
185 | canvas.redraw();
|
---|
186 | }
|
---|
187 | });
|
---|
188 | Button scalable = new Button (group2, SWT.CHECK);
|
---|
189 | scalable.setText ("Scalable");
|
---|
190 | scalable.setSelection (drawScalable);
|
---|
191 | scalable.addSelectionListener (new SelectionAdapter() {
|
---|
192 | public void widgetSelected (SelectionEvent e) {
|
---|
193 | drawScalable = ((Button)e.widget).getSelection();
|
---|
194 | createFontLists (drawScalable, drawArialOnly);
|
---|
195 | }
|
---|
196 | });
|
---|
197 | Button arialOnly = new Button (group2, SWT.CHECK);
|
---|
198 | arialOnly.setText ("Arial Only");
|
---|
199 | arialOnly.setSelection (drawArialOnly);
|
---|
200 | arialOnly.addSelectionListener (new SelectionAdapter() {
|
---|
201 | public void widgetSelected (SelectionEvent e) {
|
---|
202 | drawArialOnly = ((Button)e.widget).getSelection();
|
---|
203 | createFontLists (drawScalable, drawArialOnly);
|
---|
204 | }
|
---|
205 | });
|
---|
206 | Button national = new Button (group2, SWT.CHECK);
|
---|
207 | national.setText ("National");
|
---|
208 | national.setSelection (drawNational);
|
---|
209 | national.addSelectionListener (new SelectionAdapter() {
|
---|
210 | public void widgetSelected (SelectionEvent e) {
|
---|
211 | drawNational = ((Button)e.widget).getSelection();
|
---|
212 | updateTitle();
|
---|
213 | }
|
---|
214 | });
|
---|
215 |
|
---|
216 | FormData fdata = new FormData();
|
---|
217 | fdata.right = new FormAttachment (100, 0);
|
---|
218 | fdata.bottom = new FormAttachment (100, 0);
|
---|
219 | group1.setLayoutData (fdata);
|
---|
220 | fdata = new FormData();
|
---|
221 | fdata.left = new FormAttachment (0, 0);
|
---|
222 | fdata.bottom = new FormAttachment (100, 0);
|
---|
223 | group2.setLayoutData (fdata);
|
---|
224 | FormLayout formLayout = new FormLayout ();
|
---|
225 | bottom.setLayout (formLayout);
|
---|
226 |
|
---|
227 | GridData gdata = new GridData (
|
---|
228 | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL |
|
---|
229 | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL);
|
---|
230 | canvas.setLayoutData (gdata);
|
---|
231 | gdata = new GridData (
|
---|
232 | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL |
|
---|
233 | GridData.VERTICAL_ALIGN_CENTER);
|
---|
234 | bottom.setLayoutData (gdata);
|
---|
235 |
|
---|
236 | GridLayout gridLayout = new GridLayout (1, false);
|
---|
237 | shell.setLayout (gridLayout);
|
---|
238 | shell.setMaximized (true);
|
---|
239 | // Win32 workaround: this forces canvas bounds to be properly
|
---|
240 | // calculated for the maximized state, since windows in Windows
|
---|
241 | // cannot be maximized when not visible, in that sense that their
|
---|
242 | // real size won't change until the window is actually shown.
|
---|
243 | shell.open();
|
---|
244 |
|
---|
245 | createFontLists (drawScalable, drawArialOnly);
|
---|
246 | }
|
---|
247 |
|
---|
248 | void updateTitle () {
|
---|
249 | String title = fonts.length + " fonts - page #" + page + " of " + lastPage;
|
---|
250 | if (drawNational) {
|
---|
251 | title += " " + strCYR + " " + strLAT + " " + strJPN;
|
---|
252 | }
|
---|
253 | setTitle (title);
|
---|
254 | canvas.redraw();
|
---|
255 | }
|
---|
256 |
|
---|
257 | void createFontLists (boolean scalable, boolean arialOnly) {
|
---|
258 | String faceName = arialOnly ? "Arial" : null;
|
---|
259 | FontData[] list = display.getFontList (faceName, scalable);
|
---|
260 | fonts = new Font [list.length];
|
---|
261 | fonts_ru_RU = new Font [list.length];
|
---|
262 | fonts_en_GB = new Font [list.length];
|
---|
263 | fonts_ja_JP = new Font [list.length];
|
---|
264 | fontHeights = new int [list.length];
|
---|
265 | ArrayList pages = new ArrayList();
|
---|
266 | pages.add (new Integer (0));
|
---|
267 | if (list.length > 0) {
|
---|
268 | Rectangle r = canvas.getClientArea();
|
---|
269 | int height = 0;
|
---|
270 | for (int i = 0; i < list.length; i++) {
|
---|
271 | fonts [i] = new Font (display, list [i]);
|
---|
272 | list [i].setLocale ("ru_RU");
|
---|
273 | fonts_ru_RU [i] = new Font (display, list [i]);
|
---|
274 | list [i].setLocale ("en_GB");
|
---|
275 | fonts_en_GB [i] = new Font (display, list [i]);
|
---|
276 | list [i].setLocale ("ja_JP");
|
---|
277 | fonts_ja_JP [i] = new Font (display, list [i]);
|
---|
278 |
|
---|
279 | int h = ((display.getDPI().y * list [i].getHeight()) / 72) * 33 / 24;
|
---|
280 | if (height + h > r.height) {
|
---|
281 | pages.add (new Integer (i));
|
---|
282 | height = 0;
|
---|
283 | }
|
---|
284 | height += h;
|
---|
285 | }
|
---|
286 | }
|
---|
287 | lastPage = pages.size();
|
---|
288 | fontPages = new Integer [lastPage];
|
---|
289 | fontPages = (Integer[]) pages.toArray (fontPages);
|
---|
290 | page = 1;
|
---|
291 | prev.setEnabled (false);
|
---|
292 | next.setEnabled (lastPage > 1);
|
---|
293 | updateTitle();
|
---|
294 | }
|
---|
295 |
|
---|
296 | void destroyFonts (Font[] fonts) {
|
---|
297 | for (int i = 0; i < fonts.length; i++) {
|
---|
298 | Font f = fonts[i];
|
---|
299 | if (!f.equals (display.getSystemFont())) f.dispose();
|
---|
300 | }
|
---|
301 | }
|
---|
302 |
|
---|
303 | int drawFont (GC gc, int idx, int x0, int y0) {
|
---|
304 | Font f = fonts [idx];
|
---|
305 | FontData fd = f.getFontData() [0];
|
---|
306 | String str = " " + fd.getHeight() + ".";
|
---|
307 | String name;
|
---|
308 | if (f.equals (display.getSystemFont())) name = "<System Font>";
|
---|
309 | else name = fd.getName();
|
---|
310 | str += name.length() == 0 ? "<uninitialized>" : name;
|
---|
311 | int style = fd.getStyle();
|
---|
312 | if (style != SWT.NORMAL) {
|
---|
313 | str += " [";
|
---|
314 | if ((style & SWT.BOLD) != 0) str += "B";
|
---|
315 | if ((style & SWT.ITALIC) != 0) str += "I";
|
---|
316 | str += "]";
|
---|
317 | }
|
---|
318 |
|
---|
319 | gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK));
|
---|
320 | gc.setBackground (display.getSystemColor (SWT.COLOR_CYAN));
|
---|
321 | gc.setFont (f);
|
---|
322 | FontMetrics fm = gc.getFontMetrics();
|
---|
323 | Point box;
|
---|
324 |
|
---|
325 | if (drawNational) {
|
---|
326 | gc.drawString (str, x0, y0, !drawMetrics);
|
---|
327 | box = gc.stringExtent (str);
|
---|
328 | str = " " + strCYR;
|
---|
329 | gc.setFont (fonts_ru_RU [idx]);
|
---|
330 | gc.drawText (str, x0 + box.x, y0, !drawMetrics);
|
---|
331 | box.x += gc.textExtent (str).x;
|
---|
332 | str = " " + strLAT;
|
---|
333 | gc.setFont (fonts_en_GB [idx]);
|
---|
334 | gc.drawText (str, x0 + box.x, y0, !drawMetrics);
|
---|
335 | box.x += gc.textExtent (str).x;
|
---|
336 | str = " " + strJPN;
|
---|
337 | gc.setFont (fonts_ja_JP [idx]);
|
---|
338 | gc.drawText (str, x0 + box.x, y0, !drawMetrics);
|
---|
339 | box.x += gc.textExtent (str).x;
|
---|
340 | } else {
|
---|
341 | str += " " + getAdditionalFontInfo (fd, fm);
|
---|
342 | gc.drawString (str, x0, y0, !drawMetrics);
|
---|
343 | box = gc.stringExtent (str);
|
---|
344 | }
|
---|
345 |
|
---|
346 | if (drawMetrics) {
|
---|
347 | int h = box.y / 3;
|
---|
348 | drawCorners (gc, x0, y0, box.x - 1, box.y - 1, h);
|
---|
349 | h = fm.getHeight() - fm.getDescent();
|
---|
350 | gc.setForeground (display.getSystemColor (SWT.COLOR_RED));
|
---|
351 | gc.drawLine (x0, y0 + h, x0 + box.x - 1, y0 + h);
|
---|
352 | h = fm.getLeading();
|
---|
353 | gc.setForeground (display.getSystemColor (SWT.COLOR_BLUE));
|
---|
354 | gc.drawLine (x0, y0 + h, x0 + box.x - 1, y0 + h);
|
---|
355 | }
|
---|
356 |
|
---|
357 | return fm.getHeight();
|
---|
358 | }
|
---|
359 |
|
---|
360 | String getAdditionalFontInfo (FontData fd, FontMetrics fm) {
|
---|
361 | if (fmHndCls == null) {
|
---|
362 | fmHndCls = fm.handle.getClass();
|
---|
363 | platform = SWT.getPlatform();
|
---|
364 | }
|
---|
365 |
|
---|
366 | int lMatch = 0;
|
---|
367 | int actualHeight = 0;
|
---|
368 | String faceName = "<not_available>";
|
---|
369 |
|
---|
370 | Point dpi = display.getDPI();
|
---|
371 | actualHeight =
|
---|
372 | Math.round ((float)((fm.getAscent() + fm.getDescent()) * 72) / dpi.y);
|
---|
373 |
|
---|
374 | if (platform.equals ("pm")) {
|
---|
375 | short fsDefn;
|
---|
376 | short sNominalPointSize;
|
---|
377 | byte[] szFacename = null;
|
---|
378 | try {
|
---|
379 | lMatch = fmHndCls.getField ("lMatch").getInt (fm.handle);
|
---|
380 | fsDefn = fmHndCls.getField ("fsDefn").getShort (fm.handle);
|
---|
381 | sNominalPointSize = fmHndCls.getField ("sNominalPointSize").getShort (fm.handle);
|
---|
382 | szFacename = (byte[])fmHndCls.getField ("szFacename").get (fm.handle);
|
---|
383 |
|
---|
384 | if ((fsDefn & 0x0001 /* OS.FM_DEFN_OUTLINE */) == 0) {
|
---|
385 | actualHeight = sNominalPointSize / 10;
|
---|
386 | }
|
---|
387 | int i = 0;
|
---|
388 | while (szFacename [i] != 0) i++;
|
---|
389 | faceName = new String (szFacename, 0, i);
|
---|
390 | } catch (NoSuchFieldException x) {
|
---|
391 | } catch (IllegalAccessException x) {
|
---|
392 | }
|
---|
393 | }
|
---|
394 |
|
---|
395 | String str = "[" +
|
---|
396 | actualHeight + "." +
|
---|
397 | faceName + ";" +
|
---|
398 | fm.getHeight() + "=" +
|
---|
399 | fm.getLeading() + "+" + fm.getAscent() + "+" + fm.getDescent() + ";" +
|
---|
400 | fm.getAverageCharWidth() + ";" +
|
---|
401 | lMatch +
|
---|
402 | "] ";
|
---|
403 |
|
---|
404 | return str;
|
---|
405 | }
|
---|
406 |
|
---|
407 | void drawCorners (GC gc, int x, int y, int dx, int dy, int size) {
|
---|
408 | Color c = gc.getForeground();
|
---|
409 | gc.setForeground (display.getSystemColor (SWT.COLOR_DARK_RED));
|
---|
410 | gc.drawPolyline (
|
---|
411 | new int[] {x, y + size, x, y, x + size, y});
|
---|
412 | gc.drawPolyline (
|
---|
413 | new int[] {x + dx, y + dy - size, x + dx, y + dy, x + dx - size, y + dy});
|
---|
414 | gc.setForeground (c);
|
---|
415 | }
|
---|
416 |
|
---|
417 | void drawGrid (GC gc, int x0, int y0, int width, int height, int step) {
|
---|
418 | if (drawCheckers) {
|
---|
419 | if (background == null) {
|
---|
420 | int w = 20, h = 20;
|
---|
421 | Display display = Display.getDefault();
|
---|
422 | background = new Image (display, w, h);
|
---|
423 | GC bgc = new GC (background);
|
---|
424 | bgc.setBackground (display.getSystemColor (SWT.COLOR_WHITE));
|
---|
425 | bgc.fillRectangle(0, 0, 10, 10);
|
---|
426 | bgc.fillRectangle(10, 10, 10, 10);
|
---|
427 | bgc.setBackground (display.getSystemColor (SWT.COLOR_GRAY));
|
---|
428 | bgc.fillRectangle(10, 0, 10, 10);
|
---|
429 | bgc.fillRectangle(0, 10, 10, 10);
|
---|
430 | bgc.dispose();
|
---|
431 | }
|
---|
432 | Rectangle r = background.getBounds();
|
---|
433 | for (int y = 0; y <= height; y += r.height)
|
---|
434 | for (int x = 0; x <= width; x += r.width)
|
---|
435 | gc.drawImage (background, x0 + x, y0 + y);
|
---|
436 | } else {
|
---|
437 | gc.fillRectangle (gc.getClipping());
|
---|
438 | }
|
---|
439 | }
|
---|
440 |
|
---|
441 | }
|
---|
442 |
|
---|