Mercurial > projects > dwt-win
comparison dwt/graphics/Device.d @ 213:36f5cb12e1a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 17 May 2008 17:34:28 +0200 |
parents | ab60f3309436 |
children | fd9c62a2998e |
comparison
equal
deleted
inserted
replaced
212:ab60f3309436 | 213:36f5cb12e1a2 |
---|---|
15 import dwt.DWT; | 15 import dwt.DWT; |
16 import dwt.DWTException; | 16 import dwt.DWTException; |
17 import dwt.internal.gdip.Gdip; | 17 import dwt.internal.gdip.Gdip; |
18 import dwt.internal.win32.OS; | 18 import dwt.internal.win32.OS; |
19 | 19 |
20 import dwt.graphics.Cursor; | |
21 import dwt.graphics.GC; | |
22 import dwt.graphics.Image; | |
23 import dwt.graphics.Path; | |
24 import dwt.graphics.Pattern; | |
25 import dwt.graphics.Region; | |
26 import dwt.graphics.TextLayout; | |
27 import dwt.graphics.Transform; | |
20 import dwt.graphics.Drawable; | 28 import dwt.graphics.Drawable; |
21 import dwt.graphics.DeviceData; | 29 import dwt.graphics.DeviceData; |
22 import dwt.graphics.Rectangle; | 30 import dwt.graphics.Rectangle; |
23 import dwt.graphics.FontData; | 31 import dwt.graphics.FontData; |
24 import dwt.graphics.Font; | 32 import dwt.graphics.Font; |
25 import dwt.graphics.GCData; | 33 import dwt.graphics.GCData; |
26 import dwt.graphics.Color; | 34 import dwt.graphics.Color; |
27 | 35 |
28 import dwt.dwthelper.Runnable; | 36 import dwt.dwthelper.Runnable; |
29 import dwt.dwthelper.System; | 37 import dwt.dwthelper.System; |
38 | |
30 import dwt.dwthelper.utils; | 39 import dwt.dwthelper.utils; |
31 import tango.core.Exception; | 40 import tango.core.Exception; |
41 import tango.util.Convert; | |
42 import tango.io.Stdout; | |
32 | 43 |
33 /** | 44 /** |
34 * This class is the abstract superclass of all device objects, | 45 * This class is the abstract superclass of all device objects, |
35 * such as the Display device and the Printer device. Devices | 46 * such as the Display device and the Printer device. Devices |
36 * can have a graphics context (GC) created for them, and they | 47 * can have a graphics context (GC) created for them, and they |
47 public static bool DEBUG = true; | 58 public static bool DEBUG = true; |
48 bool debug_; | 59 bool debug_; |
49 bool tracking; | 60 bool tracking; |
50 Exception [] errors; | 61 Exception [] errors; |
51 Object [] objects; | 62 Object [] objects; |
63 Object trackingLock; | |
52 | 64 |
53 /** | 65 /** |
54 * Palette | 66 * Palette |
55 * (Warning: This field is platform dependent) | 67 * (Warning: This field is platform dependent) |
56 * <p> | 68 * <p> |
62 */ | 74 */ |
63 public HPALETTE hPalette; | 75 public HPALETTE hPalette; |
64 int [] colorRefCount; | 76 int [] colorRefCount; |
65 | 77 |
66 /* System Font */ | 78 /* System Font */ |
67 HFONT systemFont; | 79 Font systemFont; |
68 | 80 |
69 /* Font Enumeration */ | 81 /* Font Enumeration */ |
70 int nFonts = 256; | 82 int nFonts = 256; |
71 LOGFONT* [] logFonts; | 83 LOGFONT* [] logFonts; |
72 TEXTMETRIC metrics; | 84 TEXTMETRIC metrics; |
73 int[] pixels; | 85 int[] pixels; |
74 | 86 |
75 /* Scripts */ | 87 /* Scripts */ |
76 SCRIPT_PROPERTIES*[] scripts; | 88 SCRIPT_PROPERTIES*[] scripts; |
89 LOGFONT* [] logFontsCache; | |
77 | 90 |
78 /* Advanced Graphics */ | 91 /* Advanced Graphics */ |
79 ULONG_PTR gdipToken; | 92 ULONG_PTR gdipToken; |
80 | 93 |
81 bool disposed; | 94 bool disposed; |
132 * @see #create | 145 * @see #create |
133 * @see #init | 146 * @see #init |
134 * @see DeviceData | 147 * @see DeviceData |
135 */ | 148 */ |
136 public this(DeviceData data) { | 149 public this(DeviceData data) { |
137 synchronized (this.classinfo) { | 150 synchronized (Device.classinfo) { |
138 debug_ = DEBUG; | 151 debug_ = DEBUG; |
139 tracking = DEBUG; | 152 tracking = DEBUG; |
140 if (data !is null) { | 153 if (data !is null) { |
141 debug_ = data.debug_; | 154 debug_ = data.debug_; |
142 tracking = data.tracking; | 155 tracking = data.tracking; |
143 } | 156 } |
144 create (data); | |
145 init_ (); | |
146 if (tracking) { | 157 if (tracking) { |
147 errors = new Exception [128]; | 158 errors = new Exception [128]; |
148 objects = new Object [128]; | 159 objects = new Object [128]; |
149 } | 160 trackingLock = new Object (); |
150 | 161 } |
151 /* Initialize the system font slot */ | 162 create (data); |
152 systemFont = getSystemFont().handle; | 163 init_ (); |
153 gdipToken = 0; | 164 gdipToken = 0; |
154 } | 165 } |
155 } | 166 } |
156 | 167 |
157 /** | 168 /** |
177 if (disposed) DWT.error(DWT.ERROR_DEVICE_DISPOSED); | 188 if (disposed) DWT.error(DWT.ERROR_DEVICE_DISPOSED); |
178 } | 189 } |
179 | 190 |
180 void checkGDIP() { | 191 void checkGDIP() { |
181 if (gdipToken) return; | 192 if (gdipToken) return; |
182 static if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED); | 193 int oldErrorMode = 0; |
183 int oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS); | 194 static if (!OS.IsWinCE) oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS); |
184 try { | 195 try { |
185 ULONG_PTR token; | 196 ULONG_PTR token; |
186 GdiplusStartupInput input; | 197 GdiplusStartupInput input; |
187 input.GdiplusVersion = 1; | 198 input.GdiplusVersion = 1; |
188 if (Gdip.GdiplusStartup ( &token, &input, null ) is 0) { | 199 if (Gdip.GdiplusStartup ( &token, &input, null ) is 0) { |
189 gdipToken = token; | 200 gdipToken = token; |
190 } | 201 } |
191 } catch (Exception t) { | 202 } catch (Exception t) { |
192 DWT.error (DWT.ERROR_NO_GRAPHICS_LIBRARY, t, " [GDI+ is required]"); //$NON-NLS-1$ | 203 DWT.error (DWT.ERROR_NO_GRAPHICS_LIBRARY, t, " [GDI+ is required]"); //$NON-NLS-1$ |
193 } finally { | 204 } finally { |
194 OS.SetErrorMode (oldErrorMode); | 205 if (!OS.IsWinCE) OS.SetErrorMode (oldErrorMode); |
195 } | 206 } |
196 } | 207 } |
197 | 208 |
198 /** | 209 /** |
199 * Creates the device in the operating system. If the device | 210 * Creates the device in the operating system. If the device |
270 * @see #release | 281 * @see #release |
271 * @see #destroy | 282 * @see #destroy |
272 * @see #checkDevice | 283 * @see #checkDevice |
273 */ | 284 */ |
274 public void dispose () { | 285 public void dispose () { |
275 if (isDisposed()) return; | 286 synchronized (Device.classinfo) { |
276 checkDevice (); | 287 if (isDisposed()) return; |
277 release (); | 288 checkDevice (); |
278 destroy (); | 289 release (); |
279 disposed = true; | 290 destroy (); |
280 if (tracking) { | 291 disposed = true; |
281 objects = null; | 292 if (tracking) { |
282 errors = null; | 293 synchronized (trackingLock) { |
294 printErrors (); | |
295 objects = null; | |
296 errors = null; | |
297 trackingLock = null; | |
298 } | |
299 } | |
283 } | 300 } |
284 } | 301 } |
285 | 302 |
286 void dispose_Object (Object object) { | 303 void dispose_Object (Object object) { |
287 for (int i=0; i<objects.length; i++) { | 304 synchronized (trackingLock) { |
288 if (objects [i] is object) { | 305 for (int i=0; i<objects.length; i++) { |
289 objects [i] = null; | 306 if (objects [i] is object) { |
290 errors [i] = null; | 307 objects [i] = null; |
291 return; | 308 errors [i] = null; |
309 return; | |
310 } | |
292 } | 311 } |
293 } | 312 } |
294 } | 313 } |
295 | 314 |
296 static extern(Windows) int EnumFontFamFunc (ENUMLOGFONT* lpelfe, NEWTEXTMETRIC* lpntme, int FontType, int lParam) { | 315 static extern(Windows) int EnumFontFamFunc (ENUMLOGFONT* lpelfe, NEWTEXTMETRIC* lpntme, int FontType, int lParam) { |
367 public DeviceData getDeviceData () { | 386 public DeviceData getDeviceData () { |
368 checkDevice(); | 387 checkDevice(); |
369 DeviceData data = new DeviceData (); | 388 DeviceData data = new DeviceData (); |
370 data.debug_ = debug_; | 389 data.debug_ = debug_; |
371 data.tracking = tracking; | 390 data.tracking = tracking; |
372 int count = 0, length = 0; | 391 if (tracking) { |
373 if (tracking) length = objects.length; | 392 synchronized (trackingLock) { |
374 for (int i=0; i<length; i++) { | 393 int count = 0, length = objects.length; |
375 if (objects [i] !is null) count++; | 394 for (int i=0; i<length; i++) { |
376 } | 395 if (objects [i] !is null) count++; |
377 int index = 0; | 396 } |
378 data.objects = new Object [count]; | 397 int index = 0; |
379 data.errors = new Exception [count]; | 398 data.objects = new Object [count]; |
380 for (int i=0; i<length; i++) { | 399 data.errors = new Exception [count]; |
381 if (objects [i] !is null) { | 400 for (int i=0; i<length; i++) { |
382 data.objects [index] = objects [i]; | 401 if (objects [i] !is null) { |
383 data.errors [index] = errors [i]; | 402 data.objects [index] = objects [i]; |
384 index++; | 403 data.errors [index] = errors [i]; |
385 } | 404 index++; |
405 } | |
406 } | |
407 } | |
408 } else { | |
409 data.objects = new Object [0]; | |
410 data.errors = new Exception [0]; | |
386 } | 411 } |
387 return data; | 412 return data; |
388 } | 413 } |
389 | 414 |
390 /** | 415 /** |
658 protected void init_ () { | 683 protected void init_ () { |
659 if (debug_) { | 684 if (debug_) { |
660 static if (!OS.IsWinCE) OS.GdiSetBatchLimit(1); | 685 static if (!OS.IsWinCE) OS.GdiSetBatchLimit(1); |
661 } | 686 } |
662 | 687 |
688 /* Initialize the system font slot */ | |
689 systemFont = getSystemFont(); | |
690 | |
663 /* Initialize scripts list */ | 691 /* Initialize scripts list */ |
664 static if (!OS.IsWinCE) { | 692 static if (!OS.IsWinCE) { |
665 SCRIPT_PROPERTIES** ppSp; | 693 SCRIPT_PROPERTIES** ppSp; |
666 int piNumScripts; | 694 int piNumScripts; |
667 OS.ScriptGetProperties (&ppSp, &piNumScripts); | 695 OS.ScriptGetProperties (&ppSp, &piNumScripts); |
770 * invoke any other method using the device. | 798 * invoke any other method using the device. |
771 * | 799 * |
772 * @return <code>true</code> when the device is disposed and <code>false</code> otherwise | 800 * @return <code>true</code> when the device is disposed and <code>false</code> otherwise |
773 */ | 801 */ |
774 public bool isDisposed () { | 802 public bool isDisposed () { |
775 return disposed; | 803 synchronized (Device.classinfo) { |
804 return disposed; | |
805 } | |
776 } | 806 } |
777 | 807 |
778 /** | 808 /** |
779 * Loads the font specified by a file. The font will be | 809 * Loads the font specified by a file. The font will be |
780 * present in the list of fonts available to the application. | 810 * present in the list of fonts available to the application. |
800 } | 830 } |
801 return false; | 831 return false; |
802 } | 832 } |
803 | 833 |
804 void new_Object (Object object) { | 834 void new_Object (Object object) { |
805 for (int i=0; i<objects.length; i++) { | 835 synchronized (trackingLock) { |
806 if (objects [i] is null) { | 836 for (int i=0; i<objects.length; i++) { |
807 objects [i] = object; | 837 if (objects [i] is null) { |
808 errors [i] = new Exception ( "" ); | 838 objects [i] = object; |
809 return; | 839 errors [i] = new Exception ( "" ); |
810 } | 840 return; |
811 } | 841 } |
812 Object [] newObjects = new Object [objects.length + 128]; | 842 } |
813 System.arraycopy (objects, 0, newObjects, 0, objects.length); | 843 Object [] newObjects = new Object [objects.length + 128]; |
814 newObjects [objects.length] = object; | 844 System.arraycopy (objects, 0, newObjects, 0, objects.length); |
815 objects = newObjects; | 845 newObjects [objects.length] = object; |
816 Exception [] newErrors = new Exception [errors.length + 128]; | 846 objects = newObjects; |
817 System.arraycopy (errors, 0, newErrors, 0, errors.length); | 847 Exception [] newErrors = new Exception [errors.length + 128]; |
818 newErrors [errors.length] = new Exception (""); | 848 System.arraycopy (errors, 0, newErrors, 0, errors.length); |
819 errors = newErrors; | 849 newErrors [errors.length] = new Exception (""); |
850 errors = newErrors; | |
851 } | |
852 } | |
853 | |
854 void printErrors () { | |
855 if (!DEBUG) return; | |
856 if (tracking) { | |
857 synchronized (trackingLock) { | |
858 if (objects is null || errors is null) return; | |
859 int objectCount = 0; | |
860 int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0; | |
861 int paths = 0, patterns = 0, regions = 0, textLayouts = 0, transforms = 0; | |
862 for (int i=0; i<objects.length; i++) { | |
863 Object object = objects [i]; | |
864 if (object !is null) { | |
865 objectCount++; | |
866 if (null !is cast(Color)object ) colors++; | |
867 if (null !is cast(Cursor)object ) cursors++; | |
868 if (null !is cast(Font)object ) fonts++; | |
869 if (null !is cast(GC)object ) gcs++; | |
870 if (null !is cast(Image)object ) images++; | |
871 if (null !is cast(Path)object ) paths++; | |
872 if (null !is cast(Pattern)object ) patterns++; | |
873 if (null !is cast(Region)object ) regions++; | |
874 if (null !is cast(TextLayout)object ) textLayouts++; | |
875 if (null !is cast(Transform)object ) transforms++; | |
876 } | |
877 } | |
878 if (objectCount !is 0) { | |
879 String string = "Summary: "; | |
880 if (colors !is 0) string ~= to!(String)(colors) ~ " Color(s), "; | |
881 if (cursors !is 0) string ~= to!(String)(cursors) ~ " Cursor(s), "; | |
882 if (fonts !is 0) string ~= to!(String)(fonts) ~ " Font(s), "; | |
883 if (gcs !is 0) string ~= to!(String)(gcs) ~ " GC(s), "; | |
884 if (images !is 0) string ~= to!(String)(images) ~ " Image(s), "; | |
885 if (paths !is 0) string ~= to!(String)(paths) ~ " Path(s), "; | |
886 if (patterns !is 0) string ~= to!(String)(patterns) ~ " Pattern(s), "; | |
887 if (regions !is 0) string ~= to!(String)(regions) ~ " Region(s), "; | |
888 if (textLayouts !is 0) string ~= to!(String)(textLayouts) ~ " TextLayout(s), "; | |
889 if (transforms !is 0) string ~= to!(String)(transforms) ~ " Transforms(s), "; | |
890 if (string.length !is 0) { | |
891 string = string.substring (0, string.length - 2); | |
892 Stderr.formatln ( "{}", string); | |
893 } | |
894 for (int i=0; i<errors.length; i++) { | |
895 if (errors [i] !is null) ExceptionPrintStackTrace( errors [i], Stderr); | |
896 } | |
897 } | |
898 } | |
899 } | |
820 } | 900 } |
821 | 901 |
822 /** | 902 /** |
823 * Releases any internal resources back to the operating | 903 * Releases any internal resources back to the operating |
824 * system and clears all fields except the device handle. | 904 * system and clears all fields except the device handle. |
846 if (gdipToken) { | 926 if (gdipToken) { |
847 Gdip.GdiplusShutdown ( gdipToken ); | 927 Gdip.GdiplusShutdown ( gdipToken ); |
848 } | 928 } |
849 gdipToken = 0; // TODO: assignment of 0 might not be valid for token | 929 gdipToken = 0; // TODO: assignment of 0 might not be valid for token |
850 scripts = null; | 930 scripts = null; |
931 logFontsCache = null; | |
851 if (hPalette !is null) OS.DeleteObject (hPalette); | 932 if (hPalette !is null) OS.DeleteObject (hPalette); |
852 hPalette = null; | 933 hPalette = null; |
853 colorRefCount = null; | 934 colorRefCount = null; |
854 logFonts = null; | 935 logFonts = null; |
855 nFonts = 0; | 936 nFonts = 0; |