161 Claus Gittinger |
161 Claus Gittinger |
162 " |
162 " |
163 ! ! |
163 ! ! |
164 |
164 |
165 !Color class methodsFor:'initialization'! |
165 !Color class methodsFor:'initialization'! |
166 |
|
167 allocateColorsIn:aColorVector on:aDevice |
|
168 "{ Pragma: +optSpace }" |
|
169 |
|
170 "preallocates a nR x nG x nB colorMap for later use in dithering. |
|
171 Doing so has the advantage that the system will never run out of colors, |
|
172 however, colors may be either inexact or dithered." |
|
173 |
|
174 |clr round devClr| |
|
175 |
|
176 round := 0. |
|
177 1 to:aColorVector size do:[:dstIndex | |
|
178 clr := aColorVector at:dstIndex. |
|
179 devClr := clr exactOn:aDevice. |
|
180 devClr isNil ifTrue:[ |
|
181 round == 0 ifTrue:[ |
|
182 Logger info:'scavenge to reclaim colors'. |
|
183 ObjectMemory scavenge. |
|
184 round := 1. |
|
185 devClr := clr exactOn:aDevice. |
|
186 ]. |
|
187 devClr isNil ifTrue:[ |
|
188 round == 1 ifTrue:[ |
|
189 Logger info:'collect garbage to reclaim colors'. |
|
190 ObjectMemory |
|
191 garbageCollect; finalize. |
|
192 round := 2. |
|
193 devClr := clr exactOn:aDevice. |
|
194 ]. |
|
195 devClr isNil ifTrue:[ |
|
196 round == 2 ifTrue:[ |
|
197 Logger info:'lowSpaceCleanup and collect garbage to reclaim colors'. |
|
198 ObjectMemory |
|
199 performLowSpaceCleanup; |
|
200 garbageCollect; finalize. |
|
201 round := 3. |
|
202 devClr := clr exactOn:aDevice. |
|
203 ]. |
|
204 devClr isNil ifTrue:[ |
|
205 ColorAllocationFailSignal raiseErrorString:'failed to allocate fix color'. |
|
206 ^ self |
|
207 ]. |
|
208 ]. |
|
209 ]. |
|
210 ]. |
|
211 aColorVector at:dstIndex put:devClr. |
|
212 ]. |
|
213 |
|
214 "Modified: / 02-03-2017 / 17:43:36 / stefan" |
|
215 ! |
|
216 |
|
217 colorCubeWithRed:nRed green:nGreen blue:nBlue |
|
218 "{ Pragma: +optSpace }" |
|
219 |
|
220 |nR "{Class: SmallInteger }" |
|
221 nG "{Class: SmallInteger }" |
|
222 nB "{Class: SmallInteger }" |
|
223 dR dG dB red green blue dstIndex clr round |
|
224 colorCube| |
|
225 |
|
226 nR := nRed. |
|
227 nG := nGreen. |
|
228 nB := nBlue. |
|
229 |
|
230 dR := 100.0 / (nR - 1). |
|
231 dG := 100.0 / (nG - 1). |
|
232 dB := 100.0 / (nB - 1). |
|
233 |
|
234 colorCube := Array new:(nR * nG * nB). |
|
235 |
|
236 round := 0. |
|
237 |
|
238 dstIndex := 1. |
|
239 1 to:nR do:[:sR | |
|
240 red := dR * (sR - 1). |
|
241 1 to:nG do:[:sG | |
|
242 green := dG * (sG - 1). |
|
243 1 to:nB do:[:sB | |
|
244 blue := dB * (sB - 1). |
|
245 clr := self red:red green:green blue:blue. |
|
246 colorCube at:dstIndex put:clr. |
|
247 dstIndex := dstIndex + 1 |
|
248 ] |
|
249 ] |
|
250 ]. |
|
251 ^ colorCube |
|
252 |
|
253 "Created: 11.7.1996 / 17:55:32 / cg" |
|
254 "Modified: 10.1.1997 / 15:37:13 / cg" |
|
255 ! |
|
256 |
|
257 flushDeviceColors |
|
258 "unassign all colors from their device" |
|
259 |
|
260 self allInstances do:[:aColor | |
|
261 aColor restored |
|
262 ]. |
|
263 |
|
264 "Modified: 24.2.1997 / 18:27:06 / cg" |
|
265 ! |
|
266 |
|
267 flushDeviceColorsFor:aDevice |
|
268 self allInstancesDo:[:aColor | |
|
269 aColor device == aDevice ifTrue:[ |
|
270 aColor restored |
|
271 ] |
|
272 ] |
|
273 ! |
|
274 |
|
275 getColors6x6x4 |
|
276 "{ Pragma: +optSpace }" |
|
277 |
|
278 "preallocates a 6x6x4 (144) colorMap and later uses those colors only. |
|
279 Doing so has the advantage that the system will never run out of colors, |
|
280 however, colors may be either inexact or dithered." |
|
281 |
|
282 self getColorsRed:6 green:6 blue:4 |
|
283 |
|
284 " |
|
285 Color getColors6x6x4 |
|
286 " |
|
287 ! |
|
288 |
|
289 getColors6x6x5 |
|
290 "{ Pragma: +optSpace }" |
|
291 |
|
292 "preallocates a 6x6x5 (180) colorMap and later uses those colors only. |
|
293 Doing so has the advantage that the system will never run out of colors, |
|
294 however, colors may be either inexact or dithered." |
|
295 |
|
296 self getColorsRed:6 green:6 blue:5 |
|
297 |
|
298 " |
|
299 Color getColors6x6x5 |
|
300 " |
|
301 ! |
|
302 |
|
303 getColors6x6x6 |
|
304 "{ Pragma: +optSpace }" |
|
305 |
|
306 "preallocates a 6x6x6 (196) colorMap and later uses those colors only. |
|
307 Doing so has the advantage that the system will never run out of colors, |
|
308 however, colors may be either inexact or dithered." |
|
309 |
|
310 self getColorsRed:6 green:6 blue:6 |
|
311 |
|
312 " |
|
313 Color getColors6x6x6 |
|
314 " |
|
315 ! |
|
316 |
|
317 getColors6x7x4 |
|
318 "{ Pragma: +optSpace }" |
|
319 |
|
320 "preallocates a 6x7x4 (168) colorMap and later uses those colors only. |
|
321 Doing so has the advantage that the system will never run out of colors, |
|
322 however, colors may be either inexact or dithered." |
|
323 |
|
324 self getColorsRed:6 green:7 blue:4 |
|
325 |
|
326 " |
|
327 Color getColors6x7x4 |
|
328 " |
|
329 |
|
330 "Created: 12.6.1996 / 17:41:57 / cg" |
|
331 ! |
|
332 |
|
333 getColors7x8x4 |
|
334 "{ Pragma: +optSpace }" |
|
335 |
|
336 "preallocates a 7x8x4 (224) colorMap and later uses those colors only. |
|
337 Doing so has the advantage that the system will never run out of colors, |
|
338 however, colors may be either inexact or dithered." |
|
339 |
|
340 self getColorsRed:7 green:8 blue:4 |
|
341 |
|
342 " |
|
343 Color getColors7x8x4 |
|
344 " |
|
345 ! |
|
346 |
|
347 getColorsRed:nRed green:nGreen blue:nBlue |
|
348 "{ Pragma: +optSpace }" |
|
349 |
|
350 "preallocates a nR x nG x nB colorMap for later use in dithering. |
|
351 Doing so has the advantage that the system will never run out of colors, |
|
352 however, colors may be either inexact or dithered." |
|
353 |
|
354 self getColorsRed:nRed green:nGreen blue:nBlue on:Screen current |
|
355 |
|
356 " |
|
357 Color getColorsRed:2 green:2 blue:2 |
|
358 " |
|
359 |
|
360 "Modified: 11.7.1996 / 17:58:09 / cg" |
|
361 ! |
|
362 |
|
363 getColorsRed:nRed green:nGreen blue:nBlue on:aDevice |
|
364 "{ Pragma: +optSpace }" |
|
365 |
|
366 "preallocates a nR x nG x nB colorMap for later use in dithering. |
|
367 Doing so has the advantage that the system will never run out of colors, |
|
368 however, colors may be either inexact or dithered." |
|
369 |
|
370 |nR "{Class: SmallInteger }" |
|
371 nG "{Class: SmallInteger }" |
|
372 nB "{Class: SmallInteger }" |
|
373 dR dG dB fixColors| |
|
374 |
|
375 aDevice visualType == #TrueColor ifTrue:[^ self]. |
|
376 |
|
377 nR := nRed. |
|
378 nG := nGreen. |
|
379 nB := nBlue. |
|
380 |
|
381 dR := 100.0 / (nR - 1). |
|
382 dG := 100.0 / (nG - 1). |
|
383 dB := 100.0 / (nB - 1). |
|
384 |
|
385 fixColors := self colorCubeWithRed:nRed green:nGreen blue:nBlue. |
|
386 self allocateColorsIn:fixColors on:aDevice. |
|
387 |
|
388 aDevice setFixColors:fixColors numRed:nR numGreen:nG numBlue:nB |
|
389 |
|
390 " |
|
391 Color getColorsRed:2 green:2 blue:2 on:Display |
|
392 " |
|
393 |
|
394 "Created: 11.7.1996 / 17:55:32 / cg" |
|
395 "Modified: 10.1.1997 / 15:37:13 / cg" |
|
396 ! |
|
397 |
|
398 getGrayColors:nGray on:aDevice |
|
399 "{ Pragma: +optSpace }" |
|
400 |
|
401 "preallocates nGray gray colors for later use in dithering. |
|
402 Doing so has the advantage that the system will never run out of colors, |
|
403 however, colors may be either inexact or dithered." |
|
404 |
|
405 |nG "{Class: SmallInteger }" |
|
406 d fixGrayColors| |
|
407 |
|
408 aDevice visualType == #TrueColor ifTrue:[^ self]. |
|
409 |
|
410 nG := nGray. |
|
411 d := 100.0 / (nG - 1). |
|
412 |
|
413 fixGrayColors := self grayColorVector:nGray. |
|
414 self allocateColorsIn:fixGrayColors on:aDevice. |
|
415 |
|
416 aDevice setFixGrayColors:fixGrayColors |
|
417 |
|
418 " |
|
419 Color getGrayColors:16 on:Display |
|
420 " |
|
421 |
|
422 "Created: 23.6.1997 / 15:29:50 / cg" |
|
423 ! |
|
424 |
|
425 getPrimaryColorsOn:aDevice |
|
426 "{ Pragma: +optSpace }" |
|
427 |
|
428 "preallocate the primary colors. |
|
429 Doing so during early startup prevents us from running out |
|
430 of (at least those required) colors later. |
|
431 This guarantees, that at least some colors are available |
|
432 for dithering (although, with only black, white, red, green and blue, |
|
433 dithered images look very poor)." |
|
434 |
|
435 |colors white black red green blue clr dDepth |
|
436 lastPix "{ Class: SmallInteger }" | |
|
437 |
|
438 (aDevice notNil and:[aDevice ditherColors isNil]) ifTrue:[ |
|
439 white := (self red:100 green:100 blue:100) exactOn:aDevice. |
|
440 white colorId isNil ifTrue:[ |
|
441 'Color [warning]: cannot allocate white color' errorPrintCR. |
|
442 ]. |
|
443 black := (self red:0 green:0 blue:0) exactOn:aDevice. |
|
444 black colorId isNil ifTrue:[ |
|
445 'Color [warning]: cannot allocate black color' errorPrintCR. |
|
446 ]. |
|
447 |
|
448 aDevice hasColors ifTrue:[ |
|
449 red := (self red:100 green:0 blue:0) exactOn:aDevice. |
|
450 green := (self red:0 green:100 blue:0) exactOn:aDevice. |
|
451 blue := (self red:0 green:0 blue:100) exactOn:aDevice. |
|
452 (red isNil |
|
453 or:[green isNil |
|
454 or:[blue isNil |
|
455 or:[red colorId isNil |
|
456 or:[green colorId isNil |
|
457 or:[blue colorId isNil]]]]]) ifTrue:[ |
|
458 'Color [warning]: cannot allocate primary color(s)' errorPrintCR. |
|
459 dDepth := aDevice depth. |
|
460 ((dDepth >= 4) and:[dDepth <= 8]) ifTrue:[ |
|
461 "/ |
|
462 "/ see what we have ... |
|
463 "/ |
|
464 lastPix := (1 bitShift:dDepth) - 1. |
|
465 0 to:lastPix do:[:pixel | |
|
466 colors := OrderedCollection new. |
|
467 aDevice getRGBFrom:pixel into:[:r :g :b | |
|
468 colors add:((Color red:r green:g blue:b) exactOn:aDevice). |
|
469 ] |
|
470 ]. |
|
471 red := (self red:100 green:0 blue:0) nearestOn:aDevice. |
|
472 green := (self red:0 green:100 blue:0) nearestOn:aDevice. |
|
473 blue := (self red:0 green:0 blue:100) nearestOn:aDevice. |
|
474 ] ifFalse:[ |
|
475 aDevice hasColors:false. |
|
476 aDevice hasGrayscales:false. |
|
477 red := green := blue := nil. |
|
478 ] |
|
479 ] |
|
480 ]. |
|
481 |
|
482 aDevice == Display ifTrue:[ |
|
483 "/ keep those around for the main display |
|
484 White := white. |
|
485 Black := black. |
|
486 Red := red. |
|
487 Green := green. |
|
488 Blue := blue |
|
489 ]. |
|
490 |
|
491 aDevice visualType ~~ #TrueColor ifTrue:[ |
|
492 aDevice hasColors ifTrue:[ |
|
493 |
|
494 "preallocate some colors for dithering |
|
495 - otherwise, they may not be available when we need them ... |
|
496 these are: black, white, grey50, |
|
497 red, green, blue, yellow, cyan and magenta. |
|
498 " |
|
499 |
|
500 colors := OrderedCollection new. |
|
501 clr := (self gray:50) exactOn:aDevice. |
|
502 (clr notNil and:[clr colorId notNil]) ifTrue:[ |
|
503 colors add:clr |
|
504 ]. |
|
505 |
|
506 colors add:white; add:black; add:red; add:green; add:blue. |
|
507 |
|
508 colors add:((self red:100 green:100 blue:0) exactOn:aDevice). |
|
509 colors add:((self red:100 green:0 blue:100) exactOn:aDevice). |
|
510 colors add:((self red:0 green:100 blue:100) exactOn:aDevice). |
|
511 ]. |
|
512 |
|
513 aDevice hasGrayscales ifTrue:[ |
|
514 aDevice hasColors ifFalse:[ |
|
515 colors := OrderedCollection new. |
|
516 colors add:((self gray:50) exactOn:aDevice). |
|
517 colors add:white; add:black. |
|
518 |
|
519 ]. |
|
520 colors add:((self gray:25) exactOn:aDevice). |
|
521 colors add:((self gray:33) exactOn:aDevice). |
|
522 colors add:((self gray:67) exactOn:aDevice). |
|
523 colors add:((self gray:75) exactOn:aDevice). |
|
524 ]. |
|
525 |
|
526 colors notNil ifTrue:[ |
|
527 colors := colors select:[:clr | clr notNil and:[clr colorId notNil]]. |
|
528 aDevice setDitherColors:(colors asArray). |
|
529 ] |
|
530 ] |
|
531 ] |
|
532 |
|
533 "Created: 11.7.1996 / 18:09:28 / cg" |
|
534 "Modified: 21.10.1997 / 02:42:28 / cg" |
|
535 ! |
|
536 |
|
537 grayColorVector:nGray |
|
538 |nG "{Class: SmallInteger }" |
|
539 d gray dstIndex clr round |
|
540 grayColors| |
|
541 |
|
542 nG := nGray. |
|
543 d := 100.0 / (nG - 1). |
|
544 |
|
545 grayColors := Array new:nG. |
|
546 |
|
547 round := 0. |
|
548 |
|
549 dstIndex := 1. |
|
550 1 to:nG do:[:sG | |
|
551 gray := d * (sG - 1). |
|
552 clr := self red:gray green:gray blue:gray. |
|
553 grayColors at:dstIndex put:clr. |
|
554 dstIndex := dstIndex + 1 |
|
555 ]. |
|
556 ^ grayColors |
|
557 |
|
558 " |
|
559 Color getGrayColors:16 on:Display |
|
560 " |
|
561 |
|
562 "Created: 23.6.1997 / 15:29:50 / cg" |
|
563 ! |
|
564 |
166 |
565 initialize |
167 initialize |
566 "setup tracker of known colors and initialize classvars with |
168 "setup tracker of known colors and initialize classvars with |
567 heavily used colors" |
169 heavily used colors" |
568 |
170 |
3942 |
3493 |
3943 "Created: 14.6.1996 / 20:13:22 / cg" |
3494 "Created: 14.6.1996 / 20:13:22 / cg" |
3944 "Modified: 11.7.1996 / 18:20:14 / cg" |
3495 "Modified: 11.7.1996 / 18:20:14 / cg" |
3945 ! ! |
3496 ! ! |
3946 |
3497 |
|
3498 !Color class methodsFor:'utilities'! |
|
3499 |
|
3500 allocateColorsIn:aColorVector on:aDevice |
|
3501 "{ Pragma: +optSpace }" |
|
3502 |
|
3503 "preallocates a nR x nG x nB colorMap for later use in dithering. |
|
3504 Doing so has the advantage that the system will never run out of colors, |
|
3505 however, colors may be either inexact or dithered." |
|
3506 |
|
3507 |clr round devClr| |
|
3508 |
|
3509 round := 0. |
|
3510 1 to:aColorVector size do:[:dstIndex | |
|
3511 clr := aColorVector at:dstIndex. |
|
3512 devClr := clr exactOn:aDevice. |
|
3513 devClr isNil ifTrue:[ |
|
3514 round == 0 ifTrue:[ |
|
3515 Logger info:'scavenge to reclaim colors'. |
|
3516 ObjectMemory scavenge. |
|
3517 round := 1. |
|
3518 devClr := clr exactOn:aDevice. |
|
3519 ]. |
|
3520 devClr isNil ifTrue:[ |
|
3521 round == 1 ifTrue:[ |
|
3522 Logger info:'collect garbage to reclaim colors'. |
|
3523 ObjectMemory |
|
3524 garbageCollect; finalize. |
|
3525 round := 2. |
|
3526 devClr := clr exactOn:aDevice. |
|
3527 ]. |
|
3528 devClr isNil ifTrue:[ |
|
3529 round == 2 ifTrue:[ |
|
3530 Logger info:'lowSpaceCleanup and collect garbage to reclaim colors'. |
|
3531 ObjectMemory |
|
3532 performLowSpaceCleanup; |
|
3533 garbageCollect; finalize. |
|
3534 round := 3. |
|
3535 devClr := clr exactOn:aDevice. |
|
3536 ]. |
|
3537 devClr isNil ifTrue:[ |
|
3538 ColorAllocationFailSignal raiseErrorString:'failed to allocate fix color'. |
|
3539 ^ self |
|
3540 ]. |
|
3541 ]. |
|
3542 ]. |
|
3543 ]. |
|
3544 aColorVector at:dstIndex put:devClr. |
|
3545 ]. |
|
3546 |
|
3547 "Modified: / 02-03-2017 / 17:43:36 / stefan" |
|
3548 ! |
|
3549 |
|
3550 best:numColors ditherColorsForImage:anImage |
|
3551 "work in progress" |
|
3552 |
|
3553 |bigCube boxMax numBits numGray usedColors |
|
3554 minRed maxRed minGreen maxGreen minBlue maxBlue |
|
3555 boundaryColors boxesSegmented segments boxesToDo enumerateNeighbors |
|
3556 firstTry segmentColors| |
|
3557 |
|
3558 ((anImage photometric == #blackIs0) or:[anImage photometric == #whiteIs0]) ifTrue:[ |
|
3559 numGray := (1 bitShift:anImage depth) min:numColors. |
|
3560 ^ self grayColorVector:numGray |
|
3561 ]. |
|
3562 (anImage photometric == #palette) ifTrue:[ |
|
3563 "/ all gray? |
|
3564 (anImage colorMap conform:[:clr | clr isGrayColor]) ifTrue:[ |
|
3565 numGray := ((1 bitShift:anImage depth) min:anImage colorMap size) min:numColors. |
|
3566 ^ self grayColorVector:numGray |
|
3567 ]. |
|
3568 ]. |
|
3569 |
|
3570 boxMax := 63. |
|
3571 numBits := 6. |
|
3572 firstTry := true. |
|
3573 |
|
3574 [ |
|
3575 "/ first, a rough cube with less precision... |
|
3576 bigCube := IntegerArray new:(boxMax+1)*(boxMax+1)*(boxMax+1). |
|
3577 |
|
3578 firstTry ifTrue:[ |
|
3579 usedColors := Set new. |
|
3580 minRed := minGreen := minBlue := 255. |
|
3581 maxRed := maxGreen := maxBlue := 0. |
|
3582 ]. |
|
3583 |
|
3584 anImage |
|
3585 rgbValuesFromX:0 y:0 |
|
3586 toX:(anImage width-1) y:(anImage height-1) |
|
3587 do:[:x :y :rgb | |
|
3588 |redByte greenByte blueByte r g b idx oldCount| |
|
3589 |
|
3590 redByte := (rgb rightShift:16) bitAnd:16rFF. |
|
3591 greenByte := (rgb rightShift:8) bitAnd:16rFF. |
|
3592 blueByte := (rgb) bitAnd:16rFF. |
|
3593 |
|
3594 r := redByte rightShift:(8-numBits). |
|
3595 g := greenByte rightShift:(8-numBits). |
|
3596 b := blueByte rightShift:(8-numBits). |
|
3597 idx := (((r * (boxMax+1))+g)*(boxMax+1))+b+1. |
|
3598 oldCount := bigCube at:idx. |
|
3599 |
|
3600 firstTry ifTrue:[ |
|
3601 redByte < minRed ifTrue:[minRed := redByte] ifFalse:[redByte > maxRed ifTrue:[maxRed := redByte]]. |
|
3602 greenByte < minGreen ifTrue:[minGreen := greenByte] ifFalse:[greenByte > maxGreen ifTrue:[maxGreen := greenByte]]. |
|
3603 blueByte < minBlue ifTrue:[minBlue := blueByte] ifFalse:[blueByte > maxBlue ifTrue:[maxBlue := blueByte]]. |
|
3604 |
|
3605 oldCount == 0 ifTrue:[ |
|
3606 usedColors add:rgb. |
|
3607 ]. |
|
3608 ]. |
|
3609 bigCube at:idx put:oldCount+1. |
|
3610 ]. |
|
3611 |
|
3612 firstTry ifTrue:[ |
|
3613 usedColors size <= numColors ifTrue:[ |
|
3614 "/ huh - that will be easy!! |
|
3615 ^ usedColors asArray. |
|
3616 ]. |
|
3617 |
|
3618 "/ if not even the basic colors fit, dither to b&w |
|
3619 numColors == 2 ifTrue:[ |
|
3620 ^ { Color black . Color white } |
|
3621 ]. |
|
3622 "/ if not even the basic colors fit, dither to b&w |
|
3623 numColors == 4 ifTrue:[ |
|
3624 ^ { Color black . Color red . Color green . Color blue. } |
|
3625 ]. |
|
3626 |
|
3627 "/ we need the at least the 8 corners for dithering, at least... |
|
3628 boundaryColors := OrderedCollection new. |
|
3629 { minRed . maxRed } do:[:r | |
|
3630 { minGreen . maxGreen } do:[:g | |
|
3631 { minBlue . maxBlue } do:[:b | |
|
3632 boundaryColors add:(Color redByte:r greenByte:g blueByte:b) |
|
3633 ]. |
|
3634 ]. |
|
3635 ]. |
|
3636 numColors == 8 ifTrue:[ |
|
3637 ^ boundaryColors |
|
3638 ]. |
|
3639 ]. |
|
3640 firstTry := false. |
|
3641 |
|
3642 "/ |
|
3643 "/ find and generate connected subarea box sets |
|
3644 "/ |
|
3645 boxesSegmented := Set new. |
|
3646 segments := OrderedCollection new. |
|
3647 |
|
3648 boxesToDo := OrderedCollection new. |
|
3649 |
|
3650 "/ each box has 9+9+3+3+1+1 neighbors |
|
3651 "/ |
|
3652 enumerateNeighbors := |
|
3653 [:rgb :aBlock| |
|
3654 |r g b| |
|
3655 |
|
3656 r := (rgb rightShift:(numBits+numBits)) bitAnd:boxMax. |
|
3657 g := (rgb rightShift:numBits) bitAnd:boxMax. |
|
3658 b := (rgb) bitAnd:boxMax. |
|
3659 r-1 to:r+1 do:[:n_r | |
|
3660 (n_r between:0 and:boxMax) ifTrue:[ |
|
3661 g-1 to:g+1 do:[:n_g | |
|
3662 (n_g between:0 and:boxMax) ifTrue:[ |
|
3663 b-1 to:b+1 do:[:n_b | |
|
3664 (n_b between:0 and:boxMax) ifTrue:[ |
|
3665 ((n_r == r) and:[n_g == g and:[n_b == b]]) ifFalse:[ |
|
3666 aBlock value:((((n_r * (boxMax+1))+n_g)*(boxMax+1))+n_b). |
|
3667 ] |
|
3668 ] |
|
3669 ] |
|
3670 ] |
|
3671 ] |
|
3672 ] |
|
3673 ]. |
|
3674 ]. |
|
3675 |
|
3676 0 to:boxMax do:[:r | |
|
3677 0 to:boxMax do:[:g | |
|
3678 0 to:boxMax do:[:b | |
|
3679 |rgb| |
|
3680 |
|
3681 rgb := (((r * (boxMax+1))+g)*(boxMax+1))+b. |
|
3682 (bigCube at:rgb+1) ~~ 0 ifTrue:[ |
|
3683 (boxesSegmented includes:rgb) ifFalse:[ |
|
3684 |currentSegment| |
|
3685 |
|
3686 "/ start a segment |
|
3687 currentSegment := OrderedCollection new. |
|
3688 segments add:currentSegment. |
|
3689 |
|
3690 boxesToDo add:rgb. |
|
3691 boxesSegmented add:rgb. |
|
3692 |
|
3693 [boxesToDo notEmpty] whileTrue:[ |
|
3694 |rgb| |
|
3695 |
|
3696 rgb := boxesToDo removeLast. |
|
3697 currentSegment add:rgb. |
|
3698 |
|
3699 enumerateNeighbors value:rgb value:[:n_rgb | |
|
3700 (bigCube at:n_rgb+1) ~~ 0 ifTrue:[ |
|
3701 "/ neighbor has used pixels as well... |
|
3702 (boxesSegmented includes:n_rgb) ifFalse:[ |
|
3703 "/ neighbor was not processed... |
|
3704 boxesSegmented add:rgb. |
|
3705 boxesToDo add:n_rgb. |
|
3706 ]. |
|
3707 ]. |
|
3708 ]. |
|
3709 ]. |
|
3710 ]. |
|
3711 ]. |
|
3712 ] |
|
3713 ] |
|
3714 ]. |
|
3715 |
|
3716 (segments size < numColors) ifTrue:[ |
|
3717 segmentColors := segments |
|
3718 collect:[:eachSegment | |
|
3719 |n sumRed sumGreen sumBlue centerRed centerGreen centerBlue| |
|
3720 |
|
3721 "/ compute central point |
|
3722 "/ as center of mass (taking count per box as weight) |
|
3723 "/ this central point will be placed into the colormap. |
|
3724 sumRed := sumGreen := sumBlue := 0. |
|
3725 n := eachSegment size. |
|
3726 |
|
3727 eachSegment do:[:rgbOfBoxInSegment | |
|
3728 |r g b| |
|
3729 |
|
3730 r := (rgbOfBoxInSegment rightShift:(numBits+numBits)) bitAnd:boxMax. |
|
3731 g := (rgbOfBoxInSegment rightShift:numBits) bitAnd:boxMax. |
|
3732 b := (rgbOfBoxInSegment) bitAnd:boxMax. |
|
3733 sumRed :=sumRed + r. |
|
3734 sumGreen := sumGreen + g. |
|
3735 sumBlue := sumBlue + b. |
|
3736 ]. |
|
3737 centerRed := (sumRed / n) rounded. |
|
3738 centerGreen := (sumGreen / n) rounded. |
|
3739 centerBlue := (sumBlue / n) rounded. |
|
3740 |
|
3741 centerRed := (centerRed bitShift:(8-numBits)) |
|
3742 bitOr:(centerRed bitShift:(8-numBits-numBits)). |
|
3743 centerGreen := (centerGreen bitShift:(8-numBits)) |
|
3744 bitOr:(centerGreen bitShift:(8-numBits-numBits)). |
|
3745 centerBlue := (centerBlue bitShift:(8-numBits)) |
|
3746 bitOr:(centerBlue bitShift:(8-numBits-numBits)). |
|
3747 |
|
3748 Color redByte:centerRed greenByte:centerGreen blueByte:centerBlue. |
|
3749 ] |
|
3750 as:OrderedCollection. |
|
3751 "/ can we add black & white? |
|
3752 (segmentColors includes:Color white) ifFalse:[ |
|
3753 segmentColors add:Color white. |
|
3754 ]. |
|
3755 (segmentColors includes:Color black) ifFalse:[ |
|
3756 segmentColors add:Color black. |
|
3757 ]. |
|
3758 "/ can we add the boundary colors? |
|
3759 boundaryColors do:[:each | |
|
3760 (segmentColors size < numColors) ifTrue:[ |
|
3761 (segmentColors includes:each) ifFalse:[ |
|
3762 segmentColors add:each. |
|
3763 ]. |
|
3764 ]. |
|
3765 ]. |
|
3766 ^ segmentColors. |
|
3767 ]. |
|
3768 |
|
3769 numBits := numBits - 1. |
|
3770 boxMax := ((boxMax+1) // 2) - 1. |
|
3771 |
|
3772 numBits == 0 ifTrue:[ |
|
3773 self error. |
|
3774 ]. |
|
3775 ] loop. |
|
3776 |
|
3777 " |
|
3778 Color |
|
3779 best:16 |
|
3780 ditherColorsForImage:(Image fromFile:'../../goodies/bitmaps/pcxImages/lena_depth8_palette.pcx') |
|
3781 |
|
3782 Color |
|
3783 best:16 |
|
3784 ditherColorsForImage:(Image fromFile:'../../goodies/bitmaps/pcxImages/lena_depth24_rgb.pcx') |
|
3785 |
|
3786 Color |
|
3787 best:16 |
|
3788 ditherColorsForImage:((Image fromFile:'../../goodies/bitmaps/pcxImages/lena_depth8_palette.pcx') asGrayImageDepth:8) |
|
3789 |
|
3790 " |
|
3791 |
|
3792 "Created: / 29-08-2017 / 14:31:19 / cg" |
|
3793 "Modified (comment): / 29-08-2017 / 20:00:32 / cg" |
|
3794 ! |
|
3795 |
|
3796 browserColors |
|
3797 "return the palette, known as 'the color cube', 'the Netscape palette', |
|
3798 or 'the Browser-Safe palette'. |
|
3799 This is familiar to all seasoned Web designers and graphics production specialists; |
|
3800 Use this map for low-color-res depth 8 (gif-) images, if old pseudo displays are to be |
|
3801 supported." |
|
3802 |
|
3803 ^ self colorCubeWithRed:6 green:6 blue:6. |
|
3804 |
|
3805 " |
|
3806 |img| |
|
3807 |
|
3808 img := Image width:(8*6*6)+1 height:(8*6)+1 depth:8. |
|
3809 img colorMap:(Color browserColors). |
|
3810 img pixelFunction: |
|
3811 [:x :y | |
|
3812 |r g b| |
|
3813 |
|
3814 (y \\ 8 == 0 ) ifTrue:[ |
|
3815 86 |
|
3816 ] ifFalse:[ |
|
3817 x \\ 8 == 0 ifTrue:[ |
|
3818 86 |
|
3819 ] ifFalse:[ |
|
3820 r := g := b := 0. |
|
3821 'y is green component'. |
|
3822 g := 5-(y // 8). |
|
3823 'x inside subsquare is blue component'. |
|
3824 b := (x \\ (8*6)) // 8. |
|
3825 'subsquare is red component'. |
|
3826 r := (x // (8*6)). |
|
3827 ((r*6)+g)*6+b |
|
3828 ] |
|
3829 ]. |
|
3830 ]. |
|
3831 img inspect. |
|
3832 " |
|
3833 |
|
3834 "Created: / 29-08-2017 / 17:01:23 / cg" |
|
3835 ! |
|
3836 |
|
3837 colorCubeWithRed:nRed green:nGreen blue:nBlue |
|
3838 "given a number of red, green and blue shades, |
|
3839 return a color cube (map) containing those colors. |
|
3840 Eg, return a map containing any combination of the |
|
3841 nRed, nGreen and nBlue shades. |
|
3842 This is used for dithering of deep images onto limited-depth canvases |
|
3843 for example: with nRed,nGreen,nBlue == 2,3,2 |
|
3844 you will get a cube of 2*3*2 = 12 colors, with two shades of red (0 and 255), |
|
3845 threed shades of green (0, 127 and 255) and two shades of blue (0 and 255)." |
|
3846 |
|
3847 "{ Pragma: +optSpace }" |
|
3848 |
|
3849 |nR "{Class: SmallInteger }" |
|
3850 nG "{Class: SmallInteger }" |
|
3851 nB "{Class: SmallInteger }" |
|
3852 dR dG dB red green blue dstIndex clr round |
|
3853 colorCube| |
|
3854 |
|
3855 nR := nRed. |
|
3856 nG := nGreen. |
|
3857 nB := nBlue. |
|
3858 |
|
3859 dR := 100.0 / (nR - 1). |
|
3860 dG := 100.0 / (nG - 1). |
|
3861 dB := 100.0 / (nB - 1). |
|
3862 |
|
3863 colorCube := Array new:(nR * nG * nB). |
|
3864 |
|
3865 round := 0. |
|
3866 |
|
3867 dstIndex := 1. |
|
3868 1 to:nR do:[:sR | |
|
3869 red := dR * (sR - 1). |
|
3870 1 to:nG do:[:sG | |
|
3871 green := dG * (sG - 1). |
|
3872 1 to:nB do:[:sB | |
|
3873 blue := dB * (sB - 1). |
|
3874 clr := self red:red green:green blue:blue. |
|
3875 colorCube at:dstIndex put:clr. |
|
3876 dstIndex := dstIndex + 1 |
|
3877 ] |
|
3878 ] |
|
3879 ]. |
|
3880 ^ colorCube |
|
3881 |
|
3882 " |
|
3883 Color colorCubeWithRed:2 green:2 blue:2 |
|
3884 Color colorCubeWithRed:2 green:3 blue:2 |
|
3885 Color colorCubeWithRed:3 green:4 blue:3 |
|
3886 " |
|
3887 |
|
3888 "Created: / 11-07-1996 / 17:55:32 / cg" |
|
3889 "Modified: / 10-01-1997 / 15:37:13 / cg" |
|
3890 "Modified (comment): / 29-08-2017 / 14:27:58 / cg" |
|
3891 ! |
|
3892 |
|
3893 flushDeviceColors |
|
3894 "unassign all colors from their device" |
|
3895 |
|
3896 self allInstances do:[:aColor | |
|
3897 aColor restored |
|
3898 ]. |
|
3899 |
|
3900 "Modified: 24.2.1997 / 18:27:06 / cg" |
|
3901 ! |
|
3902 |
|
3903 flushDeviceColorsFor:aDevice |
|
3904 self allInstancesDo:[:aColor | |
|
3905 aColor device == aDevice ifTrue:[ |
|
3906 aColor restored |
|
3907 ] |
|
3908 ] |
|
3909 ! |
|
3910 |
|
3911 getColors6x6x4 |
|
3912 "{ Pragma: +optSpace }" |
|
3913 |
|
3914 "preallocates a 6x6x4 (144) colorMap and later uses those colors only |
|
3915 on a palette display (pseudoColor visual). |
|
3916 |
|
3917 Doing so has the advantage that the system will never run out of colors, |
|
3918 however, colors may be either inexact or dithered." |
|
3919 |
|
3920 self getColorsRed:6 green:6 blue:4 |
|
3921 |
|
3922 " |
|
3923 Color getColors6x6x4 |
|
3924 " |
|
3925 |
|
3926 "Modified (comment): / 29-08-2017 / 17:22:22 / cg" |
|
3927 ! |
|
3928 |
|
3929 getColors6x6x5 |
|
3930 "{ Pragma: +optSpace }" |
|
3931 |
|
3932 "preallocates a 6x6x5 (180) colorMap and later uses those colors only |
|
3933 on a palette display (pseudoColor visual). |
|
3934 |
|
3935 Doing so has the advantage that the system will never run out of colors, |
|
3936 however, colors may be either inexact or dithered." |
|
3937 |
|
3938 self getColorsRed:6 green:6 blue:5 |
|
3939 |
|
3940 " |
|
3941 Color getColors6x6x5 |
|
3942 " |
|
3943 |
|
3944 "Modified (comment): / 29-08-2017 / 17:22:17 / cg" |
|
3945 ! |
|
3946 |
|
3947 getColors6x6x6 |
|
3948 "{ Pragma: +optSpace }" |
|
3949 |
|
3950 "preallocates a 6x6x6 (196) colorMap and later uses those colors only |
|
3951 on a palette display (pseudoColor visual). |
|
3952 |
|
3953 Doing so has the advantage that the system will never run out of colors, |
|
3954 however, colors may be either inexact or dithered." |
|
3955 |
|
3956 self getColorsRed:6 green:6 blue:6 |
|
3957 |
|
3958 " |
|
3959 Color getColors6x6x6 |
|
3960 " |
|
3961 |
|
3962 "Modified (comment): / 29-08-2017 / 17:22:10 / cg" |
|
3963 ! |
|
3964 |
|
3965 getColors6x7x4 |
|
3966 "{ Pragma: +optSpace }" |
|
3967 |
|
3968 "preallocates a 6x7x4 (168) colorMap and later uses those colors only |
|
3969 on a palette display (pseudoColor visual). |
|
3970 |
|
3971 Doing so has the advantage that the system will never run out of colors, |
|
3972 however, colors may be either inexact or dithered." |
|
3973 |
|
3974 self getColorsRed:6 green:7 blue:4 |
|
3975 |
|
3976 " |
|
3977 Color getColors6x7x4 |
|
3978 " |
|
3979 |
|
3980 "Created: / 12-06-1996 / 17:41:57 / cg" |
|
3981 "Modified (comment): / 29-08-2017 / 17:22:04 / cg" |
|
3982 ! |
|
3983 |
|
3984 getColors7x8x4 |
|
3985 "{ Pragma: +optSpace }" |
|
3986 |
|
3987 "preallocates a 7x8x4 (224) colorMap and later uses those colors only |
|
3988 on a palette display (pseudoColor visual). |
|
3989 |
|
3990 Doing so has the advantage that the system will never run out of colors, |
|
3991 however, colors may be either inexact or dithered." |
|
3992 |
|
3993 self getColorsRed:7 green:8 blue:4 |
|
3994 |
|
3995 " |
|
3996 Color getColors7x8x4 |
|
3997 " |
|
3998 |
|
3999 "Modified (comment): / 29-08-2017 / 17:21:56 / cg" |
|
4000 ! |
|
4001 |
|
4002 getColorsRed:nRed green:nGreen blue:nBlue |
|
4003 "{ Pragma: +optSpace }" |
|
4004 |
|
4005 "preallocates a nR x nG x nB colorMap for later use in dithering |
|
4006 on a palette display (pseudoColor visual). |
|
4007 |
|
4008 Doing so has the advantage that the system will never run out of colors, |
|
4009 however, colors may be either inexact or dithered." |
|
4010 |
|
4011 self getColorsRed:nRed green:nGreen blue:nBlue on:Screen current |
|
4012 |
|
4013 " |
|
4014 Color getColorsRed:2 green:2 blue:2 |
|
4015 " |
|
4016 |
|
4017 "Modified: / 11-07-1996 / 17:58:09 / cg" |
|
4018 "Modified (comment): / 29-08-2017 / 16:47:34 / cg" |
|
4019 ! |
|
4020 |
|
4021 getColorsRed:nRed green:nGreen blue:nBlue on:aDevice |
|
4022 "{ Pragma: +optSpace }" |
|
4023 |
|
4024 "preallocates a nR x nG x nB colorMap for later use in dithering |
|
4025 on a palette display (pseudoColor visual). |
|
4026 |
|
4027 Doing so has the advantage that the system will never run out of colors, |
|
4028 however, colors may be either inexact or dithered." |
|
4029 |
|
4030 |nR "{Class: SmallInteger }" |
|
4031 nG "{Class: SmallInteger }" |
|
4032 nB "{Class: SmallInteger }" |
|
4033 dR dG dB fixColors| |
|
4034 |
|
4035 aDevice visualType == #TrueColor ifTrue:[^ self]. |
|
4036 |
|
4037 nR := nRed. |
|
4038 nG := nGreen. |
|
4039 nB := nBlue. |
|
4040 |
|
4041 dR := 100.0 / (nR - 1). |
|
4042 dG := 100.0 / (nG - 1). |
|
4043 dB := 100.0 / (nB - 1). |
|
4044 |
|
4045 fixColors := self colorCubeWithRed:nRed green:nGreen blue:nBlue. |
|
4046 self allocateColorsIn:fixColors on:aDevice. |
|
4047 |
|
4048 aDevice setFixColors:fixColors numRed:nR numGreen:nG numBlue:nB |
|
4049 |
|
4050 " |
|
4051 Color getColorsRed:2 green:2 blue:2 on:Display |
|
4052 " |
|
4053 |
|
4054 "Created: / 11-07-1996 / 17:55:32 / cg" |
|
4055 "Modified: / 10-01-1997 / 15:37:13 / cg" |
|
4056 "Modified (comment): / 29-08-2017 / 16:47:38 / cg" |
|
4057 ! |
|
4058 |
|
4059 getGrayColors:nGray on:aDevice |
|
4060 "{ Pragma: +optSpace }" |
|
4061 |
|
4062 "preallocates nGray gray colors for later use in dithering |
|
4063 on a palette display (pseudoColor visual). |
|
4064 |
|
4065 Doing so has the advantage that the system will never run out of colors, |
|
4066 however, colors may be either inexact or dithered." |
|
4067 |
|
4068 |nG "{Class: SmallInteger }" |
|
4069 d fixGrayColors| |
|
4070 |
|
4071 aDevice visualType == #TrueColor ifTrue:[^ self]. |
|
4072 |
|
4073 nG := nGray. |
|
4074 d := 100.0 / (nG - 1). |
|
4075 |
|
4076 fixGrayColors := self grayColorVector:nGray. |
|
4077 self allocateColorsIn:fixGrayColors on:aDevice. |
|
4078 |
|
4079 aDevice setFixGrayColors:fixGrayColors |
|
4080 |
|
4081 " |
|
4082 Color getGrayColors:16 on:Display |
|
4083 " |
|
4084 |
|
4085 "Created: / 23-06-1997 / 15:29:50 / cg" |
|
4086 "Modified (comment): / 29-08-2017 / 17:23:18 / cg" |
|
4087 ! |
|
4088 |
|
4089 getPrimaryColorsOn:aDevice |
|
4090 "{ Pragma: +optSpace }" |
|
4091 |
|
4092 "preallocate the primary colors on a palette display (pseudoColor visual). |
|
4093 |
|
4094 Doing so during early startup prevents us from running out |
|
4095 of (at least those required) colors later. |
|
4096 This guarantees, that at least some colors are available |
|
4097 for dithering (although, with only black, white, red, green and blue, |
|
4098 dithered images look very poor)." |
|
4099 |
|
4100 |colors white black red green blue clr dDepth |
|
4101 lastPix "{ Class: SmallInteger }" | |
|
4102 |
|
4103 (aDevice notNil and:[aDevice ditherColors isNil]) ifTrue:[ |
|
4104 white := (self red:100 green:100 blue:100) exactOn:aDevice. |
|
4105 white colorId isNil ifTrue:[ |
|
4106 'Color [warning]: cannot allocate white color' errorPrintCR. |
|
4107 ]. |
|
4108 black := (self red:0 green:0 blue:0) exactOn:aDevice. |
|
4109 black colorId isNil ifTrue:[ |
|
4110 'Color [warning]: cannot allocate black color' errorPrintCR. |
|
4111 ]. |
|
4112 |
|
4113 aDevice hasColors ifTrue:[ |
|
4114 red := (self red:100 green:0 blue:0) exactOn:aDevice. |
|
4115 green := (self red:0 green:100 blue:0) exactOn:aDevice. |
|
4116 blue := (self red:0 green:0 blue:100) exactOn:aDevice. |
|
4117 (red isNil |
|
4118 or:[green isNil |
|
4119 or:[blue isNil |
|
4120 or:[red colorId isNil |
|
4121 or:[green colorId isNil |
|
4122 or:[blue colorId isNil]]]]]) ifTrue:[ |
|
4123 'Color [warning]: cannot allocate primary color(s)' errorPrintCR. |
|
4124 dDepth := aDevice depth. |
|
4125 ((dDepth >= 4) and:[dDepth <= 8]) ifTrue:[ |
|
4126 "/ |
|
4127 "/ see what we have ... |
|
4128 "/ |
|
4129 lastPix := (1 bitShift:dDepth) - 1. |
|
4130 0 to:lastPix do:[:pixel | |
|
4131 colors := OrderedCollection new. |
|
4132 aDevice getRGBFrom:pixel into:[:r :g :b | |
|
4133 colors add:((Color red:r green:g blue:b) exactOn:aDevice). |
|
4134 ] |
|
4135 ]. |
|
4136 red := (self red:100 green:0 blue:0) nearestOn:aDevice. |
|
4137 green := (self red:0 green:100 blue:0) nearestOn:aDevice. |
|
4138 blue := (self red:0 green:0 blue:100) nearestOn:aDevice. |
|
4139 ] ifFalse:[ |
|
4140 aDevice hasColors:false. |
|
4141 aDevice hasGrayscales:false. |
|
4142 red := green := blue := nil. |
|
4143 ] |
|
4144 ] |
|
4145 ]. |
|
4146 |
|
4147 aDevice == Display ifTrue:[ |
|
4148 "/ keep those around for the main display |
|
4149 White := white. |
|
4150 Black := black. |
|
4151 Red := red. |
|
4152 Green := green. |
|
4153 Blue := blue |
|
4154 ]. |
|
4155 |
|
4156 aDevice visualType ~~ #TrueColor ifTrue:[ |
|
4157 aDevice hasColors ifTrue:[ |
|
4158 |
|
4159 "preallocate some colors for dithering |
|
4160 - otherwise, they may not be available when we need them ... |
|
4161 these are: black, white, grey50, |
|
4162 red, green, blue, yellow, cyan and magenta. |
|
4163 " |
|
4164 |
|
4165 colors := OrderedCollection new. |
|
4166 clr := (self gray:50) exactOn:aDevice. |
|
4167 (clr notNil and:[clr colorId notNil]) ifTrue:[ |
|
4168 colors add:clr |
|
4169 ]. |
|
4170 |
|
4171 colors add:white; add:black; add:red; add:green; add:blue. |
|
4172 |
|
4173 colors add:((self red:100 green:100 blue:0) exactOn:aDevice). |
|
4174 colors add:((self red:100 green:0 blue:100) exactOn:aDevice). |
|
4175 colors add:((self red:0 green:100 blue:100) exactOn:aDevice). |
|
4176 ]. |
|
4177 |
|
4178 aDevice hasGrayscales ifTrue:[ |
|
4179 aDevice hasColors ifFalse:[ |
|
4180 colors := OrderedCollection new. |
|
4181 colors add:((self gray:50) exactOn:aDevice). |
|
4182 colors add:white; add:black. |
|
4183 |
|
4184 ]. |
|
4185 colors add:((self gray:25) exactOn:aDevice). |
|
4186 colors add:((self gray:33) exactOn:aDevice). |
|
4187 colors add:((self gray:67) exactOn:aDevice). |
|
4188 colors add:((self gray:75) exactOn:aDevice). |
|
4189 ]. |
|
4190 |
|
4191 colors notNil ifTrue:[ |
|
4192 colors := colors select:[:clr | clr notNil and:[clr colorId notNil]]. |
|
4193 aDevice setDitherColors:(colors asArray). |
|
4194 ] |
|
4195 ] |
|
4196 ] |
|
4197 |
|
4198 "Created: / 11-07-1996 / 18:09:28 / cg" |
|
4199 "Modified: / 21-10-1997 / 02:42:28 / cg" |
|
4200 "Modified (comment): / 29-08-2017 / 17:23:36 / cg" |
|
4201 ! |
|
4202 |
|
4203 grayColorVector:nGray |
|
4204 |nG "{Class: SmallInteger }" |
|
4205 d gray dstIndex clr round |
|
4206 grayColors| |
|
4207 |
|
4208 nG := nGray. |
|
4209 d := 100.0 / (nG - 1). |
|
4210 |
|
4211 grayColors := Array new:nG. |
|
4212 |
|
4213 round := 0. |
|
4214 |
|
4215 dstIndex := 1. |
|
4216 1 to:nG do:[:sG | |
|
4217 gray := d * (sG - 1). |
|
4218 clr := self red:gray green:gray blue:gray. |
|
4219 grayColors at:dstIndex put:clr. |
|
4220 dstIndex := dstIndex + 1 |
|
4221 ]. |
|
4222 ^ grayColors |
|
4223 |
|
4224 " |
|
4225 Color getGrayColors:16 on:Display |
|
4226 " |
|
4227 |
|
4228 "Created: 23.6.1997 / 15:29:50 / cg" |
|
4229 ! |
|
4230 |
|
4231 standardDitherColorsForDepth8 |
|
4232 "return a set of colors useful for dithering (roughly 200 colors); |
|
4233 This includes a color cube and the main grayScale colors." |
|
4234 |
|
4235 |ditherColors| |
|
4236 |
|
4237 ditherColors := self colorCubeWithRed:6 green:8 blue:4. |
|
4238 ditherColors := ditherColors , |
|
4239 ( #(10 20 25 30 40 50 60 70 75 80 90) |
|
4240 collect:[:grayPercent | Color gray:grayPercent] |
|
4241 thenSelect:[:grey | (ditherColors includes:grey) not] ) |
|
4242 asArray. |
|
4243 ^ ditherColors |
|
4244 |
|
4245 " |
|
4246 self standardDitherColorsForDepth8 |
|
4247 " |
|
4248 |
|
4249 "Modified: / 29-08-2017 / 17:29:58 / cg" |
|
4250 ! |
|
4251 |
|
4252 vgaColors |
|
4253 "{ Pragma: +optSpace }" |
|
4254 |
|
4255 |colors| |
|
4256 |
|
4257 colors := Array new:16. |
|
4258 colors at:1 put:(Color rgbValue:16rFFFFFF). |
|
4259 colors at:2 put:(Color rgbValue:16rC0C0C0). |
|
4260 colors at:3 put:(Color rgbValue:16r808080). |
|
4261 colors at:4 put:(Color rgbValue:16r000000). |
|
4262 colors at:5 put:(Color rgbValue:16rFF0000). |
|
4263 colors at:6 put:(Color rgbValue:16r800000). |
|
4264 colors at:7 put:(Color rgbValue:16r008000). |
|
4265 colors at:8 put:(Color rgbValue:16r00FF00). |
|
4266 colors at:9 put:(Color rgbValue:16r0000FF). |
|
4267 colors at:10 put:(Color rgbValue:16r000080). |
|
4268 colors at:11 put:(Color rgbValue:16rFF00FF). |
|
4269 colors at:12 put:(Color rgbValue:16r800080). |
|
4270 colors at:13 put:(Color rgbValue:16rFFFF00). |
|
4271 colors at:14 put:(Color rgbValue:16r808000). |
|
4272 colors at:15 put:(Color rgbValue:16r00FFFF). |
|
4273 colors at:16 put:(Color rgbValue:16r008080). |
|
4274 ^ colors |
|
4275 |
|
4276 "Created: / 07-07-2006 / 13:36:15 / cg" |
|
4277 ! ! |
|
4278 |
3947 !Color methodsFor:'Compatibility-ST80'! |
4279 !Color methodsFor:'Compatibility-ST80'! |
3948 |
4280 |
3949 asDevicePaintOn:aDevice |
4281 asDevicePaintOn:aDevice |
3950 "ST-80 compatibility: an alias for on:. |
4282 "ST-80 compatibility: an alias for on:. |
3951 create a new Color representing the same color as |
4283 create a new Color representing the same color as |