[squeak-dev] The Inbox: Graphics-nice.408.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri May 17 19:29:36 UTC 2019


Le ven. 17 mai 2019 à 19:33, Chris Cunningham <cunningham.cb at gmail.com> a
écrit :

> I like it (Based on reading it only - not loading/testing).
>
> > The new class variable is initialized in postscript.
> > It must be re-initialized each time we change the definition of a named
> Color.
>
> So, each time we change a definition, we have to change the postscript,
> since it is only run on change, right?
> If so, this is worth putting  a comment anywhere Color names are defined
> (i.e., those methods and external packages); otherwise we will fail to
> follow this requirement at some point.
>
> -cbc
>
> I was thinking of
1) adding a test
2) have some form of auto-correction
(that would be easy in the test, even it feels somehow strange to have
self-correcting tests)

The symptom if we change the definition of a named Color is that it won't
print itself named (the previous definition will).
Also if we add a new named Color but forget to update the map...
No catastropic consequences. But a comment is indeed welcome in class
comment and #name comment.

Maybe we could adopt a different way of registering named colors thru a
pragma...


> On Fri, May 17, 2019 at 8:58 AM Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com> wrote:
>
>> No objection?
>>
>> Le jeu. 16 mai 2019 à 15:14, <commits at source.squeak.org> a écrit :
>>
>>> Nicolas Cellier uploaded a new version of Graphics to project The Inbox:
>>> http://source.squeak.org/inbox/Graphics-nice.408.mcz
>>>
>>> ==================== Summary ====================
>>>
>>> Name: Graphics-nice.408
>>> Author: nice
>>> Time: 16 May 2019, 3:12:54.000487 pm
>>> UUID: cc271e8f-330d-d649-a848-128e2d849f03
>>> Ancestors: Graphics-mt.406
>>>
>>> Use a map rgb->#names rather than iterating thru/performing all known
>>> colorNames.
>>>
>>> This is especially useful if we intend to add more color names.
>>> Note that names do not need to be unique.
>>> The first appearing name in colorNames will be used.
>>>
>>> Color colorNames collect: [:sym | Color perform: sym].
>>>
>>> (Color colorNames reject: [:sym | (Color perform: sym) name = sym])
>>>         collect: [:sym | sym -> (Color perform: sym) name].
>>>
>>> The new class variable is initialized in postscript.
>>> It must be re-initialized each time we change the definition of a named
>>> Color.
>>>
>>> The rgb code has been used as key rather than the Color itself.
>>> This is because it is unique and cheap (SmallInteger).
>>>
>>> =============== Diff against Graphics-mt.406 ===============
>>>
>>> Item was changed:
>>>   Object subclass: #Color
>>>         instanceVariableNames: 'rgb cachedDepth cachedBitPattern'
>>> +       classVariableNames: 'Black Blue BlueShift Brown CachedColormaps
>>> ColorChart ColorNames ComponentMask ComponentMax Cyan DarkGray Gray
>>> GrayToIndexMap Green GreenShift HalfComponentMask HighLightBitmaps
>>> IndexedColors LightBlue LightBrown LightCyan LightGray LightGreen
>>> LightMagenta LightOrange LightRed LightYellow Magenta MaskingMap Orange
>>> PaleBlue PaleBuff PaleGreen PaleMagenta PaleOrange PalePeach PaleRed
>>> PaleTan PaleYellow PantonePurpleU PureBlue PureCyan PureGreen PureMagenta
>>> PureRed PureYellow RGBToNames RandomStream Red RedShift TranslucentPatterns
>>> Transparent VeryDarkGray VeryLightGray VeryPaleRed VeryVeryDarkGray
>>> VeryVeryLightGray White Yellow'
>>> -       classVariableNames: 'Black Blue BlueShift Brown CachedColormaps
>>> ColorChart ColorNames ComponentMask ComponentMax Cyan DarkGray Gray
>>> GrayToIndexMap Green GreenShift HalfComponentMask HighLightBitmaps
>>> IndexedColors LightBlue LightBrown LightCyan LightGray LightGreen
>>> LightMagenta LightOrange LightRed LightYellow Magenta MaskingMap Orange
>>> PaleBlue PaleBuff PaleGreen PaleMagenta PaleOrange PalePeach PaleRed
>>> PaleTan PaleYellow PantonePurpleU PureBlue PureCyan PureGreen PureMagenta
>>> PureRed PureYellow RandomStream Red RedShift TranslucentPatterns
>>> Transparent VeryDarkGray VeryLightGray VeryPaleRed VeryVeryDarkGray
>>> VeryVeryLightGray White Yellow'
>>>         poolDictionaries: ''
>>>         category: 'Graphics-Primitives'!
>>>
>>>   !Color commentStamp: '<historical>' prior: 0!
>>>   This class represents abstract color, regardless of the depth of
>>> bitmap it will be shown in.  At the very last moment a Color is converted
>>> to a pixelValue that depends on the depth of the actual Bitmap inside the
>>> Form it will be used with.  The supported depths (in bits) are 1, 2, 4, 8,
>>> 16, and 32.  The number of actual colors at these depths are: 2, 4, 16,
>>> 256, 32768, and 16 million.  (See comment in BitBlt.)  To change the depth
>>> of the Display and set how many colors you can see, execute: (Display
>>> newDepth: 8).  (See comment in DisplayMedium)
>>>         Color is represented as the amount of light in red, green, and
>>> blue.  White is (1.0, 1.0, 1.0) and black is (0, 0, 0).  Pure red is (1.0,
>>> 0, 0).  These colors are "additive".  Think of Color's instance variables
>>> as:
>>>         r       amount of red, a Float between 0.0 and 1.0.
>>>         g       amount of green, a Float between 0.0 and 1.0.
>>>         b       amount of blue, a Float between 0.0 and 1.0.
>>>   (But, in fact, the three are encoded as values from 0 to 1023 and
>>> combined in a single integer, rgb.  The user does not need to know this.)
>>>         Many colors are named.  You find a color by name by sending a
>>> message to class Color, for example (Color lightBlue).  Also, (Color red:
>>> 0.2 green: 0.6 blue: 1.0) or (Color r: 0.2 g: 0.6 b: 1.0) creates a color.
>>> (see below)
>>>         A color is essentially immutable.  Once you set red, green, and
>>> blue, you cannot change them.  Instead, create a new Color and use it.
>>>         Applications such as contour maps and bar graphs will want to
>>> display one of a set of shades based on a number.  Convert the range of
>>> this number to an integer from 1 to N.  Then call (Color green lightShades:
>>> N) to get an Array of colors from white to green.  Use the Array messages
>>> at:, atPin:, or atWrap: to pull out the correct color from the array.
>>> atPin: gives the first (or last) color if the index is out of range.
>>> atWrap: wraps around to the other end if the index is out of range.
>>>         Here are some fun things to run in when your screen has color:
>>>                 Pen new mandala: 30 diameter: Display height-100.
>>>                 Pen new web  "Draw with the mouse, opt-click to end"
>>>                 Display fillWhite.  Pen new hilberts: 5.
>>>                 Form toothpaste: 30  "Draw with mouse, opt-click to end"
>>>   You might also want to try the comment in
>>>         Form>class>examples>tinyText...
>>>
>>>
>>>   Messages:
>>>         mixed: proportion with: aColor  Answer this color mixed with the
>>> given color additively. The proportion, a number between 0.0 and 1.0,
>>> determines what what fraction of the receiver to use in the mix.
>>>
>>>         +       add two colors
>>>         -       subtract two colors
>>>         *       multiply the values of r, g, b by a number or an Array
>>> of factors.  ((Color named: #white) * 0.3) gives a darkish gray.  (aColor *
>>> #(0 0 0.9)) gives a color with slightly less blue.
>>>         /       divide a color by a factor or an array of three factors.
>>>
>>>         errorForDepth: d     How close the nearest color at this depth
>>> is to this abstract color.  Sum of the squares of the RGB differences,
>>> square rooted and normalized to 1.0.  Multiply by 100 to get percent.
>>>
>>>         hue                     Returns the hue of the color. On a wheel
>>> from 0 to 360 with pure red at 0 and again at 360.
>>>         saturation      Returns the saturation of the color.  0.0 to 1.0
>>>         brightness      Returns the brightness of the color.  0.0 to 1.0
>>>
>>>         name    Look to see if this Color has a name.
>>>         display Show a swatch of this color tracking the cursor.
>>>
>>>         lightShades: thisMany           An array of thisMany colors from
>>> white to the receiver.
>>>         darkShades: thisMany            An array of thisMany colors from
>>> black to the receiver.  Array is of length num.
>>>         mix: color2 shades: thisMany            An array of thisMany
>>> colors from the receiver to color2.
>>>         wheel: thisMany                 An array of thisMany colors
>>> around the color wheel starting and ending at the receiver.
>>>
>>>         pixelValueForDepth: d    Returns the bits that appear be in a
>>> Bitmap of this depth for this color.  Represents the nearest available
>>> color at this depth.  Normal users do not need to know which pixelValue is
>>> used for which color.
>>>
>>>   Messages to Class Color.
>>>         red: r green: g blue: b         Return a color with the given r,
>>> g, and b components.
>>>         r: g: b:                Same as above, for fast typing.
>>>
>>>         hue: h saturation: s brightness: b              Create a color
>>> with the given hue, saturation, and brightness.
>>>
>>>         pink
>>>         blue
>>>         red ... Many colors have messages that return an instance of
>>> Color.
>>>         canUnderstand: #brown     Returns true if #brown is a defined
>>> color.
>>>         names           An OrderedCollection of the names of the colors.
>>>         named: #notAllThatGray put: aColor    Add a new color to the
>>> list and create an access message and a class variable for it.
>>>         fromUser        Shows the palette of colors available at this
>>> display depth.  Click anywhere to return the color you clicked on.
>>>
>>>         hotColdShades: thisMany An array of thisMany colors showing
>>> temperature from blue to red to white hot.
>>>
>>>       stdColorsForDepth: d        An Array of colors available at this
>>> depth.  For 16 bit and 32 bits, returns a ColorGenerator.  It responds to
>>> at: with a Color for that index, simulating a very big Array.
>>>
>>>      colorFromPixelValue: value depth: d    Returns a Color whose bit
>>> pattern (inside a Bitmap) at this depth is the number specified.  Normal
>>> users do not need to use this.
>>>
>>>   (See also comments in these classes: Form, Bitmap, BitBlt, Pattern,
>>> MaskedForm.)!
>>>
>>> Item was changed:
>>>   ----- Method: Color class>>initializeNames (in category 'class
>>> initialization') -----
>>>   initializeNames
>>>         "Name some colors."
>>>         "Color initializeNames"
>>>
>>>         ColorNames := Set new.
>>>         self named: #black put: (Color r: 0 g: 0 b: 0).
>>>         self named: #veryVeryDarkGray put: (Color r: 0.125 g: 0.125 b:
>>> 0.125).
>>>         self named: #veryDarkGray put: (Color r: 0.25 g: 0.25 b: 0.25).
>>>         self named: #darkGray put: (Color r: 0.375 g: 0.375 b: 0.375).
>>>         self named: #gray put: (Color r: 0.5 g: 0.5 b: 0.5).
>>>         self named: #lightGray put: (Color r: 0.625 g: 0.625 b: 0.625).
>>>         self named: #veryLightGray put: (Color r: 0.75 g: 0.75 b: 0.75).
>>>         self named: #veryVeryLightGray put: (Color r: 0.875 g: 0.875 b:
>>> 0.875).
>>>         self named: #white put: (Color r: 1.0 g: 1.0 b: 1.0).
>>>         self named: #red put: (Color r: 1.0 g: 0 b: 0).
>>>         self named: #yellow put: (Color r: 1.0 g: 1.0 b: 0).
>>>         self named: #green put: (Color r: 0 g: 1.0 b: 0).
>>>         self named: #cyan put: (Color r: 0 g: 1.0 b: 1.0).
>>>         self named: #blue put: (Color r: 0 g: 0 b: 1.0).
>>>         self named: #magenta put: (Color r: 1.0 g: 0 b: 1.0).
>>>         self named: #brown put: (Color r: 0.6 g: 0.2 b: 0).
>>>         self named: #orange put: (Color r: 1.0 g: 0.6 b: 0).
>>>         self named: #lightRed put: (Color r: 1.0 g: 0.8 b: 0.8).
>>>         self named: #lightYellow put: (Color r: 1.0 g: 1.0 b: 0.8).
>>>         self named: #lightGreen put: (Color r: 0.8 g: 1.0 b: 0.6).
>>>         self named: #lightCyan put: (Color r: 0.4 g: 1.0 b: 1.0).
>>>         self named: #lightBlue put: (Color r: 0.8 g: 1.0 b: 1.0).
>>>         self named: #lightMagenta put: (Color r: 1.0 g: 0.8 b: 1.0).
>>>         self named: #lightBrown put: (Color r: 1.0 g: 0.6 b: 0.2).
>>>         self named: #lightOrange put: (Color r: 1.0 g: 0.8 b: 0.4).
>>>         self named: #transparent put: (TranslucentColor new alpha: 0.0).
>>>         self named: #paleBuff put: (Color r: 254 g: 250 b: 235 range:
>>> 255).
>>>         self named: #paleBlue put: (Color r: 222 g: 249 b: 254 range:
>>> 255).
>>>         self named: #paleYellow put: (Color r: 255 g: 255 b: 217 range:
>>> 255).
>>>         self named: #paleGreen put: (Color r: 223 g: 255 b: 213 range:
>>> 255).
>>>         self named: #paleRed put: (Color r: 255 g: 230 b: 230 range:
>>> 255).
>>>         self named: #veryPaleRed put: (Color r: 255 g: 242 b: 242 range:
>>> 255).
>>>         self named: #paleTan put: (Color r: 235 g: 224 b: 199 range:
>>> 255).
>>>         self named: #paleMagenta put: (Color r: 255 g: 230 b: 255 range:
>>> 255).
>>>         self named: #paleOrange put: (Color r: 253 g: 237 b: 215 range:
>>> 255).
>>>         self named: #palePeach put: (Color r: 255 g: 237 b: 213 range:
>>> 255).
>>>         self named: #pantonePurpleU put: (Color r: 193 g: 81 b: 184
>>> range: 255).
>>> +       self initializeNamesMap
>>>
>>>   !
>>>
>>> Item was added:
>>> + ----- Method: Color class>>initializeNamesMap (in category 'class
>>> initialization') -----
>>> + initializeNamesMap
>>> +       "enable mapping a color to its name"
>>> +       "Color initializeNamesMap"
>>> +
>>> +       RGBToNames := Dictionary new.
>>> +       self colorNames do: [:sym | (self perform: sym) addName: sym]!
>>>
>>> Item was added:
>>> + ----- Method: Color>>addName: (in category 'other') -----
>>> + addName: aSymbol
>>> +       "private - associate a name to this color."
>>> +
>>> +       | knownNames |
>>> +       [(self class respondsTo: aSymbol) and: [(self class perform:
>>> aSymbol) = self]] assert.
>>> +       knownNames := RGBToNames at: rgb ifAbsent: [#()].
>>> +       (knownNames includes: aSymbol)
>>> +               ifFalse: [ RGBToNames at: rgb put: (knownNames copyWith:
>>> aSymbol)]!
>>>
>>> Item was changed:
>>>   ----- Method: Color>>name (in category 'other') -----
>>>   name
>>> +       "Return this color's name, or nil if it has no name."
>>> -       "Return this color's name, or nil if it has no name. Only
>>> returns a name if it exactly matches the named color."
>>>
>>> +       ^ (RGBToNames at: rgb ifAbsent: [nil]) ifNotNil: [:names | names
>>> at: 1 ifAbsent: [nil]]!
>>> -       ^ self class colorNames detect: [ :name | (Color perform: name)
>>> = self ] ifNone: [ nil ]!
>>>
>>> Item was added:
>>> + ----- Method: TranslucentColor>>addName: (in category 'other') -----
>>> + addName: aSymbol
>>> +       "private - associate a name to this color.
>>> +       Don't do it, Translucent colors are not uniquely identified by
>>> their rgb components"
>>> +
>>> +       ^self!
>>>
>>> Item was added:
>>> + ----- Method: TranslucentColor>>name (in category 'other') -----
>>> + name
>>> +       self = Color transparent ifTrue: [^#transparent].
>>> +       ^nil!
>>>
>>> Item was changed:
>>>   (PackageInfo named: 'Graphics') postscript: '
>>> + "Initialize RGBToName dictionary"
>>> + Color initializeNamesMap.'!
>>> - " Reset DejaVu to current version "
>>> - StrikeFont initialize.'!
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20190517/c5b8b3b7/attachment.html>


More information about the Squeak-dev mailing list