Make #pharoLogo for PolymorphSystemSettings use a FormSet for the logo at scale 1 and 2#16305
Conversation
|
I converted this to a draft. In the new forms, the shapes of the logo have darkened edges. Snippet to zoom in on the top of the ‘h’: ((Form fromBinaryStream: PolymorphSystemSettings pharoLogoContents base64Decoded readStream)
contentsOfArea: (75@0 extent: 30@30)) magnifyBy: 5 smoothing: 1I’m not sure how to fix that though. |
|
Having done some reading, I understand the problem is the new forms use premultiplied alpha, while what ImageMorph expects, and what the old form uses, is straight alpha. See the section ‘Straight versus premultiplied’ in the Wikipedia article on ‘Alpha compositing’. I could convert from premultiplied to straight: commit e4f54c1. It would seem better to draw the forms directly using straight alpha, but I’m not sure that’s possible: the documentation for image surfaces in Cairo doesn’t seem to list a counterpart that uses straight alpha for ‘CAIRO_FORMAT_ARGB32’ which uses premultiplied alpha. Unless it’s ‘CAIRO_FORMAT_RGBA128F’ but the description doesn’t say. @tinchodias: Perhaps you know more about this question of straight versus premultiplied alpha in Cairo and Athens? |
|
Hello @Rinzwind I will read more in detail of this FormSet issue during the week, but for the moment I send you the imformation I have at hand. I learnt a bit of this topic, for example in: pharo-graphics/Alexandrie#35 The following are parts of emails I sent to bloc mailing list: The Bloc image background had a Form converted to Cairo image, and the debugging tool converts again to Form to show it in a Morph. An instance of AeCairoImageSurface can be created from a Form, and it provides asForm to get again a Form, but there was an error in the middle that is shown in this example: Curiosity: Both formats are 32 bits, and ARGB order, but there is calculation to perform on each pixel on conversion. Cairo format is described as follows: CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with alpha in the upper 8 bits, then red, then green, then blue. The 32-bit quantities are stored native-endian. Pre-multiplied alpha is used. (That is, 50% transparent red is 0x80800000, not 0x80ff0000.) Form, is "straight alpha", that can be explained as: "In this world, RGB and alpha are independent. You can change one without affecting the other. To make an object fade out, you would gradually reduce its alpha value while leaving RGB unchanged." We already had the conversion Form -> Cairo, but not the Cairo -> Form, so that's what I pushed to close the issue. Plus added 2 tests. and then: I had to push a further fix. Now the conversion from Cairo (premultiplied alpha) to Form (straight alpha), restores the brightness (or saturation?) of each translucent pixel (non opaque). As this is proper to Cairo to Form conversion, it's not only Alexandrie, also Athens-Cairo should do it. Left: current, Right: applying the transformation from the premultiplied format of Cairo: zoom: |
|
Thank you for the discussion. This is great to have you around. |
…o at scale 1 and 2.
2a6989c to
d11937b
Compare
|
@tinchodias: Thanks for the info! I have now regenerated byteArray := ByteArray streamContents: [ :byteArrayStream |
| surfaceForm convertedForm |
surfaceForm := surface asForm.
convertedForm := Form extent: surfaceForm extent depth: 32.
0 to: convertedForm width do: [ :x |
0 to: convertedForm height do: [ :y |
| color |
color := surfaceForm colorAt: x@y.
convertedForm colorAt: x@y put:
(color alpha > 0 ifTrue: [ color / color alpha ] ifFalse: [ color ]) ] ].
PNGReadWriter putForm: convertedForm onStream: byteArrayStream ].I force-pushed the branch to a new commit to avoid keeping the previously generated methods, which are a bit large, in the history. |
|
Is it ready for the merge now? |
|
Yes, please do merge this! |




This pull request makes
#pharoLogofor PolymorphSystemSettings use a FormSet for the logo at scale 1 and 2. I used the snippet given below to generate#pharoLogoContents1and#pharoLogoContents2. The send of#fill_opacity:in the snippet is a workaround, the ‘flare’ path is drawn fully opaque otherwise.