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;