2124 pX := x rounded. |
2124 pX := x rounded. |
2125 pY := y rounded. |
2125 pY := y rounded. |
2126 |
2126 |
2127 deviceForm := aForm asFormOn:device. |
2127 deviceForm := aForm asFormOn:device. |
2128 deviceForm isNil ifTrue:[ |
2128 deviceForm isNil ifTrue:[ |
2129 'DeviceGraphicsContext [warning]: cannot create device-form' errorPrintCR. |
2129 'DeviceGraphicsContext [warning]: cannot create device-form' errorPrintCR. |
2130 ^self |
2130 ^self |
2131 ]. |
2131 ]. |
2132 id := deviceForm id. |
2132 id := deviceForm id. |
2133 |
2133 |
2134 id isNil ifTrue:[ |
2134 id isNil ifTrue:[ |
2135 'DeviceGraphicsContext [warning]: invalid form draw - ignored' errorPrintCR. |
2135 'DeviceGraphicsContext [warning]: invalid form draw - ignored' errorPrintCR. |
2136 ^ self |
2136 ^ self |
2137 ]. |
2137 ]. |
2138 gcId isNil ifTrue:[ |
2138 gcId isNil ifTrue:[ |
2139 self initGC |
2139 self initGC |
2140 ]. |
2140 ]. |
2141 (deviceFormGCId := deviceForm gcId) isNil ifTrue:[ |
2141 (deviceFormGCId := deviceForm gcId) isNil ifTrue:[ |
2142 "/ device needGCForBitmapSource - i.e. WIN32 |
2142 "/ device needGCForBitmapSource - i.e. WIN32 |
2143 device platformName ~= 'X11' ifTrue:[ |
2143 device platformName ~= 'X11' ifTrue:[ |
2144 deviceForm initGC. |
2144 deviceForm initGC. |
2145 deviceFormGCId := deviceForm gcId. |
2145 deviceFormGCId := deviceForm gcId. |
2146 ] |
2146 ] |
2147 ]. |
2147 ]. |
2148 |
2148 |
2149 " |
2149 " |
2150 a deep form ignores paint/bgPaint settings |
2150 a deep form ignores paint/bgPaint settings |
2151 " |
2151 " |
2152 mask := aForm mask. |
2152 mask := aForm mask. |
2153 |
2153 |
2154 ((aForm depth ~~ 1) |
2154 ((aForm depth ~~ 1) or:[mask notNil]) ifTrue:[ |
2155 or:[mask notNil]) ifTrue:[ |
2155 mask notNil ifTrue:[ |
2156 mask notNil ifTrue:[ |
2156 mask depth ~~ 1 ifTrue:[ |
2157 mask depth == 1 ifFalse:[ |
2157 'DEVGC: alpha channel not yet supported' errorPrintCR. |
2158 'DEVGC: alpha channel not yet supported' errorPrintCR. |
2158 ] ifFalse:[ |
2159 ] ifTrue:[ |
2159 deviceMask := mask asFormOn:device. |
2160 deviceMask := mask asFormOn:device. |
2160 deviceMask isNil ifTrue:[ |
2161 deviceMask isNil ifTrue:[ |
2161 'DeviceGraphicsContext [warning]: cannot create device-mask' errorPrintCR. |
2162 'DeviceGraphicsContext [warning]: cannot create device-mask' errorPrintCR. |
2162 ^self |
2163 ^self |
2163 ]. |
2164 ]. |
2164 maskId := deviceMask id. |
2165 maskId := deviceMask id. |
2165 maskId notNil ifTrue:[ |
2166 maskId notNil ifTrue:[ |
2166 deviceMask gcId isNil ifTrue:[deviceMask initGC]. |
2167 deviceMask gcId isNil ifTrue:[deviceMask initGC]. |
2167 allColor := Color allColor. |
2168 allColor := Color allColor. |
2168 allBits := allColor colorId. |
2169 allBits := allColor colorId. |
2169 |
2170 |
2170 (deviceForm depth == device depth |
2171 (deviceForm depth == device depth |
2171 and:[aForm maskedPixelsAre0]) ifTrue:[ |
2172 and:[aForm maskedPixelsAre0]) ifTrue:[ |
2172 "/ can do it without a temporary pixmap: |
2173 "/ can do it without a temporary pixmap: |
2173 "/ or-in the form into the inverse stamped-out area |
2174 "/ or-in the form into the inverse stamped-out area |
2174 "/ of the destination. |
2175 "/ of the destination. |
2175 "/ Oring is of course only possible if we know that |
2176 "/ Oring is of course only possible if we know that |
2176 "/ masked pixels are already zero in the form. |
2177 "/ masked pixels are already zero in the form. |
2177 |
2178 |
2178 "/ stamp out using mask |
2179 "/ stamp out using mask |
2179 device setForeground:0 background:allBits in:gcId. |
2180 device setForeground:0 background:allBits in:gcId. |
2180 device setFunction:#and in:gcId. |
2181 device setFunction:#and in:gcId. |
2181 device |
2182 device |
2182 copyPlaneFromPixmapId:maskId |
2183 copyPlaneFromPixmapId:maskId |
2183 x:0 |
2184 x:0 |
2184 y:0 |
2185 y:0 |
2185 gc:(deviceMask gcId) |
2186 gc:(deviceMask gcId) |
2186 to:drawableId |
2187 to:drawableId |
2187 x:pX |
2188 x:pX |
2188 y:pY |
2189 y:pY |
2189 gc:gcId |
2190 gc:gcId |
2190 width:w |
2191 width:w |
2191 height:h. |
2192 height:h. |
2192 "/ or-in the form |
2193 "/ or-in the form |
2193 device setFunction:#or in:gcId. |
2194 device setFunction:#or in:gcId. |
2194 device |
2195 device |
2195 copyFromPixmapId:id |
2196 copyFromPixmapId:id |
2196 x:0 |
2197 x:0 |
2197 y:0 |
2198 y:0 |
2198 gc:deviceFormGCId |
2199 gc:deviceFormGCId |
2199 to:drawableId |
2200 to:drawableId |
2200 x:pX |
2201 x:pX |
2201 y:pY |
2202 y:pY |
2202 gc:gcId |
2203 gc:gcId |
2203 width:w |
2204 width:w |
2204 height:h. |
2205 height:h. |
2205 ] ifFalse:[ |
2206 ] ifFalse:[ |
2206 "/ must do it slow, using a temporary form .. |
2207 "/ must do it slow, using a temporary form .. |
2207 |
2208 |
2208 " |
2209 " |
2209 create temp-form; |
2210 create temp-form; |
2210 " |
2211 " |
2211 tmpForm := Form width:w height:h depth:device depth onDevice:device. |
2212 tmpForm := Form width:w height:h depth:device depth onDevice:device. |
2212 tmpForm isNil ifTrue:[ |
2213 tmpForm isNil ifTrue:[ |
2213 'DeviceGraphicsContext [warning]: cannot create temp form' errorPrintCR. |
2214 'DeviceGraphicsContext [warning]: cannot create temp form' errorPrintCR. |
2214 ^self |
2215 ^self |
2215 ]. |
2216 ]. |
2216 tmpForm initGC. |
2217 tmpForm initGC. |
2217 tmpId := tmpForm id. |
2218 tmpId := tmpForm id. |
2218 tmpGCId := tmpForm gcId. |
2219 tmpGCId := tmpForm gcId. |
2219 |
2220 |
2220 " |
2221 " |
2221 fill tempform with image |
2222 fill tempform with image |
2222 " |
2223 " |
2223 aForm depth == 1 ifTrue:[ |
2224 aForm depth == 1 ifTrue:[ |
2224 (colorMap := deviceForm colorMap) notNil ifTrue:[ |
2225 (colorMap := aForm colorMap) notNil ifTrue:[ |
2225 colorMap size < 2 ifTrue:[ |
2226 colorMap size < 2 ifTrue:[ |
2226 device |
2227 device |
2227 setForegroundColor:(colorMap at:1) |
2228 setForegroundColor:(colorMap at:1) |
2228 in:tmpGCId. |
2229 in:tmpGCId. |
2229 ] ifFalse:[ |
2230 ] ifFalse:[ |
2230 device |
2231 device |
2231 setForegroundColor:(colorMap at:2) |
2232 setForegroundColor:(colorMap at:2) |
2232 backgroundColor:(colorMap at:1) |
2233 backgroundColor:(colorMap at:1) |
2233 in:tmpGCId. |
2234 in:tmpGCId. |
2234 ] |
2235 ] |
2235 ]. |
2236 ]. |
2236 device |
2237 device |
2237 copyPlaneFromPixmapId:id |
2238 copyPlaneFromPixmapId:id |
2238 x:0 |
2239 x:0 |
2239 y:0 |
2240 y:0 |
2240 gc:deviceFormGCId |
2241 gc:deviceFormGCId |
2241 to:tmpId |
2242 to:tmpId |
2242 x:0 |
2243 x:0 |
2243 y:0 |
2244 y:0 |
2244 gc:tmpGCId |
2245 gc:tmpGCId |
2245 width:w |
2246 width:w |
2246 height:h. |
2247 height:h. |
2247 ] ifFalse:[ |
2248 ] ifFalse:[ |
2248 device |
2249 device |
2249 copyFromPixmapId:id |
2250 copyFromPixmapId:id |
2250 x:0 |
2251 x:0 |
2251 y:0 |
2252 y:0 |
2252 gc:deviceFormGCId |
2253 gc:deviceFormGCId |
2253 to:tmpId |
2254 to:tmpId |
2254 x:0 |
2255 x:0 |
2255 y:0 |
2256 y:0 |
2256 gc:tmpGCId |
2257 gc:tmpGCId |
2257 width:w |
2258 width:w |
2258 height:h. |
2259 height:h. |
2259 ]. |
2260 ]. |
2260 |
2261 |
2261 " |
2262 " |
2262 stamp out mask in temp form |
2263 stamp out mask in temp form |
2263 " |
2264 " |
2264 device |
2265 device setForeground:allBits background:0 in:tmpGCId. |
2265 setForeground:allBits background:0 in:tmpGCId; |
2266 device setFunction:#and in:tmpGCId. |
2266 setFunction:#and in:tmpGCId; |
2267 device |
2267 copyPlaneFromPixmapId:maskId |
2268 copyPlaneFromPixmapId:maskId |
2268 x:0 |
2269 x:0 |
2269 y:0 |
2270 y:0 |
2270 gc:(deviceMask gcId) |
2271 gc:(deviceMask gcId) |
2271 to:tmpId |
2272 to:tmpId |
2272 x:0 |
2273 x:0 |
2273 y:0 |
2274 y:0 |
2274 gc:tmpGCId |
2275 gc:tmpGCId |
2275 width:w |
2276 width:w |
2276 height:h. |
2277 height:h. |
2277 |
2278 |
2278 " |
2279 " |
2279 stamp out mask in destination |
2280 stamp out mask in destination |
2280 " |
2281 " |
2281 device |
2282 device setForeground:0 background:allBits in:gcId. |
2282 setForeground:0 background:allBits in:gcId; |
2283 device setFunction:#and in:gcId. |
2283 setFunction:#and in:gcId; |
2284 device |
2284 copyPlaneFromPixmapId:maskId |
2285 copyPlaneFromPixmapId:maskId |
2285 x:0 |
2286 x:0 |
2286 y:0 |
2287 y:0 |
2287 gc:(deviceMask gcId) |
2288 gc:(deviceMask gcId) |
2288 to:drawableId |
2289 to:drawableId |
2289 x:pX |
2290 x:pX |
2290 y:pY |
2291 y:pY |
2291 gc:gcId |
2292 gc:gcId |
2292 width:w |
2293 width:w |
2293 height:h. |
2294 height:h. |
2294 |
2295 |
2295 " |
2296 " |
2296 or-in tempform-bits ... |
2297 or-in tempform-bits ... |
2297 " |
2298 " |
2298 device |
2299 device setFunction:#or in:gcId. |
2299 setFunction:#or in:gcId; |
2300 device |
2300 copyFromPixmapId:tmpId |
2301 copyFromPixmapId:tmpId |
2301 x:0 |
2302 x:0 |
2302 y:0 |
2303 y:0 |
2303 gc:tmpGCId |
2304 gc:tmpGCId |
2304 to:drawableId |
2305 to:drawableId |
2305 x:pX |
2306 x:pX |
2306 y:pY |
2307 y:pY |
2307 gc:gcId |
2308 gc:gcId |
2308 width:w |
2309 width:w |
2309 height:h. |
2310 height:h. |
2310 |
2311 |
2311 " |
2312 " |
2312 release tempForm immediately |
2313 release tempForm immediately |
2313 (although GC will eventually do it, |
2314 (although GC will eventually do it, |
2314 this creates less stress to the Xserver in the meanwhile ...) |
2315 this creates less stress to the Xserver in the meanwhile ...) |
2315 " |
2316 " |
2316 tmpForm destroy. |
2317 tmpForm destroy. |
2317 ]. |
2318 ]. |
2318 |
2319 |
2319 "/ restore GC |
2320 "/ restore GC |
2320 foreground notNil ifTrue:[ |
2321 foreground notNil ifTrue:[ |
2321 device setForegroundColor:foreground in:gcId. |
2322 device setForegroundColor:foreground in:gcId. |
2322 ]. |
2323 ]. |
2323 background notNil ifTrue:[ |
2324 background notNil ifTrue:[ |
2324 device setBackgroundColor:background in:gcId |
2325 device setBackgroundColor:background in:gcId |
2325 ]. |
2326 ]. |
2326 device setFunction:function in:gcId. |
2327 device setFunction:function in:gcId. |
2327 ^ self |
2328 ^ self |
2328 ] |
2329 ] |
2329 ] |
2330 ] |
2330 ]. |
2331 ]. |
2331 |
2332 |
2332 device |
2333 device |
2333 copyFromPixmapId:id |
2334 copyFromPixmapId:id |
2334 x:0 |
2335 x:0 |
2335 y:0 |
2336 y:0 |
2336 gc:deviceForm gcId |
2337 gc:deviceForm gcId |
2337 to:drawableId |
2338 to:drawableId |
2338 x:pX |
2339 x:pX |
2339 y:pY |
2340 y:pY |
2340 gc:gcId |
2341 gc:gcId |
2341 width:w |
2342 width:w |
2342 height:h. |
2343 height:h. |
2343 ^ self |
2344 ^ self |
|
2345 ]. |
2344 ]. |
2346 |
2345 |
2347 " |
2346 " |
2348 the following code is somewhat complicated, since it has to deal |
2347 the following code is somewhat complicated, since it has to deal |
2349 with dithered paint colors, which cannot be done directly on most |
2348 with dithered paint colors, which cannot be done directly on most |
2355 |
2354 |
2356 " |
2355 " |
2357 if paint is not a real color, we have to do it the hard way ... |
2356 if paint is not a real color, we have to do it the hard way ... |
2358 " |
2357 " |
2359 easy ifTrue:[ |
2358 easy ifTrue:[ |
2360 paint isColor ifFalse:[ |
2359 paint isColor ifTrue:[ |
2361 paintDither := paint. |
2360 paintDither := paint ditherForm. |
2362 easy := false |
2361 paintDither notNil ifTrue:[ |
2363 ] ifTrue:[ |
2362 easy := false. |
2364 paintDither := paint ditherForm. |
2363 ] |
2365 paintDither notNil ifTrue:[ |
2364 ] ifFalse:[ |
2366 easy := false. |
2365 paintDither := paint. |
2367 ] |
2366 easy := false |
2368 ]. |
2367 ]. |
2369 ]. |
2368 ]. |
2370 |
2369 |
2371 allColor := Color allColor. |
2370 allColor := Color allColor. |
2372 allBits := allColor colorId. |
2371 allBits := allColor colorId. |
2373 |
2372 |
2374 easy ifTrue:[ |
2373 easy ifTrue:[ |
2375 " |
2374 " |
2376 paint is a real color |
2375 paint is a real color |
2377 " |
2376 " |
2378 |
2377 |
2379 " |
2378 " |
2380 if paint color is all-0 or all-1's, we can do it in one |
2379 if paint color is all-0 or all-1's, we can do it in one |
2381 operation ... |
2380 operation ... |
2382 " |
2381 " |
2383 fgId := paint colorId. |
2382 fgId := paint colorId. |
2384 |
2383 |
2385 ((fgId ~~ ((1 bitShift:device depth)-1)) |
2384 ((fgId ~~ ((1 bitShift:device depth)-1)) |
2386 and:[fgId ~~ allBits]) ifTrue:[ |
2385 and:[fgId ~~ allBits]) ifTrue:[ |
2387 " |
2386 " |
2388 clear fg-bits ... |
2387 clear fg-bits ... |
2389 " |
2388 " |
2390 device setForeground:0 background:allBits in:gcId. |
2389 device setForeground:0 background:allBits in:gcId. |
2391 device setFunction:#and in:gcId. |
2390 device setFunction:#and in:gcId. |
2392 device |
2391 device |
2393 copyPlaneFromPixmapId:id |
2392 copyPlaneFromPixmapId:id |
2394 x:0 |
2393 x:0 |
2395 y:0 |
2394 y:0 |
2396 gc:deviceFormGCId |
2395 gc:deviceFormGCId |
2397 to:drawableId |
2396 to:drawableId |
2398 x:pX |
2397 x:pX |
2399 y:pY |
2398 y:pY |
2400 gc:gcId |
2399 gc:gcId |
2401 width:w |
2400 width:w |
2402 height:h. |
2401 height:h. |
2403 ]. |
2402 ]. |
2404 |
2403 |
2405 fgId ~~ 0 ifTrue:[ |
2404 fgId ~~ 0 ifTrue:[ |
2406 " |
2405 " |
2407 or-in fg-bits ... |
2406 or-in fg-bits ... |
2408 " |
2407 " |
2409 device setForeground:fgId background:0 in:gcId. |
2408 device setForeground:fgId background:0 in:gcId. |
2410 device setFunction:#or in:gcId. |
2409 device setFunction:#or in:gcId. |
2411 device |
2410 device |
2412 copyPlaneFromPixmapId:id |
2411 copyPlaneFromPixmapId:id |
2413 x:0 |
2412 x:0 |
2414 y:0 |
2413 y:0 |
2415 gc:deviceFormGCId |
2414 gc:deviceFormGCId |
2416 to:drawableId |
2415 to:drawableId |
2417 x:pX |
2416 x:pX |
2418 y:pY |
2417 y:pY |
2419 gc:gcId |
2418 gc:gcId |
2420 width:w |
2419 width:w |
2421 height:h |
2420 height:h |
2422 ]. |
2421 ]. |
2423 " |
2422 " |
2424 flush foreground/background cache |
2423 flush foreground/background cache |
2425 " |
2424 " |
2426 foreground := nil. |
2425 foreground := nil. |
2427 background := nil. |
2426 background := nil. |
2428 device setFunction:function in:gcId. |
2427 device setFunction:function in:gcId. |
2429 ^ self |
2428 ^ self |
2430 ]. |
2429 ]. |
2431 |
2430 |
2432 function == #or ifTrue:[ |
2431 function == #or ifTrue:[ |
2433 easy := paint notNil |
2432 easy := paint notNil |
2434 and:[paint isColor |
2433 and:[paint isColor |
2435 and:[paint ditherForm isNil]]. |
2434 and:[paint ditherForm isNil]]. |
2436 easy ifTrue:[ |
2435 easy ifTrue:[ |
2437 easy := bgPaint isNil |
2436 easy := bgPaint isNil |
2438 or:[bgPaint isColor |
2437 or:[bgPaint isColor |
2439 and:[bgPaint colorId == 0]] |
2438 and:[bgPaint colorId == 0]] |
2440 ]. |
2439 ]. |
2441 easy ifTrue:[ |
2440 easy ifTrue:[ |
2442 fgId := paint colorId. |
2441 fgId := paint colorId. |
2443 |
2442 |
2444 fgId ~~ 0 ifTrue:[ |
2443 fgId ~~ 0 ifTrue:[ |
2445 " |
2444 " |
2446 or-in fg-bits ... |
2445 or-in fg-bits ... |
2447 " |
2446 " |
2448 device setForeground:fgId background:0 in:gcId. |
2447 device setForeground:fgId background:0 in:gcId. |
2449 device |
2448 device |
2450 copyPlaneFromPixmapId:id |
2449 copyPlaneFromPixmapId:id |
2451 x:0 |
2450 x:0 |
2452 y:0 |
2451 y:0 |
2453 gc:deviceFormGCId |
2452 gc:deviceFormGCId |
2454 to:drawableId |
2453 to:drawableId |
2455 x:pX |
2454 x:pX |
2456 y:pY |
2455 y:pY |
2457 gc:gcId |
2456 gc:gcId |
2458 width:w |
2457 width:w |
2459 height:h |
2458 height:h |
2460 ]. |
2459 ]. |
2461 " |
2460 " |
2462 flush foreground/background cache |
2461 flush foreground/background cache |
2463 " |
2462 " |
2464 foreground := nil. |
2463 foreground := nil. |
2465 background := nil. |
2464 background := nil. |
2466 ^ self |
2465 ^ self |
2467 ]. |
2466 ]. |
2468 ]. |
2467 ]. |
2469 |
2468 |
2470 " |
2469 " |
2471 hard case; paint is a dithered color |
2470 hard case; paint is a dithered color |
2472 " |
2471 " |