[FIX] Indented text and selection
Hans-Martin Mosner
hm.mosner at cityweb.de
Wed Jan 5 19:04:22 UTC 2000
This changeset fixes a bug with selection to the left of indented text
(the virtual tabs used for indenting would cause a crossedX condition,
which leads to wrong cursor positioning)
Hans-Martin
-------------- next part --------------
'From Squeak2.7alpha of 11 October 1999 [latest update: #1716] on 5 January 2000 at 5:40:55 pm'!
"Change Set: Indentation-hmm
Date: 5 January 2000
Author: Hans-Martin Mosner
Fixes a bug with selecting to the left of text with a TextIndent attribute"!
!CharacterBlockScanner methodsFor: 'scanning' stamp: 'hmm 1/5/2000 07:13'!
characterBlockAtPoint: aPoint index: index in: textLine
| runLength lineStop done stopCondition |
line _ textLine.
characterIndex _ index. " == nil means scanning for point"
characterPoint _ aPoint.
(characterPoint == nil or: [characterPoint y > line bottom])
ifTrue: [characterPoint _ line bottomRight].
(text isEmpty or: [(characterPoint y < line top or: [characterPoint x < line left])
or: [characterIndex ~~ nil and: [characterIndex < line first]]])
ifTrue: [^ (CharacterBlock new stringIndex: line first text: text
topLeft: line leftMargin at line top extent: 0 @ textStyle lineGrid)
textLine: line].
rightMargin _ line rightMargin.
destX _ leftMargin _ line leftMarginForAlignment: textStyle alignment.
destY _ line top.
lastIndex _ line first.
self setStopConditions. "also sets font"
self adjustForIndentationLevel.
runLength _ text runLengthFor: line first.
characterIndex ~~ nil
ifTrue: [lineStop _ characterIndex "scanning for index"]
ifFalse: [lineStop _ line last "scanning for point"].
runStopIndex _ lastIndex + (runLength - 1) min: lineStop.
lastCharacterExtent _ 0 @ line lineHeight.
spaceCount _ 0.
done _ false.
[done] whileFalse:
[stopCondition _ self scanCharactersFrom: lastIndex to: runStopIndex
in: text string rightX: characterPoint x
stopConditions: stopConditions kern: kern displaying: false.
"see setStopConditions for stopping conditions for character block operations."
self lastCharacterExtentSetX: (specialWidth == nil
ifTrue: [font widthOf: (text at: lastIndex)]
ifFalse: [specialWidth]).
(self perform: stopCondition) ifTrue:
[^ (CharacterBlock new
stringIndex: (characterIndex==nil ifTrue: [lastIndex] ifFalse: [characterIndex])
text: text topLeft: characterPoint extent: lastCharacterExtent)
textLine: line]]! !
!CharacterBlockScanner methodsFor: 'private' stamp: 'hmm 1/5/2000 07:05'!
adjustForIndentationLevel
"Advance destX to the indented position without executing the tab action. IndentationLevel is cleared to suppress its effect later.
This is needed to fix a bug when a selection is made to the left of indented text. - hmm"
self indentationLevel timesRepeat: [
destX _ textStyle
nextTabXFrom: destX
leftMargin: leftMargin
rightMargin: rightMargin].
indentationLevel _ 0! !
!CharacterBlockScanner methodsFor: 'private' stamp: 'hmm 1/2/2000 20:56'!
buildCharacterBlockIn: para
| lineIndex runLength lineStop done stopCondition |
"handle nullText"
(para numberOfLines = 0 or: [text size = 0])
ifTrue: [^ CharacterBlock new stringIndex: 1 "like being off end of string"
text: para text
topLeft: (para leftMarginForDisplayForLine: 1)
@ para compositionRectangle top
extent: 0 @ textStyle lineGrid].
"find the line"
lineIndex _ para lineIndexOfTop: characterPoint y.
destY _ para topAtLineIndex: lineIndex.
line _ para lines at: lineIndex.
rightMargin _ para rightMarginForDisplay.
(lineIndex = para numberOfLines and:
[(destY + line lineHeight) < characterPoint y])
ifTrue: ["if beyond lastLine, force search to last character"
self characterPointSetX: rightMargin]
ifFalse: [characterPoint y < (para compositionRectangle) top
ifTrue: ["force search to first line"
characterPoint _ (para compositionRectangle) topLeft].
characterPoint x > rightMargin
ifTrue: [self characterPointSetX: rightMargin]].
destX _ leftMargin _ para leftMarginForDisplayForLine: lineIndex.
nextLeftMargin_ para leftMarginForDisplayForLine: lineIndex+1.
lastIndex _ line first.
self setStopConditions. "also sets font"
self adjustForIndentationLevel.
runLength _ (text runLengthFor: line first).
characterIndex ~~ nil
ifTrue: [lineStop _ characterIndex "scanning for index"]
ifFalse: [lineStop _ line last].
(runStopIndex _ lastIndex + (runLength - 1)) > lineStop
ifTrue: [runStopIndex _ lineStop].
lastCharacterExtent _ 0 @ line lineHeight.
spaceCount _ 0. done _ false.
[done]
whileFalse:
[stopCondition _ self scanCharactersFrom: lastIndex to: runStopIndex
in: text string rightX: characterPoint x
stopConditions: stopConditions kern: kern displaying: false.
"see setStopConditions for stopping conditions for character block operations."
self lastCharacterExtentSetX: (font widthOf: (text at: lastIndex)).
(self perform: stopCondition)
ifTrue: [^ CharacterBlock new stringIndex: lastIndex text: text
topLeft: characterPoint extent: lastCharacterExtent]]! !
More information about the Squeak-dev
mailing list
|