[squeak-dev] The Trunk: Graphics-tpr.226.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Sep 23 19:42:56 UTC 2013


tim Rowledge uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-tpr.226.mcz

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

Name: Graphics-tpr.226
Author: tpr
Time: 23 September 2013, 12:42:11.34 pm
UUID: 842c37b1-aab4-41a7-b8ff-1411a96c4590
Ancestors: Graphics-tpr.225

A first step in improvingthe characterscanner tree(s);
mostly split out kerning and non-kerning scanning. Also add some guide comments for later parts of the work, so some methods are only changed in comment.

=============== Diff against Graphics-tpr.225 ===============

Item was added:
+ ----- Method: AbstractFont>>isPairKerningCapable (in category 'testing') -----
+ isPairKerningCapable
+ "a hopefully temporary test method; better factoring of scan/measure/display should remove the need for it.
+ Only FreeType fonts would currently add this to return true"
+ 	^false!

Item was removed:
- ----- Method: AbstractFont>>widthAndKernedWidthOfLeft:right:into: (in category 'kerning') -----
- widthAndKernedWidthOfLeft: leftCharacter right: rightCharacterOrNil into: aTwoElementArray
- 	"Set the first element of aTwoElementArray to the width of leftCharacter and 
- 	the second element to the width of left character when kerned with
- 	rightCharacterOrNil. Answer aTwoElementArray"
- 	| w k |
- 	w := self widthOf: leftCharacter.
- 	rightCharacterOrNil isNil
- 		ifTrue:[
- 			aTwoElementArray 
- 				at: 1 put: w; 
- 				at: 2 put: w]
- 		ifFalse:[
- 			k := self kerningLeft: leftCharacter right: rightCharacterOrNil.
- 			aTwoElementArray 
- 				at: 1 put: w; 
- 				at: 2 put: w+k].
- 	^aTwoElementArray
- 	!

Item was changed:
  ----- Method: CharacterScanner>>basicScanCharactersFrom:to:in:rightX:stopConditions:kern: (in category 'scanning') -----
+ basicScanCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta 
+ 	"In ancient days this would have called primitive 103 to scan a string with StrikeFont, but time moves on. See historicalScanCharactersFrom:to:in:rightX:stopConditions:kern: if you're curious. This code handles the newer shape of CharacterScanner but does *no* pair kerning.
+ 	There is a pretty deep assumption of simple ASCII strings and characters - beware"
+ 	| ascii nextDestX char |
- basicScanCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta
- 	"Primitive. This is the inner loop of text display--but see 
- 	scanCharactersFrom: to:rightX: which would get the string, 
- 	stopConditions and displaying from the instance. March through source 
- 	String from startIndex to stopIndex. If any character is flagged with a 
- 	non-nil entry in stops, then return the corresponding value. Determine 
- 	width of each character from xTable, indexed by map. 
- 	If dextX would exceed rightX, then return stops at: 258. 
- 	Advance destX by the width of the character. If stopIndex has been
- 	reached, then return stops at: 257. Optional. 
- 	See Object documentation whatIsAPrimitive."
- 	| ascii nextDestX char  floatDestX widthAndKernedWidth nextChar atEndOfRun |
- 	<primitive: 103>
  	lastIndex := startIndex.
- 	floatDestX := destX.
- 	widthAndKernedWidth := Array new: 2.
- 	atEndOfRun := false.
  	[lastIndex <= stopIndex]
