[squeak-dev] The Trunk: Graphics-nice.282.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Dec 20 00:35:41 UTC 2013


Nicolas Cellier uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-nice.282.mcz

==================== Summary ====================

Name: Graphics-nice.282
Author: nice
Time: 20 December 2013, 1:34:17.553 am
UUID: 89166f93-3989-4cbd-aa5e-14f949960b9b
Ancestors: Graphics-nice.281

1) Fix initialization of a Form bits. the guard against wrong bitsSize were never invoked on new instances.

2) Accelerate a bit Color>>pixelValueForDepth:,
2.a) Most frequent usage nowadays is for 32 bits depth, so raise this case to the top.
2.b) the guard against rgb=0 being used for marking transparent can be factored out
   (Note that Squeak was not the only app. to use this trick, like explained at
    http://en.wikipedia.org/wiki/Palette_%28computing%29#Transparent_color_in_palettes)
2.c) The (LargeInteger new: 4) trick is now more straightforward thanks to 2.b)
   Note 1: the normalize could be replaced by yourself in 32 bits images,
   but the futur never were so close than now ;) - I mean Spur
   Note 2: I check that using SmallInteger arithmetic and final LargeIntegerization is slower, COG or not.
   So the (LargeInteger new: 4) trick will stay a while longer.
   It would be more efficient to reduce Color componentMax to: 255.0, then use a single + 16rFF000000...

3) Guard more Form bits inst. var. access with unhibernate.
  This was not applied to pixelValueAt: because this message is used inside tight loops,
  and it would be preferable (more efficient) to fail the primitive, and unhibernate in the fallback code.

4) Classify a few methods exclusively used by PostScript generation under 'postscript generation'.
  I know they virtually could be used for something else, but there's enough API to digest and classification helps.
  It will be time to unclassify eventually if ever someone send those messages

=============== Diff against Graphics-nice.281 ===============

Item was changed:
  ----- Method: Color>>pixelValueForDepth: (in category 'conversions') -----
  pixelValueForDepth: d
  	"Returns an integer representing the bits that appear in a single pixel of this color in a Form of the given depth. The depth must be one of 1, 2, 4, 8, 16, or 32. Contrast with pixelWordForDepth: and bitPatternForDepth:, which return either a 32-bit word packed with the given pixel value or a multiple-word Bitmap containing a pattern. The inverse is the class message colorFromPixelValue:depth:"
  	"Details: For depths of 8 or less, the result is a colorMap index. For depths of 16 and 32, it is a direct color value with 5 or 8 bits per color component."
  	"Transparency: The pixel value zero is reserved for transparent. For depths greater than 8, black maps to the darkest possible blue."
  
+ 	| rgbVal |
+ 	d > 8 "most common case"
+ 		ifTrue:
+ 			[rgbVal := rgb = 0
+ 				ifTrue: [1]  "closest black that is not transparent in RGB"
+ 				ifFalse: [rgb].
- 	| rgbBlack val |
- 	d = 8 ifTrue: [^ self closestPixelValue8].  "common case"
- 	d < 8 ifTrue: [
- 		d = 4 ifTrue: [^ self closestPixelValue4].
- 		d = 2 ifTrue: [^ self closestPixelValue2].
- 		d = 1 ifTrue: [^ self closestPixelValue1]].
  
+ 			d = 32 ifTrue: [
+ 				"eight bits per component; top 8 bits set to all ones (opaque alpha)"
+ 				^(LargePositiveInteger new: 4)
+ 					at: 4 put: 16rFF;
+ 					at: 3 put: ((rgbVal bitShift: -22) bitAnd: 16rFF);
+ 					at: 2 put: ((rgbVal bitShift: -12) bitAnd: 16rFF);
+ 					at: 1 put: ((rgbVal bitShift: -2) bitAnd: 16rFF);
+ 					normalize "normalize is not necessary as long as SmallInteger maxVal highBit < 32, but let's be future proof"].
+ 				
+ 			d = 16 ifTrue: [
+ 				"five bits per component; top bits ignored"
+ 				^(((rgbVal bitShift: -15) bitAnd: 16r7C00) bitOr:
+ 					 ((rgbVal bitShift: -10) bitAnd: 16r03E0)) bitOr:
+ 					 ((rgbVal bitShift: -5) bitAnd: 16r001F)].
- 	rgbBlack := 1.  "closest black that is not transparent in RGB"
  
+ 			d = 12 ifTrue: [  "for indexing a color map with 4 bits per color component"
+ 				^(((rgbVal bitShift: -18) bitAnd: 16r0F00) bitOr:
+ 					 ((rgbVal bitShift: -12) bitAnd: 16r00F0)) bitOr:
+ 					 ((rgbVal bitShift: -6) bitAnd: 16r000F)].
- 	d = 16 ifTrue: [
- 		"five bits per component; top bits ignored"
- 		val := (((rgb bitShift: -15) bitAnd: 16r7C00) bitOr:
- 			 ((rgb bitShift: -10) bitAnd: 16r03E0)) bitOr:
- 			 ((rgb bitShift: -5) bitAnd: 16r001F).
- 		^ val = 0 ifTrue: [rgbBlack] ifFalse: [val]].
  
+ 			d = 9 ifTrue: [  "for indexing a color map with 3 bits per color component"
+ 				^(((rgbVal bitShift: -21) bitAnd: 16r01C0) bitOr:
+ 					 ((rgbVal bitShift: -14) bitAnd: 16r0038)) bitOr:
+ 					 ((rgbVal bitShift: -7) bitAnd: 16r0007)]].
+ 	d = 8 ifTrue: [^ self closestPixelValue8].
+ 	d = 4 ifTrue: [^ self closestPixelValue4].
+ 	d = 2 ifTrue: [^ self closestPixelValue2]..
+ 	d = 1 ifTrue: [^ self closestPixelValue1].
- 	d = 32 ifTrue: [
- 		"eight bits per component; top 8 bits set to all ones (opaque alpha)"
- 		val := LargePositiveInteger new: 4.
- 		val at: 3 put: ((rgb bitShift: -22) bitAnd: 16rFF).
- 		val at: 2 put: ((rgb bitShift: -12) bitAnd: 16rFF).
- 		val at: 1 put: ((rgb bitShift: -2) bitAnd: 16rFF).
- 		val normalize = 0 ifTrue: [val at: 1 put: 1].  "closest non-transparent black"
- 		val at: 4 put: 16rFF.  "opaque alpha"
- 		^ val normalize].
  
