'From Cuis 1.0 of 21 August 2009 [latest update: #268] on 24 August 2009 at 10:25:41 am'!
!classDefinition: #DisplayScanner category: #'Graphics-Text'!
CharacterScanner subclass: #DisplayScanner
	instanceVariableNames: 'bitBlt lineY runX foregroundColor backgroundColor fillBlt lineHeight paragraphColor morphicOffset ignoreColorChanges '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Graphics-Text'!

!DisplayScanner methodsFor: 'scanning' stamp: 'jmv 8/24/2009 10:23'!
displayLine: textLine offset: offset leftInRun: leftInRun
	"The call on the primitive (scanCharactersFrom:to:in:rightX:) will be interrupted according to an array of stop conditions passed to the scanner at which time the code to handle the stop condition is run and the call on the primitive continued until a stop condition returns true (which means the line has terminated).  leftInRun is the # of characters left to scan in the current run; when 0, it is time to call setStopConditions."
	| done stopCondition nowLeftInRun startIndex string lastPos |
	line _ textLine.
	morphicOffset _ offset.
	lineY _ line top + offset y.
	lineHeight _ line lineHeight.
	rightMargin _ line rightMargin + offset x.
	lastIndex _ line first.
	leftInRun <= 0 ifTrue: [self setStopConditions].
	leftMargin _ (line leftMarginForAlignment: alignment) + offset x.
	destX _ runX _ leftMargin.
	lastIndex _ line first.
	leftInRun <= 0
		ifTrue: [nowLeftInRun _ text runLengthFor: lastIndex]
		ifFalse: [nowLeftInRun _ leftInRun].
	destY _ lineY + line baseline - font ascent.
	runStopIndex _ lastIndex + (nowLeftInRun - 1) min: line last.
	spaceCount _ 0.
	done _ false.
	string _ text string.
	[done] whileFalse:[
		startIndex _ lastIndex.
		lastPos _ destX@destY.
		stopCondition _ self scanCharactersFrom: lastIndex to: runStopIndex
						in: string rightX: rightMargin stopConditions: stopConditions
						kern: kern.
		lastIndex >= startIndex ifTrue:[
			font displayString: string on: bitBlt 
				from: startIndex to: lastIndex at: lastPos kern: kern].
		"see setStopConditions for stopping conditions for displaying."
		done _ self perform: stopCondition].
	^ runStopIndex - lastIndex   "Number of characters remaining in the current run"! !

!DisplayScanner methodsFor: 'private' stamp: 'jmv 8/24/2009 10:23'!
text: t foreground: foreColor ignoreColorChanges: shadowMode
	text _ t.
	actualTextStyle _ t initialStyle.
	foregroundColor _ paragraphColor _ foreColor.
	ignoreColorChanges _ shadowMode! !


!FormCanvas methodsFor: 'drawing' stamp: 'jmv 8/24/2009 10:21'!
paragraph: para bounds: bounds color: c

	| scanner |
	self setPaintColor: c.
	scanner _ (port clippedBy: (bounds translateBy: origin))
		displayScannerFor: para
		foreground: (self shadowColor ifNil: [c])
		ignoreColorChanges: self shadowColor notNil.
	para displayOn: (self copyClipRect: bounds) using: scanner at: origin+ bounds topLeft! !


!GrafPort methodsFor: 'accessing' stamp: 'jmv 8/24/2009 10:19'!
displayScannerFor: para foreground: foreColor ignoreColorChanges: shadowMode

	^ (DisplayScanner new 
			text: para text
			foreground: foreColor
			ignoreColorChanges: shadowMode)
		setPort: self clone
! !

GrafPort removeSelector: #displayScannerFor:foreground:background:ignoreColorChanges:!
DisplayScanner removeSelector: #plainTab!
DisplayScanner removeSelector: #text:foreground:background:fillBlt:ignoreColorChanges:!
DisplayScanner removeSelector: #text:textStyle:foreground:background:fillBlt:ignoreColorChanges:!
!classDefinition: #DisplayScanner category: #'Graphics-Text'!
CharacterScanner subclass: #DisplayScanner
	instanceVariableNames: 'bitBlt lineY runX foregroundColor lineHeight paragraphColor morphicOffset ignoreColorChanges'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Graphics-Text'!
