1# This file is a Tcl script to test the code in the file tkTextIndex.c.
2# This file is organized in the standard fashion for Tcl tests.
3#
4# Copyright (c) 1994 The Regents of the University of California.
5# Copyright (c) 1994 Sun Microsystems, Inc.
6# Copyright (c) 1998-1999 by Scriptics Corporation.
7# All rights reserved.
8#
9# RCS: @(#) $Id$
10
11package require tcltest 2.1
12eval tcltest::configure $argv
13tcltest::loadTestedCommands
14namespace import -force tcltest::test
15
16catch {destroy .t}
17text .t -font {Courier -12} -width 20 -height 10
18pack append . .t {top expand fill}
19update
20.t debug on
21wm geometry . {}
22  
23# The statements below reset the main window;  it's needed if the window
24# manager is mwm to make mwm forget about a previous minimum size setting.
25
26wm withdraw .
27wm minsize . 1 1
28wm positionfrom . user
29wm deiconify .
30
31.t insert 1.0 "Line 1
32abcdefghijklm
3312345
34Line 4
35b\u4e4fy GIrl .#@? x_yz
36!@#$%
37Line 7"
38
39image create photo textimage -width 10 -height 10
40textimage put red -to 0 0 9 9
41
42test textIndex-1.1 {TkTextMakeByteIndex} {testtext} {
43    # (lineIndex < 0)
44    testtext .t byteindex -1 3
45} {1.0 0}
46test textIndex-1.2 {TkTextMakeByteIndex} {testtext} {
47    # (lineIndex < 0), because lineIndex == strtol(argv[2]) - 1
48    testtext .t byteindex 0 3
49} {1.0 0}
50test textIndex-1.3 {TkTextMakeByteIndex} {testtext} {
51    # not (lineIndex < 0)
52    testtext .t byteindex 1 3
53} {1.3 3}
54test textIndex-1.4 {TkTextMakeByteIndex} {testtext} {
55    # (byteIndex < 0)
56    testtext .t byteindex 3 -1
57} {3.0 0}
58test textIndex-1.5 {TkTextMakeByteIndex} {testtext} {
59    # not (byteIndex < 0)
60    testtext .t byteindex 3 3
61} {3.3 3}
62test textIndex-1.6 {TkTextMakeByteIndex} {testtext} {
63    # (indexPtr->linePtr == NULL)
64    testtext .t byteindex 9 2
65} {8.0 0}
66test textIndex-1.7 {TkTextMakeByteIndex} {testtext} {
67    # not (indexPtr->linePtr == NULL)
68    testtext .t byteindex 7 2
69} {7.2 2}
70test textIndex-1.8 {TkTextMakeByteIndex: shortcut for 0} {testtext} {
71    # (byteIndex == 0)
72    testtext .t byteindex 1 0
73} {1.0 0}
74test textIndex-1.9 {TkTextMakeByteIndex: shortcut for 0} {testtext} {
75    # not (byteIndex == 0)
76    testtext .t byteindex 3 80
77} {3.5 5}
78test textIndex-1.10 {TkTextMakeByteIndex: verify index is in range} {testtext} {
79    # for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) 
80    # one segment
81
82    testtext .t byteindex 3 5
83} {3.5 5}
84test textIndex-1.11 {TkTextMakeByteIndex: verify index is in range} {testtext} {
85    # for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
86    #     index += segPtr->size
87    # Multiple segments, make sure add segment size to index.
88
89    .t mark set foo 3.2 
90    set x [testtext .t byteindex 3 7]
91    .t mark unset foo
92    set x
93} {3.5 5}
94test textIndex-1.12 {TkTextMakeByteIndex: verify index is in range} {testtext} {
95    # (segPtr == NULL)
96    testtext .t byteindex 3 7
97} {3.5 5}
98test textIndex-1.13 {TkTextMakeByteIndex: verify index is in range} {testtext} {
99    # not (segPtr == NULL)
100    testtext .t byteindex 3 4
101} {3.4 4}
102test textIndex-1.14 {TkTextMakeByteIndex: verify index is in range} {testtext} {
103    # (index + segPtr->size > byteIndex)
104    # in this segment.
105
106    testtext .t byteindex 3 4
107} {3.4 4}
108test textIndex-1.15 {TkTextMakeByteIndex: verify index is in range} {testtext} {
109    # (index + segPtr->size > byteIndex), index != 0
110    # in this segment.
111
112    .t mark set foo 3.2
113    set x [testtext .t byteindex 3 4]
114    .t mark unset foo
115    set x
116} {3.4 4}
117test textIndex-1.16 {TkTextMakeByteIndex: UTF-8 characters} {testtext} {
118    testtext .t byteindex 5 100
119} {5.18 20}
120test textIndex-1.17 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
121	{testtext} {
122    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) 
123    # Wrong answer would be \xb9 (the 2nd byte of UTF rep of 0x4e4f).
124
125    set x [testtext .t byteindex 5 2]
126    list $x [.t get insert]
127} {{5.2 4} y}
128test textIndex-1.18 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
129	{testtext} {
130    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) 
131    testtext .t byteindex 5 1
132    .t get insert
133} "\u4e4f"
134
135test textIndex-2.1 {TkTextMakeCharIndex} {
136    # (lineIndex < 0)
137    .t index -1.3
138} 1.0
139test textIndex-2.2 {TkTextMakeCharIndex} {
140    # (lineIndex < 0), because lineIndex == strtol(argv[2]) - 1
141    .t index 0.3
142} 1.0
143test textIndex-2.3 {TkTextMakeCharIndex} {
144    # not (lineIndex < 0)
145    .t index 1.3
146} 1.3
147test textIndex-2.4 {TkTextMakeCharIndex} {
148    # (charIndex < 0)
149    .t index 3.-1
150} 3.0
151test textIndex-2.5 {TkTextMakeCharIndex} {
152    # (charIndex < 0)
153    .t index 3.3
154} 3.3
155test textIndex-2.6 {TkTextMakeCharIndex} {
156    # (indexPtr->linePtr == NULL)
157    .t index 9.2
158} 8.0
159test textIndex-2.7 {TkTextMakeCharIndex} {
160    # not (indexPtr->linePtr == NULL)
161    .t index 7.2
162} 7.2
163test textIndex-2.8 {TkTextMakeCharIndex: verify index is in range} {
164    # for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
165    # one segment
166
167    .t index 3.5
168} 3.5
169test textIndex-2.9 {TkTextMakeCharIndex: verify index is in range} {
170    # for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
171    # Multiple segments, make sure add segment size to index.
172
173    .t mark set foo 3.2 
174    set x [.t index 3.7]
175    .t mark unset foo
176    set x
177} 3.5
178test textIndex-2.10 {TkTextMakeCharIndex: verify index is in range} {
179    # (segPtr == NULL)
180    .t index 3.7
181} 3.5
182test textIndex-2.11 {TkTextMakeCharIndex: verify index is in range} {
183    # not (segPtr == NULL)
184    .t index 3.4
185} 3.4
186test textIndex-2.12 {TkTextMakeCharIndex: verify index is in range} {
187    # (segPtr->typePtr == &tkTextCharType)
188    # Wrong answer would be \xb9 (the 2nd byte of UTF rep of 0x4e4f).
189
190    .t mark set insert 5.2
191    .t get insert
192} y
193test textIndex-2.13 {TkTextMakeCharIndex: verify index is in range} {
194    # not (segPtr->typePtr == &tkTextCharType)
195
196    .t image create 5.2 -image textimage
197    .t mark set insert 5.5
198    set x [.t get insert]
199    .t delete 5.2
200    set x
201} "G"
202test textIndex-2.14 {TkTextMakeCharIndex: verify index is in range} {
203    # (charIndex < segPtr->size)
204
205    .t image create 5.0 -image textimage
206    set x [.t index 5.0]
207    .t delete 5.0
208    set x
209} 5.0
210
211.t mark set foo 3.2
212.t tag add x 2.8 2.11
213.t tag add x 6.0 6.2
214set weirdTag "funny . +- 22.1\n\t{"
215.t tag add $weirdTag 2.1  2.6
216set weirdMark "asdf \n{-+ 66.2\t"
217.t mark set $weirdMark 4.0
218.t tag config y -relief raised
219test textIndex-3.1 {TkTextGetIndex, weird mark names} {
220    list [catch {.t index $weirdMark} msg] $msg
221} {0 4.0}
222
223test textIndex-4.1 {TkTextGetIndex, tags} {
224    list [catch {.t index x.first} msg] $msg
225} {0 2.8}
226test textIndex-4.2 {TkTextGetIndex, tags} {
227    list [catch {.t index x.last} msg] $msg
228} {0 6.2}
229test textIndex-4.3 {TkTextGetIndex, weird tags} {
230    list [.t index $weirdTag.first+1c] [.t index $weirdTag.last+2c]
231} {2.2 2.8}
232test textIndex-4.4 {TkTextGetIndex, tags} {
233    list [catch {.t index x.gorp} msg] $msg
234} {1 {bad text index "x.gorp"}}
235test textIndex-4.5 {TkTextGetIndex, tags} {
236    list [catch {.t index foo.last} msg] $msg
237} {1 {bad text index "foo.last"}}
238test textIndex-4.6 {TkTextGetIndex, tags} {
239    list [catch {.t index y.first} msg] $msg
240} {1 {text doesn't contain any characters tagged with "y"}}
241test textIndex-4.7 {TkTextGetIndex, tags} {
242    list [catch {.t index x.last,} msg] $msg
243} {1 {bad text index "x.last,"}}
244test textIndex-4.8 {TkTextGetIndex, tags} {
245    .t tag add z 1.0
246    set result [list [.t index z.first] [.t index z.last]]
247    .t tag delete z
248    set result
249} {1.0 1.1}
250
251test textIndex-5.1 {TkTextGetIndex, "@"} {nonPortable fonts} {
252    .t index @12,9
253} 1.1
254test textIndex-5.2 {TkTextGetIndex, "@"} {fonts} {
255    .t index @-2,7
256} 1.0
257test textIndex-5.3 {TkTextGetIndex, "@"} {fonts} {
258    .t index @10,-7
259} 1.0
260test textIndex-5.4 {TkTextGetIndex, "@"} {fonts} {
261    list [catch {.t index @x} msg] $msg
262} {1 {bad text index "@x"}}
263test textIndex-5.5 {TkTextGetIndex, "@"} {fonts} {
264    list [catch {.t index @10q} msg] $msg
265} {1 {bad text index "@10q"}}
266test textIndex-5.6 {TkTextGetIndex, "@"} {fonts} {
267    list [catch {.t index @10,} msg] $msg
268} {1 {bad text index "@10,"}}
269test textIndex-5.7 {TkTextGetIndex, "@"} {fonts} {
270    list [catch {.t index @10,a} msg] $msg
271} {1 {bad text index "@10,a"}}
272test textIndex-5.8 {TkTextGetIndex, "@"} {fonts} {
273    list [catch {.t index @10,9,} msg] $msg
274} {1 {bad text index "@10,9,"}}
275
276test textIndex-6.1 {TkTextGetIndex, numeric} {
277    list [catch {.t index 2.3} msg] $msg
278} {0 2.3}
279test textIndex-6.2 {TkTextGetIndex, numeric} {
280    list [catch {.t index -} msg] $msg
281} {1 {bad text index "-"}}
282test textIndex-6.3 {TkTextGetIndex, numeric} {
283    list [catch {.t index 2.end} msg] $msg
284} {0 2.13}
285test textIndex-6.4 {TkTextGetIndex, numeric} {
286    list [catch {.t index 2.x} msg] $msg
287} {1 {bad text index "2.x"}}
288test textIndex-6.5 {TkTextGetIndex, numeric} {
289    list [catch {.t index 2.3x} msg] $msg
290} {1 {bad text index "2.3x"}}
291
292test textIndex-7.1 {TkTextGetIndex, miscellaneous other bases} {
293    list [catch {.t index end} msg] $msg
294} {0 8.0}
295test textIndex-7.2 {TkTextGetIndex, miscellaneous other bases} {
296    list [catch {.t index foo} msg] $msg
297} {0 3.2}
298test textIndex-7.3 {TkTextGetIndex, miscellaneous other bases} {
299    list [catch {.t index foo+1c} msg] $msg
300} {0 3.3}
301
302test textIndex-8.1 {TkTextGetIndex, modifiers} {
303    list [catch {.t index 2.1+1char} msg] $msg
304} {0 2.2}
305test textIndex-8.2 {TkTextGetIndex, modifiers} {
306    list [catch {.t index "2.1  	+1char"} msg] $msg
307} {0 2.2}
308test textIndex-8.3 {TkTextGetIndex, modifiers} {
309    list [catch {.t index 2.1-1char} msg] $msg
310} {0 2.0}
311test textIndex-8.4 {TkTextGetIndex, modifiers} {
312    list [catch {.t index {2.1  }} msg] $msg
313} {0 2.1}
314test textIndex-8.5 {TkTextGetIndex, modifiers} {
315    list [catch {.t index {2.1+foo bar}} msg] $msg
316} {1 {bad text index "2.1+foo bar"}}
317test textIndex-8.6 {TkTextGetIndex, modifiers} {
318    list [catch {.t index {2.1 foo bar}} msg] $msg
319} {1 {bad text index "2.1 foo bar"}}
320
321test textIndex-9.1 {TkTextIndexCmp} {
322    list [.t compare 3.1 < 3.2] [.t compare 3.1 == 3.2]
323} {1 0}
324test textIndex-9.2 {TkTextIndexCmp} {
325    list [.t compare 3.2 < 3.2] [.t compare 3.2 == 3.2]
326} {0 1}
327test textIndex-9.3 {TkTextIndexCmp} {
328    list [.t compare 3.3 < 3.2] [.t compare 3.3 == 3.2]
329} {0 0}
330test textIndex-9.4 {TkTextIndexCmp} {
331    list [.t compare 2.1 < 3.2] [.t compare 2.1 == 3.2]
332} {1 0}
333test textIndex-9.5 {TkTextIndexCmp} {
334    list [.t compare 4.1 < 3.2] [.t compare 4.1 == 3.2]
335} {0 0}
336
337test textIndex-10.1 {ForwBack} {
338    list [catch {.t index {2.3 + x}} msg] $msg
339} {1 {bad text index "2.3 + x"}}
340test textIndex-10.2 {ForwBack} {
341    list [catch {.t index {2.3 + 2 chars}} msg] $msg
342} {0 2.5}
343test textIndex-10.3 {ForwBack} {
344    list [catch {.t index {2.3 + 2c}} msg] $msg
345} {0 2.5}
346test textIndex-10.4 {ForwBack} {
347    list [catch {.t index {2.3 - 3ch}} msg] $msg
348} {0 2.0}
349test textIndex-10.5 {ForwBack} {
350    list [catch {.t index {1.3 + 3 lines}} msg] $msg
351} {0 4.3}
352test textIndex-10.6 {ForwBack} {
353    list [catch {.t index {2.3 -1l}} msg] $msg
354} {0 1.3}
355test textIndex-10.7 {ForwBack} {
356    list [catch {.t index {2.3 -1 gorp}} msg] $msg
357} {1 {bad text index "2.3 -1 gorp"}}
358test textIndex-10.8 {ForwBack} {
359    list [catch {.t index {2.3 - 4 lines}} msg] $msg
360} {0 1.3}
361test textIndex-10.9 {ForwBack} {
362    .t mark set insert 2.0
363    list [catch {.t index {insert -0 chars}} msg] $msg
364} {0 2.0}
365test textIndex-10.10 {ForwBack} {
366    .t mark set insert 2.end
367    list [catch {.t index {insert +0 chars}} msg] $msg
368} {0 2.13}
369
370test textIndex-11.1 {TkTextIndexForwBytes} {testtext} {
371    testtext .t forwbytes 2.3 -7
372} {1.3 3}
373test textIndex-11.2 {TkTextIndexForwBytes} {testtext} {
374    testtext .t forwbytes 2.3 5
375} {2.8 8}
376test textIndex-11.3 {TkTextIndexForwBytes} {testtext} {
377    testtext .t forwbytes 2.3 10
378} {2.13 13}
379test textIndex-11.4 {TkTextIndexForwBytes} {testtext} {
380    testtext .t forwbytes 2.3 11
381} {3.0 0}
382test textIndex-11.5 {TkTextIndexForwBytes} {testtext} {
383    testtext .t forwbytes 2.3 57
384} {7.6 6}
385test textIndex-11.6 {TkTextIndexForwBytes} {testtext} {
386    testtext .t forwbytes 2.3 58
387} {8.0 0}
388test textIndex-11.7 {TkTextIndexForwBytes} {testtext} {
389    testtext .t forwbytes 2.3 59
390} {8.0 0}
391
392test textIndex-12.1 {TkTextIndexForwChars} {
393    # (charCount < 0)
394    .t index {2.3 + -7 chars}
395} 1.3
396test textIndex-12.2 {TkTextIndexForwChars} {
397    # not (charCount < 0)
398    .t index {2.3 + 5 chars}
399} 2.8
400test textIndex-12.3 {TkTextIndexForwChars: find index} {
401    # for ( ; segPtr != NULL; segPtr = segPtr->nextPtr)
402    # one loop
403    .t index {2.3 + 9 chars}
404} 2.12
405test textIndex-12.4 {TkTextIndexForwChars: find index} {
406    # for ( ; segPtr != NULL; segPtr = segPtr->nextPtr)
407    # multiple loops
408    .t mark set foo 2.5
409    set x [.t index {2.3 + 9 chars}]
410    .t mark unset foo
411    set x
412} 2.12
413test textIndex-12.5 {TkTextIndexForwChars: find index} {
414    # for ( ; segPtr != NULL; segPtr = segPtr->nextPtr)
415    # border condition: last char
416
417    .t index {2.3 + 10 chars}
418} 2.13
419test textIndex-12.6 {TkTextIndexForwChars: find index} {
420    # for ( ; segPtr != NULL; segPtr = segPtr->nextPtr)
421    # border condition: segPtr == NULL -> beginning of next line
422    
423    .t index {2.3 + 11 chars}
424} 3.0
425test textIndex-12.7 {TkTextIndexForwChars: find index} {
426    # (segPtr->typePtr == &tkTextCharType)
427    .t index {2.3 + 2 chars}
428} 2.5
429test textIndex-12.8 {TkTextIndexForwChars: find index} {
430    # (charCount == 0)
431    # No more chars, so we found byte offset.
432
433    .t index {2.3 + 2 chars}
434} 2.5
435test textIndex-12.9 {TkTextIndexForwChars: find index} {
436    # not (segPtr->typePtr == &tkTextCharType)
437
438    .t image create 2.4 -image textimage
439    set x [.t get {2.3 + 3 chars}]
440    .t delete 2.4
441    set x    
442} "f"
443test textIndex-12.10 {TkTextIndexForwChars: find index} {
444    # dstPtr->byteIndex += segPtr->size - byteOffset
445    # When moving to next segment, account for bytes in last segment.
446    # Wrong answer would be 2.4
447
448    .t mark set foo 2.4
449    set x [.t index {2.3 + 5 chars}]
450    .t mark unset foo
451    set x
452} 2.8
453test textIndex-12.11 {TkTextIndexForwChars: go to next line} {
454    # (linePtr == NULL)
455    .t index {7.6 + 3 chars}
456} 8.0
457test textIndex-12.12 {TkTextIndexForwChars: go to next line} {
458    # Reset byteIndex to 0 now that we are on a new line.
459    # Wrong answer would be 2.9
460    .t index {1.3 + 6 chars}
461} 2.2
462test textIndex-12.13 {TkTextIndexForwChars} {
463    # right to end
464    .t index {2.3 + 56 chars}
465} 8.0
466test textIndex-12.14 {TkTextIndexForwChars} {
467    # try to go past end
468    .t index {2.3 + 57 chars}
469} 8.0
470
471test textIndex-13.1 {TkTextIndexBackBytes} {testtext} {
472    testtext .t backbytes 3.2 -10
473} {4.6 6}
474test textIndex-13.2 {TkTextIndexBackBytes} {testtext} {
475    testtext .t backbytes 3.2 2
476} {3.0 0}
477test textIndex-13.3 {TkTextIndexBackBytes} {testtext} {
478    testtext .t backbytes 3.2 3
479} {2.13 13}
480test textIndex-13.4 {TkTextIndexBackBytes} {testtext} {
481    testtext .t backbytes 3.2 22
482} {1.1 1}
483test textIndex-13.5 {TkTextIndexBackBytes} {testtext} {
484    testtext .t backbytes 3.2 23
485} {1.0 0}
486test textIndex-13.6 {TkTextIndexBackBytes} {testtext} {
487    testtext .t backbytes 3.2 24
488} {1.0 0}
489
490test textIndex-14.1 {TkTextIndexBackChars} {
491    # (charCount < 0)
492    .t index {3.2 - -10 chars}
493} 4.6
494test textIndex-14.2 {TkTextIndexBackChars} {
495    # not (charCount < 0)
496    .t index {3.2 - 2 chars}
497} 3.0
498test textIndex-14.3 {TkTextIndexBackChars: find starting segment} {
499    # for (segPtr = dstPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
500    # single loop
501
502    .t index {3.2 - 3 chars}
503} 2.13
504test textIndex-14.4 {TkTextIndexBackChars: find starting segment} {
505    # for (segPtr = dstPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
506    # multiple loop
507
508    .t mark set foo1 2.5
509    .t mark set foo2 2.7
510    .t mark set foo3 2.10
511    set x [.t index {2.9 - 1 chars}]
512    .t mark unset foo1 foo2 foo3
513    set x
514} 2.8
515test textIndex-14.5 {TkTextIndexBackChars: find starting seg and offset} {
516    # for (segPtr = dstPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr)
517    # Make sure segSize was decremented.  Wrong answer would be 2.10
518
519    .t mark set foo 2.2
520    set x [.t index {2.9 - 1 char}]
521    .t mark unset foo
522    set x
523} 2.8
524test textIndex-14.6 {TkTextIndexBackChars: back over characters} {
525    # (segPtr->typePtr == &tkTextCharType)
526
527    .t index {3.2 - 22 chars}
528} 1.1
529test textIndex-14.7 {TkTextIndexBackChars: loop backwards over chars} {
530    # (charCount == 0)
531    # No more chars, so we found byte offset.
532
533    .t index {3.4 - 2 chars}
534} 3.2
535test textIndex-14.8 {TkTextIndexBackChars: loop backwards over chars} {
536    # (p == start)
537    # Still more chars, but we reached beginning of segment
538
539    .t image create 5.6 -image textimage
540    set x [.t index {5.8 - 3 chars}]
541    .t delete 5.6
542    set x
543} 5.5
544test textIndex-14.9 {TkTextIndexBackChars: back over image} {
545    # not (segPtr->typePtr == &tkTextCharType)
546
547    .t image create 5.6 -image textimage
548    set x [.t get {5.8 - 4 chars}]
549    .t delete 5.6
550    set x
551} "G"
552test textIndex-14.10 {TkTextIndexBackChars: move to previous segment} {
553    # (segPtr != oldPtr)
554    # More segments to go
555
556    .t mark set foo 3.4
557    set x [.t index {3.5 - 2 chars}]
558    .t mark unset foo
559    set x
560} 3.3
561test textIndex-14.11 {TkTextIndexBackChars: move to previous segment} {
562    # not (segPtr != oldPtr)
563    # At beginning of line.
564
565    .t mark set foo 3.4
566    set x [.t index {3.5 - 10 chars}]
567    .t mark unset foo
568    set x
569} 2.9
570test textIndex-14.12 {TkTextIndexBackChars: move to previous line} {
571    # (lineIndex == 0) 
572    .t index {1.5 - 10 chars}
573} 1.0
574test textIndex-14.13 {TkTextIndexBackChars: move to previous line} {
575    # not (lineIndex == 0) 
576    .t index {2.5 - 10 chars}
577} 1.2
578test textIndex-14.14 {TkTextIndexBackChars: move to previous line} {
579    # for (segPtr = oldPtr; segPtr != NULL; segPtr = segPtr->nextPtr)
580    # Set byteIndex to end of previous line so we can subtract more
581    # bytes from it.  Otherwise we get an TkTextIndex with a negative
582    # byteIndex.
583
584    .t index {2.5 - 6 chars}
585} 1.6
586test textIndex-14.15 {TkTextIndexBackChars: UTF} {
587    .t get {5.3 - 1 chars}
588} y
589test textIndex-14.16 {TkTextIndexBackChars: UTF} {
590    .t get {5.3 - 2 chars}
591} \u4e4f
592test textIndex-14.17 {TkTextIndexBackChars: UTF} {
593    .t get {5.3 - 3 chars}
594} b
595
596proc getword index {
597    .t get [.t index "$index wordstart"] [.t index "$index wordend"]
598}
599test textIndex-15.1 {StartEnd} {
600    list [catch {.t index {2.3 lineend}} msg] $msg
601} {0 2.13}
602test textIndex-15.2 {StartEnd} {
603    list [catch {.t index {2.3 linee}} msg] $msg
604} {0 2.13}
605test textIndex-15.3 {StartEnd} {
606    list [catch {.t index {2.3 line}} msg] $msg
607} {1 {bad text index "2.3 line"}}
608test textIndex-15.4 {StartEnd} {
609    list [catch {.t index {2.3 linestart}} msg] $msg
610} {0 2.0}
611test textIndex-15.5 {StartEnd} {
612    list [catch {.t index {2.3 lines}} msg] $msg
613} {0 2.0}
614test textIndex-15.6 {StartEnd} {
615    getword 5.3
616} { }
617test textIndex-15.7 {StartEnd} {
618    getword 5.4
619} GIrl
620test textIndex-15.8 {StartEnd} {
621    getword 5.7
622} GIrl
623test textIndex-15.9 {StartEnd} {
624    getword 5.8
625} { }
626test textIndex-15.10 {StartEnd} {
627    getword 5.14
628} x_yz
629test textIndex-15.11 {StartEnd} {
630    getword 6.2
631} #
632test textIndex-15.12 {StartEnd} {
633    getword 3.4
634} 12345
635.t tag add x 2.8 2.11
636test textIndex-15.13 {StartEnd} {
637    list [catch {.t index {2.2 worde}} msg] $msg
638} {0 2.13}
639test textIndex-15.14 {StartEnd} {
640    list [catch {.t index {2.12 words}} msg] $msg
641} {0 2.0}
642test textIndex-15.15 {StartEnd} {
643    list [catch {.t index {2.12 word}} msg] $msg
644} {1 {bad text index "2.12 word"}}
645
646test textIndex-16.1 {TkTextPrintIndex} {
647    set t [text .t2]
648    $t insert end \n
649    $t window create end -window [button $t.b]
650    set result [$t index end-2c]
651    pack $t
652    catch {destroy $t}
653} 0
654
655test textIndex-16.2 {TkTextPrintIndex} {
656    set t [text .t2]
657    $t insert end \n
658    $t window create end -window [button $t.b]
659    set result [$t tag add {} end-2c]
660    pack $t
661    catch {destroy $t}
662} 0
663
664test textIndex-17.1 {Object indices} {
665    set res {}
666    set t [text .t2 -height 20]
667    for {set i 0} {$i < 100} {incr i} {
668	$t insert end $i\n
669    }
670    pack $t
671    update
672    set idx @0,0
673    lappend res $idx [$t index $idx]
674    $t yview scroll 2 pages
675    lappend res $idx [$t index $idx]
676    catch {destroy $t}
677    unset i
678    unset idx
679    list $res
680} {{@0,0 1.0 @0,0 37.0}}
681
682test textIndex-18.1 {Object indices don't cache mark names} {
683    set res {}
684    text .t2
685    .t2 insert 1.0 1234\n1234\n1234
686    set pos "insert"
687    lappend res [.t2 index $pos]
688    .t2 mark set $pos 3.0
689    lappend res [.t2 index $pos]
690    .t2 mark set $pos 1.0
691    lappend res [.t2 index $pos]
692    catch {destroy .t2}
693    set res
694} {3.4 3.0 1.0}
695
696frame .f -width 100 -height 20
697pack append . .f left
698
699set fixedFont {Courier -12}
700set fixedHeight [font metrics $fixedFont -linespace]
701set fixedWidth [font measure $fixedFont m]
702
703set varFont {Times -14}
704set bigFont {Helvetica -24}
705destroy .t
706text .t -font $fixedFont -width 20 -height 10 -wrap char
707pack append . .t {top expand fill}
708.t tag configure big -font $bigFont
709.t debug on
710wm geometry . {}
711
712# The statements below reset the main window;  it's needed if the window
713# manager is mwm to make mwm forget about a previous minimum size setting.
714
715wm withdraw .
716wm minsize . 1 1
717wm positionfrom . user
718wm deiconify .
719update
720
721# Some window managers (like olwm under SunOS 4.1.3) misbehave in a way
722# that tends to march windows off the top and left of the screen.  If
723# this happens, some tests will fail because parts of the window will
724# not need to be displayed (because they're off-screen).  To keep this
725# from happening, move the window if it's getting near the left or top
726# edges of the screen.
727
728if {([winfo rooty .] < 50) || ([winfo rootx .] < 50)} {
729    wm geom . +50+50
730}
731
732set str [string repeat "hello " 20]
733
734.t insert end "$str one two three four five six seven height nine ten\n"
735.t insert end "$str one two three four five six seven height nine ten\n"
736.t insert end "$str one two three four five six seven height nine ten\n"
737
738test textIndex-19.1 {Display lines} {
739    .t index "2.7 displaylinestart"
740} {2.0}
741
742test textIndex-19.2 {Display lines} {
743    .t index "2.7 displaylineend"
744} {2.19}
745
746test textIndex-19.3 {Display lines} {
747    .t index "2.30 displaylinestart"
748} {2.20}
749
750test textIndex-19.4 {Display lines} {
751    .t index "2.30 displaylineend"
752} {2.39}
753
754test textIndex-19.5 {Display lines} {
755    .t index "2.40 displaylinestart"
756} {2.40}
757
758test textIndex-19.6 {Display lines} {
759    .t index "2.40 displaylineend"
760} {2.59}
761
762test textIndex-19.7 {Display lines} {
763    .t index "2.7 +1displaylines"
764} {2.27}
765
766test textIndex-19.8 {Display lines} {
767    .t index "2.7 -1displaylines"
768} {1.167}
769
770test textIndex-19.9 {Display lines} {
771    .t index "2.30 +1displaylines"
772} {2.50}
773
774test textIndex-19.10 {Display lines} {
775    .t index "2.30 -1displaylines"
776} {2.10}
777
778test textIndex-19.11 {Display lines} {
779    .t index "2.40 +1displaylines"
780} {2.60}
781
782test textIndex-19.12 {Display lines} {
783    .t index "2.40 -1displaylines"
784} {2.20}
785
786test textIndex-19.13 {Display lines} {
787    destroy .t
788    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
789    scrollbar .sbar -command ".txt yview"
790    grid .txt .sbar -sticky news
791    grid configure .sbar -sticky ns
792    grid rowconfigure    . 0 -weight 1
793    grid columnconfigure . 0 -weight 1
794    .txt configure -width 10
795    .txt tag config STAMP -elide 1
796    .txt tag config NICK-tick -elide 0
797    .txt insert end "+++++ Loading History ++++++++++++++++\n"
798    .txt mark set HISTORY {2.0 - 1 line}
799    .txt insert HISTORY {	} STAMP
800    .txt insert HISTORY {tick	} {NICK NICK-tick}
801    .txt insert HISTORY "\n" {NICK NICK-tick}
802    .txt insert HISTORY {[23:51]	} STAMP
803    .txt insert HISTORY "\n" {NICK NICK-tick}
804    # Must not crash
805    .txt index "2.0 - 2 display lines"
806    destroy .txt .sbar
807} {}
808
809proc text_test_word {startend chars start} {
810    destroy .t
811    text .t
812    .t insert end $chars
813    if {[regexp {end} $start]} {
814	set start [.t index "${start}chars -2c"]
815    } else {
816	set start [.t index "1.0 + ${start}chars"]
817    }
818    if {[.t compare $start >= "end-1c"]} {
819	set start "end-2c"
820    }
821    set res [.t index "$start $startend"]
822    .t count 1.0 $res
823}
824
825# Following tests copied from tests from string wordstart/end in Tcl
826
827test textIndex-21.4 {text index wordend} {
828    text_test_word wordend abc. -1
829} 3
830test textIndex-21.5 {text index wordend} {
831    text_test_word wordend abc. 100
832} 4
833test textIndex-21.6 {text index wordend} {
834    text_test_word wordend "word_one two three" 2
835} 8
836test textIndex-21.7 {text index wordend} {
837    text_test_word wordend "one .&# three" 5
838} 6
839test textIndex-21.8 {text index wordend} {
840    text_test_word worde "x.y" 0
841} 1
842test textIndex-21.9 {text index wordend} {
843    text_test_word worde "x.y" end-1
844} 2
845test textIndex-21.10 {text index wordend, unicode} {
846    text_test_word wordend "xyz\u00c7de fg" 0
847} 6
848test textIndex-21.11 {text index wordend, unicode} {
849    text_test_word wordend "xyz\uc700de fg" 0
850} 6
851test textIndex-21.12 {text index wordend, unicode} {
852    text_test_word wordend "xyz\u203fde fg" 0
853} 6
854test textIndex-21.13 {text index wordend, unicode} {
855    text_test_word wordend "xyz\u2045de fg" 0
856} 3
857test textIndex-21.14 {text index wordend, unicode} {
858    text_test_word wordend "\uc700\uc700 abc" 8
859} 6
860
861test textIndex-22.5 {text index wordstart} {
862    text_test_word wordstart "one two three_words" 400
863} 8
864test textIndex-22.6 {text index wordstart} {
865    text_test_word wordstart "one two three_words" 2
866} 0
867test textIndex-22.7 {text index wordstart} {
868    text_test_word wordstart "one two three_words" -2
869} 0
870test textIndex-22.8 {text index wordstart} {
871    text_test_word wordstart "one .*&^ three" 6
872} 6
873test textIndex-22.9 {text index wordstart} {
874    text_test_word wordstart "one two three" 4
875} 4
876test textIndex-22.10 {text index wordstart} {
877    text_test_word wordstart "one two three" end-5
878} 7
879test textIndex-22.11 {text index wordstart, unicode} {
880    text_test_word wordstart "one tw\u00c7o three" 7
881} 4
882test textIndex-22.12 {text index wordstart, unicode} {
883    text_test_word wordstart "ab\uc700\uc700 cdef ghi" 12
884} 10
885test textIndex-22.13 {text index wordstart, unicode} {
886    text_test_word wordstart "\uc700\uc700 abc" 8
887} 3
888
889test textIndex-23.1 {text paragraph start} {
890    pack [text .t2]
891    .t2 insert end " Text"
892    set res 2.0
893    for {set i 0} {$i < 2} {incr i} {
894	lappend res [::tk::TextPrevPara .t2 [lindex $res end]]
895    }
896    destroy .t2
897    set res
898} {2.0 1.1 1.1}
899
900test textIndex-24.1 {text mark prev} {
901    pack [text .t2]
902    .t2 insert end [string repeat "1 2 3 4 5 6 7 8 9 0\n" 12]
903    .t2 mark set 1.0 10.0
904    update
905    # then this crash Tk:
906    set res [.t2 mark previous 10.10]
907    destroy .t2
908    set res
909} {1.0}
910
911# cleanup
912rename textimage {}
913catch {destroy .t}
914cleanupTests
915return
916