- 	d = 12 ifTrue: [  "for indexing a color map with 4 bits per color component"
- 		val := (((rgb bitShift: -18) bitAnd: 16r0F00) bitOr:
- 			 ((rgb bitShift: -12) bitAnd: 16r00F0)) bitOr:
- 			 ((rgb bitShift: -6) bitAnd: 16r000F).
- 		^ val = 0 ifTrue: [rgbBlack] ifFalse: [val]].
- 
- 	d = 9 ifTrue: [  "for indexing a color map with 3 bits per color component"
- 		val := (((rgb bitShift: -21) bitAnd: 16r01C0) bitOr:
- 			 ((rgb bitShift: -14) bitAnd: 16r0038)) bitOr:
- 			 ((rgb bitShift: -7) bitAnd: 16r0007).
- 		^ val = 0 ifTrue: [rgbBlack] ifFalse: [val]].
- 
  	self error: 'unknown pixel depth: ', d printString
  !

Item was changed:
  ----- Method: Form>>setExtent:depth:bits: (in category 'private') -----
  setExtent: extent depth: bitsPerPixel bits: bitmap
  	"Create a virtual bit map with the given extent and bitsPerPixel."
  
  	width := extent x asInteger.
  	width < 0 ifTrue: [width := 0].
  	height := extent y asInteger.
  	height < 0 ifTrue: [height := 0].
  	depth := bitsPerPixel.
+ 	depth := bitsPerPixel.
+ 	(bitmap isNil
+ 		or:[(bitmap class isWords and: [self bitsSize = bitmap size])
+ 		or: [bitmap class isBytes and: [self bitsSize * 4 = bitmap size]]])
+ 			ifFalse:[^self error:'Bad dimensions'].
- 	(bits isNil or:[self bitsSize = bitmap size]) ifFalse:[^self error:'Bad dimensions'].
  	bits := bitmap!

Item was changed:
+ ----- Method: Form>>store15To24HexBitsOn: (in category 'postscript generation') -----
- ----- Method: Form>>store15To24HexBitsOn: (in category 'fileIn/Out') -----
  store15To24HexBitsOn:aStream
  
  	| buf lineWidth |
  
  	"write data for 16-bit form, optimized for encoders writing directly to files to do one single file write rather than 12. I'm not sure I understand the significance of the shifting pattern, but I think I faithfully translated it from the original"
  
  	lineWidth := 0.
  	buf := String new: 12.
+ 	self unhibernate.
  	bits do: [:word | | i | 
  		i := 0.
  		"upper pixel"
  		buf at: (i := i + 1) put: ((word bitShift: -27) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -32) bitAnd: 8) asHexDigit.
  
  		buf at: (i := i + 1) put: ((word bitShift: -22) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -27) bitAnd: 8) asHexDigit.
  
  		buf at: (i := i + 1) put: ((word bitShift: -17) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -22) bitAnd: 8) asHexDigit.
  
  		"lower pixel"
  
  		buf at: (i := i + 1) put: ((word bitShift: -11) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -16) bitAnd: 8) asHexDigit.
  
  		buf at: (i := i + 1) put: ((word bitShift: -6) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -11) bitAnd: 8) asHexDigit.
  
  		buf at: (i := i + 1) put: ((word bitShift: -1) bitAnd: 15) asHexDigit.
  		buf at: (i := i + 1) put: ((word bitShift: -6) bitAnd: 8) asHexDigit.
  		aStream nextPutAll: buf.
  		lineWidth := lineWidth + 12.
  		lineWidth > 100 ifTrue: [ aStream cr. lineWidth := 0 ].
  		"#( 31 26 21 15 10 5 )  do:[:startBit | ]"
  	].!

Item was changed:
+ ----- Method: Form>>store32To24HexBitsOn: (in category 'postscript generation') -----
- ----- Method: Form>>store32To24HexBitsOn: (in category 'fileIn/Out') -----
  store32To24HexBitsOn:aStream
  	^self storeBits:20 to:0 on:aStream.!

Item was changed:
+ ----- Method: Form>>storeBits:to:on: (in category 'postscript generation') -----
- ----- Method: Form>>storeBits:to:on: (in category 'fileIn/Out') -----
  storeBits:startBit to:stopBit on:aStream
+ 	self unhibernate.
  	bits storeBits:startBit to:stopBit on:aStream.!

Item was changed:
  ----- Method: Form>>storeBitsOn:base: (in category 'fileIn/Out') -----
  storeBitsOn:aStream base:anInteger
+ 	self unhibernate.
  	bits do: [:word | 
  		anInteger = 10
  			ifTrue: [aStream space]
  			ifFalse: [aStream crtab: 2].
  		word storeOn: aStream base: anInteger].
  !

Item was changed:
+ ----- Method: Form>>storeHexBitsOn: (in category 'postscript generation') -----
- ----- Method: Form>>storeHexBitsOn: (in category 'fileIn/Out') -----
  storeHexBitsOn:aStream
  	^self storeBits:28 to:0 on:aStream.!



More information about the Squeak-dev mailing list