+ 		whileTrue: [
+ 			"get the character value"
+ 			char := sourceString at: lastIndex.
- 		whileTrue: 
- 			[char := (sourceString at: lastIndex).
  			ascii := char asciiValue + 1.
+ 			"if there is an entry in 'stops' for this value, return it"
+ 			(stops at: ascii)
+ 				ifNotNil: [^ stops at: ascii].
+ 			"bump nextDestX by the width of the current character"
+ 			nextDestX := destX + (font widthOf: char).
+ 			"if the next x is past the right edge, return crossedX"
+ 			nextDestX > rightX
+ 				ifTrue: [^ stops crossedX].
+ 			"update destX and incorporate thr kernDelta"
+ 			destX := nextDestX + kernDelta.
- 			(stops at: ascii) == nil ifFalse: [^stops at: ascii].
- 			"Note: The following is querying the font about the width
- 			since the primitive may have failed due to a non-trivial
- 			mapping of characters to glyphs or a non-existing xTable."
- 			nextChar := (lastIndex + 1 <= stopIndex) 
- 				ifTrue:[sourceString at: lastIndex + 1]
- 				ifFalse:[
- 					atEndOfRun := true.
- 					"if there is a next char in sourceString, then get the kern 
- 					and store it in pendingKernX"
- 					lastIndex + 1 <= sourceString size
- 						ifTrue:[sourceString at: lastIndex + 1]
- 						ifFalse:[	nil]].
- 			font 
- 				widthAndKernedWidthOfLeft: char 
- 				right: nextChar
- 				into: widthAndKernedWidth.
- 			nextDestX := floatDestX + (widthAndKernedWidth at: 1).
- 			nextDestX > rightX ifTrue: [^stops crossedX].
- 			floatDestX := floatDestX + kernDelta + (widthAndKernedWidth at: 2).
- 			atEndOfRun 
- 				ifTrue:[
- 					pendingKernX := (widthAndKernedWidth at: 2) - (widthAndKernedWidth at: 1).
- 					floatDestX := floatDestX - pendingKernX].
- 			destX := floatDestX.
  			lastIndex := lastIndex + 1].
  	lastIndex := stopIndex.
+ 	^ stops endOfRun!
- 	^stops endOfRun!

Item was added:
+ ----- Method: CharacterScanner>>basicScanKernableCharactersFrom:to:in:rightX:stopConditions:kern: (in category 'scanning') -----
+ basicScanKernableCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta 
+ 	"In ancient days this would have called primitive 103 to scan a string with StrikeFont, but time moves on. See historicalScanCharactersFrom:to:in:rightX:stopConditions:kern: if you're curious. This code handles the newer shape of CharacterScanner and provides some support for fonts that have pair-kerning; this may be removable with some better factoring.
+ 	There is a pretty deep assumption of simple ASCII strings and characters - beware"
+ 	| ascii nextDestX char floatDestX widthAndKernedWidth nextCharOrNil atEndOfRun |
+ 	lastIndex := startIndex.
+ 	floatDestX := destX.
+ 	widthAndKernedWidth := Array new: 2.
+ 	atEndOfRun := false.
+ 	[lastIndex <= stopIndex]
+ 		whileTrue: [
+ 			"get the character value"
+ 			char := sourceString at: lastIndex.
+ 			ascii := char asciiValue + 1.
+ 			"if there is an entry in 'stops' for this value, return it"
+ 			(stops at: ascii)
+ 				ifNotNil: [^ stops at: ascii].
+ 			"get the next character..."
+ 			nextCharOrNil := lastIndex + 1 <= stopIndex
+ 						ifTrue: [sourceString at: lastIndex + 1]
+ 						ifFalse: ["if we're at or past the stopIndex, see if there is anything in the full string"
+ 							atEndOfRun := true.
+ 							lastIndex + 1 <= sourceString size
+ 								ifTrue: [sourceString at: lastIndex + 1]].
+ 			"get the font's kerning info for the pair of current character and next character"
+ 			"for almost all fonts in common use this is a waste of time since they don't support pair kerning and both values are #widthOf: char"
+ 			font
+ 				widthAndKernedWidthOfLeft: char
+ 				right: nextCharOrNil
+ 				into: widthAndKernedWidth.
+ 			"bump nextDestX by the width of the current character"
+ 			nextDestX := floatDestX
+ 						+ (widthAndKernedWidth at: 1).
+ 			"if the next x is past the right edge, return crossedX"
+ 			nextDestX > rightX
+ 				ifTrue: [^ stops crossedX].
+ 			"bump floatDestX by the *kerned* width of the current
+ 			character, which is where the *next* char will go"
+ 			floatDestX := floatDestX + kernDelta
+ 						+ (widthAndKernedWidth at: 2).
+ 			"if we are at the end of this run we keep track of the
+ 			character-kern-delta for possible later use and then rather
+ 			insanely remove that character-kern-delta from floatDestX,
+ 			making it equivalent to (old floatDestX) + kernDelta +
+ 			width-of-character - no idea why"
+ 			atEndOfRun
+ 				ifTrue: [pendingKernX := (widthAndKernedWidth at: 2)
+ 								- (widthAndKernedWidth at: 1).
+ 					floatDestX := floatDestX - pendingKernX].
+ 			"save the next x for next time around the loop"
+ 			destX := floatDestX.
+ 			lastIndex := lastIndex + 1].
+ 	lastIndex := stopIndex.
+ 	^ stops endOfRun!

Item was added:
+ ----- Method: CharacterScanner>>historicalScanCharactersFrom:to:in:rightX:stopConditions:kern: (in category 'scanning') -----
+ historicalScanCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta
+ 	"Primitive. This is the inner loop of text display--but see 
+ 	scanCharactersFrom: to:rightX: which would get the string, 
+ 	stopConditions and displaying from the instance. March through source 
+ 	String from startIndex to stopIndex. If any character is flagged with a 
+ 	non-nil entry in stops, then return the corresponding value. Determine 
+ 	width of each character from xTable, indexed by map. 
+ 	If dextX would exceed rightX, then return stops at: 258. 
+ 	Advance destX by the width of the character. If stopIndex has been
+ 	reached, then return stops at: 257. Optional. 
+ 	See Object documentation whatIsAPrimitive.
+ 	Historical note: this primitive has been unusable since about Squeak 2.8 when the shape of the CharracterScanner class changed. It is left here as a reminder that the actual primitive still needs supporting in the VM to keep old images such as Scratch1.4 alive - tpr"
+ 	| ascii nextDestX char |
+ 	<primitive: 103>
+ 	lastIndex _ startIndex.
+ 	[lastIndex <= stopIndex]
+ 		whileTrue: 
+ 			[char _ (sourceString at: lastIndex).
+ 			ascii _ char asciiValue + 1.
+ 			(stops at: ascii) == nil ifFalse: [^stops at: ascii].
+ 			"Note: The following is querying the font about the width
+ 			since the primitive may have failed due to a non-trivial
+ 			mapping of characters to glyphs or a non-existing xTable."
+ 			nextDestX _ destX + (font widthOf: char).
+ 			nextDestX > rightX ifTrue: [^stops at: CrossedX].
+ 			destX _ nextDestX + kernDelta.
+ 			lastIndex _ lastIndex + 1].
+ 	lastIndex _ stopIndex.
+ 	^stops at: EndOfRun
+ !

Item was changed:
  ----- Method: CharacterScanner>>isBreakableAtIndex: (in category 'scanner methods') -----
  isBreakableAtIndex: index
+ "appears t obe unused - cf MultiCharacterScanner>isBreakableAt:in:in"
- 
  	^ (EncodedCharSet at: ((text at: index) leadingChar + 1)) isBreakableAt: index in: text.
  !

Item was changed:
  ----- Method: CharacterScanner>>scanCharactersFrom:to:in:rightX:stopConditions:kern: (in category 'scanning') -----
+ scanCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta 
- scanCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta
- 
  	| startEncoding selector |
+ 	sourceString isByteString
+ 		ifTrue: [font isPairKerningCapable
+ 				ifTrue: [^ self
+ 						basicScanKernableCharactersFrom: startIndex
+ 						to: (stopIndex min: sourceString size)
+ 						in: sourceString
+ 						rightX: rightX
+ 						stopConditions: stops
+ 						kern: kernDelta]
+ 				ifFalse: [^ self
+ 						basicScanCharactersFrom: startIndex
+ 						to: (stopIndex min: sourceString size)
+ 						in: sourceString
+ 						rightX: rightX
+ 						stopConditions: stops
+ 						kern: kernDelta]].
+ 	sourceString isWideString
+ 		ifTrue: [startIndex > stopIndex
+ 				ifTrue: [lastIndex := stopIndex.
+ 					^ stops endOfRun].
+ 			startEncoding := (sourceString at: startIndex) leadingChar.
+ 			selector := EncodedCharSet scanSelectorAt: startEncoding.
+ 			^ self
+ 				perform: selector
+ 				withArguments: (Array
+ 						with: startIndex
+ 						with: stopIndex
+ 						with: sourceString
+ 						with: rightX
+ 						with: stops
+ 						with: kernDelta)].
+ 	^ stops endOfRun!
- 	(sourceString isByteString) ifTrue: [^ self basicScanCharactersFrom: startIndex to: (stopIndex min: sourceString size) in: sourceString rightX: rightX stopConditions: stops kern: kernDelta.].
- 
- 	(sourceString isWideString) ifTrue: [
- 		startIndex > stopIndex ifTrue: [lastIndex := stopIndex. ^ stops endOfRun].
- 		startEncoding :=  (sourceString at: startIndex) leadingChar.
- 		selector := EncodedCharSet scanSelectorAt: startEncoding.
- 		^ self perform: selector withArguments: (Array with: startIndex with: stopIndex with: sourceString with: rightX with: stops with: kernDelta).
- 	].
- 	
- 	^ stops endOfRun
- !

Item was removed:
- ----- Method: CharacterScanner>>scanMultiCharactersCombiningFrom:to:in:rightX:stopConditions:kern: (in category 'scanner methods') -----
- scanMultiCharactersCombiningFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta
- 	"Implement a workaround for unicode composing.
- 	a MultiCharacterScanner should better be used to handle combination."
- 
- 	^self scanMultiCharactersFrom: startIndex to: stopIndex in: sourceString rightX: rightX stopConditions: stops kern: kernDelta!



More information about the Squeak-dev mailing list