[squeak-dev] The Trunk: Morphic-EG.1983.mcz

commits at source.squeak.org commits at source.squeak.org
Thu May 5 12:44:18 UTC 2022


Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-EG.1983.mcz

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

Name: Morphic-EG.1983
Author: EG
Time: 5 May 2022, 7:05:04.44181 am
UUID: fa611fc3-37ca-4bce-a541-5c5265fc8d3a
Ancestors: Morphic-mt.1982

Switching from AnimatedImageMorph pre-composing full Forms from AnimatedImageFrames to doing live composition during animation playback. The composition of frames is based on the disposal information for each frame.
  
This should decrease loading times for displaying animated GIFs in the system.

For the moment, we only handle #leaveCurrent and #restoreBackground disposals, though these seem to cover 99% of cases in the wild.

=============== Diff against Morphic-mt.1982 ===============

Item was changed:
  ImageMorph subclass: #AnimatedImageMorph
+ 	instanceVariableNames: 'images delays stepTime imageIndex disposals'
- 	instanceVariableNames: 'images delays stepTime imageIndex'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Morphic-Basic'!
  
  !AnimatedImageMorph commentStamp: 'EG 12/4/2021 12:33' prior: 0!
  I am an ImageMorph that can hold more than one image. Each image has its own delay time. I am most commonly created using GIFReaderWriter when it contains multiple images/frames.!

Item was removed:
- ----- Method: AnimatedImageMorph>>composedFormsFromReader: (in category 'frame composition') -----
- composedFormsFromReader: aGIFReader
- 	"Compose a collection of Forms that are composited
- 	from the incoming collection of Frames. We do this instead of
- 	compositing each Form on the fly for performance reasons.
- 	With this method, we can achieve better framerates for
- 	Animated GIFs."
- 	| nextForm compForm |
- 	nextForm := Form extent: (aGIFReader canvasWidth)@(aGIFReader canvasHeight) depth: 32.
- 	^ aGIFReader frames collect: [ :frame |
- 		frame form displayOn: nextForm at: 0 at 0 rule: Form paint.
- 		compForm := nextForm.
- 		frame disposal = #leaveCurrent
- 			ifTrue: [ nextForm := nextForm copy ]
- 			ifFalse: [ frame disposal = #restoreBackground
- 				ifTrue: [ nextForm := Form extent: (aGIFReader canvasWidth)@(aGIFReader canvasHeight) depth: 32 ]].
- 		compForm ]!

Item was added:
+ ----- Method: AnimatedImageMorph>>fromFrames: (in category 'initialization') -----
+ fromFrames: aFrameCollection
+ 	"Initialize this morph from a colleciton of 
+ 	AnimatedImageFrames"
+ 	delays := OrderedCollection new.
+ 	disposals := OrderedCollection new.
+ 	images := OrderedCollection new.
+ 	aFrameCollection do: [ :frame |
+ 		delays add: frame delay.
+ 		disposals add: frame disposal.
+ 		images add: frame form ].!

Item was changed:
  ----- Method: AnimatedImageMorph>>fromGIFReader: (in category 'initialization') -----
  fromGIFReader: aGIFReader
+ 	self 
+ 		fromFrames: aGIFReader frames;
+ 		color: aGIFReader backgroundColor;
+ 		width: aGIFReader canvasWidth;
+ 		height: aGIFReader canvasHeight.
+ 		
+ 	"Set the current active image form to
+ 	a form that is the same dimensions as this morph"
+ 	self image: ((FormCanvas extent: (aGIFReader canvasWidth)@(aGIFReader canvasHeight))
+ 		fillColor: self color;
+ 		drawImage: images first
+ 		at: images first offset;
+ 		form)!
- 	delays := aGIFReader delays.
- 	self
- 		stepTime: aGIFReader delays first;
- 		images: (self composedFormsFromReader: aGIFReader);
- 		yourself!

Item was changed:
  ----- Method: AnimatedImageMorph>>step (in category 'stepping and presenter') -----
  step
+ 	| disposal canvas current |
+ 	"If we are about to go beyond the number of images,
+ 	then loop back to the first one"
+ 	((imageIndex) >= images size)
- 	((imageIndex + 1) >= images size)
  		ifTrue: [ imageIndex := 1 ]
  		ifFalse: [ imageIndex := imageIndex + 1 ].
+ 		
+ 	current := images at: imageIndex.
+ 
+ 	"If this is the first image in the sequence, we don't
+ 	have a previous disposal to look at. So just paint
+ 	the image -- equiv to #leaveCurrent"
+ 	canvas := image getCanvas.
+ 	(imageIndex == 1)
+ 		ifTrue: [
+ 			image getCanvas drawImage: current at: current offset ]
+ 		ifFalse: [
+ 			"Otherwise, we need to look at the previous image's disposal method
+ 			to see if we should restore the background"
+ 			disposal := disposals at: imageIndex - 1.
+ 			(disposal == #restoreBackground)
+ 				ifTrue: [
+ 					"canvas 
+ 						fillRectangle: self bounds
+ 						color: self color"
+ 					canvas := (Form extent: canvas extent depth: 32) getCanvas.
+ 					canvas fillRectangle: ((current offset) corner: (current offset + current extent)) color: self color.
+ 					canvas drawImage: current at: current offset ]
+ 				ifFalse: [ canvas paintImage: current at: current offset ]
+ 			 ].
+ 	self image: canvas form.
+ 	self stepTime: (delays at: imageIndex)!
- 	self
- 		stepTime: (delays at: imageIndex);
- 		image: (images at: imageIndex)
- !



More information about the Squeak-dev mailing list