56 I provide the common protocol for a graphicsContext which is associated with a particular |
56 I provide the common protocol for a graphicsContext which is associated with a particular |
57 device (i.e. Bitmaps, Pixmaps, RootWindow and Windows in Xs world, but also postscript |
57 device (i.e. Bitmaps, Pixmaps, RootWindow and Windows in Xs world, but also postscript |
58 printer pages or fax pages). |
58 printer pages or fax pages). |
59 |
59 |
60 My instance variables are mainly caching device-related stuff (such as font- and color-Ids) |
60 My instance variables are mainly caching device-related stuff (such as font- and color-Ids) |
61 to avoid needless message traffic. This class is abstract, no direct instances of it |
61 to avoid needless message traffic. |
62 exist in the system. |
|
63 All real work is done by my device, which is accessed via the device instance variable. |
62 All real work is done by my device, which is accessed via the device instance variable. |
64 Most drawing requests are simply forwarded to it, others are simulated by using more basic |
63 Most drawing requests are simply forwarded to it, others are simulated by using more basic |
65 drawing functions (see GraphicsContext drawing vs. basic drawing category). |
64 drawing functions (see GraphicsContext drawing vs. basic drawing category). |
66 |
65 |
67 The added variables foreground/background are the drawing colors actually |
66 The added variables foreground/background are the drawing colors actually |
71 (there are some operations and special cases, for which a direct access to |
70 (there are some operations and special cases, for which a direct access to |
72 fg/bg makes sense) |
71 fg/bg makes sense) |
73 |
72 |
74 [Instance variables:] |
73 [Instance variables:] |
75 |
74 |
76 drawableId <SmallInteger> my drawableId on the device (a device handle) |
75 drawableId <SmallInteger> my drawableId on the device (a device handle) |
77 |
76 |
78 gcId <SmallInteger> my gc's ID on the device (a device handle) |
77 gcId <SmallInteger> my gc's ID on the device (a device handle) |
79 |
78 |
80 deviceFont <Font> the actual font, currently set in the device |
79 deviceFont <Font> the actual font, currently set in the device |
81 |
80 |
82 foreground <Color> the device foreground color used for drawing |
81 foreground <Color> the device foreground color used for drawing |
83 |
82 |
84 background <Color> the device background color used for drawing |
83 background <Color> the device background color used for drawing |
85 |
84 |
86 [see also:] |
85 [see also:] |
87 DeviceWorkstation |
86 DeviceWorkstation |
88 Color Font Cursor |
87 Color Font Cursor |
89 |
88 |
90 [author:] |
89 [author:] |
91 Claus Gittinger |
90 Claus Gittinger |
92 |
91 |
93 " |
92 " |
94 ! ! |
|
95 |
|
96 !DeviceGraphicsContext class methodsFor:'initialization'! |
|
97 |
|
98 initialize |
|
99 Lobby isNil ifTrue:[ |
|
100 Lobby := Registry new. |
|
101 ] |
|
102 |
|
103 "Modified: / 29.1.1998 / 12:56:12 / cg" |
|
104 ! ! |
93 ! ! |
105 |
94 |
106 !DeviceGraphicsContext class methodsFor:'instance creation'! |
95 !DeviceGraphicsContext class methodsFor:'instance creation'! |
107 |
96 |
108 new |
97 new |
163 "Modified: 2.4.1997 / 19:19:35 / cg" |
152 "Modified: 2.4.1997 / 19:19:35 / cg" |
164 ! ! |
153 ! ! |
165 |
154 |
166 !DeviceGraphicsContext class methodsFor:'cleanup'! |
155 !DeviceGraphicsContext class methodsFor:'cleanup'! |
167 |
156 |
168 cleanupLobbyForChildrenOfViewWithDevice:aDevice id:anId |
|
169 "recursively clean all the subcomponents of the handle with id anId. |
|
170 This must be done on finalization, because descendent handles |
|
171 are destroyed implicitly when a parent handle is destroyed." |
|
172 |
|
173 |parents newChildren| |
|
174 |
|
175 parents := Array with:anId address. |
|
176 |
|
177 [ |
|
178 newChildren := Set new. |
|
179 Lobby unregisterAllForWhichHandle:[:handle | |
|
180 |parentId| |
|
181 |
|
182 handle notNil |
|
183 and:[handle device == aDevice |
|
184 and:[(parentId := handle parentId) notNil |
|
185 and:[(parents includes:parentId) |
|
186 and:[newChildren add:handle id. true]]]]. |
|
187 ]. |
|
188 parents := newChildren. |
|
189 ] doWhile:[parents notEmpty]. |
|
190 ! |
|
191 |
|
192 lowSpaceCleanup |
157 lowSpaceCleanup |
193 CachedScaledForms := CachedScales := nil |
158 CachedScaledForms := CachedScales := nil |
194 ! |
|
195 |
|
196 releaseResourcesOnDevice:aDevice |
|
197 "this is sent when a display connection is closed, |
|
198 to release all cached bitmap/window objects from that device" |
|
199 |
|
200 Lobby unregisterAllForWhich:[:aDrawable | aDrawable graphicsDevice == aDevice] |
|
201 |
|
202 "Created: 16.1.1997 / 16:43:52 / cg" |
|
203 ! ! |
|
204 |
|
205 !DeviceGraphicsContext methodsFor:'Compatibility-ST80'! |
|
206 |
|
207 key |
|
208 ^ self id |
|
209 ! ! |
|
210 |
|
211 !DeviceGraphicsContext methodsFor:'Compatibility-VW'! |
|
212 |
|
213 displayBackgroundIfNeededOn: aGraphicsContext |
|
214 aGraphicsContext clearView. |
|
215 ! |
|
216 |
|
217 inactiveForegroundColor |
|
218 "a dummy method to support VW widgets" |
|
219 |
|
220 ^ self foregroundColor |
|
221 ! |
|
222 |
|
223 selectionBackgroundColor |
|
224 "a dummy method to support VW widgets" |
|
225 |
|
226 ^ self foregroundColor |
|
227 ! |
|
228 |
|
229 selectionForegroundColor |
|
230 "a dummy method to support VW widgets" |
|
231 |
|
232 ^ self backgroundColor |
|
233 ! |
|
234 |
|
235 separatorColor |
|
236 "a dummy method to support VW widgets" |
|
237 |
|
238 ^ self foregroundColor |
|
239 ! ! |
159 ! ! |
240 |
160 |
241 !DeviceGraphicsContext methodsFor:'accessing'! |
161 !DeviceGraphicsContext methodsFor:'accessing'! |
242 |
162 |
243 at:aPoint |
163 at:aPoint |
363 ] |
281 ] |
364 |
282 |
365 "Modified: 12.5.1996 / 22:23:03 / cg" |
283 "Modified: 12.5.1996 / 22:23:03 / cg" |
366 ! |
284 ! |
367 |
285 |
368 clipByChildren |
|
369 "drawing shall be done into my view only (default)" |
|
370 |
|
371 <resource:#obsolete> |
|
372 |
|
373 self obsoleteMethodWarning:'use #clippedByChildren:true'. |
|
374 ^ self clippedByChildren:true |
|
375 |
|
376 "Created: 17.7.1996 / 13:25:55 / cg" |
|
377 ! |
|
378 |
|
379 clipRect |
|
380 "return the clipping rectangle for drawing. If there is currently no clipRect, |
|
381 a dummy is created." |
|
382 |
|
383 |rect| |
|
384 |
|
385 (rect := clipRect) isNil ifTrue:[ |
|
386 rect := 0@0 extent:(self extent). |
|
387 ]. |
|
388 "/ nope - it is already kept in logical coordinates |
|
389 "/ transformation notNil ifTrue:[ |
|
390 "/ rect := transformation applyInverseTo:rect. |
|
391 "/ ]. |
|
392 ^ rect |
|
393 |
|
394 "Modified: / 20-10-2006 / 13:24:21 / cg" |
|
395 ! |
|
396 |
|
397 clippedByChildren:aBoolean |
286 clippedByChildren:aBoolean |
398 "turn on/off drawing over children. |
287 "turn on/off drawing over children. |
399 If on, a superview may draw 'over' its children. |
288 If on, a superview may draw 'over' its children. |
400 If off (the default), drawing is 'under' its children. |
289 If off (the default), drawing is 'under' its children. |
401 Only useful for the rootView, to draw over any visible views. |
290 Only useful for the rootView, to draw over any visible views. |
555 a nil clipping rectangle means: no clipping (i.e. whole view is drawable - incl. margins)" |
458 a nil clipping rectangle means: no clipping (i.e. whole view is drawable - incl. margins)" |
556 |
459 |
557 ^ clipRect |
460 ^ clipRect |
558 ! |
461 ! |
559 |
462 |
560 deviceClippingRectangle |
|
561 "answer the clipping rectangle for drawing in device coordinates, or nil." |
|
562 |
|
563 |x y w h transformedRectangle| |
|
564 |
|
565 (clipRect isNil or:[transformation isNil]) ifTrue:[ |
|
566 ^ clipRect. |
|
567 ]. |
|
568 |
|
569 transformedRectangle := transformation transformRectangle:clipRect. |
|
570 |
|
571 x := transformedRectangle left. |
|
572 y := transformedRectangle top. |
|
573 w := transformedRectangle width + 1. |
|
574 h := transformedRectangle height + 1. |
|
575 |
|
576 (x class == SmallInteger) ifFalse:[ |
|
577 w := w + (x - x truncated). |
|
578 x := x truncated |
|
579 ]. |
|
580 (y class == SmallInteger) ifFalse:[ |
|
581 h := h + (y - y truncated). |
|
582 y := y truncated |
|
583 ]. |
|
584 (w class == SmallInteger) ifFalse:[ |
|
585 w := w ceiling. |
|
586 ]. |
|
587 (h class == SmallInteger) ifFalse:[ |
|
588 h := h ceiling. |
|
589 ]. |
|
590 w := w max:0. |
|
591 h := h max:0. |
|
592 |
|
593 ^ Rectangle left:x top:y width:w height:h |
|
594 ! |
|
595 |
|
596 deviceClippingRectangle:aRectangleOrNil |
|
597 "set the clipping rectangle for drawing (in device coordinates); |
|
598 a nil argument turns off clipping (i.e. whole view is drawable - incl. margins)" |
|
599 |
|
600 |x y w h newLogicalClipRect| |
|
601 |
|
602 aRectangleOrNil isNil ifTrue:[ |
|
603 clipRect isNil ifTrue:[^ self]. |
|
604 gcId notNil ifTrue:[ |
|
605 device noClipIn:drawableId gc:gcId |
|
606 ]. |
|
607 clipRect := nil. |
|
608 ^ self. |
|
609 ]. |
|
610 |
|
611 transformation isNil ifTrue:[ |
|
612 newLogicalClipRect := aRectangleOrNil |
|
613 ] ifFalse:[ |
|
614 newLogicalClipRect := transformation applyInverseTo:aRectangleOrNil |
|
615 ]. |
|
616 |
|
617 (clipRect = newLogicalClipRect) ifTrue:[^ self]. |
|
618 |
|
619 gcId notNil ifTrue:[ |
|
620 x := aRectangleOrNil left rounded. |
|
621 y := aRectangleOrNil top rounded. |
|
622 w := aRectangleOrNil width rounded. |
|
623 h := aRectangleOrNil height rounded. |
|
624 device setClipX:x y:y width:w height:h in:drawableId gc:gcId |
|
625 ]. |
|
626 clipRect := newLogicalClipRect |
|
627 |
|
628 "Modified: / 22.5.1996 / 13:12:07 / cg" |
|
629 "Created: / 14.9.1998 / 18:50:31 / cg" |
|
630 ! |
|
631 |
|
632 drawableId |
463 drawableId |
633 ^drawableId |
464 ^drawableId |
634 |
465 |
635 "Created: / 10-07-2008 / 10:20:04 / Jan Vrany <vranyj1@fel.cvut.cz>" |
466 "Created: / 10-07-2008 / 10:20:04 / Jan Vrany <vranyj1@fel.cvut.cz>" |
636 "Modified (format): / 26-04-2016 / 07:11:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
467 "Modified (format): / 26-04-2016 / 07:11:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
796 transformation notNil ifTrue:[ |
618 transformation notNil ifTrue:[ |
797 pO := transformation transformPoint:aPoint. |
619 pO := transformation transformPoint:aPoint. |
798 x:= pO x. |
620 x:= pO x. |
799 y := pO y. |
621 y := pO y. |
800 ]. |
622 ]. |
801 x := x rounded. |
|
802 y := y rounded. |
|
803 |
623 |
804 gcId notNil ifTrue:[ |
624 gcId notNil ifTrue:[ |
805 device setMaskOriginX:x y:y in:gcId |
625 device setMaskOriginX:x rounded y:y rounded in:gcId |
806 ] |
626 ] |
807 ] |
627 ] |
808 |
628 |
809 "Created: / 26.1.1998 / 19:03:02 / cg" |
629 "Created: / 26.1.1998 / 19:03:02 / cg" |
810 ! |
630 ! |
811 |
631 |
812 maskOriginX:orgX y:orgY |
632 maskOriginX:orgX y:orgY |
813 "set the origin of the pattern" |
633 "set the origin of the pattern" |
814 |
634 |
815 self maskOrigin:(orgX @ orgY) |
635 self maskOrigin:(orgX @ orgY) |
816 ! |
|
817 |
|
818 noClipByChildren |
|
819 "drawing shall also be done into subviews" |
|
820 |
|
821 <resource:#obsolete> |
|
822 |
|
823 self obsoleteMethodWarning:'use #clippedByChildren:false'. |
|
824 ^ self clippedByChildren:false |
|
825 |
|
826 "Created: 17.7.1996 / 14:15:54 / cg" |
|
827 ! |
636 ! |
828 |
637 |
829 paint:aColor |
638 paint:aColor |
830 "set the drawing color, which may be a real color, a dithered one |
639 "set the drawing color, which may be a real color, a dithered one |
831 or even an image." |
640 or even an image." |
1143 x:dstX y:dstY |
949 x:dstX y:dstY |
1144 width:srcW height:srcH "all senders set srcW/srcH to self width / self height" |
950 width:srcW height:srcH "all senders set srcW/srcH to self width / self height" |
1145 with:gcId. |
951 with:gcId. |
1146 ! |
952 ! |
1147 |
953 |
1148 copyBitsFrom:aByteArray bitsPerPixel:bpp depth:depth width:srcW height:srcH x:srcX y:srcY toX:dstX y:dstY |
954 copyFrom:aGC x:srcX y:srcY toX:dstX y:dstY width:w height:h depth:depth |
1149 "copy bits from a smalltalk byteArray. |
|
1150 The bits found there are supposed to be in the devices native format (i.e. |
|
1151 translated to allocated color indices on pseudoColor devices and padded as required. |
|
1152 The byteOrder is MSB and will be converted as appropriate by the underlying devices |
|
1153 method to whatever the device needs. |
|
1154 Assumes the source bits are in ST/X's natural padding (i.e. 8-bit padded)" |
|
1155 |
|
1156 self |
|
1157 copyBitsFrom:aByteArray |
|
1158 bitsPerPixel:bpp |
|
1159 depth:depth |
|
1160 padding:8 |
|
1161 width:srcW |
|
1162 height:srcH |
|
1163 x:srcX |
|
1164 y:srcY |
|
1165 toX:dstX |
|
1166 y:dstY |
|
1167 ! |
|
1168 |
|
1169 copyFrom:aDrawable x:srcX y:srcY toX:dstX y:dstY width:w height:h |
|
1170 "copy from aDrawable into the receiver; |
|
1171 the source may be the receiver as well - in this case its a scroll. |
|
1172 All coordinates are in device coordinates." |
|
1173 |
|
1174 ^ self |
|
1175 copyFrom:aDrawable |
|
1176 x:srcX y:srcY |
|
1177 toX:dstX y:dstY |
|
1178 width:w height:h |
|
1179 async:false |
|
1180 |
|
1181 "Modified: 29.1.1997 / 13:12:36 / cg" |
|
1182 ! |
|
1183 |
|
1184 copyFrom:aDrawable x:srcX y:srcY toX:dstX y:dstY width:w height:h async:async |
|
1185 "copy from aDrawable into the receiver; |
955 "copy from aDrawable into the receiver; |
1186 the source may be the receiver as well - in this case its a scroll. |
956 the source may be the receiver as well - in this case its a scroll. |
1187 All coordinates are in device coordinates. |
957 All coordinates are in device coordinates. |
1188 If the receiver is a view AND async is true, the call returns immediately |
958 If the receiver is a view AND async is true, the call returns immediately |
1189 - otherwise, it returns when the scroll operation is finished. |
959 - otherwise, it returns when the scroll operation is finished. |
1190 (not all devices care for this). |
960 (not all devices care for this). |
1191 If the receiver is a pixmap, the call always returns immediately." |
961 If the receiver is a pixmap, the call always returns immediately." |
1192 |
962 |
1193 |deviceDrawable id srcGCId asy| |
963 |srcGCId srcDrawableId| |
1194 |
|
1195 ((aDrawable graphicsDevice ~~ device) |
|
1196 or:[aDrawable isImage]) ifTrue:[ |
|
1197 deviceDrawable := aDrawable asFormOn:device. |
|
1198 ] ifFalse:[ |
|
1199 deviceDrawable := aDrawable |
|
1200 ]. |
|
1201 |
|
1202 id := deviceDrawable id. |
|
1203 |
|
1204 "temporary ... |
|
1205 this fixes a problem after restart on another display, |
|
1206 when a file-bitmap was not found. |
|
1207 In this case, the id of the bitmap will be nil. |
|
1208 This will be fixed soon (no longer use device>>bitmapFromFile:). |
|
1209 " |
|
1210 id isNil ifTrue:[ |
|
1211 Smalltalk isStandAloneApp ifFalse:[ |
|
1212 'DeviceGraphicsContext [warning]: invalid bitmap copy - ignored' infoPrintCR. |
|
1213 ]. |
|
1214 ^ self |
|
1215 ]. |
|
1216 |
964 |
1217 gcId isNil ifTrue:[ |
965 gcId isNil ifTrue:[ |
1218 self initGC |
966 self initGC |
1219 ]. |
967 ]. |
1220 |
968 |
1221 deviceDrawable gcId isNil ifTrue:[deviceDrawable initGC]. |
969 aGC initGC. |
1222 srcGCId := deviceDrawable gcId. |
970 srcGCId := aGC gcId. |
1223 |
971 srcDrawableId := aGC drawableId. |
1224 ((deviceDrawable depth == 1) and:[device depth ~~ 1]) ifTrue:[ |
972 |
1225 deviceDrawable isForm ifTrue:[ |
973 ((depth == 1) and:[device depth ~~ 1]) ifTrue:[ |
|
974 aGC isPixmap ifTrue:[ |
1226 device |
975 device |
1227 copyPlaneFromPixmapId:id |
976 copyPlaneFromPixmapId:srcDrawableId |
1228 x:srcX |
977 x:srcX |
1229 y:srcY |
978 y:srcY |
1230 gc:srcGCId |
979 gc:srcGCId |
1231 to:drawableId |
980 to:drawableId |
1232 x:dstX |
981 x:dstX |
1246 gc:gcId |
995 gc:gcId |
1247 width:w |
996 width:w |
1248 height:h |
997 height:h |
1249 ] |
998 ] |
1250 ] ifFalse:[ |
999 ] ifFalse:[ |
1251 deviceDrawable isForm ifTrue:[ |
1000 aGC isPixmap ifTrue:[ |
1252 device |
1001 device |
1253 copyFromPixmapId:id |
1002 copyFromPixmapId:srcDrawableId |
1254 x:srcX |
1003 x:srcX |
1255 y:srcY |
1004 y:srcY |
1256 gc:srcGCId |
1005 gc:srcGCId |
1257 to:drawableId |
1006 to:drawableId |
1258 x:dstX |
1007 x:dstX |
1259 y:dstY |
1008 y:dstY |
1260 gc:gcId |
1009 gc:gcId |
1261 width:w |
1010 width:w |
1262 height:h |
1011 height:h |
1263 ] ifFalse:[ |
1012 ] ifFalse:[ |
1264 asy := async or:[self isView not]. |
|
1265 asy ifFalse:[ |
|
1266 self catchExpose |
|
1267 ]. |
|
1268 device |
1013 device |
1269 copyFromId:id |
1014 copyFromId:srcDrawableId |
1270 x:srcX |
1015 x:srcX |
1271 y:srcY |
1016 y:srcY |
1272 gc:srcGCId |
1017 gc:srcGCId |
1273 to:drawableId |
1018 to:drawableId |
1274 x:dstX |
1019 x:dstX |
1275 y:dstY |
1020 y:dstY |
1276 gc:gcId |
1021 gc:gcId |
1277 width:w |
1022 width:w |
1278 height:h. |
1023 height:h. |
1279 asy ifFalse:[ |
|
1280 device flush. |
|
1281 self waitForExpose |
|
1282 ] |
|
1283 ] |
1024 ] |
1284 ] |
1025 ]. |
1285 |
1026 ! |
1286 "Created: / 29.1.1997 / 13:02:10 / cg" |
1027 |
1287 "Modified: / 31.7.1998 / 17:23:43 / cg" |
1028 copyPlaneFrom:aGC x:srcX y:srcY toX:dstX y:dstY width:w height:h |
1288 ! |
|
1289 |
|
1290 copyPlaneFrom:aDrawable x:srcX y:srcY toX:dstX y:dstY width:w height:h |
|
1291 "copy one plane from aDrawable into the receiver. 0's are drawn in |
1029 "copy one plane from aDrawable into the receiver. 0's are drawn in |
1292 background, while 1's are drawn with foreground color. |
1030 background, while 1's are drawn with foreground color. |
1293 The depth of aDrawable must (should) be 1. |
1031 The depth of aDrawable must (should) be 1. |
1294 The drawable must have been allocated on the same device. |
1032 The drawable must have been allocated on the same device. |
1295 All coordinates are in device coordinates." |
1033 All coordinates are in device coordinates." |
1296 |
1034 |
1297 |deviceDrawable id| |
1035 |srcGCId srcDrawableId| |
1298 |
1036 |
1299 ((aDrawable graphicsDevice ~~ device) |
1037 gcId isNil ifTrue:[ |
1300 or:[aDrawable isImage]) ifTrue:[ |
1038 self initGC |
1301 deviceDrawable := aDrawable asFormOn:device. |
1039 ]. |
|
1040 |
|
1041 aGC initGC. |
|
1042 srcGCId := aGC gcId. |
|
1043 srcDrawableId := aGC drawableId. |
|
1044 |
|
1045 aGC isPixmap ifTrue:[ |
|
1046 device |
|
1047 copyPlaneFromPixmapId:srcDrawableId |
|
1048 x:srcX |
|
1049 y:srcY |
|
1050 gc:srcGCId |
|
1051 to:drawableId |
|
1052 x:dstX |
|
1053 y:dstY |
|
1054 gc:gcId |
|
1055 width:w |
|
1056 height:h |
1302 ] ifFalse:[ |
1057 ] ifFalse:[ |
1303 deviceDrawable := aDrawable |
1058 device |
1304 ]. |
1059 copyPlaneFromId:srcDrawableId |
1305 |
1060 x:srcX |
1306 id := deviceDrawable id. |
1061 y:srcY |
1307 |
1062 gc:srcGCId |
1308 "temporary ... |
1063 to:drawableId |
1309 this fixes a problem after restart on another display, |
1064 x:dstX |
1310 when a file-bitmap was not found. |
1065 y:dstY |
1311 In this case, the id of the bitmap will be nil. |
1066 gc:gcId |
1312 This will be fixed soon (no longer use device>>bitmapFromFile:). |
1067 width:w |
1313 " |
1068 height:h |
1314 id isNil ifTrue:[ |
|
1315 'DeviceGraphicsContext [warning]: invalid copyPlane - ignored' errorPrintCR. |
|
1316 ^ self |
|
1317 ]. |
|
1318 |
|
1319 gcId isNil ifTrue:[ |
|
1320 self initGC |
|
1321 ]. |
|
1322 |
|
1323 deviceDrawable isForm ifTrue:[ |
|
1324 deviceDrawable gcId isNil ifTrue:[ |
|
1325 deviceDrawable initGC |
|
1326 ]. |
|
1327 device |
|
1328 copyPlaneFromPixmapId:id |
|
1329 x:srcX |
|
1330 y:srcY |
|
1331 gc:(deviceDrawable gcId) |
|
1332 to:drawableId |
|
1333 x:dstX |
|
1334 y:dstY |
|
1335 gc:gcId |
|
1336 width:w |
|
1337 height:h |
|
1338 ] ifFalse:[ |
|
1339 device |
|
1340 copyPlaneFromId:id |
|
1341 x:srcX |
|
1342 y:srcY |
|
1343 gc:(deviceDrawable gcId) |
|
1344 to:drawableId |
|
1345 x:dstX |
|
1346 y:dstY |
|
1347 gc:gcId |
|
1348 width:w |
|
1349 height:h |
|
1350 ] |
1069 ] |
1351 |
1070 |
1352 "Modified: / 22.8.1998 / 15:15:52 / cg" |
1071 "Modified: / 22.8.1998 / 15:15:52 / cg" |
1353 ! ! |
1072 ! ! |
1354 |
1073 |
1862 "draw a substring at the coordinate x/y - |
1581 "draw a substring at the coordinate x/y - |
1863 draw foreground-pixels only (in current paint-color), |
1582 draw foreground-pixels only (in current paint-color), |
1864 leaving background as-is. If the transformation involves scaling, |
1583 leaving background as-is. If the transformation involves scaling, |
1865 the font's point-size is scaled as appropriate." |
1584 the font's point-size is scaled as appropriate." |
1866 |
1585 |
1867 self displayString:aString from:index1 to:index2 x:x y:y opaque:false maxWidth:nil |
1586 self displayString:aString from:index1 to:index2 x:x y:y opaque:false maxWidth:nil. |
1868 ! |
1587 ! |
1869 |
1588 |
1870 displayString:aString from:index1 to:index2 x:x y:y opaque:opaque |
1589 displayString:aString from:index1 to:index2 x:x y:y opaque:opaque |
1871 "draw part of a string with both fg and bg at x/y in current font" |
1590 "draw part of a string with both fg and bg at x/y in current font" |
1872 |
1591 |
1873 ^ self displayString:aString from:index1 to:index2 x:x y:y opaque:opaque maxWidth:nil. |
1592 ^ self displayString:aString from:index1 to:index2 x:x y:y opaque:opaque maxWidth:nil |
1874 ! |
1593 ! |
1875 |
1594 |
1876 displayString:aStringArg from:index1Arg to:index2Arg x:x y:y opaque:opaqueArg maxWidth:maxWidth |
1595 displayString:aStringArg from:index1Arg to:index2Arg x:x y:y opaque:opaqueArg maxWidth:maxWidth |
1877 "draw a substring at the coordinate x/y - draw foreground pixels in |
1596 "draw a substring at the coordinate x/y - draw foreground pixels in |
1878 paint-color and (if opaque is true), background pixels in bgPaint-color. |
1597 paint-color and (if opaque is true), background pixels in bgPaint-color. |
1879 If the transformation involves scaling, the font's point-size is scaled as appropriate. |
1598 If the transformation involves scaling, the font's point-size is scaled as appropriate. |
1880 Assuming that device can only draw in device colors, we have to handle |
1599 Assuming that device can only draw in device colors, we have to handle |
1881 the case where paint and/or bgPaint are dithered colors. |
1600 the case where paint and/or bgPaint are dithered colors. |
1882 maxWidth is the maximum width of the string in pixels or nil if unknown." |
1601 maxWidth is the maximum width of the string in pixels or nil if unknown." |
1883 |
1602 |
1884 |opaque index1 index2 easy w h savedPaint fgId bgId |
1603 |opaque index1 index2 easy w h savedPaint fgId bgId pX pY fontUsed fontsEncoding sz aString |
1885 fontId pX pY fontUsed fontsEncoding aString |
|
1886 nSkipLeft nChars wString wSkipLeft index2Guess| |
1604 nSkipLeft nChars wString wSkipLeft index2Guess| |
1887 |
1605 |
1888 index1 := index1Arg. |
1606 index1 := index1Arg. |
1889 index2 := index2Arg. |
1607 index2 := index2Arg. |
1890 opaque := opaqueArg. |
1608 opaque := opaqueArg. |
1899 |
1617 |
1900 gcId isNil ifTrue:[ |
1618 gcId isNil ifTrue:[ |
1901 self initGC |
1619 self initGC |
1902 ]. |
1620 ]. |
1903 |
1621 |
1904 (aStringArg isString not or:[aStringArg isText]) ifTrue:[ |
1622 aStringArg isPlainString ifFalse:[ |
1905 " |
1623 " |
1906 hook for non-strings (i.e. attributed text) |
1624 hook for non-strings (i.e. attributed text) |
1907 that 'thing' should know how to display itself ... |
1625 that 'thing' should know how to display itself ... |
1908 " |
1626 " |
1909 aStringArg displayOn:self x:x y:y from:index1 to:index2 opaque:opaque. |
1627 aStringArg displayOn:self x:x y:y from:index1 to:index2 opaque:opaque. |
1910 ^ self |
1628 ^ self |
1911 ]. |
1629 ]. |
1912 |
1630 |
1913 "/ transcode the string into the font's encoding... |
1631 "/ transcode the string into the fonts encoding... |
1914 aString := aStringArg. |
1632 aString := aStringArg. |
1915 fontsEncoding := font encoding. |
1633 fontsEncoding := font encoding. |
1916 |
|
1917 "/ This is now obsolete, as we are always using unicode internally. |
|
1918 "/ so the next line should be changed to fontsEncoding ~~ #unicode |
|
1919 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
1634 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
1920 [ |
1635 [ |
1921 aString := CharacterEncoder encodeString:aString from:characterEncoding into:fontsEncoding. |
1636 aString := CharacterEncoder encodeString:aString from:characterEncoding into:fontsEncoding. |
1922 ] on:CharacterEncoderError do:[:ex| |
1637 ] on:CharacterEncoderError do:[:ex| |
1923 "substitute a default value for codes that cannot be represented |
1638 "substitute a default value for codes that cannot be represented |
2013 pX := pX + wSkipLeft. |
1724 pX := pX + wSkipLeft. |
2014 "/ ('skip %d w=%d x=%d' printfWith:nSkipLeft with:wSkipLeft with:x) printCR. |
1725 "/ ('skip %d w=%d x=%d' printfWith:nSkipLeft with:wSkipLeft with:x) printCR. |
2015 ]. |
1726 ]. |
2016 |
1727 |
2017 "/ ('n=%d w=%d' printfWith:nChars with:wString) printCR. |
1728 "/ ('n=%d w=%d' printfWith:nChars with:wString) printCR. |
2018 [ |
1729 [ |
2019 index2Guess := (index1+nChars-1) min:index2. |
1730 index2Guess := (index1+nChars-1) min:index2. |
2020 wString := fontUsed widthOf:aString from:index1 to:index2Guess. |
1731 wString := fontUsed widthOf:aString from:index1 to:index2Guess. |
2021 ((pX+wString) < maxWidth) and:[ index2Guess < index2] |
1732 ((pX+wString) < maxWidth) and:[ index2Guess < index2] |
2022 ] whileTrue:[ "/ not enough... |
1733 ] whileTrue:[ "/ not enough... |
2023 nChars := (nChars * 1.1) rounded. |
1734 nChars := (nChars * 1.1) rounded. |
2024 ]. |
1735 ]. |
2025 "/ ('n=%d w=%d' printfWith:nChars with:wString) printCR. |
1736 "/ ('n=%d w=%d' printfWith:nChars with:wString) printCR. |
2026 index2 := index2Guess. |
1737 index2 := index2Guess. |
2073 "draw a string at the coordinate x/y - |
1784 "draw a string at the coordinate x/y - |
2074 draw foreground-pixels only (in current paint-color), |
1785 draw foreground-pixels only (in current paint-color), |
2075 leaving background as-is. If the transformation involves scaling, |
1786 leaving background as-is. If the transformation involves scaling, |
2076 the font's point-size is scaled as appropriate." |
1787 the font's point-size is scaled as appropriate." |
2077 |
1788 |
2078 self displayString:aString from:1 to:aString size x:x y:y opaque:false maxWidth:nil |
1789 self displayString:aString from:1 to:aString size x:x y:y opaque:false maxWidth:nil. |
2079 ! |
1790 ! |
2080 |
1791 |
2081 displayUnscaledForm:formToDraw x:x y:y |
1792 displayUnscaledForm:formToDraw x:x y:y |
2082 "draw a form or image non opaque and unscaled; |
1793 "draw a form or image non opaque and unscaled; |
2083 if its a 1-plane bitmap, 1-bits are drawn in the |
1794 if its a 1-plane bitmap, 1-bits are drawn in the |
3003 background := nil. |
2714 background := nil. |
3004 |
2715 |
3005 "Modified: 22.4.1997 / 21:44:10 / cg" |
2716 "Modified: 22.4.1997 / 21:44:10 / cg" |
3006 ! |
2717 ! |
3007 |
2718 |
3008 displayDeviceOpaqueString:aString from:index1 to:index2 in:font x:x y:y |
2719 displayDeviceOpaqueString:aStringArg from:index1 to:index2 in:fontArg x:x y:y |
3009 "draw a substring at the coordinate x/y - draw foreground pixels in |
2720 "draw a substring at the coordinate x/y - draw foreground pixels in |
3010 paint-color and background pixels in bgPaint-color. |
2721 paint-color and background pixels in bgPaint-color. |
3011 Assuming that device can only draw in device colors, we have to handle |
2722 Assuming that device can only draw in device colors, we have to handle |
3012 the case where paint and/or bgPaint are dithered colors. |
2723 the case where paint and/or bgPaint are dithered colors. |
3013 No translation or scaling is done." |
2724 No translation or scaling is done." |
3014 |
2725 |
3015 |easy w h savedPaint fgId bgId allColor allBits noColor |
2726 |easy w h savedPaint fgId bgId allColor allBits noColor bgForm fgForm tmpForm maskForm dx dy pX pY fontUsed aString |
3016 id bgForm fgForm tmpForm maskForm dx dy pX pY fontUsed s |
|
3017 deviceDepth fontsEncoding ascent| |
2727 deviceDepth fontsEncoding ascent| |
3018 |
2728 |
3019 " |
2729 " |
3020 if backgroundPaint color is nil, we assume |
2730 if backgroundPaint color is nil, we assume |
3021 this is a non-opaque draw |
2731 this is a non-opaque draw |
3022 " |
2732 " |
3023 bgPaint isNil ifTrue:[ |
2733 bgPaint isNil ifTrue:[ |
3024 self displayDeviceString:aString from:index1 to:index2 x:x y:y. |
2734 self displayDeviceString:aString from:index1 to:index2 in:font x:x y:y. |
3025 ^ self |
2735 ^ self |
|
2736 ]. |
|
2737 |
|
2738 gcId isNil ifTrue:[ |
|
2739 self initGC |
|
2740 ]. |
|
2741 |
|
2742 fontUsed := fontArg onDevice:device. |
|
2743 deviceFont ~~ fontUsed ifTrue:[ |
|
2744 (fontUsed installInDeviceForGCId:gcId) isNil ifTrue:[ |
|
2745 "error - no such font" |
|
2746 ^ self. |
|
2747 ]. |
|
2748 deviceFont := fontUsed. |
3026 ]. |
2749 ]. |
3027 |
2750 |
3028 aString isPlainString ifFalse:[ |
2751 aString isPlainString ifFalse:[ |
3029 " |
2752 " |
3030 hook for non-strings (i.e. attributed text) |
2753 hook for non-strings (i.e. attributed text) |
3035 ]. |
2758 ]. |
3036 |
2759 |
3037 pX := x rounded. |
2760 pX := x rounded. |
3038 pY := y rounded. |
2761 pY := y rounded. |
3039 |
2762 |
3040 font isAlienFont ifTrue:[ |
2763 aString := aStringArg. |
3041 " |
2764 |
3042 hook for alien fonts |
|
3043 that 'font' should know how to display the string ... |
|
3044 " |
|
3045 font displayOpaqueString:aString from:index1 to:index2 x:pX y:pY in:self. |
|
3046 ^ self |
|
3047 ]. |
|
3048 |
|
3049 gcId isNil ifTrue:[ |
|
3050 self initGC |
|
3051 ]. |
|
3052 |
|
3053 |
|
3054 s := aString. |
|
3055 fontUsed := font onDevice:device. |
|
3056 fontsEncoding := fontUsed encoding. |
2765 fontsEncoding := fontUsed encoding. |
3057 |
|
3058 "/ This is now obsolete, as we are always using unicode internally. |
2766 "/ This is now obsolete, as we are always using unicode internally. |
3059 "/ so the next line should be changed to fontsEncoding ~~ #unicode |
2767 "/ so the next line should be changed to fontsEncoding ~~ #unicode |
3060 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
2768 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
3061 [ |
2769 [ |
3062 s := CharacterEncoder encodeString:s from:characterEncoding into:fontsEncoding. |
2770 aString := CharacterEncoder encodeString:aString from:characterEncoding into:fontsEncoding. |
3063 ] on:CharacterEncoderError do:[:ex| |
2771 ] on:CharacterEncoderError do:[:ex| |
3064 "substitute a default value for codes that cannot be represented |
2772 "substitute a default value for codes that cannot be represented |
3065 in the new character set" |
2773 in the new character set" |
3066 ex proceedWith:ex defaultValue. |
2774 ex proceedWith:ex defaultValue. |
3067 ]. |
2775 ]. |
3068 ]. |
2776 ]. |
3069 |
2777 |
3070 id := fontUsed fontId. |
2778 fontUsed isAlienFont ifTrue:[ |
3071 id isNil ifTrue:[ |
2779 " |
3072 "this should not happen, since #onDevice tries replacement fonts" |
2780 hook for alien fonts |
3073 'STX[DeviceGraphicsContext] no font: ' errorPrint. fontUsed errorPrintCR. |
2781 that 'font' should know how to display the string ... |
|
2782 " |
|
2783 fontUsed displayOpaqueString:aString from:index1 to:index2 x:pX y:pY in:self. |
3074 ^ self |
2784 ^ self |
3075 ]. |
|
3076 |
|
3077 deviceFont ~~ fontUsed ifTrue:[ |
|
3078 device setFont:id in:gcId. |
|
3079 deviceFont := fontUsed |
|
3080 ]. |
2785 ]. |
3081 |
2786 |
3082 " |
2787 " |
3083 if bgPaint or paint is not a real Color, we have to do it the hard way ... |
2788 if bgPaint or paint is not a real Color, we have to do it the hard way ... |
3084 " |
2789 " |
3240 stamp-out background (have now bg-bits with fg=0 in bgForm) |
2945 stamp-out background (have now bg-bits with fg=0 in bgForm) |
3241 " |
2946 " |
3242 bgForm font:fontUsed. |
2947 bgForm font:fontUsed. |
3243 bgForm paint:noColor on:allColor. |
2948 bgForm paint:noColor on:allColor. |
3244 bgForm function:#and. |
2949 bgForm function:#and. |
3245 bgForm displayString:s from:index1 to:index2 x:0 y:ascent. |
2950 bgForm displayString:aString from:index1 to:index2 x:0 y:ascent. |
3246 |
2951 |
3247 " |
2952 " |
3248 stamp-out foreground |
2953 stamp-out foreground |
3249 " |
2954 " |
3250 maskForm font:fontUsed. |
2955 maskForm font:fontUsed. |
3251 maskForm paint:allColor on:noColor. |
2956 maskForm paint:allColor on:noColor. |
3252 maskForm displayOpaqueString:s from:index1 to:index2 x:0 y:ascent. |
2957 maskForm displayString:aString from:index1 to:index2 x:0 y:ascent opaque:true. |
3253 |
2958 |
3254 fgForm function:#and. |
2959 fgForm function:#and. |
3255 fgForm copyFrom:maskForm x:0 y:0 toX:0 y:0 width:w height:h. |
2960 fgForm copyFrom:maskForm x:0 y:0 toX:0 y:0 width:w height:h. |
3256 |
2961 |
3257 " |
2962 " |
3313 No translation or scaling is done" |
3018 No translation or scaling is done" |
3314 |
3019 |
3315 self displayDeviceOpaqueString:aString from:1 to:(aString size) in:font x:x y:y |
3020 self displayDeviceOpaqueString:aString from:1 to:(aString size) in:font x:x y:y |
3316 ! |
3021 ! |
3317 |
3022 |
3318 displayDeviceString:aString from:index1 to:index2 in:font x:x y:y |
3023 displayDeviceString:aStringArg from:index1 to:index2 in:fontArg x:x y:y |
3319 "draw a substring at the coordinate x/y - |
3024 "draw a substring at the coordinate x/y - |
3320 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3025 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3321 No translation or scaling is done" |
3026 No translation or scaling is done" |
3322 |
3027 |
3323 |id pX pY fontUsed s fontsEncoding| |
3028 |fontUsed aString fontsEncoding| |
3324 |
3029 |
3325 " |
3030 " |
3326 hook for non-strings (i.e. attributed text) |
3031 hook for non-strings (i.e. attributed text) |
3327 " |
3032 " |
3328 aString isPlainString ifFalse:[ |
3033 aString isPlainString ifFalse:[ |
3329 ^ aString displayOn:self x:x y:y from:index1 to:index2 |
3034 ^ aString displayOn:self x:x y:y from:index1 to:index2 |
3330 ]. |
3035 ]. |
3331 |
3036 |
3332 pX := x rounded. |
|
3333 pY := y rounded. |
|
3334 |
|
3335 font isAlienFont ifTrue:[ |
|
3336 " |
|
3337 hook for alien fonts |
|
3338 that 'font' should know how to display the string ... |
|
3339 " |
|
3340 font displayOpaqueString:aString from:index1 to:index2 x:pX y:pY in:self. |
|
3341 ^ self |
|
3342 ]. |
|
3343 |
|
3344 gcId isNil ifTrue:[ |
3037 gcId isNil ifTrue:[ |
3345 self initGC |
3038 self initGC |
3346 ]. |
3039 ]. |
3347 |
3040 |
3348 s := aString. |
3041 fontUsed := fontArg onDevice:device. |
3349 fontUsed := font onDevice:device. |
3042 deviceFont ~~ fontUsed ifTrue:[ |
|
3043 (fontUsed installInDeviceForGCId:gcId) isNil ifTrue:[ |
|
3044 "error - no such font" |
|
3045 ^ self. |
|
3046 ]. |
|
3047 deviceFont := fontUsed. |
|
3048 ]. |
|
3049 |
|
3050 aString := aStringArg. |
|
3051 |
3350 fontsEncoding := fontUsed encoding. |
3052 fontsEncoding := fontUsed encoding. |
3351 |
|
3352 "/ This is now obsolete, as we are always using unicode internally. |
|
3353 "/ so the next line should be changed to fontsEncoding ~~ #unicode |
|
3354 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
3053 (characterEncoding ~~ fontsEncoding) ifTrue:[ |
3355 [ |
3054 [ |
3356 s := CharacterEncoder encodeString:s from:characterEncoding into:fontsEncoding. |
3055 aString := CharacterEncoder encodeString:aString from:characterEncoding into:fontsEncoding. |
3357 ] on:CharacterEncoderError do:[:ex| |
3056 ] on:CharacterEncoderError do:[:ex| |
3358 "substitute a default value for codes that cannot be represented |
3057 "substitute a default value for codes that cannot be represented |
3359 in the new character set" |
3058 in the new character set" |
3360 ex proceedWith:ex defaultValue. |
3059 ex proceedWith:ex defaultValue. |
3361 ]. |
3060 ]. |
3362 ]. |
3061 ]. |
3363 |
3062 fontUsed isAlienFont ifTrue:[ |
3364 id := fontUsed fontId. |
3063 " |
3365 id isNil ifTrue:[ |
3064 hook for alien fonts |
3366 "this should not happen, since #onDevice tries replacement fonts" |
3065 that 'font' should know how to display the string ... |
3367 'STX[DeviceGraphicsContext] no font: ' errorPrint. fontUsed errorPrintCR. |
3066 " |
|
3067 fontUsed displayString:aString from:index1 to:index2 x:x rounded y:y rounded in:self. |
3368 ^ self |
3068 ^ self |
3369 ] ifFalse:[ |
3069 ]. |
3370 deviceFont ~~ fontUsed ifTrue:[ |
3070 |
3371 device setFont:id in:gcId. |
3071 self displayDeviceString:aString from:index1 to:index2 x:x y:y opaque:false. |
3372 deviceFont := fontUsed |
|
3373 ]. |
|
3374 device displayString:s from:index1 to:index2 x:pX y:pY in:drawableId with:gcId |
|
3375 ] |
|
3376 |
3072 |
3377 "Modified: 1.7.1997 / 17:08:48 / cg" |
3073 "Modified: 1.7.1997 / 17:08:48 / cg" |
3378 ! |
3074 ! |
3379 |
3075 |
3380 displayDeviceString:aString from:index1 to:index2 x:x y:y |
3076 displayDeviceString:aString from:index1 to:index2 x:x y:y |
3381 "draw a substring at the coordinate x/y - |
3077 "draw a substring at the coordinate x/y - |
3382 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3078 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3383 No translation or scaling is done" |
3079 No translation or scaling is done" |
3384 |
3080 |
3385 self displayDeviceString:aString from:index1 to:index2 in:font x:x y:y |
3081 self displayDeviceString:aString from:index1 to:index2 in:font x:x y:y |
|
3082 ! |
|
3083 |
|
3084 displayDeviceString:aString from:index1 to:index2 x:x y:y opaque:opaque |
|
3085 "draw a substring at the coordinate x/y - |
|
3086 draw foreground-pixels only (in current paint-color), leaving background as-is. |
|
3087 No translation or scaling is done" |
|
3088 |
|
3089 gcId isNil ifTrue:[ |
|
3090 self initGC |
|
3091 ]. |
|
3092 |
|
3093 device displayString:aString from:index1 to:index2 x:x rounded y:y rounded in:drawableId with:gcId opaque:opaque. |
3386 ! |
3094 ! |
3387 |
3095 |
3388 displayDeviceString:aString x:x y:y |
3096 displayDeviceString:aString x:x y:y |
3389 "draw a string at the coordinate x/y - |
3097 "draw a string at the coordinate x/y - |
3390 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3098 draw foreground-pixels only (in current paint-color), leaving background as-is. |
3526 ! ! |
3234 ! ! |
3527 |
3235 |
3528 !DeviceGraphicsContext methodsFor:'filling'! |
3236 !DeviceGraphicsContext methodsFor:'filling'! |
3529 |
3237 |
3530 clearDeviceRectangleX:x y:y width:w height:h |
3238 clearDeviceRectangleX:x y:y width:w height:h |
3531 "clear a rectangular area to viewBackground - |
3239 "clear a rectangular area to background" |
3532 redefined since GraphicsMedium fills with background |
3240 |
3533 - not viewBackground as we want here." |
3241 |oldPaint| |
3534 |
3242 |
3535 |oldPaint viewBackground| |
|
3536 |
|
3537 viewBackground := self viewBackground. |
|
3538 viewBackground isNil ifTrue:[^ self]. "/ how can this happen? |
|
3539 |
|
3540 " |
|
3541 fill in device coordinates - not logical coordinates |
|
3542 " |
|
3543 oldPaint := paint. |
3243 oldPaint := paint. |
3544 self paint:viewBackground. |
3244 self paint:bgPaint. |
3545 self fillDeviceRectangleX:x y:y width:w height:h "with:viewBackground". |
3245 self fillDeviceRectangleX:x y:y width:w height:h. |
3546 self paint:oldPaint |
3246 self paint:oldPaint |
3547 |
3247 ! |
3548 "Modified: / 04-05-1999 / 13:00:34 / cg" |
3248 |
3549 "Created: / 30-12-2011 / 14:32:14 / cg" |
3249 clearRectangleX:left y:top width:w height:h |
|
3250 "clear the rectangular area in the receiver to background" |
|
3251 |
|
3252 |oldPaint| |
|
3253 |
|
3254 oldPaint := paint. |
|
3255 self paint:bgPaint. |
|
3256 self fillRectangleX:left y:top width:w height:h. |
|
3257 self paint:oldPaint |
3550 ! |
3258 ! |
3551 |
3259 |
3552 fillArcX:x y:y width:w height:h from:startAngle angle:angle |
3260 fillArcX:x y:y width:w height:h from:startAngle angle:angle |
3553 "draw a filled arc; apply transformation if nonNil" |
3261 "draw a filled arc; apply transformation if nonNil" |
3554 |
3262 |
3714 Since we do not need a gc-object for the drawable until something is |
3422 Since we do not need a gc-object for the drawable until something is |
3715 really drawn, none is created up to the first draw. |
3423 really drawn, none is created up to the first draw. |
3716 This method is sent, when the first drawing happens" |
3424 This method is sent, when the first drawing happens" |
3717 |
3425 |
3718 drawableType == #window ifTrue:[ |
3426 drawableType == #window ifTrue:[ |
|
3427 gcId := device gcForBitmap:drawableId. |
|
3428 ] ifFalse:[ |
3719 gcId := device gcFor:drawableId. |
3429 gcId := device gcFor:drawableId. |
3720 ] ifFalse:[ |
3430 ]. |
3721 gcId := device gcForBitmap:drawableId. |
3431 device registerGraphicsContext:self. "this is a registerChange:" |
3722 ]. |
|
3723 Lobby registerChange:self. |
|
3724 |
3432 |
3725 "Modified: / 19-03-1997 / 11:07:52 / cg" |
3433 "Modified: / 19-03-1997 / 11:07:52 / cg" |
3726 "Modified: / 25-02-2016 / 10:12:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
3434 "Modified: / 25-02-2016 / 10:12:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
3727 ! |
3435 ! |
3728 |
3436 |
3738 drawableType == #window ifTrue:[ |
3446 drawableType == #window ifTrue:[ |
3739 device destroyView:nil withId:id. |
3447 device destroyView:nil withId:id. |
3740 ] ifFalse:[ |
3448 ] ifFalse:[ |
3741 device destroyPixmap:id. |
3449 device destroyPixmap:id. |
3742 ]. |
3450 ]. |
3743 ]. |
3451 device unregisterGraphicsContext:self. |
3744 Lobby unregister:self. |
3452 ]. |
3745 ! |
3453 ! |
3746 |
3454 |
3747 destroyGC |
3455 destroyGC |
3748 |id| |
3456 |id| |
3749 |
3457 |
3750 id := gcId. |
3458 id := gcId. |
3751 id notNil ifTrue:[ |
3459 id notNil ifTrue:[ |
3752 gcId := nil. |
3460 gcId := nil. |
3753 device destroyGC:id. |
3461 device destroyGC:id. |
3754 ]. |
3462 ]. |
3755 ! |
3463 ! |
3756 |
3464 |
3757 initGC |
3465 initGC |
3758 "since we do not need a gc-object for the drawable until something is |
3466 "since we do not need a gc-object for the drawable until something is |
3759 really drawn, none is created. |
3467 really drawn, none is created. |
3760 This method is sent, when the first drawing happens" |
3468 This method is sent, when the first drawing happens" |
3761 |
3469 |
3762 |fgId bgId p fontId| |
3470 |fgId bgId p fontId| |
3763 |
3471 |
3764 gcId notNil ifTrue:[^ self]. |
3472 gcId notNil ifTrue:[ |
|
3473 "already initialized" |
|
3474 ^ self |
|
3475 ]. |
3765 drawableId isNil ifTrue:[ |
3476 drawableId isNil ifTrue:[ |
3766 "/ |
3477 "/ |
3767 "/ the drawable has been closed (or was never open) |
3478 "/ the drawable has been closed (or was never open) |
3768 "/ no drawing is possible. |
3479 "/ no drawing is possible. |
3769 "/ |
3480 "/ |
3927 !DeviceGraphicsContext methodsFor:'private'! |
3636 !DeviceGraphicsContext methodsFor:'private'! |
3928 |
3637 |
3929 setDevice:aDevice id:aDrawbleId gcId:aGCId |
3638 setDevice:aDevice id:aDrawbleId gcId:aGCId |
3930 "private" |
3639 "private" |
3931 |
3640 |
3932 device := aDevice. |
3641 self device:aDevice. |
|
3642 drawableId := aDrawbleId. |
3933 gcId := aGCId. |
3643 gcId := aGCId. |
3934 drawableId := aDrawbleId |
3644 (aDrawbleId notNil and:[aDevice notNil]) ifTrue:[ |
|
3645 aDevice registerGraphicsContext:self. |
|
3646 ]. |
3935 ! |
3647 ! |
3936 |
3648 |
3937 setGCForPaint |
3649 setGCForPaint |
3938 "private; given a complex color (i.e. a pixmap or dithered color, |
3650 "private; given a complex color (i.e. a pixmap or dithered color, |
3939 setup the GC to draw in this color. |
3651 setup the GC to draw in this color. |
3940 A helper for paint and paint:on:" |
3652 A helper for paint and paint:on:" |
3941 |
3653 |
3942 |dither map pixelId p fg bg vOrg ditherDepth deviceDepth| |
3654 |dither map pixelId p fg bg vOrg ditherDepth deviceDepth| |
3943 |
3655 |
3944 gcId notNil ifTrue:[ |
3656 gcId notNil ifTrue:[ |
3945 paint isSymbol ifTrue:[ |
3657 paint isSymbol ifTrue:[ |
3946 "map symbols to colors" |
3658 "map symbols to colors" |
3947 paint := Color perform:paint ifNotUnderstood:[Color yellow]. |
3659 paint := Color perform:paint ifNotUnderstood:[Color yellow]. |
3948 ]. |
3660 ]. |
3949 p := paint. |
3661 p := paint. |
3950 |
3662 |
3951 p isColor ifTrue:[ |
3663 p isColor ifTrue:[ |
3952 paint := p := p onDevice:device. |
3664 paint := p := p onDevice:device. |
3953 pixelId := p colorId. |
3665 pixelId := p colorId. |
3954 pixelId notNil ifTrue:[ |
3666 pixelId notNil ifTrue:[ |
3955 " |
3667 " |
3956 a real (undithered) color |
3668 a real (undithered) color |
3957 " |
3669 " |
3958 mask notNil ifTrue:[ |
3670 mask notNil ifTrue:[ |
3959 mask := nil. |
3671 mask := nil. |
3960 device setBitmapMask:nil in:gcId |
3672 device setBitmapMask:nil in:gcId |
3961 ]. |
3673 ]. |
3962 (p ~~ foreground) ifTrue:[ |
3674 (p ~~ foreground) ifTrue:[ |
3963 foreground := paint. |
3675 foreground := paint. |
3964 device setForeground:pixelId in:gcId |
3676 device setForeground:pixelId in:gcId |
3965 ]. |
3677 ]. |
3966 ^ self |
3678 ^ self |
3967 ]. |
3679 ]. |
3968 "a dithered color" |
3680 "a dithered color" |
3969 dither := paint ditherForm. |
3681 dither := paint ditherForm. |
3970 ] ifFalse:[ |
3682 ] ifFalse:[ |
3971 "mhmh - seems to be some kind of form ..." |
3683 "mhmh - seems to be some kind of form ..." |
3972 paint := paint onDevice:device. |
3684 paint := paint onDevice:device. |
3973 dither := paint. |
3685 dither := paint. |
3974 ]. |
3686 ]. |
3975 " |
3687 " |
3976 a dithered color or image |
3688 a dithered color or image |
3977 " |
3689 " |
3978 (ditherDepth := dither depth) == 1 ifTrue:[ |
3690 (ditherDepth := dither depth) == 1 ifTrue:[ |
3979 "a simple 0/1 bitmap" |
3691 "a simple 0/1 bitmap" |
3980 map := dither colorMap. |
3692 map := dither colorMap. |
3981 "temporary (kludgy) fix for destroyed paint" |
3693 "temporary (kludgy) fix for destroyed paint" |
3982 p := paint. |
3694 p := paint. |
3983 map isNil ifTrue:[ |
3695 map isNil ifTrue:[ |
3984 fg := Color black. |
3696 fg := self blackColor. |
3985 bg := Color white. |
3697 bg := self whiteColor. |
3986 ] ifFalse:[ |
3698 ] ifFalse:[ |
3987 fg := map at:2. |
3699 fg := map at:2. |
3988 bg := map at:1. |
3700 bg := map at:1. |
3989 ]. |
3701 ]. |
3990 self foreground:fg background:bg. |
3702 self foreground:fg background:bg. |
3991 paint := p |
3703 paint := p |
3992 ] ifFalse:[ |
3704 ] ifFalse:[ |
3993 deviceDepth := device depth. |
3705 deviceDepth := device depth. |
3994 (ditherDepth ~~ deviceDepth) ifTrue:[ |
3706 (ditherDepth ~~ deviceDepth) ifTrue:[ |
3995 dither := dither asFormOn:device. |
3707 dither := dither asFormOn:device. |
3996 ditherDepth := dither depth. |
3708 ditherDepth := dither depth. |
3997 (dither isNil or:[ditherDepth ~~ deviceDepth]) ifTrue:[ |
3709 (dither isNil or:[ditherDepth ~~ deviceDepth]) ifTrue:[ |
3998 self error:'bad dither'. |
3710 self error:'bad dither'. |
3999 ^ self |
3711 ^ self |
4000 ] |
3712 ] |
4001 ] |
3713 ] |
4002 ]. |
3714 ]. |
4003 self mask:dither. |
3715 self mask:dither. |
4004 vOrg := self viewOrigin. |
3716 vOrg := self viewOrigin. |
4005 self maskOriginX:vOrg x negated y:vOrg y negated. |
3717 self maskOriginX:vOrg x negated y:vOrg y negated. |
4006 ] |
3718 ] |
4007 |
3719 |
4008 "Created: 16.5.1996 / 15:35:51 / cg" |
3720 "Created: 16.5.1996 / 15:35:51 / cg" |
4009 "Modified: 6.6.1997 / 12:55:38 / cg" |
3721 "Modified: 6.6.1997 / 12:55:38 / cg" |
4010 ! |
3722 ! |
4011 |
3723 |
4012 setId:aDrawbleId |
3724 setId:aDrawableId |
4013 "private" |
3725 "private" |
4014 |
3726 |
4015 drawableId := aDrawbleId |
3727 drawableId := aDrawableId |
4016 |
3728 |
4017 "Created: / 6.2.1998 / 12:44:45 / cg" |
3729 "Created: / 6.2.1998 / 12:44:45 / cg" |
4018 ! |
3730 ! |
4019 |
3731 |
4020 subViewChangedSizeOrOrigin |
3732 subViewChangedSizeOrOrigin |
4094 "return the number of pixels (not rounded) for millis millimeter" |
3806 "return the number of pixels (not rounded) for millis millimeter" |
4095 |
3807 |
4096 ^ device verticalPixelPerMillimeter * millis |
3808 ^ device verticalPixelPerMillimeter * millis |
4097 ! ! |
3809 ! ! |
4098 |
3810 |
|
3811 !DeviceGraphicsContext methodsFor:'testing'! |
|
3812 |
|
3813 isPixmap |
|
3814 ^ drawableType == #pixmap |
|
3815 ! |
|
3816 |
|
3817 isWindow |
|
3818 ^ drawableType == #window |
|
3819 ! ! |
|
3820 |
4099 !DeviceGraphicsContext methodsFor:'view creation'! |
3821 !DeviceGraphicsContext methodsFor:'view creation'! |
4100 |
3822 |
4101 createBitmapFromArray:data width:width height:height |
3823 createBitmapFromArray:data width:width height:height |
4102 "create a bitmap from data and set the drawableId" |
3824 "create a bitmap from data and set the drawableId" |
4103 |
3825 |
|
3826 drawableType := #pixmap. |
4104 drawableId := device createBitmapFromArray:data width:width height:height. |
3827 drawableId := device createBitmapFromArray:data width:width height:height. |
4105 drawableType := #pixmap. |
3828 device registerGraphicsContext:self. "this is a registerChange:" |
4106 Lobby registerChange:self. |
|
4107 ! |
3829 ! |
4108 |
3830 |
4109 createPixmapWidth:w height:h depth:d |
3831 createPixmapWidth:w height:h depth:d |
4110 "create a pixmap and set the drawableId" |
3832 "create a pixmap and set the drawableId" |
4111 |
3833 |
4281 finalize |
4003 finalize |
4282 "the view for which I am a handle was collected |
4004 "the view for which I am a handle was collected |
4283 - release system resources" |
4005 - release system resources" |
4284 |
4006 |
4285 drawableId notNil ifTrue:[ |
4007 drawableId notNil ifTrue:[ |
4286 [ |
4008 [ |
4287 (device viewIdKnown:drawableId) ifTrue:[ |
4009 (device viewIdKnown:drawableId) ifTrue:[ |
4288 "/ 'Display [info]: recycled view (' infoPrint. v infoPrint. ') not destroyed: ' infoPrint. |
4010 "/ 'Display [info]: recycled view (' infoPrint. v infoPrint. ') not destroyed: ' infoPrint. |
4289 "/ drawableId displayString infoPrintCR. |
4011 "/ drawableId displayString infoPrintCR. |
4290 drawableId := nil. |
4012 drawableId := nil. |
4291 ] ifFalse:[ |
4013 ] ifFalse:[ |
4292 |id| |
4014 |id| |
4293 |
4015 |
4294 (id := gcId) notNil ifTrue:[ |
4016 (id := gcId) notNil ifTrue:[ |
4295 gcId := nil. |
4017 gcId := nil. |
4296 device deviceIOErrorSignal handle:[:ex | |
4018 device deviceIOErrorSignal handle:[:ex | |
4297 ] do:[ |
4019 ] do:[ |
4298 device destroyGC:id. |
4020 device destroyGC:id. |
4299 ] |
4021 ] |
4300 ]. |
4022 ]. |
4301 |
4023 |
4302 id := drawableId. |
4024 id := drawableId. |
4303 drawableId := nil. |
4025 drawableId := nil. |
4304 device deviceIOErrorSignal handle:[:ex | |
4026 device deviceIOErrorSignal handle:[:ex | |
4305 ] do:[ |
4027 ] do:[ |
4306 device destroyView:nil withId:id. |
4028 device destroyView:nil withId:id. |
4307 ]. |
4029 ]. |
4308 |
4030 |
4309 "When a window ist destroyed, all its subwindows are also destroyed. |
4031 "When a window ist destroyed, all its subwindows are also destroyed. |
4310 Unregister all the subwindows, to avoid destroying of reused windoeIds |
4032 Unregister all the subwindows, to avoid destroying of reused windowIds |
4311 later." |
4033 later." |
4312 DeviceGraphicsContext cleanupLobbyForChildrenOfViewWithDevice:device id:id. |
4034 device cleanupLobbyForChildrenOfViewWithId:id. |
4313 ] |
4035 ] |
4314 ] valueUninterruptably. |
4036 ] valueUninterruptably. |
4315 ]. |
4037 ]. |
4316 |
4038 |
4317 "Created: / 25.9.1997 / 10:01:46 / stefan" |
4039 "Created: / 25.9.1997 / 10:01:46 / stefan" |
4318 "Modified: / 15.11.2001 / 14:17:12 / cg" |
4040 "Modified: / 15.11.2001 / 14:17:12 / cg" |
4319 ! ! |
4041 ! ! |