Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Silence compiler warnings, especially signed/unsigned problems. The handling of inline functions (C99 support) has been improved. C99 support for Linux/UNIX enabled. Some preparations for older Visual Studio compilers. Minor fix of test case (the use of abbreviated commands may break future releases). |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | revised_text | tip-466 |
Files: | files | file ages | folders |
SHA1: |
e8542fce34ce0ec8ad91b0fff24341a2 |
User & Date: | gcramer 2017-02-23 14:35:55 |
2017-02-23
| ||
17:00 | Fixed MSVC warning C4098: 'void' function returning a value check-in: 887724cd user: fvogel tags: revised_text, tip-466 | |
14:35 | Silence compiler warnings, especially signed/unsigned problems. The handling of inline functions (C99 support) has been improved. C99 support for Linux/UNIX enabled. Some preparations for older Visual Studio compilers. Minor fix of test case (the use of abbreviated commands may break future releases). check-in: e8542fce user: gcramer tags: revised_text, tip-466 | |
2017-02-22
| ||
21:36 | Remove this from previous commit. Not yet convinced that -DMODULE_SCOPE="" is the best or correct solution. check-in: 4d30798b user: fvogel tags: revised_text, tip-466 | |
Changes to generic/tkAlloc.h.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TK_ALLOC #define _TK_ALLOC #include "tcl.h" #if TK_VALGRIND | > < < | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TK_ALLOC #define _TK_ALLOC #include "tcl.h" #include <stdlib.h> #if TK_VALGRIND /* enables compiler check that these functions will not be used */ # undef ckalloc # undef ckrealloc # undef ckfree #else /* if !TK_VALGRIND */ |
︙ | ︙ |
Changes to generic/tkBitField.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | #include "tkBitField.h" #include "tkIntSet.h" #include "tkAlloc.h" #include <string.h> #include <assert.h> | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include "tkBitField.h" #include "tkIntSet.h" #include "tkAlloc.h" #include <string.h> #include <assert.h> #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkBitFieldPriv.h" #endif #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif |
︙ | ︙ | |||
61 62 63 64 65 66 67 | # define MsbIndex(x) ((sizeof(unsigned long long)*8 - 1) - __builtin_clzll(x)) # else /* !(defined(__GNUC__) || defined(__clang__)) */ static unsigned LsbIndex(uint64_t x) { | | > | > | > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # define MsbIndex(x) ((sizeof(unsigned long long)*8 - 1) - __builtin_clzll(x)) # else /* !(defined(__GNUC__) || defined(__clang__)) */ static unsigned LsbIndex(uint64_t x) { /* Source: http://chessprogramming.wikispaces.com/BitScan (adapted for MSVC) */ static const unsigned MultiplyDeBruijnBitPosition[64] = { 0, 1, 48, 2, 57, 49, 28, 3, 61, 58, 50, 42, 38, 29, 17, 4, 62, 55, 59, 36, 53, 51, 43, 22, 45, 39, 33, 30, 24, 18, 12, 5, 63, 47, 56, 27, 60, 41, 37, 16, 54, 35, 52, 21, 44, 32, 23, 11, 46, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6 }; uint64_t idx = ((uint64_t) ((x & -((int64_t) x))*UINT64_C(0x03f79d71b4cb0a89))) >> 58; return MultiplyDeBruijnBitPosition[idx]; } static unsigned MsbIndex(uint64_t x) { /* * Source: http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i * (extended to 64 bit by GC) */ static const uint8_t Table[16] = { -1, 0, 1,1, 2,2,2,2, 3,3,3,3,3,3,3,3 }; unsigned r = 0; uint64_t xk; if ((xk = x >> 32)) { r = 32; x = xk; } if ((xk = x >> 16)) { r += 16; x = xk; } |
︙ | ︙ | |||
118 119 120 121 122 123 124 | # else /* defined(__GNUC__) || defined(__clang__) */ # if 1 /* On my system this is the fastest method, only about 5% slower than __builtin_ctz(). */ static unsigned LsbIndex(uint32_t x) { | > | > > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | # else /* defined(__GNUC__) || defined(__clang__) */ # if 1 /* On my system this is the fastest method, only about 5% slower than __builtin_ctz(). */ static unsigned LsbIndex(uint32_t x) { /* * Source: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear * (adapted for MSVC) */ static const unsigned MultiplyDeBruijnBitPosition[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; return MultiplyDeBruijnBitPosition[((uint32_t) ((x & -((int32_t) x))*0x077cb531)) >> 27]; } # else |
︙ | ︙ | |||
1162 1163 1164 1165 1166 1167 1168 | TkBitField *bf) { memset(bf->bits, 0xff, BYTE_SIZE(bf->size)); ResetUnused(bf); } | | | | 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | TkBitField *bf) { memset(bf->bits, 0xff, BYTE_SIZE(bf->size)); ResetUnused(bf); } #ifndef NDEBUG # include <stdio.h> void TkBitPrint( const TkBitField *bf) { unsigned i; const char *comma = ""; assert(bf); printf("%d:{ ", TkBitCount(bf)); for (i = TkBitFindFirst(bf); i != TK_BIT_NPOS; i = TkBitFindNext(bf, i)) { printf("%s%d", comma, i); comma = ", "; } printf(" }\n"); } #endif /* NDEBUG */ #if TK_UNUSED_BITFIELD_FUNCTIONS /* * These functions are not needed anymore, but shouldn't be removed, because sometimes * any of these functions might be useful. */ |
︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 | return true; } #endif /* TK_UNUSED_BITFIELD_FUNCTIONS */ | | < | | | | | | | | | | | | | | | | | 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 | return true; } #endif /* TK_UNUSED_BITFIELD_FUNCTIONS */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern TkBitField *TkBitNew(unsigned size); extern const unsigned char *TkBitData(const TkBitField *bf); extern unsigned TkBitByteSize(const TkBitField *bf); extern unsigned TkBitRefCount(const TkBitField *bf); extern void TkBitIncrRefCount(TkBitField *bf); extern unsigned TkBitDecrRefCount(TkBitField *bf); extern bool TkBitIsEmpty(const TkBitField *bf); extern unsigned TkBitSize(const TkBitField *bf); extern bool TkBitTest(const TkBitField *bf, unsigned n); extern bool TkBitNone(const TkBitField *bf); extern bool TkBitIntersects(const TkBitField *bf1, const TkBitField *bf2); extern void TkBitSet(TkBitField *bf, unsigned n); extern void TkBitUnset(TkBitField *bf, unsigned n); extern void TkBitPut(TkBitField *bf, unsigned n, bool value); extern unsigned TkBitAdjustSize(unsigned size); #endif /* TK_C99_INLINE_SUPPORT */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkBitField.h.
︙ | ︙ | |||
15 16 17 18 19 20 21 | #ifndef _TK #include "tk.h" #endif #include "tkBool.h" #include <stdint.h> | < < < < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #ifndef _TK #include "tk.h" #endif #include "tkBool.h" #include <stdint.h> #ifdef TCL_WIDE_INT_IS_LONG typedef uint64_t TkBitWord; #else typedef uint32_t TkBitWord; #endif |
︙ | ︙ | |||
136 137 138 139 140 141 142 | bool TkBitTestAndUnset(TkBitField *bf, unsigned n); void TkBitFill(TkBitField *bf); void TkBitClear(TkBitField *bf); /* Return nearest multiple of TK_BIT_NBITS which is greater or equal to given argument. */ inline unsigned TkBitAdjustSize(unsigned size); | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | bool TkBitTestAndUnset(TkBitField *bf, unsigned n); void TkBitFill(TkBitField *bf); void TkBitClear(TkBitField *bf); /* Return nearest multiple of TK_BIT_NBITS which is greater or equal to given argument. */ inline unsigned TkBitAdjustSize(unsigned size); #ifndef NDEBUG void TkBitPrint(const TkBitField *bf); #endif #if TK_CHECK_ALLOCS void TkBitCheckAllocs(); #endif |
︙ | ︙ | |||
169 170 171 172 173 174 175 | const TkBitField *add2, const TkBitField *sub2); /* ((bf1 + (add - sub)) & add) == ((bf2 + (add - sub)) & add) */ bool TkBitInnerJoinDifferenceIsEqual(const TkBitField *bf1, const TkBitField *bf2, const TkBitField *add, const TkBitField *sub); #endif /* TK_UNUSED_BITFIELD_FUNCTIONS */ | | < | 163 164 165 166 167 168 169 170 171 172 173 174 175 | const TkBitField *add2, const TkBitField *sub2); /* ((bf1 + (add - sub)) & add) == ((bf2 + (add - sub)) & add) */ bool TkBitInnerJoinDifferenceIsEqual(const TkBitField *bf1, const TkBitField *bf2, const TkBitField *add, const TkBitField *sub); #endif /* TK_UNUSED_BITFIELD_FUNCTIONS */ #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkBitFieldPriv.h" #endif #endif /* _TKBITFIELD */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkBitFieldPriv.h.
︙ | ︙ | |||
22 23 24 25 26 27 28 | #endif /* _TKBITFIELDPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> | < < < < < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #endif /* _TKBITFIELDPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> #define TK_BIT_WORD_INDEX(n) ((n) >> ((TK_BIT_NBITS + 128) >> 5)) #define TK_BIT_INDEX(n) ((n) & (TK_BIT_NBITS - 1)) #define TK_BIT_MASK(n) (((TkBitWord) 1) << (n)) #define TK_BIT_COUNT_WORDS(n) ((n + TK_BIT_NBITS - 1)/TK_BIT_NBITS) |
︙ | ︙ | |||
201 202 203 204 205 206 207 208 209 210 211 | { if (value) { TkBitSet(bf, n); } else { TkBitUnset(bf, n); } } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ | > | 195 196 197 198 199 200 201 202 203 204 205 206 | { if (value) { TkBitSet(bf, n); } else { TkBitUnset(bf, n); } } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkBool.h.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 | enum { true = (int) 1, false = (int) 0 }; #endif #ifdef __cplusplus } /* extern "C" */ #endif #endif /* _TK_BOOL */ /* vi:set ts=8 sw=4: */ | > > > > > > > > > > > > > > > > > > > > > > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | enum { true = (int) 1, false = (int) 0 }; #endif #ifdef __cplusplus } /* extern "C" */ #endif /* * For the text widget stuff (and related files) this is a basic header * file, so it's the appropriate place for the C99 inline support macros. */ #ifdef _MSC_VER # if defined(include) # define TK_C99_INLINE_SUPPORT # elif _MSC_VER >= 1400 # define inline __inline # define TK_C99_INLINE_SUPPORT # define TK_C99_INLINE_DEFINED # else # define inline # define TK_C99_INLINE_DEFINED # endif #elif __STDC_VERSION__ >= 199901L # define TK_C99_INLINE_SUPPORT #else # define inline # define TK_C99_INLINE_DEFINED #endif #endif /* _TK_BOOL */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkIntSet.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkIntSet.h" #include "tkBitField.h" #include "tkAlloc.h" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkIntSet.h" #include "tkBitField.h" #include "tkAlloc.h" #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkIntSetPriv.h" #endif #include <string.h> #include <assert.h> |
︙ | ︙ | |||
1555 1556 1557 1558 1559 1560 1561 | return true; } #endif /* !TK_TEXT_DONT_USE_BITFIELDS */ | | | 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 | return true; } #endif /* !TK_TEXT_DONT_USE_BITFIELDS */ #ifndef NDEBUG # include <stdio.h> void TkIntSetPrint( const TkIntSet *set) { |
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | for (i = 0; i < n; ++i) { printf("%s%d", comma, set->buf[i]); comma = ", "; } printf(" }\n"); } | | | 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 | for (i = 0; i < n; ++i) { printf("%s%d", comma, set->buf[i]); comma = ", "; } printf(" }\n"); } #endif /* NDEBUG */ #if TK_UNUSED_INTSET_FUNCTIONS /* * These functions are not needed anymore, but shouldn't be removed, because sometimes * any of these functions might be useful. */ |
︙ | ︙ | |||
2120 2121 2122 2123 2124 2125 2126 | return true; } #endif /* TK_UNUSED_INTSET_FUNCTIONS */ | | < | | | | | | | | | | | | | | | | | | | | 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 | return true; } #endif /* TK_UNUSED_INTSET_FUNCTIONS */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern unsigned TkIntSetByteSize(const TkIntSet *set); extern const unsigned char *TkIntSetData(const TkIntSet *set); extern bool TkIntSetIsEmpty(const TkIntSet *set); extern unsigned TkIntSetSize(const TkIntSet *set); extern unsigned TkIntSetMax(const TkIntSet *set); extern unsigned TkIntSetRefCount(const TkIntSet *set); extern void TkIntSetIncrRefCount(TkIntSet *set); extern unsigned TkIntSetDecrRefCount(TkIntSet *set); extern TkIntSetType TkIntSetAccess(const TkIntSet *set, unsigned index); extern bool TkIntSetTest(const TkIntSet *set, unsigned n); extern bool TkIntSetNone(const TkIntSet *set); extern bool TkIntSetAny(const TkIntSet *set); extern bool TkIntSetIsEqual(const TkIntSet *set1, const TkIntSet *set2); extern bool TkIntSetContains(const TkIntSet *set1, const TkIntSet *set2); extern bool TkIntSetDisjunctive(const TkIntSet *set1, const TkIntSet *set2); extern bool TkIntSetIntersects(const TkIntSet *set1, const TkIntSet *set2); extern unsigned TkIntSetFindFirst(const TkIntSet *set); extern unsigned TkIntSetFindNext(const TkIntSet *set); extern TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, bool add); #endif /* __STDC_VERSION__ >= 199901L */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkIntSet.h.
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include <stdint.h> #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif | < < < < < < < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <stdint.h> #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif struct TkBitField; typedef uint32_t TkIntSetType; /* |
︙ | ︙ | |||
146 147 148 149 150 151 152 | TkIntSet *TkIntSetAdd(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetErase(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetTestAndSet(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetTestAndUnset(TkIntSet *set, unsigned n) __warn_unused__; inline TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, bool add) __warn_unused__; TkIntSet *TkIntSetClear(TkIntSet *set) __warn_unused__; | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | TkIntSet *TkIntSetAdd(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetErase(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetTestAndSet(TkIntSet *set, unsigned n) __warn_unused__; TkIntSet *TkIntSetTestAndUnset(TkIntSet *set, unsigned n) __warn_unused__; inline TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, bool add) __warn_unused__; TkIntSet *TkIntSetClear(TkIntSet *set) __warn_unused__; #ifndef NDEBUG void TkIntSetPrint(const TkIntSet *set); #endif #if TK_UNUSED_INTSET_FUNCTIONS /* |
︙ | ︙ | |||
179 180 181 182 183 184 185 | const TkIntSet *add, const TkIntSet *sub); #endif /* TK_UNUSED_INTSET_FUNCTIONS */ #undef __warn_unused__ | | | < < | 172 173 174 175 176 177 178 179 180 181 182 183 184 | const TkIntSet *add, const TkIntSet *sub); #endif /* TK_UNUSED_INTSET_FUNCTIONS */ #undef __warn_unused__ #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkIntSetPriv.h" #endif #endif /* _TKINTSET */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkIntSetPriv.h.
︙ | ︙ | |||
30 31 32 33 34 35 36 | #endif /* _TKINTSETPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> | < < < < < < | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #endif /* _TKINTSETPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> extern TkIntSetType * TkIntSetLowerBound( TkIntSetType *first, TkIntSetType *last, TkIntSetType value); |
︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 282 | TkIntSet *set, unsigned n, bool add) { assert(set); return add ? TkIntSetAdd(set, n) : TkIntSetErase(set, n); } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ | > | 266 267 268 269 270 271 272 273 274 275 276 277 | TkIntSet *set, unsigned n, bool add) { assert(set); return add ? TkIntSetAdd(set, n) : TkIntSetErase(set, n); } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkQTree.c.
︙ | ︙ | |||
44 45 46 47 48 49 50 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkQTree.h" #include "tkAlloc.h" | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkQTree.h" #include "tkAlloc.h" #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkQTreePriv.h" #endif #include <tcl.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
1126 1127 1128 1129 1130 1131 1132 | return cd.count; } #endif /* QTREE_SEARCH_RECTS_CONTAINING */ | | < | | | | | | | | 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 | return cd.count; } #endif /* QTREE_SEARCH_RECTS_CONTAINING */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern bool TkQTreeRectIsEmpty(const TkQTreeRect *rect); extern bool TkQTreeRectIsEqual(const TkQTreeRect *rect1, const TkQTreeRect *rect2); extern bool TkQTreeRectContainsPoint(const TkQTreeRect *rect, TkQTreeCoord x, TkQTreeCoord y); extern bool TkQTreeRectContainsRect(const TkQTreeRect *rect1, const TkQTreeRect *rect2); extern bool TkQTreeRectIntersects(const TkQTreeRect *rect1, const TkQTreeRect *rect2); extern TkQTreeRect *TkQTreeRectSet(TkQTreeRect *rect, TkQTreeCoord xmin, TkQTreeCoord ymin, TkQTreeCoord xmax, TkQTreeCoord ymax); extern TkQTreeRect *TkQTreeRectTranslate(TkQTreeRect *rect, TkQTreeCoord dx, TkQTreeCoord dy); #endif /* __STDC_VERSION__ >= 199901L */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkQTree.h.
︙ | ︙ | |||
15 16 17 18 19 20 21 | #ifndef _TKINT #include "tkInt.h" #endif #include "tkBool.h" #include <stdint.h> | < < < < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #ifndef _TKINT #include "tkInt.h" #endif #include "tkBool.h" #include <stdint.h> /* ========================================================================= * Definitions for rectangle support. * ========================================================================= */ typedef int32_t TkQTreeCoord; |
︙ | ︙ | |||
166 167 168 169 170 171 172 | unsigned TkQTreeSearchRectsContaining(const TkQTree tree, const TkQTreeRect *rect, TkQTreeCallback cbHit, TkQTreeClientData cbArg); #endif /* QTREE_SEARCH_RECTS_CONTAINING */ | | | < < | 160 161 162 163 164 165 166 167 168 169 170 171 172 | unsigned TkQTreeSearchRectsContaining(const TkQTree tree, const TkQTreeRect *rect, TkQTreeCallback cbHit, TkQTreeClientData cbArg); #endif /* QTREE_SEARCH_RECTS_CONTAINING */ #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkQTreePriv.h" #endif #endif /* _TKQTREE */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkQTreePriv.h.
︙ | ︙ | |||
14 15 16 17 18 19 20 | #endif #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> | < < < < < < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #endif #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> inline bool TkQTreeRectIsEmpty( const TkQTreeRect *rect) { assert(rect); |
︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 | rect->xmin += dx; rect->xmax += dx; rect->ymin += dy; rect->ymax += dy; return rect; } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ | > | 149 150 151 152 153 154 155 156 157 158 159 160 | rect->xmin += dx; rect->xmax += dx; rect->ymin += dy; rect->ymax += dy; return rect; } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkRangeList.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | #include "tkRangeList.h" #include "tkAlloc.h" #include <tk.h> #include <string.h> #include <assert.h> | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include "tkRangeList.h" #include "tkAlloc.h" #include <tk.h> #include <string.h> #include <assert.h> #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkRangeListPriv.h" #endif #ifndef MIN # define MIN(a,b) ((a) < (b) ? a : b) #endif |
︙ | ︙ | |||
38 39 40 41 42 43 44 | #define MEM_SIZE(size) ((unsigned) (Tk_Offset(TkRangeList, items) + (size)*sizeof(TkRange))) DEBUG_ALLOC(unsigned tkRangeListCountNew = 0); DEBUG_ALLOC(unsigned tkRangeListCountDestroy = 0); | | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #define MEM_SIZE(size) ((unsigned) (Tk_Offset(TkRangeList, items) + (size)*sizeof(TkRange))) DEBUG_ALLOC(unsigned tkRangeListCountNew = 0); DEBUG_ALLOC(unsigned tkRangeListCountDestroy = 0); #ifndef NDEBUG static unsigned ComputeRangeSize( const TkRangeList *ranges) { unsigned i; int count = 0; for (i = 0; i < ranges->size; ++i) { count += TkRangeSpan(ranges->items + i); } return count; } #endif /* NDEBUG */ static TkRange * LowerBound( TkRange *first, TkRange *last, int low) |
︙ | ︙ | |||
648 649 650 651 652 653 654 | } assert(ComputeRangeSize(ranges) == ranges->count); return ranges; } | | | | < | | | | | | | | | | | | | | 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | } assert(ComputeRangeSize(ranges) == ranges->count); return ranges; } #ifndef NDEBUG void TkRangeListPrint( const TkRangeList *ranges) { unsigned i; for (i = 0; i < ranges->size; ++i) { printf("{%d,%d} ", ranges->items[i].low, ranges->items[i].high); } printf("(%d)\n", ranges->count); } #endif /* NDEBUG */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern int TkRangeSpan(const TkRange *range); extern bool TkRangeTest(const TkRange *range, int value); extern int TkRangeListLow(const TkRangeList *ranges); extern int TkRangeListHigh(const TkRangeList *ranges); extern unsigned TkRangeListSpan(const TkRangeList *ranges); extern unsigned TkRangeListCount(const TkRangeList *ranges); extern unsigned TkRangeListSize(const TkRangeList *ranges); extern const TkRange *TkRangeListAccess(const TkRangeList *ranges, unsigned index); extern const TkRange *TkRangeListFirst(const TkRangeList *ranges); extern const TkRange *TkRangeListNext(const TkRangeList *ranges, const TkRange *item); extern bool TkRangeListIsEmpty(const TkRangeList *ranges); extern bool TkRangeListContains(const TkRangeList *ranges, int value); extern bool TkRangeListContainsRange(const TkRangeList *ranges, int low, int high); #endif /* __STDC_VERSION__ >= 199901L */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkRangeList.h.
︙ | ︙ | |||
19 20 21 22 23 24 25 | #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif | < < < < < < | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif typedef struct TkRange { int low; int high; } TkRange; /* |
︙ | ︙ | |||
190 191 192 193 194 195 196 | * the given range (high - low + 1). Adjacent entries (pairs) will be amalgamated * automatically. * * Example: TkRangeListDelete({{5,6} {8,9}}, 1, 5) -> {{1} {3,4}} */ TkRangeList *TkRangeListDelete(TkRangeList *ranges, int low, int high); | | | < < | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | * the given range (high - low + 1). Adjacent entries (pairs) will be amalgamated * automatically. * * Example: TkRangeListDelete({{5,6} {8,9}}, 1, 5) -> {{1} {3,4}} */ TkRangeList *TkRangeListDelete(TkRangeList *ranges, int low, int high); #ifndef NDEBUG void TkRangeListPrint(const TkRangeList *ranges); #endif #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkRangeListPriv.h" #endif #endif /* _TKRANGELIST */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkRangeListPriv.h.
︙ | ︙ | |||
15 16 17 18 19 20 21 | #ifdef _TK_NEED_IMPLEMENTATION #include <stddef.h> #include <assert.h> | < < < < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #ifdef _TK_NEED_IMPLEMENTATION #include <stddef.h> #include <assert.h> inline int TkRangeSpan( const TkRange *range) { assert(range); |
︙ | ︙ | |||
160 161 162 163 164 165 166 167 168 169 170 | const TkRange *item) { assert(item); assert(ranges); assert(ranges->items <= item && item < ranges->items + ranges->size); return ++item == ranges->items + ranges->size ? NULL : item; } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ | > | 154 155 156 157 158 159 160 161 162 163 164 165 | const TkRange *item) { assert(item); assert(ranges); assert(ranges->items <= item && item < ranges->items + ranges->size); return ++item == ranges->items + ranges->size ? NULL : item; } #undef _TK_NEED_IMPLEMENTATION #endif /* _TK_NEED_IMPLEMENTATION */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkText.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | #include "tkTextUndo.h" #include "tkTextTagSet.h" #include "tkBitField.h" #include <stdlib.h> #include <ctype.h> #include <assert.h> | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include "tkTextUndo.h" #include "tkTextTagSet.h" #include "tkBitField.h" #include <stdlib.h> #include <ctype.h> #include <assert.h> #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextPriv.h" #endif #ifndef MAX # define MAX(a,b) ((a) < (b) ? b : a) #endif #ifndef MIN # define MIN(a,b) ((a) < (b) ? a : b) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Support of tk8.5. |
︙ | ︙ | |||
756 757 758 759 760 761 762 | * * Side effects: * Calls Tcl_GetString(objPtr) if objPtr->bytes is not yet resolved. * *-------------------------------------------------------------- */ | | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 | * * Side effects: * Calls Tcl_GetString(objPtr) if objPtr->bytes is not yet resolved. * *-------------------------------------------------------------- */ static int GetByteLength( Tcl_Obj *objPtr) { assert(objPtr); if (!objPtr->bytes) { Tcl_GetString(objPtr); |
︙ | ︙ | |||
2046 2047 2048 2049 2050 2051 2052 | result = TCL_ERROR; goto done; } } for (; i < objc; i += 2) { TkTextIndex index1, index2; | | | 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 | result = TCL_ERROR; goto done; } } for (; i < objc; i += 2) { TkTextIndex index1, index2; Tcl_Obj *get; if (!TkTextGetIndexFromObj(interp, textPtr, objv[i], &index1)) { if (objPtr) { Tcl_DecrRefCount(objPtr); } result = TCL_ERROR; goto done; |
︙ | ︙ | |||
4258 4259 4260 4261 4262 4263 4264 | TkTextParseHyphenRules( TkText *textPtr, Tcl_Obj *objPtr, int *rulesPtr) { int rules = 0; Tcl_Obj **argv; | | > | 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 | TkTextParseHyphenRules( TkText *textPtr, Tcl_Obj *objPtr, int *rulesPtr) { int rules = 0; Tcl_Obj **argv; int argc, i; unsigned k; assert(rulesPtr); if (Tcl_ListObjGetElements(textPtr->interp, objPtr, &argc, &argv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < argc; ++i) { |
︙ | ︙ | |||
5385 5386 5387 5388 5389 5390 5391 | int compare = TkTextIndexCompare(indexPtr1, indexPtr2); if (compare == 0) { return 0; } if (compare > 0) { | | | 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 | int compare = TkTextIndexCompare(indexPtr1, indexPtr2); if (compare == 0) { return 0; } if (compare > 0) { return -((int) TkTextIndexCount(textPtr, indexPtr2, indexPtr1, type)); } return TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
5967 5968 5969 5970 5971 5972 5973 | */ static void TextBlinkProc( ClientData clientData) /* Pointer to record describing text. */ { TkText *textPtr = clientData; | | | 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 | */ static void TextBlinkProc( ClientData clientData) /* Pointer to record describing text. */ { TkText *textPtr = clientData; unsigned oldFlags = textPtr->flags; if (textPtr->state == TK_TEXT_STATE_DISABLED || !(textPtr->flags & HAVE_FOCUS) || textPtr->insertOffTime == 0) { if (!(textPtr->flags & HAVE_FOCUS) && textPtr->insertUnfocussed != TK_TEXT_INSERT_NOFOCUS_NONE) { /* * The widget doesn't have the focus yet it is configured to |
︙ | ︙ | |||
6125 6126 6127 6128 6129 6130 6131 | *destroyed = true; return rc; } TkTextIndexRebuild(&index1); } if (tagPtr) { | | | | 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 | *destroyed = true; return rc; } TkTextIndexRebuild(&index1); } if (tagPtr) { int i; if (Tcl_ListObjGetElements(interp, tagPtr, &numTags, &tagNamePtrs) != TCL_OK) { rc = TCL_ERROR; } else if (numTags > 0) { TkTextTag *tagPtr; tagInfoPtr = TkTextTagSetResize(NULL, sharedTextPtr->tagInfoSize); for (i = 0; i < numTags; ++i) { tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(tagNamePtrs[i]), NULL); #if !TK_TEXT_DONT_USE_BITFIELDS if (tagPtr->index >= TkTextTagSetSize(tagInfoPtr)) { tagInfoPtr = TkTextTagSetResize(NULL, sharedTextPtr->tagInfoSize); } #endif tagInfoPtr = TkTextTagSetAdd(tagInfoPtr, tagPtr->index); |
︙ | ︙ | |||
6760 6761 6762 6763 6764 6765 6766 | /* * TODO: Use new elide structure, but this requires a redesign of the whole * search algorithm. */ for ( ; leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) { if (segPtr->typePtr == &tkTextCharType) { | | | 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 | /* * TODO: Use new elide structure, but this requires a redesign of the whole * search algorithm. */ for ( ; leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) { if (segPtr->typePtr == &tkTextCharType) { int size = searchSpecPtr->exact ? segPtr->size : (int) CountCharsInSeg(segPtr); if (!searchSpecPtr->searchElide && TkTextSegmentIsElided(textPtr, segPtr)) { matchOffset += size; } else { leftToScan -= size; } } else if (searchSpecPtr->searchHyphens && segPtr->typePtr == &tkTextHyphenType) { |
︙ | ︙ | |||
7101 7102 7103 7104 7105 7106 7107 | }; enum opts { DUMP_ALL, DUMP_TAG_BINDINGS, DUMP_CHARS, DUMP_CMD, DUMP_TAG_CONFIGS, DUMP_DISCARD_SEL, DUMP_DISPLAY_CHARS, DUMP_DISPLAY_TEXT, DUMP_DONT_RESOLVE, DUMP_ELIDE, DUMP_IMG, DUMP_INSERT_MARK, DUMP_MARK, DUMP_NESTED, DUMP_NODE, DUMP_TEXT_CONFIGS, DUMP_TAG, DUMP_TEXT, DUMP_WIN }; | | | > | 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 | }; enum opts { DUMP_ALL, DUMP_TAG_BINDINGS, DUMP_CHARS, DUMP_CMD, DUMP_TAG_CONFIGS, DUMP_DISCARD_SEL, DUMP_DISPLAY_CHARS, DUMP_DISPLAY_TEXT, DUMP_DONT_RESOLVE, DUMP_ELIDE, DUMP_IMG, DUMP_INSERT_MARK, DUMP_MARK, DUMP_NESTED, DUMP_NODE, DUMP_TEXT_CONFIGS, DUMP_TAG, DUMP_TEXT, DUMP_WIN }; static const unsigned dumpFlags[] = { 0, TK_DUMP_TAG_BINDINGS, TK_DUMP_CHARS, 0, TK_DUMP_TAG_CONFIGS, TK_DUMP_DISCARD_SEL, TK_DUMP_DISPLAY_CHARS, TK_DUMP_DISPLAY_TEXT, TK_DUMP_DONT_RESOLVE, TK_DUMP_ELIDE, TK_DUMP_IMG, TK_DUMP_INSERT_MARK, TK_DUMP_MARK, TK_DUMP_NESTED, TK_DUMP_NODE, TK_DUMP_TEXT_CONFIGS, TK_DUMP_TAG, TK_DUMP_TEXT, TK_DUMP_WIN }; int arg; unsigned i; unsigned flags = 0; const char *myOptStrings[sizeof(optStrings)/sizeof(optStrings[0])]; int myOptIndices[sizeof(optStrings)/sizeof(optStrings[0])]; int myOptCount; assert(what); assert(!index1 == !index2); |
︙ | ︙ | |||
7869 7870 7871 7872 7873 7874 7875 | values[2] = Tcl_NewStringObj(buffer, -1); tuple = Tcl_NewListObj(3, values); if (!command) { Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple); Tcl_DecrRefCount(tuple); return true; } else { | | | 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 | values[2] = Tcl_NewStringObj(buffer, -1); tuple = Tcl_NewListObj(3, values); if (!command) { Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple); Tcl_DecrRefCount(tuple); return true; } else { unsigned oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree); Tcl_DString buf; int code; Tcl_DStringInit(&buf); Tcl_DStringAppend(&buf, Tcl_GetString(command), -1); Tcl_DStringAppend(&buf, " ", -1); Tcl_DStringAppend(&buf, Tcl_GetString(tuple), -1); |
︙ | ︙ | |||
7912 7913 7914 7915 7916 7917 7918 | static bool ObjIsEqual( Tcl_Obj *obj1, Tcl_Obj *obj2) { char const *b1, *b2; | | | 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 | static bool ObjIsEqual( Tcl_Obj *obj1, Tcl_Obj *obj2) { char const *b1, *b2; int i, length; assert(obj1); assert(obj2); b1 = Tcl_GetString(obj1); b2 = Tcl_GetString(obj2); |
︙ | ︙ | |||
8511 8512 8513 8514 8515 8516 8517 | static void InspectRetainedUndoItems( const TkSharedText *sharedTextPtr, Tcl_Obj *objPtr) { if (sharedTextPtr->undoTagListCount > 0 || sharedTextPtr->undoMarkListCount > 0) { Tcl_Obj *resultPtr = Tcl_NewObj(); | > | | | | | | 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 | static void InspectRetainedUndoItems( const TkSharedText *sharedTextPtr, Tcl_Obj *objPtr) { if (sharedTextPtr->undoTagListCount > 0 || sharedTextPtr->undoMarkListCount > 0) { Tcl_Obj *resultPtr = Tcl_NewObj(); unsigned i; int len; for (i = 0; i < sharedTextPtr->undoTagListCount; ++i) { TkTextInspectUndoTagItem(sharedTextPtr, sharedTextPtr->undoTagList[i], resultPtr); } for (i = 0; i < sharedTextPtr->undoMarkListCount; ++i) { TkTextInspectUndoMarkItem(sharedTextPtr, &sharedTextPtr->undoMarkList[i], resultPtr); } Tcl_ListObjLength(NULL, resultPtr, &len); if (len == 0) { Tcl_IncrRefCount(resultPtr); Tcl_DecrRefCount(resultPtr); } else { Tcl_ListObjAppendElement(NULL, objPtr, resultPtr); } } } |
︙ | ︙ | |||
8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 | TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TkTextUndoStack st = sharedTextPtr->undoStack; Tcl_Obj *var = arrayPtr ? arrayPtr : Tcl_NewStringObj("", 0); Tcl_Obj *name[INFO_LAST]; Tcl_Obj *value[INFO_LAST]; int usedTags, i; name[INFO_UNDOSTACKSIZE ] = Tcl_NewStringObj("undostacksize", -1); name[INFO_REDOSTACKSIZE ] = Tcl_NewStringObj("redostacksize", -1); name[INFO_UNDODEPTH ] = Tcl_NewStringObj("undodepth", -1); name[INFO_REDODEPTH ] = Tcl_NewStringObj("redodepth", -1); name[INFO_UNDOBYTESIZE ] = Tcl_NewStringObj("undobytesize", -1); name[INFO_REDOBYTESIZE ] = Tcl_NewStringObj("redobytesize", -1); | > | 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 | TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TkTextUndoStack st = sharedTextPtr->undoStack; Tcl_Obj *var = arrayPtr ? arrayPtr : Tcl_NewStringObj("", 0); Tcl_Obj *name[INFO_LAST]; Tcl_Obj *value[INFO_LAST]; int usedTags, i; unsigned k; name[INFO_UNDOSTACKSIZE ] = Tcl_NewStringObj("undostacksize", -1); name[INFO_REDOSTACKSIZE ] = Tcl_NewStringObj("redostacksize", -1); name[INFO_UNDODEPTH ] = Tcl_NewStringObj("undodepth", -1); name[INFO_REDODEPTH ] = Tcl_NewStringObj("redodepth", -1); name[INFO_UNDOBYTESIZE ] = Tcl_NewStringObj("undobytesize", -1); name[INFO_REDOBYTESIZE ] = Tcl_NewStringObj("redobytesize", -1); |
︙ | ︙ | |||
9090 9091 9092 9093 9094 9095 9096 | value[INFO_TAGS ] = Tcl_NewIntObj(sharedTextPtr->numTags); value[INFO_USEDTAGS ] = Tcl_NewIntObj(usedTags); value[INFO_MARKS ] = Tcl_NewIntObj(sharedTextPtr->numMarks); value[INFO_GENERATEDMARKS] = Tcl_NewIntObj(sharedTextPtr->numPrivateMarks); value[INFO_LINESPERNODE ] = Tcl_NewIntObj(TkBTreeLinesPerNode(sharedTextPtr->tree)); Tcl_UnsetVar(interp, Tcl_GetString(var), 0); | | | | 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 | value[INFO_TAGS ] = Tcl_NewIntObj(sharedTextPtr->numTags); value[INFO_USEDTAGS ] = Tcl_NewIntObj(usedTags); value[INFO_MARKS ] = Tcl_NewIntObj(sharedTextPtr->numMarks); value[INFO_GENERATEDMARKS] = Tcl_NewIntObj(sharedTextPtr->numPrivateMarks); value[INFO_LINESPERNODE ] = Tcl_NewIntObj(TkBTreeLinesPerNode(sharedTextPtr->tree)); Tcl_UnsetVar(interp, Tcl_GetString(var), 0); for (k = 0; k < sizeof(name)/sizeof(name[0]); ++k) { Tcl_ObjSetVar2(interp, var, name[k], value[k], 0); } return var; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
9171 9172 9173 9174 9175 9176 9177 | segPtr = TkTextIndexGetContentSegment(&index, &offset1); } lastPtr = TkTextIndexGetContentSegment(indexPtr2, &offset2); if (segPtr == lastPtr) { if (segPtr->typePtr == &tkTextCharType) { | | > | | | | | | 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 | segPtr = TkTextIndexGetContentSegment(&index, &offset1); } lastPtr = TkTextIndexGetContentSegment(indexPtr2, &offset2); if (segPtr == lastPtr) { if (segPtr->typePtr == &tkTextCharType) { Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset1, MIN(maxBytes, (unsigned) (offset2 - offset1))); } } else { TkTextLine *linePtr = segPtr->sectionPtr->linePtr; TkTextIndexClear(&index, textPtr); if (segPtr->typePtr == &tkTextCharType) { unsigned nbytes = MIN(maxBytes, (unsigned) segPtr->size - offset1); Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset1, nbytes); if ((maxBytes -= nbytes) == 0) { return resultPtr; } } else if (segPtr->typePtr == &tkTextHyphenType) { if (includeHyphens) { Tcl_AppendToObj(resultPtr, "\xc2\xad", 2); /* U+002D */ if ((maxBytes -= MIN(maxBytes, 2u)) == 0) { return resultPtr; } } } else if (segPtr->typePtr == &tkTextBranchType) { if (visibleOnly) { TkTextIndexSetSegment(&index, segPtr = segPtr->body.branch.nextPtr); if (TkTextIndexRestrictToEndRange(&index) >= 0) { return resultPtr; /* end of text reached */ } linePtr = segPtr->sectionPtr->linePtr; } } if (!(segPtr = segPtr->nextPtr)) { assert(linePtr->nextPtr); linePtr = linePtr->nextPtr; segPtr = linePtr->segPtr; } while (segPtr != lastPtr) { if (segPtr->typePtr == &tkTextCharType) { unsigned nbytes = MIN(maxBytes, (unsigned) segPtr->size); Tcl_AppendToObj(resultPtr, segPtr->body.chars, nbytes); if ((maxBytes -= nbytes) == 0) { if (lastIndexPtr) { TkTextIndexSetSegment(lastIndexPtr, segPtr); TkTextIndexAddToByteIndex(lastIndexPtr, nbytes); } return resultPtr; /* end of text reached */ } } else if (segPtr->typePtr == &tkTextHyphenType) { if (includeHyphens) { Tcl_AppendToObj(resultPtr, "\xc2\xad", 2); /* U+002D */ if ((maxBytes -= MIN(maxBytes, 2u)) == 0) { return resultPtr; } } } else if (segPtr->typePtr == &tkTextBranchType) { if (visibleOnly) { TkTextIndexSetSegment(&index, segPtr = segPtr->body.branch.nextPtr); if (TkTextIndexRestrictToEndRange(&index) >= 0) { return resultPtr; /* end of text reached */ } linePtr = segPtr->sectionPtr->linePtr; } } if (!(segPtr = segPtr->nextPtr)) { assert(linePtr->nextPtr); linePtr = linePtr->nextPtr; segPtr = linePtr->segPtr; } } if (offset2 > 0) { Tcl_AppendToObj(resultPtr, segPtr->body.chars, MIN(maxBytes, (unsigned) offset2)); } } return resultPtr; } /* |
︙ | ︙ | |||
11343 11344 11345 11346 11347 11348 11349 | Tcl_AppendResult(interp, buf, NULL); return TCL_OK; } #endif /* TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 5 */ | | | 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 | Tcl_AppendResult(interp, buf, NULL); return TCL_OK; } #endif /* TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 5 */ #ifndef NDEBUG /* *---------------------------------------------------------------------- * * TkpTextInspect -- * * This function is for debugging only, printing the text content * on stdout. |
︙ | ︙ | |||
11382 11383 11384 11385 11386 11387 11388 | Tcl_IncrRefCount(objv[3] = Tcl_NewStringObj("-elide", -1)); Tcl_IncrRefCount(objv[4] = Tcl_NewStringObj("-chars", -1)); Tcl_IncrRefCount(objv[5] = Tcl_NewStringObj("-image", -1)); Tcl_IncrRefCount(objv[6] = Tcl_NewStringObj("-window", -1)); Tcl_IncrRefCount(objv[7] = Tcl_NewStringObj("-mark", -1)); Tcl_IncrRefCount(objv[8] = Tcl_NewStringObj("-tag", -1)); TextInspectCmd(textPtr, textPtr->interp, sizeof(objv)/sizeof(objv[0]), objv); | | | | | | 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 | Tcl_IncrRefCount(objv[3] = Tcl_NewStringObj("-elide", -1)); Tcl_IncrRefCount(objv[4] = Tcl_NewStringObj("-chars", -1)); Tcl_IncrRefCount(objv[5] = Tcl_NewStringObj("-image", -1)); Tcl_IncrRefCount(objv[6] = Tcl_NewStringObj("-window", -1)); Tcl_IncrRefCount(objv[7] = Tcl_NewStringObj("-mark", -1)); Tcl_IncrRefCount(objv[8] = Tcl_NewStringObj("-tag", -1)); TextInspectCmd(textPtr, textPtr->interp, sizeof(objv)/sizeof(objv[0]), objv); for (i = 0; i < (int) (sizeof(objv)/sizeof(objv[0])); ++i) { Tcl_DecrRefCount(objv[i]); } Tcl_ListObjGetElements(textPtr->interp, Tcl_GetObjResult(textPtr->interp), &argc, &argv); for (i = 0; i < argc; ++i) { printf("%s\n", Tcl_GetString(argv[i])); } Tcl_SetObjResult(textPtr->interp, resultPtr); Tcl_DecrRefCount(resultPtr); } #endif /* NDEBUG */ /* *---------------------------------------------------------------------- * * TkpTextDump -- * * This function is for debugging only, printing the text content * on stdout. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef NDEBUG void TkpTextDump( TkText *textPtr) { Tcl_Obj *resultPtr; Tcl_Obj *objv[4]; Tcl_Obj **argv; int argc, i; Tcl_IncrRefCount(resultPtr = Tcl_GetObjResult(textPtr->interp)); Tcl_ResetResult(textPtr->interp); Tcl_IncrRefCount(objv[0] = Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); Tcl_IncrRefCount(objv[1] = Tcl_NewStringObj("dump", -1)); Tcl_IncrRefCount(objv[2] = Tcl_NewStringObj("begin", -1)); Tcl_IncrRefCount(objv[3] = Tcl_NewStringObj("end", -1)); TextDumpCmd(textPtr, textPtr->interp, sizeof(objv)/sizeof(objv[0]), objv); for (i = 0; i < (int) (sizeof(objv)/sizeof(objv[0])); ++i) { Tcl_DecrRefCount(objv[i]); } Tcl_ListObjGetElements(textPtr->interp, Tcl_GetObjResult(textPtr->interp), &argc, &argv); for (i = 0; i < argc; i += 3) { char const *type = Tcl_GetString(argv[i]); char const *text = Tcl_GetString(argv[i + 1]); |
︙ | ︙ | |||
11489 11490 11491 11492 11493 11494 11495 | } } Tcl_SetObjResult(textPtr->interp, resultPtr); Tcl_DecrRefCount(resultPtr); } | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 | } } Tcl_SetObjResult(textPtr->interp, resultPtr); Tcl_DecrRefCount(resultPtr); } #endif /* NDEBUG */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern TkSharedText * TkBTreeGetShared(TkTextBTree tree); extern int TkBTreeGetNumberOfDisplayLines(const TkTextPixelInfo *pixelInfo); extern TkTextPixelInfo *TkBTreeLinePixelInfo(const TkText *textPtr, TkTextLine *linePtr); extern unsigned TkBTreeEpoch(TkTextBTree tree); extern unsigned TkBTreeIncrEpoch(TkTextBTree tree); extern struct Node *TkBTreeGetRoot(TkTextBTree tree); extern TkTextLine * TkBTreePrevLogicalLine(const TkSharedText *sharedTextPtr, const TkText *textPtr, TkTextLine *linePtr); extern TkTextTag * TkBTreeGetTags(const TkTextIndex *indexPtr); extern TkTextLine * TkBTreeGetStartLine(const TkText *textPtr); extern TkTextLine * TkBTreeGetLastLine(const TkText *textPtr); extern TkTextLine * TkBTreeNextLine(const TkText *textPtr, TkTextLine *linePtr); extern TkTextLine * TkBTreePrevLine(const TkText *textPtr, TkTextLine *linePtr); extern unsigned TkBTreeCountLines(const TkTextBTree tree, const TkTextLine *linePtr1, const TkTextLine *linePtr2); extern bool TkTextIsDeadPeer(const TkText *textPtr); extern bool TkTextIsStartEndMarker(const TkTextSegment *segPtr); extern bool TkTextIsSpecialMark(const TkTextSegment *segPtr); extern bool TkTextIsPrivateMark(const TkTextSegment *segPtr); extern bool TkTextIsSpecialOrPrivateMark(const TkTextSegment *segPtr); extern bool TkTextIsNormalOrSpecialMark(const TkTextSegment *segPtr); extern bool TkTextIsNormalMark(const TkTextSegment *segPtr); extern bool TkTextIsStableMark(const TkTextSegment *segPtr); extern void TkTextIndexSetEpoch(TkTextIndex *indexPtr, unsigned epoch); extern void TkTextIndexUpdateEpoch(TkTextIndex *indexPtr, unsigned epoch); extern void TkTextIndexSetPeer(TkTextIndex *indexPtr, TkText *textPtr); extern void TkTextIndexSetToLastChar2(TkTextIndex *indexPtr, TkTextLine *linePtr); extern void TkTextIndexInvalidate(TkTextIndex *indexPtr); extern TkTextLine * TkTextIndexGetLine(const TkTextIndex *indexPtr); extern TkTextSegment * TkTextIndexGetSegment(const TkTextIndex *indexPtr); extern TkSharedText * TkTextIndexGetShared(const TkTextIndex *indexPtr); extern bool TkTextIndexSameLines(const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2); extern void TkTextIndexSave(TkTextIndex *indexPtr); # if TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 7 && TCL_UTF_MAX <= 4 extern int TkUtfToUniChar(const char *src, int *chPtr); # endif #endif /* __STDC_VERSION__ >= 199901L */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 105 * End: * vi:set ts=8 sw=4: */ |
Changes to generic/tkText.h.
︙ | ︙ | |||
29 30 31 32 33 34 35 | #include <stdint.h> #ifdef MAC_OSX_TK /* required for TK_LAYOUT_WITH_BASE_CHUNKS */ # include "tkMacOSXInt.h" #endif | < < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <stdint.h> #ifdef MAC_OSX_TK /* required for TK_LAYOUT_WITH_BASE_CHUNKS */ # include "tkMacOSXInt.h" #endif #ifdef BUILD_tk # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif #if TK_CHECK_ALLOCS # define DEBUG_ALLOC(expr) expr |
︙ | ︙ | |||
755 756 757 758 759 760 761 | struct TkText *textPtr; /* If non-NULL, then this tag only applies to the given text widget * (when there are peer widgets). */ struct Node *rootPtr; /* Pointer into the B-Tree at the lowest node that completely * dominates the ranges of text occupied by the tag. At this node * there is no information about the tag. One or more children of * the node do contain information about the tag. */ | | | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | struct TkText *textPtr; /* If non-NULL, then this tag only applies to the given text widget * (when there are peer widgets). */ struct Node *rootPtr; /* Pointer into the B-Tree at the lowest node that completely * dominates the ranges of text occupied by the tag. At this node * there is no information about the tag. One or more children of * the node do contain information about the tag. */ uint32_t priority; /* Priority of this tag within widget. 0 means lowest priority. * Exactly one tag has each integer value between 0 and numTags-1. */ uint32_t index; /* Unique index for fast tag lookup. It is guaranteed that the index * number is less or equal than 'TkBitSize(sharedTextPtr->usedTags)'.*/ unsigned refCount; /* Number of objects referring to us. */ bool isDisabled; /* This tag is disabled? */ /* |
︙ | ︙ | |||
784 785 786 787 788 789 790 | TkTextUndoToken *recentTagAddRemoveToken; /* Holds the undo information of last tag add/remove operation. */ TkTextUndoToken *recentChangePriorityToken; /* Holds the undo information of last tag lower/raise operation. */ bool recentTagAddRemoveTokenIsNull; /* 'recentTagAddRemoveToken' is null, this means the pointer still * is valid, but should not be saved onto undo stack. */ | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | TkTextUndoToken *recentTagAddRemoveToken; /* Holds the undo information of last tag add/remove operation. */ TkTextUndoToken *recentChangePriorityToken; /* Holds the undo information of last tag lower/raise operation. */ bool recentTagAddRemoveTokenIsNull; /* 'recentTagAddRemoveToken' is null, this means the pointer still * is valid, but should not be saved onto undo stack. */ uint32_t savedPriority; /* Contains the priority before recentChangePriorityToken will be set. */ int32_t undoTagListIndex; /* Index to entry in 'undoTagList', is -1 if not in 'undoTagList'. */ /* * Information for displaying text with this tag. The information belows * acts as an override on information specified by lower-priority tags. * If no value is specified, then the next-lower-priority tag on the text * determins the value. The text widget itself provides defaults if no tag |
︙ | ︙ | |||
895 896 897 898 899 900 901 | bool affectsDisplay; /* True means that this tag affects the way information is * displayed on the screen (so need to redisplay if tag changes). */ bool affectsDisplayGeometry;/* True means that this tag affects the size with which * information is displayed on the screen (so need to recalculate * line dimensions if tag changes). */ Tk_OptionTable optionTable; /* Token representing the configuration specifications. */ | | | 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 | bool affectsDisplay; /* True means that this tag affects the way information is * displayed on the screen (so need to redisplay if tag changes). */ bool affectsDisplayGeometry;/* True means that this tag affects the size with which * information is displayed on the screen (so need to recalculate * line dimensions if tag changes). */ Tk_OptionTable optionTable; /* Token representing the configuration specifications. */ } TkTextTag; /* * Some definitions for tag search, used by TkBTreeStartSearch, TkBTreeStartSearchBack: */ typedef enum { SEARCH_NEXT_TAGON, /* Search for next range, this will skip the current range. */ |
︙ | ︙ | |||
1712 1713 1714 1715 1716 1717 1718 | MODULE_SCOPE int TkBTreeLoad(TkText *textPtr, Tcl_Obj *content); MODULE_SCOPE void TkBTreeDeleteIndexRange(TkSharedText *sharedTextPtr, TkTextIndex *index1Ptr, TkTextIndex *index2Ptr, int flags, TkTextUndoInfo *undoInfo); inline unsigned TkBTreeEpoch(TkTextBTree tree); inline unsigned TkBTreeIncrEpoch(TkTextBTree tree); inline struct Node * TkBTreeGetRoot(TkTextBTree tree); | | | | | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 | MODULE_SCOPE int TkBTreeLoad(TkText *textPtr, Tcl_Obj *content); MODULE_SCOPE void TkBTreeDeleteIndexRange(TkSharedText *sharedTextPtr, TkTextIndex *index1Ptr, TkTextIndex *index2Ptr, int flags, TkTextUndoInfo *undoInfo); inline unsigned TkBTreeEpoch(TkTextBTree tree); inline unsigned TkBTreeIncrEpoch(TkTextBTree tree); inline struct Node * TkBTreeGetRoot(TkTextBTree tree); MODULE_SCOPE TkTextLine * TkBTreeFindLine(TkTextBTree tree, const TkText *textPtr, unsigned line); MODULE_SCOPE TkTextLine * TkBTreeFindPixelLine(TkTextBTree tree, const TkText *textPtr, int pixels, int32_t *pixelOffset); MODULE_SCOPE TkTextLine * TkBTreeGetLogicalLine(const TkSharedText *sharedTextPtr, const TkText *textPtr, TkTextLine *linePtr); MODULE_SCOPE TkTextLine * TkBTreeNextLogicalLine(const TkSharedText *sharedTextPtr, const TkText *textPtr, TkTextLine *linePtr); inline TkTextLine * TkBTreePrevLogicalLine(const TkSharedText *sharedTextPtr, const TkText *textPtr, TkTextLine *linePtr); MODULE_SCOPE TkTextLine * TkBTreeNextDisplayLine(TkText *textPtr, TkTextLine *linePtr, unsigned *displayLineNo, unsigned offset); MODULE_SCOPE TkTextLine * TkBTreePrevDisplayLine(TkText *textPtr, TkTextLine *linePtr, unsigned *displayLineNo, unsigned offset); MODULE_SCOPE TkTextSegment * TkBTreeFindStartOfElidedRange(const TkSharedText *sharedTextPtr, const TkText *textPtr, const TkTextSegment *segPtr); MODULE_SCOPE TkTextSegment * TkBTreeFindEndOfElidedRange(const TkSharedText *sharedTextPtr, const TkText *textPtr, const TkTextSegment *segPtr); inline TkTextTag * TkBTreeGetTags(const TkTextIndex *indexPtr); MODULE_SCOPE TkTextTag * TkBTreeGetSegmentTags(const TkSharedText *sharedTextPtr, const TkTextSegment *segPtr, const TkText *textPtr); |
︙ | ︙ | |||
1909 1910 1911 1912 1913 1914 1915 | MODULE_SCOPE bool TkTextTestTag(const TkTextIndex *indexPtr, const TkTextTag *tagPtr); inline bool TkTextIsDeadPeer(const TkText *textPtr); MODULE_SCOPE void TkTextGenerateWidgetViewSyncEvent(TkText *textPtr, bool sendImmediately); MODULE_SCOPE void TkTextRunAfterSyncCmd(TkText *textPtr); MODULE_SCOPE void TkTextInvalidateLineMetrics(TkSharedText *sharedTextPtr, TkText *textPtr, TkTextLine *linePtr, unsigned lineCount, TkTextInvalidateAction action); MODULE_SCOPE void TkTextUpdateLineMetrics(TkText *textPtr, unsigned lineNum, unsigned endLine); | < < | 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 | MODULE_SCOPE bool TkTextTestTag(const TkTextIndex *indexPtr, const TkTextTag *tagPtr); inline bool TkTextIsDeadPeer(const TkText *textPtr); MODULE_SCOPE void TkTextGenerateWidgetViewSyncEvent(TkText *textPtr, bool sendImmediately); MODULE_SCOPE void TkTextRunAfterSyncCmd(TkText *textPtr); MODULE_SCOPE void TkTextInvalidateLineMetrics(TkSharedText *sharedTextPtr, TkText *textPtr, TkTextLine *linePtr, unsigned lineCount, TkTextInvalidateAction action); MODULE_SCOPE void TkTextUpdateLineMetrics(TkText *textPtr, unsigned lineNum, unsigned endLine); MODULE_SCOPE int TkTextMarkCmd(TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE TkTextSegment * TkTextFindMark(const TkText *textPtr, const char *name); MODULE_SCOPE TkTextSegment * TkTextFreeMarks(TkSharedText *sharedTextPtr, bool retainPrivateMarks); MODULE_SCOPE bool TkTextMarkNameToIndex(TkText *textPtr, const char *name, TkTextIndex *indexPtr); MODULE_SCOPE void TkTextMarkSegToIndex(TkText *textPtr, TkTextSegment *markPtr, TkTextIndex *indexPtr); |
︙ | ︙ | |||
2099 2100 2101 2102 2103 2104 2105 | # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 5 */ #undef STRUCT | | < | 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 | # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 5 */ #undef STRUCT #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextPriv.h" #endif #endif /* _TKTEXT */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 105 * End: * vi:set ts=8 sw=4: */ |
Changes to generic/tkTextBTree.c.
︙ | ︙ | |||
25 26 27 28 29 30 31 | #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif #ifndef ABS # define ABS(a) (a < 0 ? -a : a) #endif | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif #ifndef ABS # define ABS(a) (a < 0 ? -a : a) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Implementation notes: |
︙ | ︙ | |||
64 65 66 67 68 69 70 | /* * Upper and lower bounds on how many children a node may have: rebalance when * either of these limits is exceeded. MAX_CHILDREN should be twice * MIN_CHILDREN, and MIN_CHILDREN must be >= 2. */ | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* * Upper and lower bounds on how many children a node may have: rebalance when * either of these limits is exceeded. MAX_CHILDREN should be twice * MIN_CHILDREN, and MIN_CHILDREN must be >= 2. */ #define MIN_CHILDREN 16u #define MAX_CHILDREN (2u*MIN_CHILDREN) /* * The data structure below defines a node in the B-tree. */ typedef struct TkBTreeNodePixelInfo { uint32_t pixels; /* Number of vertical display pixels. */ |
︙ | ︙ | |||
492 493 494 495 496 497 498 | */ typedef union { void *ptr; uintptr_t flag; } __ptr_to_int; | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | */ typedef union { void *ptr; uintptr_t flag; } __ptr_to_int; #define POINTER_IS_MARKED(ptr) ((bool)(((__ptr_to_int *) &ptr)->flag & (uintptr_t) 1)) #define MARK_POINTER(ptr) (((__ptr_to_int *) &ptr)->flag |= (uintptr_t) 1) #define UNMARK_POINTER(ptr) (((__ptr_to_int *) &ptr)->flag &= ~(uintptr_t) 1) #define UNMARKED_INT(ptr) (((__ptr_to_int *) &ptr)->flag & ~(uintptr_t) 1) DEBUG_ALLOC(extern unsigned tkTextCountNewSegment); DEBUG_ALLOC(extern unsigned tkTextCountDestroySegment); DEBUG_ALLOC(extern unsigned tkTextCountNewNode); |
︙ | ︙ | |||
1438 1439 1440 1441 1442 1443 1444 | } /* * Increment the line and pixel counts in all the parent nodes of the * insertion point, then rebalance the tree if necessary. */ | > | | | | 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | } /* * Increment the line and pixel counts in all the parent nodes of the * insertion point, then rebalance the tree if necessary. */ /* MSVC cannot implicitly convert unsigned to signed. */ SubtractPixelCount2(treePtr, nodePtr, -((int) changeToLineCount), -((int) changeToLogicalLineCount), -((int) changeToBranchCount), -((int) size), changeToPixelInfo); linePtr->parentPtr->numChildren += changeToLineCount; if (nodePtr->numChildren > MAX_CHILDREN) { Rebalance(treePtr, nodePtr); } /* |
︙ | ︙ | |||
2207 2208 2209 2210 2211 2212 2213 | treePtr->clients -= 1; } else { /* * Clean up pixel data for the given reference. */ | | | | 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 | treePtr->clients -= 1; } else { /* * Clean up pixel data for the given reference. */ if (pixelReference == (int) (treePtr->numPixelReferences - 1)) { /* * The widget we're removing has the last index, so deletion is easier. */ RemovePixelClient(treePtr, treePtr->rootPtr, pixelReference, -1); } else { TkText *adjustPtr; RemovePixelClient(treePtr, treePtr->rootPtr, pixelReference, pixelReference); /* * Now we need to adjust the 'pixelReference' of the peer widget * whose storage we've just moved. */ adjustPtr = treePtr->sharedTextPtr->peers; while (adjustPtr) { if (adjustPtr->pixelReference == (int) treePtr->numPixelReferences - 1) { adjustPtr->pixelReference = pixelReference; break; } adjustPtr = adjustPtr->next; } assert(adjustPtr); } |
︙ | ︙ | |||
3134 3135 3136 3137 3138 3139 3140 | TestIfElided( const TkTextTag *tagPtr) { int highestPriority = -1; bool elide = false; for ( ; tagPtr; tagPtr = tagPtr->nextPtr) { | | | 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 | TestIfElided( const TkTextTag *tagPtr) { int highestPriority = -1; bool elide = false; for ( ; tagPtr; tagPtr = tagPtr->nextPtr) { if (tagPtr->elideString && (int) tagPtr->priority > highestPriority) { elide = tagPtr->elide; highestPriority = tagPtr->priority; } } return elide; } |
︙ | ︙ | |||
4260 4261 4262 4263 4264 4265 4266 | TkText *textPtr = index.textPtr; for (tagPtr = hyphenTagPtr; tagPtr; tagPtr = tagPtr->nextPtr) { if (!TkTextTagSetTest(linePtr->parentPtr->tagonPtr, tagPtr->index)) { AddTagToNode(linePtr->parentPtr, tagPtr, true); } if (tagPtr->elideString | | | 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 | TkText *textPtr = index.textPtr; for (tagPtr = hyphenTagPtr; tagPtr; tagPtr = tagPtr->nextPtr) { if (!TkTextTagSetTest(linePtr->parentPtr->tagonPtr, tagPtr->index)) { AddTagToNode(linePtr->parentPtr, tagPtr, true); } if (tagPtr->elideString && (int) tagPtr->priority > highestPriority && (!tagPtr->textPtr || tagPtr->textPtr == textPtr)) { highestPriority = (hyphenElideTagPtr = tagPtr)->priority; } } } DEBUG(indexPtr->discardConsistencyCheck = true); |
︙ | ︙ | |||
4363 4364 4365 4366 4367 4368 4369 | prevPtr = SplitSeg(indexPtr, &info); } if (info.offset >= 0) { /* * Fill increased/decreased char segment. */ segPtr = prevPtr; | | | 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 | prevPtr = SplitSeg(indexPtr, &info); } if (info.offset >= 0) { /* * Fill increased/decreased char segment. */ segPtr = prevPtr; assert(segPtr->size >= (int) (info.offset + chunkSize)); memcpy(segPtr->body.chars + info.offset, string, chunkSize); segPtr->sectionPtr->size += chunkSize; linePtr->size += chunkSize; assert(!tagInfoPtr || TkTextTagSetIsEqual(tagInfoPtr, segPtr->tagInfoPtr)); tagInfoPtr = segPtr->tagInfoPtr; } else { /* |
︙ | ︙ | |||
4516 4517 4518 4519 4520 4521 4522 | } /* * Increment the line and pixel counts in all the parent nodes of the * insertion point, then rebalance the tree if necessary. */ | > | | | 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 | } /* * Increment the line and pixel counts in all the parent nodes of the * insertion point, then rebalance the tree if necessary. */ /* MSVC cannot implicitly convert unsigned to signed. */ SubtractPixelCount2(treePtr, linePtr->parentPtr, -((int) changeToLineCount), -((int) changeToLogicalLineCount), 0, -((int) size), changeToPixelInfo); if ((linePtr->parentPtr->numChildren += changeToLineCount) > MAX_CHILDREN) { Rebalance(treePtr, linePtr->parentPtr); } /* * This line now needs to have its height recalculated. This has to be done after Rebalance. |
︙ | ︙ | |||
4554 4555 4556 4557 4558 4559 4560 | for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) { TkTextTag *tPtr = sharedTextPtr->tagLookup[i]; assert(tPtr); assert(!tPtr->isDisabled); if (tPtr->elideString | | | 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 | for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) { TkTextTag *tPtr = sharedTextPtr->tagLookup[i]; assert(tPtr); assert(!tPtr->isDisabled); if (tPtr->elideString && (int) tPtr->priority > highestPriority && (!tPtr->textPtr || tPtr->textPtr == textPtr)) { highestPriority = (tagPtr = tPtr)->priority; } } if (tagPtr) { firstSegPtr->protectionFlag = true; |
︙ | ︙ | |||
5677 5678 5679 5680 5681 5682 5683 | sectionPtr = linePtr->segPtr->sectionPtr; assert(!sectionPtr || !sectionPtr->prevPtr); assert(!linePtr->lastPtr->nextPtr); assert(!propagateChangeOfNumBranches || TkBTreeGetRoot(sharedTextPtr->tree)->numBranches >= linePtr->numBranches); | | | 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 | sectionPtr = linePtr->segPtr->sectionPtr; assert(!sectionPtr || !sectionPtr->prevPtr); assert(!linePtr->lastPtr->nextPtr); assert(!propagateChangeOfNumBranches || TkBTreeGetRoot(sharedTextPtr->tree)->numBranches >= linePtr->numBranches); changeToNumBranches = -((int) linePtr->numBranches); linePtr->numBranches = 0; linePtr->numLinks = 0; linePtr->size = 0; for (segPtr = linePtr->segPtr; segPtr; ) { if (!sectionPtr) { TkTextSection *newSectionPtr; |
︙ | ︙ | |||
5838 5839 5840 5841 5842 5843 5844 | */ static void FreeLine( const BTree *treePtr, TkTextLine *linePtr) { | | | | 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 | */ static void FreeLine( const BTree *treePtr, TkTextLine *linePtr) { unsigned i; assert(linePtr->parentPtr); DEBUG(linePtr->parentPtr = NULL); for (i = 0; i < treePtr->numPixelReferences; ++i) { TkTextDispLineInfo *dispLineInfo = linePtr->pixelInfo[i].dispLineInfo; if (dispLineInfo) { free(dispLineInfo); DEBUG_ALLOC(tkTextCountDestroyDispInfo++); } } |
︙ | ︙ | |||
5930 5931 5932 5933 5934 5935 5936 | TkTextSegment *segPtr, /* Copy text from this segment. */ unsigned offset, /* Copy text starting at this offset. */ unsigned length, /* Number of characters to copy. */ unsigned newSize) /* Character size of the new segment. */ { assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); | | | 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 | TkTextSegment *segPtr, /* Copy text from this segment. */ unsigned offset, /* Copy text starting at this offset. */ unsigned length, /* Number of characters to copy. */ unsigned newSize) /* Character size of the new segment. */ { assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); assert(segPtr->size >= (int) (offset + length)); return MakeCharSeg(segPtr->sectionPtr, segPtr->tagInfoPtr, newSize, segPtr->body.chars + offset, length); } /* *-------------------------------------------------------------- |
︙ | ︙ | |||
5964 5965 5966 5967 5968 5969 5970 | { TkTextSegment *newPtr1, *newPtr2; assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); assert(segPtr->sectionPtr); /* otherwise segment is freed */ assert(index > 0); | | | 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 | { TkTextSegment *newPtr1, *newPtr2; assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); assert(segPtr->sectionPtr); /* otherwise segment is freed */ assert(index > 0); assert((int) index < segPtr->size); newPtr1 = CopyCharSeg(segPtr, 0, index, index); newPtr2 = CopyCharSeg(segPtr, index, segPtr->size - index, segPtr->size - index); newPtr1->nextPtr = newPtr2; newPtr1->prevPtr = segPtr->prevPtr; newPtr2->nextPtr = segPtr->nextPtr; |
︙ | ︙ | |||
6097 6098 6099 6100 6101 6102 6103 | unsigned oldCapacity, newCapacity; assert(splitInfo); assert(!splitInfo->splitted); assert(splitInfo->increase != 0); assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); | | | | | 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 | unsigned oldCapacity, newCapacity; assert(splitInfo); assert(!splitInfo->splitted); assert(splitInfo->increase != 0); assert(segPtr); assert(segPtr->typePtr == &tkTextCharType); assert((int) offset <= segPtr->size); assert((int) offset < segPtr->size || segPtr->body.chars[segPtr->size - 1] != '\n'); /* * We must not split if the new char content will be appended * to the current content (i.e. offset == segPtr->size). */ if (splitInfo->forceSplit && (int) offset < segPtr->size) { unsigned newSize, decreasedSize; TkTextSegment *newPtr; splitInfo->splitted = true; if (offset == 0 && segPtr == segPtr->sectionPtr->linePtr->segPtr) { /* |
︙ | ︙ | |||
6653 6654 6655 6656 6657 6658 6659 | Node *nodePtr1; Node *nodePtr2; unsigned numSegments; unsigned maxSegments; unsigned byteSize; unsigned lineDiff; bool steadyMarks; | | | | 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 | Node *nodePtr1; Node *nodePtr2; unsigned numSegments; unsigned maxSegments; unsigned byteSize; unsigned lineDiff; bool steadyMarks; unsigned lineNo1; unsigned lineNo2; assert(firstSegPtr); assert(lastSegPtr); assert(!undoInfo || undoInfo->token); assert(!(flags & DELETE_INCLUSIVE) || firstSegPtr->typePtr->group & (SEG_GROUP_MARK|SEG_GROUP_PROTECT)); |
︙ | ︙ | |||
6786 6787 6788 6789 6790 6791 6792 | if (curNodePtr == nodePtr1 || curNodePtr == nodePtr2) { /* * Update only those nodes which will not be deleted, * because DeleteEmptyNode will do a faster update. */ SubtractPixelInfo(treePtr, curLinePtr); if (curLinePtr->numBranches) { | | | 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 | if (curNodePtr == nodePtr1 || curNodePtr == nodePtr2) { /* * Update only those nodes which will not be deleted, * because DeleteEmptyNode will do a faster update. */ SubtractPixelInfo(treePtr, curLinePtr); if (curLinePtr->numBranches) { PropagateChangeOfNumBranches(curLinePtr->parentPtr, -(int) curLinePtr->numBranches); } } if (--curNodePtr->numChildren == 0) { DeleteEmptyNode(treePtr, curNodePtr); } } |
︙ | ︙ | |||
7330 7331 7332 7333 7334 7335 7336 | *---------------------------------------------------------------------- */ TkTextLine * TkBTreeFindLine( TkTextBTree tree, /* B-tree in which to find line. */ const TkText *textPtr, /* Relative to this client of the B-tree. */ | | | | | | | 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 | *---------------------------------------------------------------------- */ TkTextLine * TkBTreeFindLine( TkTextBTree tree, /* B-tree in which to find line. */ const TkText *textPtr, /* Relative to this client of the B-tree. */ unsigned line) /* Index of desired line. */ { BTree *treePtr = (BTree *) tree; Node *nodePtr; TkTextLine *linePtr; assert(tree || textPtr); if (!treePtr) { tree = textPtr->sharedTextPtr->tree; treePtr = (BTree *) tree; } nodePtr = treePtr->rootPtr; if (nodePtr->numLines <= line) { return NULL; } /* * Check for any start/end offset for this text widget. */ if (textPtr) { line += TkBTreeLinesTo(tree, NULL, TkBTreeGetStartLine(textPtr), NULL); if (line >= nodePtr->numLines) { return NULL; } if (line > TkBTreeLinesTo(tree, NULL, TkBTreeGetLastLine(textPtr), NULL)) { return NULL; } } if (line == 0) { return nodePtr->linePtr; } if (line == nodePtr->numLines - 1) { return nodePtr->lastPtr; } /* * Work down through levels of the tree until a node is found at level 0. */ while (nodePtr->level > 0) { for (nodePtr = nodePtr->childPtr; nodePtr && nodePtr->numLines <= line; nodePtr = nodePtr->nextPtr) { line -= nodePtr->numLines; } assert(nodePtr); } /* |
︙ | ︙ | |||
9149 9150 9151 9152 9153 9154 9155 | } if (!(flags & HAS_TAGON)) { flags &= ~HAS_TAGOFF; } else if (nchilds < nodePtr->numChildren) { flags |= HAS_TAGOFF; } | | | 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 | } if (!(flags & HAS_TAGON)) { flags &= ~HAS_TAGOFF; } else if (nchilds < nodePtr->numChildren) { flags |= HAS_TAGOFF; } if (nchilds > (nodePtr->level > 0 ? 1u : 0u)) { tagPtr->rootPtr = nodePtr; } nodePtr->tagonPtr = TagSetAddOrErase(nodePtr->tagonPtr, tagPtr, !!(flags & HAS_TAGON)); nodePtr->tagoffPtr = TagSetAddOrErase(nodePtr->tagoffPtr, tagPtr, !!(flags & HAS_TAGOFF)); return flags; |
︙ | ︙ | |||
10169 10170 10171 10172 10173 10174 10175 | bool affectsDisplayGeometry = TestIfDisplayGeometryIsAffected(sharedTextPtr, affectedTagInfoPtr, discardSelection); changedProc(sharedTextPtr, textPtr, &startIndex, &endIndex, NULL, affectsDisplayGeometry); } } else { TkTextSegment *firstPtr, *lastPtr; | | | 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 | bool affectsDisplayGeometry = TestIfDisplayGeometryIsAffected(sharedTextPtr, affectedTagInfoPtr, discardSelection); changedProc(sharedTextPtr, textPtr, &startIndex, &endIndex, NULL, affectsDisplayGeometry); } } else { TkTextSegment *firstPtr, *lastPtr; unsigned lineNo1, lineNo2; if (undoInfo) { undoToken = malloc(sizeof(UndoTokenTagClear)); undoInfo->token = (TkTextUndoToken *) undoToken; undoInfo->byteSize = 0; undoToken->undoType = &undoTokenClearTagsType; undoToken->changeList = NULL; |
︙ | ︙ | |||
12277 12278 12279 12280 12281 12282 12283 | for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) { const TkTextTag *tagPtr = sharedTextPtr->tagLookup[i]; assert(tagPtr); assert(!tagPtr->isDisabled); | | | 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 | for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) { const TkTextTag *tagPtr = sharedTextPtr->tagLookup[i]; assert(tagPtr); assert(!tagPtr->isDisabled); if (tagPtr->lang[0] && (int) tagPtr->priority > highestPriority) { langPtr = tagPtr->lang; highestPriority = tagPtr->priority; } } } return langPtr; |
︙ | ︙ | |||
12614 12615 12616 12617 12618 12619 12620 | const Node *rootPtr, /* The root node. */ const Node *nodePtr, /* Node whose subtree should be checked. */ unsigned references) /* Number of referring widgets which have pixel counts. */ { const Node *childNodePtr; const TkTextLine *linePtr; const TkTextLine *prevLinePtr; | | < | | 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 | const Node *rootPtr, /* The root node. */ const Node *nodePtr, /* Node whose subtree should be checked. */ unsigned references) /* Number of referring widgets which have pixel counts. */ { const Node *childNodePtr; const TkTextLine *linePtr; const TkTextLine *prevLinePtr; unsigned numLines, numLogicalLines, numBranches, numChildren, minChildren, size, i; NodePixelInfo *pixelInfo = NULL; NodePixelInfo pixelInfoBuf[PIXEL_CLIENTS]; TkTextTagSet *tagonPtr = NULL; TkTextTagSet *tagoffPtr = NULL; TkTextTagSet *additionalTagoffPtr = NULL; unsigned memsize; if (nodePtr->level == 0 && !nodePtr->linePtr) { Tcl_Panic("CheckNodeConsistency: this node is freed"); } minChildren = nodePtr->parentPtr ? MIN_CHILDREN : (nodePtr->level > 0 ? 2 : 1); if (nodePtr->numChildren < minChildren || nodePtr->numChildren > MAX_CHILDREN) { Tcl_Panic("CheckNodeConsistency: bad child count (%d)", nodePtr->numChildren); } if (!nodePtr->linePtr) { Tcl_Panic("CheckNodeConsistency: first pointer is NULL"); } if (!nodePtr->lastPtr) { |
︙ | ︙ | |||
12685 12686 12687 12688 12689 12690 12691 | TkTextTagSetIncrRefCount(tagoffPtr = sharedTextPtr->emptyTagInfoPtr); additionalTagoffPtr = NULL; if (nodePtr->level == 0) { prevLinePtr = NULL; linePtr = nodePtr->linePtr; for (linePtr = nodePtr->linePtr; | | | | 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 | TkTextTagSetIncrRefCount(tagoffPtr = sharedTextPtr->emptyTagInfoPtr); additionalTagoffPtr = NULL; if (nodePtr->level == 0) { prevLinePtr = NULL; linePtr = nodePtr->linePtr; for (linePtr = nodePtr->linePtr; numChildren < nodePtr->numChildren; ++numChildren, ++numLines, linePtr = linePtr->nextPtr) { if (!linePtr) { Tcl_Panic("CheckNodeConsistency: unexpected end of line chain"); } if (linePtr->parentPtr != nodePtr) { Tcl_Panic("CheckNodeConsistency: line has wrong parent pointer"); } CheckSegments(sharedTextPtr, linePtr); CheckSegmentItems(sharedTextPtr, linePtr); CheckSections(linePtr); for (i = 0; i < references; ++i) { pixelInfo[i].pixels += linePtr->pixelInfo[i].height; pixelInfo[i].numDispLines += GetDisplayLines(linePtr, i); } if (tagonPtr) { tagonPtr = TkTextTagSetJoin(tagonPtr, linePtr->tagonPtr); tagoffPtr = TkTextTagSetJoin(tagoffPtr, linePtr->tagoffPtr); if (additionalTagoffPtr) { |
︙ | ︙ | |||
12755 12756 12757 12758 12759 12760 12761 | tagoffPtr = TkTextTagSetJoin(tagoffPtr, nodePtr->tagoffPtr); if (additionalTagoffPtr) { additionalTagoffPtr = TkTextTagSetIntersect(additionalTagoffPtr, nodePtr->tagonPtr); } else { TkTextTagSetIncrRefCount(additionalTagoffPtr = nodePtr->tagonPtr); } } | | | 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 | tagoffPtr = TkTextTagSetJoin(tagoffPtr, nodePtr->tagoffPtr); if (additionalTagoffPtr) { additionalTagoffPtr = TkTextTagSetIntersect(additionalTagoffPtr, nodePtr->tagonPtr); } else { TkTextTagSetIncrRefCount(additionalTagoffPtr = nodePtr->tagonPtr); } } for (i = 0; i < references; i++) { pixelInfo[i].pixels += childNodePtr->pixelInfo[i].pixels; pixelInfo[i].numDispLines += childNodePtr->pixelInfo[i].numDispLines; } } } if (size != nodePtr->size) { Tcl_Panic("CheckNodeConsistency: sum of size (%d) at level %d is wrong (%d is expected)", |
︙ | ︙ | |||
12806 12807 12808 12809 12810 12811 12812 | } } TkTextTagSetDecrRefCount(tagonPtr); TkTextTagSetDecrRefCount(tagoffPtr); TkTextTagSetDecrRefCount(additionalTagoffPtr); } | | | 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 | } } TkTextTagSetDecrRefCount(tagonPtr); TkTextTagSetDecrRefCount(tagoffPtr); TkTextTagSetDecrRefCount(additionalTagoffPtr); } for (i = 0; i < references; i++) { if (pixelInfo[i].pixels != nodePtr->pixelInfo[i].pixels) { Tcl_Panic("CheckNodeConsistency: mismatch in pixel count " "(expected: %d, counted: %d) for widget (%d) at level %d", pixelInfo[i].pixels, nodePtr->pixelInfo[i].pixels, i, nodePtr->level); } if (pixelInfo[i].numDispLines != nodePtr->pixelInfo[i].numDispLines) { Tcl_Panic("CheckNodeConsistency: mismatch in number of display lines " |
︙ | ︙ | |||
13841 13842 13843 13844 13845 13846 13847 | * *---------------------------------------------------------------------- */ static TkTextLine * GetLastDisplayLine( TkText *textPtr, | | | | | 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 | * *---------------------------------------------------------------------- */ static TkTextLine * GetLastDisplayLine( TkText *textPtr, unsigned *displayLineNo) { TkTextLine *linePtr; linePtr = textPtr->endMarker->sectionPtr->linePtr; linePtr = TkBTreeGetLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr); *displayLineNo = GetDisplayLines(linePtr, textPtr->pixelReference); return linePtr; } TkTextLine * TkBTreeNextDisplayLine( TkText *textPtr, /* Information about text widget. */ TkTextLine *linePtr, /* Start at this logical line. */ unsigned *displayLineNo, /* IN: Start at this display line number in given logical line. * OUT: Store display line number of requested display line. */ unsigned offset) /* Offset to requested display line. */ { const Node *nodePtr; const Node *parentPtr; int lineNo, numLines; unsigned numDispLines; unsigned ref; assert(textPtr); assert(linePtr->logicalLine || linePtr == TkBTreeGetStartLine(textPtr)); assert(*displayLineNo >= 0); assert(*displayLineNo < GetDisplayLines(linePtr, textPtr->pixelReference)); if (offset == 0) { return linePtr; } ref = textPtr->pixelReference; nodePtr = linePtr->parentPtr; |
︙ | ︙ | |||
13977 13978 13979 13980 13981 13982 13983 | * *---------------------------------------------------------------------- */ static TkTextLine * GetFirstDisplayLine( TkText *textPtr, | | | | | 13978 13979 13980 13981 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 13993 13994 13995 13996 13997 13998 13999 14000 14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 | * *---------------------------------------------------------------------- */ static TkTextLine * GetFirstDisplayLine( TkText *textPtr, unsigned *displayLineNo) { *displayLineNo = 0; return textPtr->startMarker->sectionPtr->linePtr; } TkTextLine * TkBTreePrevDisplayLine( TkText *textPtr, /* Information about text widget. */ TkTextLine *linePtr, /* Start at this logical line. */ unsigned *displayLineNo, /* IN: Start at this display line number in given logical line. * OUT: Store display line number of requested display line. */ unsigned offset) /* Offset to requested display line. */ { const Node *nodeStack[MAX_CHILDREN]; const Node *nodePtr; const Node *parentPtr; const Node *nPtr; unsigned numDispLines; unsigned ref; unsigned idx; int lineNo; assert(textPtr); assert(linePtr->logicalLine || linePtr == TkBTreeGetStartLine(textPtr)); assert(*displayLineNo >= 0); assert(*displayLineNo < GetDisplayLines(linePtr, textPtr->pixelReference)); if (offset == 0) { return linePtr; } ref = textPtr->pixelReference; nodePtr = linePtr->parentPtr; |
︙ | ︙ | |||
14525 14526 14527 14528 14529 14530 14531 | } if (textPtr) { const TkSharedText *sharedTextPtr = treePtr->sharedTextPtr; if (textPtr->startMarker != sharedTextPtr->startMarker) { if (linePtr1 == textPtr->startMarker->sectionPtr->linePtr) { | | | | 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 | } if (textPtr) { const TkSharedText *sharedTextPtr = treePtr->sharedTextPtr; if (textPtr->startMarker != sharedTextPtr->startMarker) { if (linePtr1 == textPtr->startMarker->sectionPtr->linePtr) { assert(TkTextSegToIndex(textPtr->startMarker) <= (int) numBytes); numBytes -= TkTextSegToIndex(textPtr->startMarker); } } if (textPtr->endMarker != sharedTextPtr->endMarker) { if (!SegIsAtStartOfLine(textPtr->endMarker)) { const TkTextLine *linePtr = textPtr->endMarker->sectionPtr->linePtr; assert(linePtr->size - TkTextSegToIndex(textPtr->endMarker) - 1 <= (int) numBytes); numBytes -= linePtr->size - TkTextSegToIndex(textPtr->endMarker) - 1; } } } return numBytes; } |
︙ | ︙ | |||
14612 14613 14614 14615 14616 14617 14618 | /* * We couldn't find a line, so search inside B-Tree for next level-0 * node which contains the byte offset. */ while (parentPtr) { | | | | 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 | /* * We couldn't find a line, so search inside B-Tree for next level-0 * node which contains the byte offset. */ while (parentPtr) { if (!nodePtr || (!HasLeftNode(nodePtr) && byteIndex >= (int) parentPtr->size)) { nodePtr = parentPtr->nextPtr; parentPtr = parentPtr->parentPtr; } else { while (nodePtr) { if (byteIndex < (int) nodePtr->size) { if (nodePtr->level > 0) { nodePtr = nodePtr->childPtr; continue; } /* * We've found the right node, now search for the line. */ |
︙ | ︙ | |||
14726 14727 14728 14729 14730 14731 14732 | for (nPtr = parentPtr->childPtr, idx = 0; nPtr != nodePtr; nPtr = nPtr->nextPtr) { nodeStack[idx++] = nPtr; } nodePtr = idx ? nodeStack[--idx] : NULL; while (parentPtr) { | | | | 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 | for (nPtr = parentPtr->childPtr, idx = 0; nPtr != nodePtr; nPtr = nPtr->nextPtr) { nodeStack[idx++] = nPtr; } nodePtr = idx ? nodeStack[--idx] : NULL; while (parentPtr) { if (!nodePtr || (!nodePtr->nextPtr && byteIndex >= (int) parentPtr->size)) { nodePtr = parentPtr; if ((parentPtr = parentPtr->parentPtr)) { for (nPtr = parentPtr->childPtr, idx = 0; nPtr != nodePtr; nPtr = nPtr->nextPtr) { nodeStack[idx++] = nPtr; } nodePtr = idx ? nodeStack[--idx] : NULL; } } else { while (nodePtr) { if (byteIndex < (int) nodePtr->size) { if (nodePtr->level > 0) { parentPtr = nodePtr; idx = 0; for (nPtr = nodePtr->childPtr; nPtr; nPtr = nPtr->nextPtr) { nodeStack[idx++] = nPtr; } nodePtr = idx ? nodeStack[--idx] : NULL; |
︙ | ︙ | |||
15885 15886 15887 15888 15889 15890 15891 | static bool CheckSections( const TkTextLine *linePtr) /* Pointer to line with sections. */ { const TkTextSection *sectionPtr = linePtr->segPtr->sectionPtr; const TkTextSegment *segPtr; | | > | 15886 15887 15888 15889 15890 15891 15892 15893 15894 15895 15896 15897 15898 15899 15900 15901 | static bool CheckSections( const TkTextLine *linePtr) /* Pointer to line with sections. */ { const TkTextSection *sectionPtr = linePtr->segPtr->sectionPtr; const TkTextSegment *segPtr; unsigned numSegs, length, count; int size, lineSize = 0; if (!sectionPtr) { Tcl_Panic("CheckSections: segment has no section"); } if (linePtr->segPtr->sectionPtr->segPtr != linePtr->segPtr) { Tcl_Panic("CheckSections: first segment has wrong section pointer"); } |
︙ | ︙ |
Changes to generic/tkTextDisp.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "tkText.h" #include "tkTextTagSet.h" #include "tkRangeList.h" #include "tkInt.h" #ifdef _WIN32 | | | | > > > > | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include "tkText.h" #include "tkTextTagSet.h" #include "tkRangeList.h" #include "tkInt.h" #ifdef _WIN32 # include "tkWinInt.h" #elif defined(__CYGWIN__) # include "tkUnixInt.h" #endif #ifdef MAC_OSX_TK # include "tkMacOSXInt.h" /* Version 8.5 has forgotten to define this constant. */ # ifndef TK_DO_NOT_DRAW # define TK_DO_NOT_DRAW 0x80 # endif #endif #include <stdlib.h> #include <assert.h> #ifndef MIN # define MIN(a,b) (a < b ? a : b) #endif #ifndef MAX # define MAX(a,b) (a < b ? b : a) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * "Calculations of line pixel heights and the size of the vertical |
︙ | ︙ | |||
78 79 80 81 82 83 84 | * undesirable mismatch between display and the vertical scrollbar. * * All such mismatches should be temporary, however, since the asynchronous * height calculations will always catch up eventually. * * For further details see the comments before and within the following * functions below: LayoutDLine, AsyncUpdateLineMetrics, GetYView, | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | * undesirable mismatch between display and the vertical scrollbar. * * All such mismatches should be temporary, however, since the asynchronous * height calculations will always catch up eventually. * * For further details see the comments before and within the following * functions below: LayoutDLine, AsyncUpdateLineMetrics, GetYView, * GetYPixelCount, UpdateOneLine, UpdateLineMetrics. * * For details of the way in which the BTree keeps track of pixel heights, see * tkTextBTree.c. Basically the BTree maintains two pieces of information: the * logical line indices and the pixel height cache. */ /* |
︙ | ︙ | |||
397 398 399 400 401 402 403 | * Information used for scrolling: */ int32_t newXPixelOffset; /* Desired x scroll position, measured as the number of pixels * off-screen to the left for a line with no left margin. */ int32_t curXPixelOffset; /* Actual x scroll position, measured as the number of pixels * off-screen to the left. */ | | | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | * Information used for scrolling: */ int32_t newXPixelOffset; /* Desired x scroll position, measured as the number of pixels * off-screen to the left for a line with no left margin. */ int32_t curXPixelOffset; /* Actual x scroll position, measured as the number of pixels * off-screen to the left. */ uint32_t maxLength; /* Length in pixels of longest line that's visible in window * (length may exceed window size). If there's no wrapping, this * will be zero. */ PixelPos curPixelPos; /* Most recent pixel position, used for the "watch" command. */ PixelPos prevPixelPos; /* Previous pixel position, used for the "watch" command. */ /* * The following information is used to implement scanning: |
︙ | ︙ | |||
548 549 550 551 552 553 554 | const char *brks; /* Buffer for line break information (for TEXT_WRAPMODE_CODEPOINT). */ TkTextIndex index; /* Current index. */ unsigned countChunks; /* Number of chunks in current display line. */ unsigned numBytesSoFar; /* The number of processed bytes (so far). */ unsigned byteOffset; /* The byte offset to start of logical line. */ unsigned dispLineOffset; /* The byte offset to start of display line. */ int increaseNumBytes; /* Increase number of consumed bytes to realize spelling changes. */ | | | | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | const char *brks; /* Buffer for line break information (for TEXT_WRAPMODE_CODEPOINT). */ TkTextIndex index; /* Current index. */ unsigned countChunks; /* Number of chunks in current display line. */ unsigned numBytesSoFar; /* The number of processed bytes (so far). */ unsigned byteOffset; /* The byte offset to start of logical line. */ unsigned dispLineOffset; /* The byte offset to start of display line. */ int increaseNumBytes; /* Increase number of consumed bytes to realize spelling changes. */ unsigned decreaseNumBytes; /* Decrease number of displayable bytes to realize spelling changes. */ unsigned displayLineNo; /* Current display line number. */ int rMargin; /* Right margin width for line. */ int hyphenRule; /* Hyphenation rule applied to last char chunk (only in hyphenation * has been applied). */ TkTextTabArray *tabArrayPtr;/* Tab stops for line; taken from style for the first character * on line. */ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ int tabSize; /* Number of pixels consumed by current tab stop. */ |
︙ | ︙ | |||
587 588 589 590 591 592 593 | } LayoutData; typedef struct DisplayInfo { int byteOffset; /* Byte offset to start of display line (subtract this offset to * get the index of display line start). */ int nextByteOffset; /* Byte offset to start of next display line (add this offset to * get the index of next display line start). */ | | | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | } LayoutData; typedef struct DisplayInfo { int byteOffset; /* Byte offset to start of display line (subtract this offset to * get the index of display line start). */ int nextByteOffset; /* Byte offset to start of next display line (add this offset to * get the index of next display line start). */ unsigned displayLineNo; /* Number of display line. */ unsigned numDispLines; /* Total number of display lines belonging to corresponding logical * line (so far). */ int pixels; /* Total height of logical line (so far). */ bool isComplete; /* The display line metric is complete for this logical line? */ const TkTextDispLineEntry *entry; /* Pointer to entry in display pixel info for displayLineNo. Note * that the predecessing entries can be accessed, but not the successing |
︙ | ︙ | |||
713 714 715 716 717 718 719 | FreeDLineAction action); static void FreeStyle(TkText *textPtr, TextStyle *stylePtr); static TextStyle * GetStyle(TkText *textPtr, TkTextSegment *segPtr); static void UpdateDefaultStyle(TkText *textPtr); static void GetXView(Tcl_Interp *interp, TkText *textPtr, bool report); static void GetYView(Tcl_Interp *interp, TkText *textPtr, bool report); static unsigned GetYPixelCount(TkText *textPtr, DLine *dlPtr); | | > > | | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | FreeDLineAction action); static void FreeStyle(TkText *textPtr, TextStyle *stylePtr); static TextStyle * GetStyle(TkText *textPtr, TkTextSegment *segPtr); static void UpdateDefaultStyle(TkText *textPtr); static void GetXView(Tcl_Interp *interp, TkText *textPtr, bool report); static void GetYView(Tcl_Interp *interp, TkText *textPtr, bool report); static unsigned GetYPixelCount(TkText *textPtr, DLine *dlPtr); static DLine * LayoutDLine(const TkTextIndex *indexPtr, unsigned displayLineNo); static int UpdateOneLine(TkText *textPtr, TkTextLine *linePtr, TkTextIndex *indexPtr, unsigned maxDispLines); static bool MeasureUp(TkText *textPtr, const TkTextIndex *srcPtr, int distance, TkTextIndex *dstPtr, int32_t *overlap); static bool MeasureDown(TkText *textPtr, TkTextIndex *srcPtr, int distance, int32_t *overlap, bool saveDisplayLines); static int NextTabStop(unsigned tabWidth, int x, int tabOrigin); static void UpdateDisplayInfo(TkText *textPtr); static void YScrollByLines(TkText *textPtr, int offset); static void YScrollByPixels(TkText *textPtr, int offset); static void TextInvalidateRegion(TkText *textPtr, TkRegion region); static void TextInvalidateLineMetrics(TkText *textPtr, TkTextLine *linePtr, unsigned lineCount, TkTextInvalidateAction action); static int CalculateDisplayLineHeight(TkText *textPtr, const TkTextIndex *indexPtr, unsigned *byteCountPtr); static TkTextDispChunk * DLineChunkOfX(TkText *textPtr, DLine *dlPtr, int x, TkTextIndex *indexPtr, bool *nearby); static void DLineIndexOfX(TkText *textPtr, TkTextDispChunk *chunkPtr, int x, TkTextIndex *indexPtr); static int DLineXOfIndex(TkText *textPtr, DLine *dlPtr, unsigned byteIndex); static ScrollMethod TextGetScrollInfoObj(Tcl_Interp *interp, TkText *textPtr, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); static void InvokeAsyncUpdateLineMetrics(TkText *textPtr); static void InvokeAsyncUpdateYScrollbar(TkText *textPtr); static void AsyncUpdateYScrollbar(ClientData clientData); static void AsyncUpdateLineMetrics(ClientData clientData); static void UpdateLineMetrics(TkText *textPtr, unsigned doThisMuch); |
︙ | ︙ | |||
815 816 817 818 819 820 821 | TEXT_DISP_ELIDED, /* type */ NULL, /* displayProc */ NULL, /* undisplayProc */ ElideMeasureProc, /* measureProc */ ElideBboxProc, /* bboxProc */ }; | | | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | TEXT_DISP_ELIDED, /* type */ NULL, /* displayProc */ NULL, /* undisplayProc */ ElideMeasureProc, /* measureProc */ ElideBboxProc, /* bboxProc */ }; #ifndef NDEBUG /* * The following counters keep statistics about redisplay that can be checked * to see how clever this code is at reducing redisplays. */ typedef struct Statistic { unsigned numRedisplays; /* Number of calls to DisplayText. */ |
︙ | ︙ | |||
935 936 937 938 939 940 941 942 943 944 945 946 947 948 | */ static const char doNotBreakAtAll[8] = { LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK }; static bool IsPowerOf2(unsigned n) { return !(n & (n - 1)); } static unsigned NextPowerOf2(uint32_t n) { --n; n |= n >> 1; n |= n >> 2; | > > | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 | */ static const char doNotBreakAtAll[8] = { LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK, LINEBREAK_NOBREAK }; static bool IsPowerOf2(unsigned n) { return !(n & (n - 1)); } static bool IsBlank(int ch) { return ch == ' ' || ch == '\t'; } static unsigned NextPowerOf2(uint32_t n) { --n; n |= n >> 1; n |= n >> 2; |
︙ | ︙ | |||
1369 1370 1371 1372 1373 1374 1375 | ranges = indexPtr->textPtr->dInfoPtr->lineMetricUpdateRanges; if (TkRangeListIsEmpty(ranges)) { return true; } | | | 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 | ranges = indexPtr->textPtr->dInfoPtr->lineMetricUpdateRanges; if (TkRangeListIsEmpty(ranges)) { return true; } return (int) TkTextIndexGetLineNumber(indexPtr, indexPtr->textPtr) < TkRangeListLow(ranges); } /* *---------------------------------------------------------------------- * * InvokeAsyncUpdateYScrollbar -- * |
︙ | ︙ | |||
1549 1550 1551 1552 1553 1554 1555 | #if TK_CHECK_ALLOCS if (hookStatFunc) { atexit(AllocStatistic); hookStatFunc = false; } #endif | | | 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 | #if TK_CHECK_ALLOCS if (hookStatFunc) { atexit(AllocStatistic); hookStatFunc = false; } #endif #ifndef NDEBUG if (!stats.perfFuncIsHooked) { atexit(PerfStatistic); stats.perfFuncIsHooked = true; } #endif } /* |
︙ | ︙ | |||
1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 | styleValues.hyphenRules = textPtr->hyphenRulesPtr ? textPtr->hyphenRules : TK_TEXT_HYPHEN_MASK; isSelected = false; for ( ; tagPtr; tagPtr = tagPtr->nextPtr) { Tk_3DBorder border; XColor *fgColor; border = tagPtr->border; fgColor = tagPtr->fgColor; /* * If this is the selection tag, and inactiveSelBorder is NULL (the * default on Windows), then we need to skip it if we don't have the * focus. */ | > > | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 | styleValues.hyphenRules = textPtr->hyphenRulesPtr ? textPtr->hyphenRules : TK_TEXT_HYPHEN_MASK; isSelected = false; for ( ; tagPtr; tagPtr = tagPtr->nextPtr) { Tk_3DBorder border; XColor *fgColor; int priority; border = tagPtr->border; fgColor = tagPtr->fgColor; priority = tagPtr->priority; /* * If this is the selection tag, and inactiveSelBorder is NULL (the * default on Windows), then we need to skip it if we don't have the * focus. */ |
︙ | ︙ | |||
1873 1874 1875 1876 1877 1878 1879 | if (tagPtr->selBorder && isSelected) { border = tagPtr->selBorder; } if (tagPtr->selFgColor != None && isSelected) { fgColor = tagPtr->selFgColor; } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 | if (tagPtr->selBorder && isSelected) { border = tagPtr->selBorder; } if (tagPtr->selFgColor != None && isSelected) { fgColor = tagPtr->selFgColor; } if (border && priority > borderPrio) { styleValues.border = border; borderPrio = priority; } if (tagPtr->borderWidthPtr && Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0' && priority > borderWidthPrio) { styleValues.borderWidth = tagPtr->borderWidth; borderWidthPrio = priority; } if (tagPtr->reliefString && priority > reliefPrio) { if (!styleValues.border) { styleValues.border = textPtr->border; } assert(tagPtr->relief < 8); styleValues.relief = tagPtr->relief; reliefPrio = priority; } if (tagPtr->bgStipple != None && priority > bgStipplePrio) { styleValues.bgStipple = tagPtr->bgStipple; bgStipplePrio = priority; } if (tagPtr->indentBgString != None && priority > indentBgPrio) { assert(tagPtr->indentBg <= 1); styleValues.indentBg = tagPtr->indentBg; indentBgPrio = priority; } if (fgColor != None && priority > fgPrio) { styleValues.fgColor = fgColor; fgPrio = priority; } if (tagPtr->tkfont != None && priority > fontPrio) { styleValues.tkfont = tagPtr->tkfont; fontPrio = priority; } if (tagPtr->fgStipple != None && priority > fgStipplePrio) { styleValues.fgStipple = tagPtr->fgStipple; fgStipplePrio = priority; } if (tagPtr->justifyString && priority > justifyPrio) { /* assert(tagPtr->justify < 8); always true due to range */ styleValues.justify = tagPtr->justify; justifyPrio = priority; } if (tagPtr->lMargin1String && priority > lMargin1Prio) { styleValues.lMargin1 = tagPtr->lMargin1; lMargin1Prio = priority; } if (tagPtr->lMargin2String && priority > lMargin2Prio) { styleValues.lMargin2 = tagPtr->lMargin2; lMargin2Prio = priority; } if (tagPtr->lMarginColor && priority > lMarginColorPrio) { styleValues.lMarginColor = tagPtr->lMarginColor; lMarginColorPrio = priority; } if (tagPtr->offsetString && priority > offsetPrio) { styleValues.offset = tagPtr->offset; offsetPrio = priority; } if (tagPtr->overstrikeString && priority > overstrikePrio) { assert(tagPtr->overstrike <= 1); styleValues.overstrike = tagPtr->overstrike; overstrikePrio = priority; if (tagPtr->overstrikeColor != None) { styleValues.overstrikeColor = tagPtr->overstrikeColor; } else if (fgColor != None) { styleValues.overstrikeColor = fgColor; } } if (tagPtr->rMarginString && priority > rMarginPrio) { styleValues.rMargin = tagPtr->rMargin; rMarginPrio = priority; } if (tagPtr->rMarginColor && priority > rMarginColorPrio) { styleValues.rMarginColor = tagPtr->rMarginColor; rMarginColorPrio = priority; } if (tagPtr->spacing1String && priority > spacing1Prio) { styleValues.spacing1 = tagPtr->spacing1; spacing1Prio = priority; } if (tagPtr->spacing2String && priority > spacing2Prio) { styleValues.spacing2 = tagPtr->spacing2; spacing2Prio = priority; } if (tagPtr->spacing3String && priority > spacing3Prio) { styleValues.spacing3 = tagPtr->spacing3; spacing3Prio = priority; } if (tagPtr->tabStringPtr && priority > tabPrio) { styleValues.tabArrayPtr = tagPtr->tabArrayPtr; tabPrio = priority; } if (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE && priority > tabStylePrio) { assert(tagPtr->tabStyle < 8); styleValues.tabStyle = tagPtr->tabStyle; tabStylePrio = priority; } if (tagPtr->eolColor && priority > eolColorPrio) { styleValues.eolColor = tagPtr->eolColor; eolColorPrio = priority; } if (tagPtr->hyphenColor && priority > hyphenColorPrio) { styleValues.hyphenColor = tagPtr->hyphenColor; hyphenColorPrio = priority; } if (tagPtr->underlineString && priority > underlinePrio) { assert(tagPtr->underline <= 1); styleValues.underline = tagPtr->underline; underlinePrio = priority; if (tagPtr->underlineColor != None) { styleValues.underlineColor = tagPtr->underlineColor; } else if (fgColor != None) { styleValues.underlineColor = fgColor; } } if (tagPtr->elideString && priority > elidePrio) { assert(tagPtr->elide <= 1); styleValues.elide = tagPtr->elide; elidePrio = priority; } if (tagPtr->langPtr && priority > langPrio) { styleValues.lang = tagPtr->lang; langPrio = priority; } if (tagPtr->hyphenRulesPtr && priority > hyphenRulesPrio) { styleValues.hyphenRules = tagPtr->hyphenRules; hyphenRulesPrio = priority; } if (tagPtr->wrapMode != TEXT_WRAPMODE_NULL && priority > wrapPrio) { /* assert(tagPtr->wrapMode < 8); always true due to range */ styleValues.wrapMode = tagPtr->wrapMode; wrapPrio = priority; } } /* * Use an existing style if there's one around that matches. */ |
︙ | ︙ | |||
2349 2350 2351 2352 2353 2354 2355 | unsigned epoch = textPtr->dInfoPtr->lineMetricUpdateEpoch; TkTextPixelInfo *pixelInfo = TkBTreeLinePixelInfo(textPtr, linePtr); unsigned oldNumDispLines = TkBTreeGetNumberOfDisplayLines(pixelInfo); TkTextDispLineInfo *dispLineInfo; TkTextLine *nextLogicalLinePtr; assert(dlPtr->byteCount > 0); | < | 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 | unsigned epoch = textPtr->dInfoPtr->lineMetricUpdateEpoch; TkTextPixelInfo *pixelInfo = TkBTreeLinePixelInfo(textPtr, linePtr); unsigned oldNumDispLines = TkBTreeGetNumberOfDisplayLines(pixelInfo); TkTextDispLineInfo *dispLineInfo; TkTextLine *nextLogicalLinePtr; assert(dlPtr->byteCount > 0); assert(linePtr->logicalLine); assert(linePtr == TkBTreeGetLogicalLine( textPtr->sharedTextPtr, textPtr, TkTextIndexGetLine(&dlPtr->index))); if (pixelInfo->epoch == epoch) { int lineNo = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, NULL); |
︙ | ︙ | |||
2830 2831 2832 2833 2834 2835 2836 | LayoutFinalizeCharInfo( LayoutData *data, bool gotTab) { CharInfo *ciPtr = data->chunkPtr->clientData; assert(data->trimSpaces ? | | | | 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 | LayoutFinalizeCharInfo( LayoutData *data, bool gotTab) { CharInfo *ciPtr = data->chunkPtr->clientData; assert(data->trimSpaces ? (int) data->chunkPtr->numBytes >= ciPtr->numBytes : (int) data->chunkPtr->numBytes == ciPtr->numBytes); /* * Update the character information. Take into account that we don't want * to display the newline character. */ if (ciPtr->u.chars[ciPtr->baseOffset + ciPtr->numBytes - 1] == '\n') { |
︙ | ︙ | |||
3259 3260 3261 3262 3263 3264 3265 | chunkPtr->skipFirstChar = true; } } } } if (data->trimSpaces) { | | | | 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 | chunkPtr->skipFirstChar = true; } } } } if (data->trimSpaces) { unsigned i; for (i = 0; i < maxBytes; ++i) { if (base[i] == ' ' && base[i + 1] == ' ') { while (base[i] == ' ') { ++i; } maxBytes = i; data->skipSpaces = true; break; } } } /* * See if there is a tab in the current chunk; if so, only layout * characters up to (and including) the tab. */ if (data->justify == TK_TEXT_JUSTIFY_LEFT) { const char *p = base; unsigned i; /* TODO: also TK_TEXT_JUSTIFY_RIGHT should support tabs */ /* TODO: direction of tabs should depend on gravity of insert mark?! */ for (i = 0; i < maxBytes; ++i, ++p) { if (*p == '\t') { maxBytes = i + 1; |
︙ | ︙ | |||
3817 3818 3819 3820 3821 3822 3823 | bool fits; data->x = prevChunkPtr->x + prevChunkPtr->width; if (prevChunkPtr == data->firstCharChunkPtr && prevChunkPtr->breakIndex <= 0) { data->maxX = INT_MAX; /* The hyphen must be shown. */ } fits = LayoutChars(data, hyphenSegPtr, hyphenSegPtr->body.hyphen.textSize, 0); | | | 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 | bool fits; data->x = prevChunkPtr->x + prevChunkPtr->width; if (prevChunkPtr == data->firstCharChunkPtr && prevChunkPtr->breakIndex <= 0) { data->maxX = INT_MAX; /* The hyphen must be shown. */ } fits = LayoutChars(data, hyphenSegPtr, hyphenSegPtr->body.hyphen.textSize, 0); assert(!fits || (int) data->chunkPtr->numBytes == hyphenSegPtr->body.hyphen.textSize); hyphenChunkPtr = data->chunkPtr; data->maxX = maxX; if (fits) { /* The hyphen fits, so we're done. */ LayoutFinalizeChunk(data); hyphenChunkPtr->numBytes = 1 + data->increaseNumBytes; |
︙ | ︙ | |||
3861 3862 3863 3864 3865 3866 3867 | * Now check if we must break because the line length have been exceeded. At this point * hyphenation is not involved. */ if (data->breakChunkPtr && (data->lastChunkPtr != data->breakChunkPtr || (data->lastChunkPtr->breakIndex > 0 | | | | | 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 | * Now check if we must break because the line length have been exceeded. At this point * hyphenation is not involved. */ if (data->breakChunkPtr && (data->lastChunkPtr != data->breakChunkPtr || (data->lastChunkPtr->breakIndex > 0 && data->lastChunkPtr->breakIndex != (int) data->lastChunkPtr->numBytes))) { unsigned addNumBytes = 0; LayoutDestroyChunks(data); if (data->breakChunkPtr->breakIndex > 0 && data->breakChunkPtr->numSpaces > 0) { const TkTextDispChunk *breakChunkPtr = data->breakChunkPtr; const CharInfo *ciPtr = breakChunkPtr->clientData; const char *p = ciPtr->u.chars + ciPtr->baseOffset + breakChunkPtr->breakIndex; const char *q = Tcl_UtfPrev(p, ciPtr->u.chars + ciPtr->baseOffset); if (IsExpandableSpace(q) && !(breakChunkPtr->wrappedAtSpace && breakChunkPtr->breakIndex == (int) breakChunkPtr->numBytes)) { addNumBytes = p - q; data->breakChunkPtr->breakIndex -= addNumBytes; data->breakChunkPtr->numSpaces -= 1; data->numSpaces -= 1; } } if (data->breakChunkPtr->breakIndex != (int) data->breakChunkPtr->numBytes) { TkTextSegment *segPtr; TkTextDispChunk *chunkPtr = data->breakChunkPtr; TkTextIndex index = *indexPtr; LayoutUndisplay(data, chunkPtr); data->chunkPtr = chunkPtr; TkTextIndexForwBytes(data->textPtr, &index, chunkPtr->byteOffset, &index); |
︙ | ︙ | |||
4016 4017 4018 4019 4020 4021 4022 | return segPtr->typePtr == &tkTextCharType && segPtr->body.chars[offset] == ' '; } static DLine * LayoutDLine( const TkTextIndex *indexPtr,/* Beginning of display line. May not necessarily point to * a character segment. */ | | | 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 | return segPtr->typePtr == &tkTextCharType && segPtr->body.chars[offset] == ' '; } static DLine * LayoutDLine( const TkTextIndex *indexPtr,/* Beginning of display line. May not necessarily point to * a character segment. */ unsigned displayLineNo) /* Display line number of logical line, needed for caching. */ { TextDInfo *dInfoPtr; DLine *dlPtr; TkText *textPtr; StyleValues *sValPtr; TkTextDispChunk *chunkPtr; TkTextDispChunkSection *sectionPtr; |
︙ | ︙ | |||
4786 4787 4788 4789 4790 4791 4792 | ComputeMissingMetric( TkText *textPtr, DisplayInfo *info, Threshold thresholdType, int threshold) { int byteOffset, additionalLines; | | | 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 | ComputeMissingMetric( TkText *textPtr, DisplayInfo *info, Threshold thresholdType, int threshold) { int byteOffset, additionalLines; unsigned displayLineNo; int *metricPtr = NULL; /* avoids compiler warning */ unsigned viewHeight; TkTextIndex index; assert(threshold >= 0); if (info->isComplete) { |
︙ | ︙ | |||
4890 4891 4892 4893 4894 4895 4896 | DLine *savedDLine; /* usable saved display lines */ DLine *prevSavedDLine; /* last old unfreed display line */ TkTextIndex index; TkTextLine *lastLinePtr; TkTextLine *linePtr; DisplayInfo info; int y, maxY, xPixelOffset, maxOffset; | | | 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 | DLine *savedDLine; /* usable saved display lines */ DLine *prevSavedDLine; /* last old unfreed display line */ TkTextIndex index; TkTextLine *lastLinePtr; TkTextLine *linePtr; DisplayInfo info; int y, maxY, xPixelOffset, maxOffset; unsigned displayLineNo; unsigned epoch; if (!(dInfoPtr->flags & DINFO_OUT_OF_DATE)) { return; } dInfoPtr->flags &= ~DINFO_OUT_OF_DATE; |
︙ | ︙ | |||
5250 5251 5252 5253 5254 5255 5256 5257 5258 | } else { bottomLine = dlPtr; } topLine = dlPtr; DEBUG(dlPtr->flags |= LINKED); TK_TEXT_DEBUG(LogTextRelayout(textPtr, &dlPtr->index)); spaceLeft -= dlPtr->height; info.displayLineNo -= 1; info.entry -= 1; | > > > | | 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 | } else { bottomLine = dlPtr; } topLine = dlPtr; DEBUG(dlPtr->flags |= LINKED); TK_TEXT_DEBUG(LogTextRelayout(textPtr, &dlPtr->index)); spaceLeft -= dlPtr->height; if (info.displayLineNo == 0) { break; } info.displayLineNo -= 1; info.entry -= 1; } while (spaceLeft > 0); dInfoPtr->dLinePtr = topLine; /* Delete remaining cached lines. */ FreeDLines(textPtr, info.dLinePtr, NULL, DLINE_FREE_TEMP); } } |
︙ | ︙ | |||
5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 | dInfoPtr->lastDLinePtr = firstPtr->prevPtr; } dInfoPtr->dLinesInvalidated = true; assert(!dInfoPtr->dLinePtr || !dInfoPtr->dLinePtr->prevPtr); ReleaseLines(textPtr, firstPtr, lastPtr, action); break; case DLINE_SAVE: { if (!firstPtr || firstPtr == lastPtr) { return NULL; } assert(firstPtr == dInfoPtr->dLinePtr); assert(lastPtr); | > > > | < | 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 | dInfoPtr->lastDLinePtr = firstPtr->prevPtr; } dInfoPtr->dLinesInvalidated = true; assert(!dInfoPtr->dLinePtr || !dInfoPtr->dLinePtr->prevPtr); ReleaseLines(textPtr, firstPtr, lastPtr, action); break; case DLINE_SAVE: { unsigned epoch; DLine *dlPtr; if (!firstPtr || firstPtr == lastPtr) { return NULL; } assert(firstPtr == dInfoPtr->dLinePtr); assert(lastPtr); epoch = dInfoPtr->lineMetricUpdateEpoch; assert(lastPtr->prevPtr); dInfoPtr->dLinePtr = lastPtr; /* * Free all expired lines, we will only save valid lines. */ |
︙ | ︙ | |||
6588 6589 6590 6591 6592 6593 6594 | * we actually re-layout. But in case of synchronous update we do a full * computation. */ if (textPtr->syncTime > 0) { maxDispLines = (doThisMuch - count + 7)/8; } | | | 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 | * we actually re-layout. But in case of synchronous update we do a full * computation. */ if (textPtr->syncTime > 0) { maxDispLines = (doThisMuch - count + 7)/8; } count += 8*UpdateOneLine(textPtr, linePtr, &index, maxDispLines); if (pixelInfo->epoch & PARTIAL_COMPUTED_BIT) { /* * We didn't complete the logical line, because it produced very many * display lines - it must be a long line wrapped many times. */ return; |
︙ | ︙ | |||
6647 6648 6649 6650 6651 6652 6653 | unsigned lineNum, /* Start at this line. */ unsigned endLine) /* Go no further than this line. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; const TkRange *range; assert(lineNum <= endLine); | | | | > | 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 | unsigned lineNum, /* Start at this line. */ unsigned endLine) /* Go no further than this line. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; const TkRange *range; assert(lineNum <= endLine); assert((int) endLine <= TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)); assert(textPtr->sharedTextPtr->allowUpdateLineMetrics); dInfoPtr->insideLineMetricUpdate = true; if ((range = TkRangeListFindNearest(dInfoPtr->lineMetricUpdateRanges, lineNum))) { TkTextLine *linePtr = NULL; unsigned count = 0; unsigned high = range->high; lineNum = range->low; endLine = MIN((int) endLine, TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr) - 1); while (true) { const TkTextPixelInfo *pixelInfo; int firstLineNum; if (lineNum > high) { /* * Note that the update process has removed the finished lines. */ if (!(range = TkRangeListFindNearest(dInfoPtr->lineMetricUpdateRanges, lineNum))) { |
︙ | ︙ | |||
6699 6700 6701 6702 6703 6704 6705 | /* * This line is not (fully) up-to-date. */ TkTextIndexClear(&index, textPtr); TkTextIndexSetToStartOfLine2(&index, linePtr); | | | < | | > | | | | | | | > | 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 | /* * This line is not (fully) up-to-date. */ TkTextIndexClear(&index, textPtr); TkTextIndexSetToStartOfLine2(&index, linePtr); UpdateOneLine(textPtr, linePtr, &index, UINT_MAX); assert(IsStartOfNotMergedLine(&index) || TkTextIndexIsEndOfText(&index)); firstLineNum = -1; /* the update has removed the line numbers from range list */ } else { firstLineNum = lineNum; } if (linePtr->nextPtr->logicalLine) { linePtr = linePtr->nextPtr; lineNum += 1; } else { linePtr = TkBTreeNextLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr); lineNum = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, NULL); } if (firstLineNum >= 0) { TkRangeListRemove(dInfoPtr->lineMetricUpdateRanges, firstLineNum, lineNum - 1); } } } dInfoPtr->insideLineMetricUpdate = false; CheckIfLineMetricIsUpToDate(textPtr); |
︙ | ︙ | |||
6814 6815 6816 6817 6818 6819 6820 | lineNum = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, &deviation); assert(lineNum < totalLines); assert(deviation >= 0); if (deviation) { | | | 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 | lineNum = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, &deviation); assert(lineNum < totalLines); assert(deviation >= 0); if (deviation) { lineCount -= MIN((int) lineCount, deviation); } if (action != TK_TEXT_INVALIDATE_ONLY && !isMonospaced && linePtr == TkBTreeGetStartLine(textPtr) && lineCount + 1 >= totalLines) { linePtr = NULL; |
︙ | ︙ | |||
6974 6975 6976 6977 6978 6979 6980 | ranges = TkRangeListAdd(ranges, lineNum, lineNum); ResetPixelInfo(TkBTreeLinePixelInfo(textPtr, TkBTreeGetLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr))); } break; } | | | 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 | ranges = TkRangeListAdd(ranges, lineNum, lineNum); ResetPixelInfo(TkBTreeLinePixelInfo(textPtr, TkBTreeGetLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr))); } break; } assert(TkRangeListIsEmpty(ranges) || TkRangeListHigh(ranges) < (int) totalLines); } else { /* * This invalidates the height of all lines in the widget. */ textPtr->dInfoPtr->lineMetricUpdateEpoch += 1; if (action == TK_TEXT_INVALIDATE_DELETE) { |
︙ | ︙ | |||
7202 7203 7204 7205 7206 7207 7208 | if (displayLineOffset > 0) { ComputeMissingMetric(textPtr, &info, THRESHOLD_LINE_OFFSET, displayLineOffset); info.numDispLines -= info.displayLineNo; while (true) { const TkTextDispLineEntry *last; | | | 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 | if (displayLineOffset > 0) { ComputeMissingMetric(textPtr, &info, THRESHOLD_LINE_OFFSET, displayLineOffset); info.numDispLines -= info.displayLineNo; while (true) { const TkTextDispLineEntry *last; if ((int) info.numDispLines >= displayLineOffset) { last = info.entry + displayLineOffset; byteOffset = last->byteOffset; break; } last = info.entry + info.numDispLines; byteOffset = last->byteOffset; displayLineOffset -= info.numDispLines; |
︙ | ︙ | |||
7226 7227 7228 7229 7230 7231 7232 | } } else if (displayLineOffset < 0) { info.numDispLines = info.displayLineNo + 1; while (true) { TkTextLine *prevLine; | | | | 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 | } } else if (displayLineOffset < 0) { info.numDispLines = info.displayLineNo + 1; while (true) { TkTextLine *prevLine; if (-displayLineOffset < (int) info.numDispLines) { int skipBack; byteOffset = (info.entry + displayLineOffset)->byteOffset; skipBack = displayLineOffset; /* * We want to cache this display line, because it's likely that this * line will be used afterwards. Take into account that probably the * last cached line has been removed. */ if ((skipBack -= removedLines) >= 0 && (int) info.numCachedLines > skipBack) { DLine *dlPtr = info.lastDLinePtr; while (dlPtr && skipBack--) { dlPtr = dlPtr->prevPtr; } if (dlPtr == info.dLinePtr) { info.dLinePtr = dlPtr->nextPtr; } |
︙ | ︙ | |||
7481 7482 7483 7484 7485 7486 7487 | * * The behaviour of this function is _undefined_ if indexPtr is not * currently at the beginning of a display line. * * Results: * The number of vertical pixels used by the display line. * | | < < < | < < < < | | | 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 | * * The behaviour of this function is _undefined_ if indexPtr is not * currently at the beginning of a display line. * * Results: * The number of vertical pixels used by the display line. * * If 'byteCountRef' is non-NULL, then returns in that pointer the number * of byte indices on the given display line (which can be used to update * indexPtr in a loop). * * Side effects: * The same as LayoutDLine and FreeDLines. * *---------------------------------------------------------------------- */ #ifndef NDEBUG static bool IsAtStartOfDisplayLine( const TkTextIndex *indexPtr) { TkTextIndex index2 = *indexPtr; assert(indexPtr->textPtr); FindDisplayLineStartEnd(indexPtr->textPtr, &index2, DISP_LINE_START, DLINE_METRIC); return TkTextIndexCompare(&index2, indexPtr) == 0; } #endif /* NDEBUG */ static int CalculateDisplayLineHeight( TkText *textPtr, /* Widget record for text widget. */ const TkTextIndex *indexPtr,/* The index at the beginning of the display line of interest. */ unsigned *byteCountRef) /* NULL or used to return the number of byte indices on the given * display line. */ |
︙ | ︙ | |||
7703 7704 7705 7706 7707 7708 7709 | return TkBTreePixelsTo(textPtr, TkTextIndexGetLine(indexPtr)) + GetPixelsTo(textPtr, indexPtr, false, NULL); } /* *---------------------------------------------------------------------- * | | | 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 | return TkBTreePixelsTo(textPtr, TkTextIndexGetLine(indexPtr)) + GetPixelsTo(textPtr, indexPtr, false, NULL); } /* *---------------------------------------------------------------------- * * UpdateOneLine -- * * This function is invoked to recalculate the height of a particular * logical line, whether that line is displayed or not. * * It must NEVER be called for the artificial last TkTextLine which is * used internally for administrative purposes only. That line must * retain its initial height of 0 otherwise the pixel height calculation |
︙ | ︙ | |||
7725 7726 7727 7728 7729 7730 7731 | * Line heights may be recalculated, and a timer to update the scrollbar * may be installed. Also see the called function CalculateDisplayLineHeight * for its side effects. * *---------------------------------------------------------------------- */ | | | | 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 | * Line heights may be recalculated, and a timer to update the scrollbar * may be installed. Also see the called function CalculateDisplayLineHeight * for its side effects. * *---------------------------------------------------------------------- */ static int UpdateOneLine( TkText *textPtr, /* Widget record for text widget. */ TkTextLine *linePtr, /* The line of which to calculate the height. */ TkTextIndex *indexPtr, /* Either NULL or an index at the start of a display line belonging * to linePtr, at which we wish to start (e.g. up to which we have * already calculated). On return this will be set to the first index * on the next line. */ unsigned maxDispLines) /* Don't compute more than this number of display lines. */ |
︙ | ︙ | |||
7774 7775 7776 7777 7778 7779 7780 | TkTextIndexForwBytes(textPtr, indexPtr, bytes, indexPtr); linePtr = TkTextIndexGetLine(indexPtr); assert(!linePtr->logicalLine || !TkTextIndexIsStartOfLine(indexPtr)); } else if (!linePtr->logicalLine || !TkTextIndexIsStartOfLine(indexPtr)) { /* * CalculateDisplayLineHeight must be called with an index at the beginning * of a display line. Force this to happen. This is needed when | | | 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 | TkTextIndexForwBytes(textPtr, indexPtr, bytes, indexPtr); linePtr = TkTextIndexGetLine(indexPtr); assert(!linePtr->logicalLine || !TkTextIndexIsStartOfLine(indexPtr)); } else if (!linePtr->logicalLine || !TkTextIndexIsStartOfLine(indexPtr)) { /* * CalculateDisplayLineHeight must be called with an index at the beginning * of a display line. Force this to happen. This is needed when * UpdateOneLine is called with a line that is merged with its * previous line: the number of merged logical lines in a display line is * calculated correctly only when CalculateDisplayLineHeight receives * an index at the beginning of a display line. In turn this causes the * merged lines to receive their correct zero pixel height in * TkBTreeAdjustPixelHeight. */ |
︙ | ︙ | |||
8931 8932 8933 8934 8935 8936 8937 | { TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TextDInfo *dInfoPtr = textPtr->dInfoPtr; XGCValues gcValues; GC newGC; bool recomputeGeometry; bool asyncLineCalculation; | | | | 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 | { TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TextDInfo *dInfoPtr = textPtr->dInfoPtr; XGCValues gcValues; GC newGC; bool recomputeGeometry; bool asyncLineCalculation; unsigned firstLineNo; unsigned lastLineNo; int maxX; if ((mask & TK_TEXT_LINE_REDRAW_BOTTOM_LINE) && dInfoPtr->lastDLinePtr) { dInfoPtr->lastDLinePtr->flags |= OLD_Y_INVALID; } /* |
︙ | ︙ | |||
9715 9716 9717 9718 9719 9720 9721 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already parsed this command * enough to know that objv[1] is "see". */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; | | > | 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already parsed this command * enough to know that objv[1] is "see". */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; int x, y, width, height, oneThird, delta; unsigned lineWidth, byteCount; DLine *dlPtr; TkTextDispChunk *chunkPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); return TCL_ERROR; } |
︙ | ︙ | |||
9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 | /* * Now make sure that the character is in view horizontally. */ if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { UpdateDisplayInfo(textPtr); } lineWidth = dInfoPtr->maxX - dInfoPtr->x; if (dInfoPtr->maxLength < lineWidth) { return TCL_OK; } /* * Take into account that the desired index is past the visible text. * It's also possible that the widget is not yet mapped. | > > > | 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 | /* * Now make sure that the character is in view horizontally. */ if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { UpdateDisplayInfo(textPtr); } assert(dInfoPtr->maxX >= dInfoPtr->x); lineWidth = dInfoPtr->maxX - dInfoPtr->x; if (dInfoPtr->maxLength < lineWidth) { return TCL_OK; } /* * Take into account that the desired index is past the visible text. * It's also possible that the widget is not yet mapped. |
︙ | ︙ | |||
11489 11490 11491 11492 11493 11494 11495 | *---------------------------------------------------------------------- */ static int DLineXOfIndex( TkText *textPtr, /* Widget record for text widget. */ DLine *dlPtr, /* Display information for this display line. */ | | | 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 | *---------------------------------------------------------------------- */ static int DLineXOfIndex( TkText *textPtr, /* Widget record for text widget. */ DLine *dlPtr, /* Display information for this display line. */ unsigned byteIndex) /* The byte index for which we want the coordinate. */ { TkTextDispChunkSection *sectionPtr, *nextPtr; TkTextDispChunk *chunkPtr; int x; if (byteIndex == 0 || !(sectionPtr = dlPtr->chunkPtr->sectionPtr)) { return 0; |
︙ | ︙ | |||
11571 11572 11573 11574 11575 11576 11577 | * takes up a very large width, this is used to return the smaller * width actually desired by the index. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; DLine *dlPtr; TkTextDispChunk *chunkPtr; TkTextDispChunkSection *sectionPtr; | | | 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 | * takes up a very large width, this is used to return the smaller * width actually desired by the index. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; DLine *dlPtr; TkTextDispChunk *chunkPtr; TkTextDispChunkSection *sectionPtr; unsigned byteCount; /* * Make sure that all of the screen layout information is up to date. */ if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { UpdateDisplayInfo(textPtr); |
︙ | ︙ | |||
12134 12135 12136 12137 12138 12139 12140 | static void ComputeSizeOfTab( LayoutData *data) { TkText *textPtr; TkTextTabArray *tabArrayPtr; | | > | 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 | static void ComputeSizeOfTab( LayoutData *data) { TkText *textPtr; TkTextTabArray *tabArrayPtr; unsigned tabWidth; int tabX; TkTextTabAlign alignment; textPtr = data->textPtr; tabArrayPtr = data->tabArrayPtr; if (!tabArrayPtr || tabArrayPtr->numTabs == 0) { /* |
︙ | ︙ | |||
12609 12610 12611 12612 12613 12614 12615 | const char *p; int count; if (segPtr->typePtr == &tkTextHyphenType) { return 1; } | | | 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 | const char *p; int count; if (segPtr->typePtr == &tkTextHyphenType) { return 1; } if ((int) chunkPtr->numBytes + byteOffset == segPtr->size) { for (nextPtr = segPtr->nextPtr; nextPtr; nextPtr = nextPtr->nextPtr) { if (nextPtr->size > 0) { if (!(nextPtr->typePtr->group & (SEG_GROUP_CHAR|SEG_GROUP_HYPHEN))) { return chunkPtr->numBytes; } break; } else if (nextPtr->typePtr == &tkTextBranchType) { |
︙ | ︙ | |||
13144 13145 13146 13147 13148 13149 13150 | * At least one character should be contained in current display line. */ bytesThatFit = CharChunkMeasureChars(chunkPtr, ciPtr->u.chars, ciPtr->baseOffset + chLen, ciPtr->baseOffset, -1, chunkPtr->x, -1, 0, &nextX); } if (spaceMode == TEXT_SPACEMODE_TRIM) { | | | | 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 | * At least one character should be contained in current display line. */ bytesThatFit = CharChunkMeasureChars(chunkPtr, ciPtr->u.chars, ciPtr->baseOffset + chLen, ciPtr->baseOffset, -1, chunkPtr->x, -1, 0, &nextX); } if (spaceMode == TEXT_SPACEMODE_TRIM) { while (IsBlank(p[bytesThatFit])) { bytesThatFit += 1; } } if (p[bytesThatFit] == '\n') { /* * A newline character takes up no space, so if the previous * character fits then so does the newline. */ bytesThatFit += 1; } else if (spaceMode == TEXT_SPACEMODE_NONE && nextX <= maxX && ((1 << wrapMode) & ((1 << TEXT_WRAPMODE_WORD) | (1 << TEXT_WRAPMODE_CODEPOINT))) && IsBlank(p[bytesThatFit]) && !(bytesThatFit == 0 && chunkPtr->prevCharChunkPtr && chunkPtr->prevCharChunkPtr->wrappedAtSpace)) { /* * Space characters are funny, in that they are considered to fit at the end * of the line. Just give the space character whatever space is left. */ |
︙ | ︙ |
Changes to generic/tkTextImage.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tkPort.h" #include "tkText.h" #include "tkTextTagSet.h" #include "tkTextUndo.h" #include <assert.h> | < < < < < < < | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include "tkPort.h" #include "tkText.h" #include "tkTextTagSet.h" #include "tkTextUndo.h" #include <assert.h> #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Support of tk8.5. |
︙ | ︙ | |||
353 354 355 356 357 358 359 | */ static bool Displayed( const TkTextEmbImage *img, const TkText *peer) { | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | */ static bool Displayed( const TkTextEmbImage *img, const TkText *peer) { return peer->pixelReference < (int) img->numClients && !TkQTreeRectIsEmpty(&img->bbox[peer->pixelReference]); } int TkTextImageCmd( TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ |
︙ | ︙ | |||
631 632 633 634 635 636 637 | for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->imageTable, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { TkTextSegment *eiPtr = Tcl_GetHashValue(hPtr); TkTextEmbImage *img = &eiPtr->body.ei; | | | 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->imageTable, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { TkTextSegment *eiPtr = Tcl_GetHashValue(hPtr); TkTextEmbImage *img = &eiPtr->body.ei; if ((int) img->numClients > textPtr->pixelReference) { memset(&img->bbox[textPtr->pixelReference], 0, sizeof(img->bbox[0])); } } } /* *-------------------------------------------------------------- |
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | */ TkQTreeRectSet(&bbox, dx, dy, Tk_Width(textPtr->tkwin) + dx, Tk_Height(textPtr->tkwin) + dy); TkQTreeConfigure(&textPtr->imageBboxTree, &bbox); textPtr->configureBboxTree = false; } | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | */ TkQTreeRectSet(&bbox, dx, dy, Tk_Width(textPtr->tkwin) + dx, Tk_Height(textPtr->tkwin) + dy); TkQTreeConfigure(&textPtr->imageBboxTree, &bbox); textPtr->configureBboxTree = false; } if ((int) img->numClients <= textPtr->pixelReference) { unsigned numClients = textPtr->pixelReference + 1; assert((img->numClients == 0) == !img->bbox); img->bbox = realloc(img->bbox, numClients * sizeof(img->bbox[0])); memset(img->bbox + img->numClients, 0, (numClients - img->numClients) * sizeof(img->bbox[0])); img->numClients = numClients; } |
︙ | ︙ |
Changes to generic/tkTextIndex.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif #ifndef MIN # define MIN(a,b) (((int) a) < ((int) b) ? a : b) #endif | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif #ifndef MIN # define MIN(a,b) (((int) a) < ((int) b) ? a : b) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Modifiers for index parsing: 'display', 'any' or nothing. |
︙ | ︙ | |||
142 143 144 145 146 147 148 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef NDEBUG static bool CheckLine( const TkTextIndex *indexPtr, const TkTextLine *linePtr) { assert(linePtr); if (indexPtr->stateEpoch == TkBTreeEpoch(indexPtr->tree)) { if (indexPtr->priv.segPtr && indexPtr->priv.segPtr->sectionPtr->linePtr != indexPtr->priv.linePtr) { return false; } if (indexPtr->priv.lineNo != -1 && indexPtr->priv.lineNo != (int) TkBTreeLinesTo(indexPtr->tree, NULL, indexPtr->priv.linePtr, NULL)) { return false; } if (indexPtr->priv.lineNoRel != -1 && indexPtr->priv.lineNoRel != (int) TkBTreeLinesTo(indexPtr->tree, indexPtr->textPtr, indexPtr->priv.linePtr, NULL)) { return false; } } if (!indexPtr->discardConsistencyCheck && indexPtr->textPtr) { const TkTextLine *startLine = TkBTreeGetStartLine(indexPtr->textPtr); const TkTextLine *endLine = TkBTreeGetLastLine(indexPtr->textPtr); int lineNo = TkBTreeLinesTo(indexPtr->tree, NULL, linePtr, NULL); if (lineNo < (int) TkBTreeLinesTo(indexPtr->tree, NULL, startLine, NULL)) { return false; } if (lineNo > (int) TkBTreeLinesTo(indexPtr->tree, NULL, endLine, NULL)) { return false; } } return true; } #endif /* NDEBUG */ static int FindStartByteIndex( const TkTextIndex *indexPtr) { const TkText *textPtr = indexPtr->textPtr; const TkTextSegment *segPtr; |
︙ | ︙ | |||
275 276 277 278 279 280 281 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef NDEBUG static bool CheckByteIndex( const TkTextIndex *indexPtr, const TkTextLine *linePtr, int byteIndex) { const TkText *textPtr = indexPtr->textPtr; |
︙ | ︙ | |||
306 307 308 309 310 311 312 | if (linePtr == textPtr->endMarker->sectionPtr->linePtr->nextPtr) { return byteIndex == 0; } } return byteIndex < linePtr->size; } | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | if (linePtr == textPtr->endMarker->sectionPtr->linePtr->nextPtr) { return byteIndex == 0; } } return byteIndex < linePtr->size; } #endif /* NDEBUG */ void TkTextIndexSetPosition( TkTextIndex *indexPtr, /* Pointer to index. */ int byteIndex, /* New byte index. */ TkTextSegment *segPtr) /* The segment which belongs to the byte index. */ { |
︙ | ︙ | |||
330 331 332 333 334 335 336 | indexPtr->priv.linePtr = segPtr->sectionPtr->linePtr; indexPtr->priv.byteIndex = byteIndex; indexPtr->priv.lineNo = -1; indexPtr->priv.lineNoRel = -1; indexPtr->priv.segPtr = segPtr; indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType; | | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | indexPtr->priv.linePtr = segPtr->sectionPtr->linePtr; indexPtr->priv.byteIndex = byteIndex; indexPtr->priv.lineNo = -1; indexPtr->priv.lineNoRel = -1; indexPtr->priv.segPtr = segPtr; indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType; #ifndef NDEBUG { int pos = SegToIndex(indexPtr->priv.linePtr, segPtr); if (segPtr->typePtr == &tkTextCharType) { assert(byteIndex - pos < segPtr->size); } else { assert(pos == byteIndex); } } #endif /* NDEBUG */ } /* *---------------------------------------------------------------------- * * TkTextIndexSetByteIndex -- * |
︙ | ︙ | |||
908 909 910 911 912 913 914 | assert(!iPtr->priv.isCharSegment || indexPtr->stateEpoch == epoch); iPtr->priv.byteIndex = SegToIndex(iPtr->priv.linePtr, iPtr->priv.segPtr); assert(CheckByteIndex(iPtr, iPtr->priv.linePtr, iPtr->priv.byteIndex)); } TkTextIndexSetEpoch(iPtr, epoch); *lineNo = TkBTreeLinesTo(iPtr->tree, textPtr, iPtr->priv.linePtr, NULL); } else { | | | 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | assert(!iPtr->priv.isCharSegment || indexPtr->stateEpoch == epoch); iPtr->priv.byteIndex = SegToIndex(iPtr->priv.linePtr, iPtr->priv.segPtr); assert(CheckByteIndex(iPtr, iPtr->priv.linePtr, iPtr->priv.byteIndex)); } TkTextIndexSetEpoch(iPtr, epoch); *lineNo = TkBTreeLinesTo(iPtr->tree, textPtr, iPtr->priv.linePtr, NULL); } else { assert(*lineNo == (int) TkBTreeLinesTo(indexPtr->tree, textPtr, indexPtr->priv.linePtr, NULL)); } return *lineNo; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1635 1636 1637 1638 1639 1640 1641 | * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ | | | | 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ #ifndef NDEBUG void TkpTextIndexDump( TkText *textPtr, /* May be NULL. */ const TkTextIndex *indexPtr)/* Pointer to index. */ { char buf[TK_POS_CHARS]; TkTextIndexPrint(TkTextIndexGetShared(indexPtr), textPtr, indexPtr, buf); printf("%s\n", buf); } #endif /* NDEBUG */ /* *--------------------------------------------------------------------------- * * TkTextNewIndexObj -- * * This function generates a Tcl_Obj description of an index, suitable |
︙ | ︙ | |||
2962 2963 2964 2965 2966 2967 2968 | } else if (!linePtr->nextPtr) { return 1; } if ((byteIndex = dstPtr->priv.byteIndex + byteCount) > linePtr->size) { DEBUG(TkTextIndex index = *srcPtr); bool rc = TkBTreeMoveForward(dstPtr, byteCount); | | | 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 | } else if (!linePtr->nextPtr) { return 1; } if ((byteIndex = dstPtr->priv.byteIndex + byteCount) > linePtr->size) { DEBUG(TkTextIndex index = *srcPtr); bool rc = TkBTreeMoveForward(dstPtr, byteCount); assert(!rc || (int) TkTextIndexCountBytes(&index, dstPtr) == byteCount); return rc ? 0 : 1; } if (byteIndex == linePtr->size) { assert(linePtr->nextPtr); TkTextIndexSetByteIndex2(dstPtr, linePtr->nextPtr, 0); } else { |
︙ | ︙ | |||
3470 3471 3472 3473 3474 3475 3476 | TkTextIndexSetByteIndex(dstPtr, byteIndex); return 0; } if (byteCount > byteIndex + 1) { DEBUG(TkTextIndex index = *srcPtr); bool rc = TkBTreeMoveBackward(dstPtr, byteCount); | | | 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 | TkTextIndexSetByteIndex(dstPtr, byteIndex); return 0; } if (byteCount > byteIndex + 1) { DEBUG(TkTextIndex index = *srcPtr); bool rc = TkBTreeMoveBackward(dstPtr, byteCount); assert(!rc || (int) TkTextIndexCountBytes(dstPtr, &index) == byteCount); return rc ? 0 : 1; } if ((byteIndex -= byteCount) >= 0) { TkTextIndexSetByteIndex(dstPtr, byteIndex); return 0; } |
︙ | ︙ |
Changes to generic/tkTextLineBreak.c.
︙ | ︙ | |||
244 245 246 247 248 249 250 | } else if (text[i] == '/' && i > 8) { /* * Ignore the breaking chance if there is a chance immediately before: * no break inside "c/o", and no break after "http://" in a long line * (a suggestion from Wu Yongwei). */ | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } else if (text[i] == '/' && i > 8) { /* * Ignore the breaking chance if there is a chance immediately before: * no break inside "c/o", and no break after "http://" in a long line * (a suggestion from Wu Yongwei). */ if (lastBreakablePos >= (int) i - 2 || (i > 40u && lastBreakablePos >= (int) i - 7 && text[i - 1] == '/')) { continue; } /* * Special rule to treat Unix paths more nicely (a suggestion from Wu Yongwei). */ |
︙ | ︙ | |||
887 888 889 890 891 892 893 | /* * This fallback is required, because ths current character conversion * algorithm in Tcl library is producing overlong sequences (a violation * of the UTF-8 standard). This observation has been reported to the * Tcl/Tk team, but the response was ignorance. */ | | | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | /* * This fallback is required, because ths current character conversion * algorithm in Tcl library is producing overlong sequences (a violation * of the UTF-8 standard). This observation has been reported to the * Tcl/Tk team, but the response was ignorance. */ unsigned k; const char *p = (const char *) text + i; pcls = AI; nbytes = Tcl_UtfNext(p) - p; for (k = 0; k < nbytes; ++k) { brks[i + k] = LINEBREAK_INSIDEACHAR; } |
︙ | ︙ |
Changes to generic/tkTextMark.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkInt.h" #include "tkText.h" #include "tk3d.h" | > > > | > > > > | > > > > | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkInt.h" #include "tkText.h" #include "tk3d.h" #include <assert.h> #if HAVE_INTTYPES_H # include <inttypes.h> #elif !defined(PRIx32) # define PRIx64 "llx" # define PRIx32 "lx" #endif #ifdef MSC_VER /* earlier versions of MSCV don't knows snprintf, but _snprintf is compatible. */ # define snprintf _snprintf #endif #ifndef MAX # define MAX(a,b) ((a) < (b) ? b : a) #endif #ifndef MIN # define MIN(a,b) ((a) < (b) ? a : b) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Forward references for functions defined in this file: |
︙ | ︙ | |||
222 223 224 225 226 227 228 | #define GET_POINTER(ptr) ((void *) (((__ptr_to_int *) &ptr)->flag & ~(uintptr_t) 1)) #define GET_NAME(seg) ((char *) GET_POINTER(seg->body.mark.ptr)) #define GET_HPTR(seg) ((Tcl_HashEntry *) seg->body.mark.ptr) #define PTR_TO_INT(ptr) ((uintptr_t) ptr) | | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | #define GET_POINTER(ptr) ((void *) (((__ptr_to_int *) &ptr)->flag & ~(uintptr_t) 1)) #define GET_NAME(seg) ((char *) GET_POINTER(seg->body.mark.ptr)) #define GET_HPTR(seg) ((Tcl_HashEntry *) seg->body.mark.ptr) #define PTR_TO_INT(ptr) ((uintptr_t) ptr) #ifndef NDEBUG # undef GET_HPTR # undef GET_NAME static Tcl_HashEntry *GET_HPTR(const TkTextSegment *markPtr) { assert(!IS_PRESERVED(markPtr)); return (Tcl_HashEntry *) markPtr->body.mark.ptr; } static char *GET_NAME(const TkTextSegment *markPtr) { assert(IS_PRESERVED(markPtr)); return (char *) GET_POINTER(markPtr->body.mark.ptr); } #endif /* NDEBUG */ DEBUG_ALLOC(extern unsigned tkTextCountNewSegment); DEBUG_ALLOC(extern unsigned tkTextCountDestroySegment); DEBUG_ALLOC(extern unsigned tkTextCountNewUndoToken); DEBUG_ALLOC(extern unsigned tkTextCountDestroyUndoToken); /* |
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 | hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, name, &dummy); markPtr = Tcl_GetHashValue(hPtr); } if (!markPtr) { if (name[0] == '#' && name[1] == '#' && name[2] == 'I') { #ifdef TCL_WIDE_INT_IS_LONG | | | | 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 | hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, name, &dummy); markPtr = Tcl_GetHashValue(hPtr); } if (!markPtr) { if (name[0] == '#' && name[1] == '#' && name[2] == 'I') { #ifdef TCL_WIDE_INT_IS_LONG static const size_t length = 32 + 2*sizeof(uint64_t); #else /* ifndef TCL_WIDE_INT_IS_LONG */ static const size_t length = 32 + 2*sizeof(uint32_t); #endif /* TCL_WIDE_INT_IS_LONG */ void *sPtr, *tPtr; unsigned num; if (strlen(name) == length && sscanf(name, "##ID##%p##%p##%u##", &sPtr, &tPtr, &num) == 3) { assert(hPtr); |
︙ | ︙ |
Changes to generic/tkTextPriv.h.
︙ | ︙ | |||
43 44 45 46 47 48 49 | }; #endif /* _TKTEXTPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> | < < < < < < | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | }; #endif /* _TKTEXTPRIV */ #ifdef _TK_NEED_IMPLEMENTATION #include <assert.h> /* *---------------------------------------------------------------------- * * TkTextIsSpecialMark -- * * Test whether this is a special mark: "insert", or "current". |
︙ | ︙ |
Changes to generic/tkTextTag.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | #include <assert.h> #include <stdlib.h> #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <assert.h> #include <stdlib.h> #ifndef MAX # define MAX(a,b) (((int) a) < ((int) b) ? b : a) #endif #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Support of tk8.5. |
︙ | ︙ | |||
2255 2256 2257 2258 2259 2260 2261 | assert(sharedTextPtr); if (!tagPtr) { return; } assert(tagPtr->undoTagListIndex >= 0); | | | 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 | assert(sharedTextPtr); if (!tagPtr) { return; } assert(tagPtr->undoTagListIndex >= 0); assert(tagPtr->undoTagListIndex < (int) sharedTextPtr->undoTagListCount); if (tagPtr->recentTagAddRemoveToken) { free(tagPtr->recentTagAddRemoveToken); DEBUG_ALLOC(tkTextCountDestroyUndoToken++); tagPtr->recentTagAddRemoveToken = NULL; } if (tagPtr->recentChangePriorityToken) { |
︙ | ︙ | |||
2337 2338 2339 2340 2341 2342 2343 | assert(sharedTextPtr->undoStack); if (!tagPtr) { return; } assert(tagPtr->undoTagListIndex >= 0); | | | 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 | assert(sharedTextPtr->undoStack); if (!tagPtr) { return; } assert(tagPtr->undoTagListIndex >= 0); assert(tagPtr->undoTagListIndex < (int) sharedTextPtr->undoTagListCount); if (tagPtr->recentTagAddRemoveToken) { if (tagPtr->recentTagAddRemoveTokenIsNull) { free(tagPtr->recentTagAddRemoveToken); DEBUG_ALLOC(tkTextCountDestroyUndoToken++); } else { TkTextUndoPushItem(sharedTextPtr->undoStack, tagPtr->recentTagAddRemoveToken, 0); |
︙ | ︙ | |||
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 | const TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TkBitField *includeBits = NULL; TkBitField *discardBits = NULL; bool discardSelection = false; TkTextTag **arrayPtr; int index, countTags, i; for (i = 3; i < objc; ++i) { const char *option = Tcl_GetString(objv[i]); if (*option != '-') { break; } | > | 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 | const TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; TkBitField *includeBits = NULL; TkBitField *discardBits = NULL; bool discardSelection = false; TkTextTag **arrayPtr; int index, countTags, i; unsigned k; for (i = 3; i < objc; ++i) { const char *option = Tcl_GetString(objv[i]); if (*option != '-') { break; } |
︙ | ︙ | |||
3265 3266 3267 3268 3269 3270 3271 | if (discardBits) { TkBitRemove(includeBits, discardBits); } arrayPtr = malloc(sharedTextPtr->numEnabledTags * sizeof(TkTextTag *)); countTags = 0; | | | | 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 | if (discardBits) { TkBitRemove(includeBits, discardBits); } arrayPtr = malloc(sharedTextPtr->numEnabledTags * sizeof(TkTextTag *)); countTags = 0; for (k = TkBitFindFirst(includeBits); k != TK_BIT_NPOS; k = TkBitFindNext(includeBits, k)) { arrayPtr[countTags++] = sharedTextPtr->tagLookup[k]; } AppendTags(interp, countTags, arrayPtr); free(arrayPtr); TkBitDecrRefCount(includeBits); if (discardBits) { |
︙ | ︙ |
Changes to generic/tkTextTagSet.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tkTextTagSet.c -- * * This module implements a set for tagging information. * * Copyright (c) 2015-2017 Gregor Cramer * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkTextTagSet.h" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tkTextTagSet.c -- * * This module implements a set for tagging information. * * Copyright (c) 2015-2017 Gregor Cramer * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkTextTagSet.h" #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextTagSetPriv.h" #endif #if !TK_TEXT_DONT_USE_BITFIELDS # include <assert.h> |
︙ | ︙ | |||
188 189 190 191 192 193 194 | TkTextTagSetToBits( const TkTextTagSet *src, int size) { assert(src); if (src->base.isSetFlag) { | | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | TkTextTagSetToBits( const TkTextTagSet *src, int size) { assert(src); if (src->base.isSetFlag) { return TkBitFromSet(&src->set, size < 0 ? (int) TkIntSetMax(&src->set) + 1 : size); } if (size < 0 || (int) TkBitSize(&src->bf) == size) { ((TkTextTagSet *) src)->base.refCount += 1; return (TkBitField *) &src->bf; } return TkBitCopy(&src->bf, size); } |
︙ | ︙ | |||
995 996 997 998 999 1000 1001 | } } } return TK_TEXT_TAG_SET_NPOS; } | | | | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | } } } return TK_TEXT_TAG_SET_NPOS; } #ifndef NDEBUG void TkTextTagSetPrint( const TkTextTagSet *set) { if (!set) { printf("<null>\n"); } else if (TkTextTagSetIsEmpty(set)) { printf("<empty>\n"); } else if (set->base.isSetFlag) { TkIntSetPrint(&set->set); } else { TkBitPrint(&set->bf); } } # endif /* NDEBUG */ # if 0 /* * These functions are not needed anymore, but shouldn't be removed, because sometimes * any of these functions might be useful. */ |
︙ | ︙ | |||
1661 1662 1663 1664 1665 1666 1667 | } return TkIntSetJoinOfDifferences(MakeCopyIfNeeded(dst), ts1, ts2); } #endif /* !TK_TEXT_USE_BITFIELDS */ | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 | } return TkIntSetJoinOfDifferences(MakeCopyIfNeeded(dst), ts1, ts2); } #endif /* !TK_TEXT_USE_BITFIELDS */ #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ #if !TK_TEXT_DONT_USE_BITFIELDS extern TkTextTagSet *TkTextTagSetNew(unsigned size); extern unsigned TkTextTagSetRefCount(const TkTextTagSet *ts); extern void TkTextTagSetIncrRefCount(TkTextTagSet *ts); extern unsigned TkTextTagSetDecrRefCount(TkTextTagSet *ts); extern TkTextTagSet *TkTextTagSetCopy(const TkTextTagSet *src); extern bool TkTextTagSetIsEmpty(const TkTextTagSet *ts); extern bool TkTextTagSetIsBitField(const TkTextTagSet *ts); extern unsigned TkTextTagSetSize(const TkTextTagSet *ts); extern unsigned TkTextTagSetCount(const TkTextTagSet *ts); extern bool TkTextTagSetTest(const TkTextTagSet *ts, unsigned n); extern bool TkTextTagSetNone(const TkTextTagSet *ts); extern bool TkTextTagSetAny(const TkTextTagSet *ts); extern bool TkTextTagSetIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2); extern bool TkTextTagSetContains(const TkTextTagSet *ts1, const TkTextTagSet *ts2); extern bool TkTextTagSetDisjunctive(const TkTextTagSet *ts1, const TkTextTagSet *ts2); extern bool TkTextTagSetIntersects(const TkTextTagSet *ts1, const TkTextTagSet *ts2); extern bool TkTextTagSetIntersectionIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2, const TkBitField *bf); extern bool TkTextTagBitContainsSet(const TkBitField *bf, const TkTextTagSet *ts); extern bool TkTextTagSetIsEqualBits(const TkTextTagSet *ts, const TkBitField *bf); extern bool TkTextTagSetContainsBits(const TkTextTagSet *ts, const TkBitField *bf); extern bool TkTextTagSetDisjunctiveBits(const TkTextTagSet *ts, const TkBitField *bf); extern bool TkTextTagSetIntersectsBits(const TkTextTagSet *ts, const TkBitField *bf); extern unsigned TkTextTagSetFindFirst(const TkTextTagSet *ts); extern unsigned TkTextTagSetFindNext(const TkTextTagSet *ts, unsigned prev); extern TkTextTagSet *TkTextTagSetAddOrErase(TkTextTagSet *ts, unsigned n, bool value); extern unsigned TkTextTagSetRangeSize(const TkTextTagSet *ts); extern const unsigned char *TkTextTagSetData(const TkTextTagSet *ts); extern unsigned TkTextTagSetByteSize(const TkTextTagSet *ts); #else /* integer set only implementation **************************************/ extern TkIntSet *TkTextTagSetNew(unsigned size); extern TkIntSet *TkTextTagSetResize(TkIntSet *ts, unsigned newSize); extern void TkTextTagSetDestroy(TkIntSet **tsPtr); extern unsigned TkTextTagSetRefCount(const TkIntSet *ts); extern void TkTextTagSetIncrRefCount(TkIntSet *ts); extern unsigned TkTextTagSetDecrRefCount(TkIntSet *ts); extern TkIntSet *TkTextTagSetCopy(const TkIntSet *src); extern bool TkTextTagSetIsEmpty(const TkIntSet *ts); extern bool TkTextTagSetIsBitField(const TkIntSet *ts); extern unsigned TkTextTagSetSize(const TkIntSet *ts); extern unsigned TkTextTagSetCount(const TkIntSet *ts); extern bool TkTextTagSetTest(const TkIntSet *ts, unsigned n); extern bool TkTextTagSetNone(const TkIntSet *ts); extern bool TkTextTagSetAny(const TkIntSet *ts); extern bool TkTextTagSetIsEqual(const TkIntSet *ts1, const TkIntSet *ts2); extern bool TkTextTagSetContains(const TkIntSet *ts1, const TkIntSet *ts2); extern bool TkTextTagSetDisjunctive(const TkIntSet *ts1, const TkIntSet *ts2); extern bool TkTextTagSetIntersects(const TkIntSet *ts1, const TkIntSet *ts2); extern bool TkTextTagSetIntersectionIsEqual(const TkIntSet *ts1, const TkIntSet *ts2, const TkBitField *bf); extern bool TkTextTagBitContainsSet(const TkBitField *bf, const TkIntSet *ts); extern bool TkTextTagSetIsEqualBits(const TkIntSet *ts, const TkBitField *bf); extern bool TkTextTagSetContainsBits(const TkIntSet *ts, const TkBitField *bf); extern bool TkTextTagSetDisjunctiveBits(const TkIntSet *ts, const TkBitField *bf); extern bool TkTextTagSetIntersectsBits(const TkIntSet *ts, const TkBitField *bf); extern unsigned TkTextTagSetFindFirst(const TkIntSet *ts); extern unsigned TkTextTagSetFindNext(const TkIntSet *ts, unsigned prev); extern unsigned TkTextTagSetFindFirstInIntersection(const TkIntSet *ts, const TkBitField *bf); extern TkIntSet *TkTextTagSetAddOrErase(TkIntSet *ts, unsigned n, bool value); extern TkIntSet *TkTextTagSetClear(TkIntSet *ts); extern unsigned TkTextTagSetRangeSize(const TkIntSet *ts); extern const unsigned char *TkTextTagSetData(const TkIntSet *ts); extern unsigned TkTextTagSetByteSize(const TkIntSet *ts); #endif /* !TK_TEXT_DONT_USE_BITFIELDS */ #endif /* __STDC_VERSION__ >= 199901L */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkTextTagSet.h.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | */ #ifndef _TKTEXTTAGSET #define _TKTEXTTAGSET #include "tkBitField.h" #include "tkIntSet.h" #include <stdint.h> #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif | > < < < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | */ #ifndef _TKTEXTTAGSET #define _TKTEXTTAGSET #include "tkBitField.h" #include "tkIntSet.h" #include "tkBool.h" #include <stdint.h> #if defined(__GNUC__) || defined(__clang__) # define __warn_unused__ __attribute__((warn_unused_result)) #else # define __warn_unused__ #endif /* * Currently our implementation is using a shared bitfield/integer set implementation. * Bitfields will be used as long as the number of tags is below a certain limit * (will be satisfied in most applications), but in some sophisticated applications * this limit will be exceeded, and in this case the integer set comes into play, * because a bitfield is too memory hungry with a large number of tags. Bitfields |
︙ | ︙ | |||
155 156 157 158 159 160 161 | TkTextTagSet *TkTextTagSetClear(TkTextTagSet *ts) __warn_unused__; inline unsigned TkTextTagSetRangeSize(const TkTextTagSet *ts); inline const unsigned char *TkTextTagSetData(const TkTextTagSet *ts); inline unsigned TkTextTagSetByteSize(const TkTextTagSet *ts); | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | TkTextTagSet *TkTextTagSetClear(TkTextTagSet *ts) __warn_unused__; inline unsigned TkTextTagSetRangeSize(const TkTextTagSet *ts); inline const unsigned char *TkTextTagSetData(const TkTextTagSet *ts); inline unsigned TkTextTagSetByteSize(const TkTextTagSet *ts); # ifndef NDEBUG void TkTextTagSetPrint(const TkTextTagSet *set); # endif # if 0 /* |
︙ | ︙ | |||
272 273 274 275 276 277 278 | inline unsigned TkTextTagSetByteSize(const TkIntSet *ts); #endif /* !TK_TEXT_DONT_USE_BITFIELDS */ #undef __warn_unused__ | | < < | 267 268 269 270 271 272 273 274 275 276 277 278 279 | inline unsigned TkTextTagSetByteSize(const TkIntSet *ts); #endif /* !TK_TEXT_DONT_USE_BITFIELDS */ #undef __warn_unused__ #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextTagSetPriv.h" #endif #endif /* _TKTEXTTAGSET */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkTextTagSetPriv.h.
︙ | ︙ | |||
62 63 64 65 66 67 68 | #ifndef _TK #include "tk.h" #endif #include <assert.h> | < < < < < < | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #ifndef _TK #include "tk.h" #endif #include <assert.h> #if !TK_TEXT_DONT_USE_BITFIELDS /* shared implementation ****************************/ inline TkTextTagSet * TkTextTagSetNew( unsigned size) |
︙ | ︙ |
Changes to generic/tkTextUndo.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | */ #include "tkTextUndo.h" #include "tkInt.h" #include "tkAlloc.h" #include <assert.h> | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | */ #include "tkTextUndo.h" #include "tkInt.h" #include "tkAlloc.h" #include <assert.h> #ifndef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextUndoPriv.h" #endif #ifndef MAX # define MAX(a,b) ((a) < (b) ? b : a) #endif |
︙ | ︙ | |||
145 146 147 148 149 150 151 | if (current) { FreeItems(stack, ¤t->data); } if (force || !current || current->capacity > InitialCapacity) { static unsigned Size = ATOM_SIZE(InitialCapacity); | | > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | if (current) { FreeItems(stack, ¤t->data); } if (force || !current || current->capacity > InitialCapacity) { static unsigned Size = ATOM_SIZE(InitialCapacity); current = stack->current = realloc(current, Size); /* NOTE: MSVS 2010 throws internal compiler error when using memset(realloc()). */ memset(current, 0, Size); current->capacity = InitialCapacity; } current->data.arraySize = 0; current->data.size = 0; current->undoSize = 0; } |
︙ | ︙ | |||
298 299 300 301 302 303 304 | stack->undoDepth += 1; stack->undoSize += atom->data.size; stack->undoItems += atom->data.arraySize; } else if (stack->doingUndo) { /* * We'll push a redo atom while performing an undo. */ | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | stack->undoDepth += 1; stack->undoSize += atom->data.size; stack->undoItems += atom->data.arraySize; } else if (stack->doingUndo) { /* * We'll push a redo atom while performing an undo. */ assert(stack->maxRedoDepth <= 0 || (int) stack->redoDepth < stack->maxRedoDepth); atom = stack->last ? stack->last->next : stack->root; SwapCurrent(stack, atom); stack->redoDepth += 1; stack->redoSize += atom->data.size; stack->redoItems += atom->data.arraySize; } else if (stack->last && stack->undoDepth == stack->maxUndoDepth) { /* |
︙ | ︙ | |||
538 539 540 541 542 543 544 | if ((0 < maxUndoDepth && maxUndoDepth < depth) || (0 <= maxRedoDepth && (unsigned) maxRedoDepth < (unsigned) stack->maxRedoDepth)) { unsigned deleteRedos = MIN(stack->redoDepth, depth - maxUndoDepth); if (0 <= maxRedoDepth && maxRedoDepth < stack->maxRedoDepth) { deleteRedos = MIN(stack->redoDepth, | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | if ((0 < maxUndoDepth && maxUndoDepth < depth) || (0 <= maxRedoDepth && (unsigned) maxRedoDepth < (unsigned) stack->maxRedoDepth)) { unsigned deleteRedos = MIN(stack->redoDepth, depth - maxUndoDepth); if (0 <= maxRedoDepth && maxRedoDepth < stack->maxRedoDepth) { deleteRedos = MIN(stack->redoDepth, MAX(deleteRedos, (unsigned) stack->maxRedoDepth - maxRedoDepth)); } stack->redoDepth -= deleteRedos; depth = maxUndoDepth - deleteRedos; if (deleteRedos > 0) { MyUndoAtom *atom = stack->root; |
︙ | ︙ | |||
944 945 946 947 948 949 950 | TkTextUndoStackIsFull( const TkTextUndoStack stack) { if (!stack) { return true; } if (stack->doingUndo) { | | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 | TkTextUndoStackIsFull( const TkTextUndoStack stack) { if (!stack) { return true; } if (stack->doingUndo) { return stack->maxRedoDepth >= 0 && (int) stack->redoDepth >= stack->maxRedoDepth; } return stack->maxUndoDepth > 0 && stack->undoDepth >= stack->maxUndoDepth; } const TkTextUndoAtom * TkTextUndoFirstUndoAtom( |
︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 | } } return NULL; } | | < | | | | | | | | | | | | | | | | | | | | | | | | | | 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | } } return NULL; } #ifdef TK_C99_INLINE_SUPPORT /* Additionally we need stand-alone object code. */ extern void TkTextUndoSetContext(TkTextUndoStack stack, TkTextUndoContext context); extern TkTextUndoContext TkTextUndoGetContext(const TkTextUndoStack stack); extern unsigned TkTextUndoGetMaxUndoDepth(const TkTextUndoStack stack); extern int TkTextUndoGetMaxRedoDepth(const TkTextUndoStack stack); extern unsigned TkTextUndoGetMaxSize(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentDepth(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentSize(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentUndoStackDepth(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentRedoStackDepth(const TkTextUndoStack stack); extern unsigned TkTextUndoCountUndoItems(const TkTextUndoStack stack); extern unsigned TkTextUndoCountRedoItems(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentUndoSize(const TkTextUndoStack stack); extern unsigned TkTextUndoGetCurrentRedoSize(const TkTextUndoStack stack); extern unsigned TkTextUndoCountCurrentUndoItems(const TkTextUndoStack stack); extern unsigned TkTextUndoCountCurrentRedoItems(const TkTextUndoStack stack); extern bool TkTextUndoContentIsIrreversible(const TkTextUndoStack stack); extern bool TkTextUndoContentIsModified(const TkTextUndoStack stack); extern bool TkTextUndoIsPerformingUndo(const TkTextUndoStack stack); extern bool TkTextUndoIsPerformingRedo(const TkTextUndoStack stack); extern bool TkTextUndoIsPerformingUndoRedo(const TkTextUndoStack stack); extern const TkTextUndoAtom *TkTextUndoCurrentUndoAtom(const TkTextUndoStack stack); extern const TkTextUndoAtom *TkTextUndoCurrentRedoAtom(const TkTextUndoStack stack); extern const TkTextUndoSubAtom *TkTextUndoGetLastUndoSubAtom(const TkTextUndoStack stack); extern bool TkTextUndoUndoStackIsFull(const TkTextUndoStack stack); extern bool TkTextUndoRedoStackIsFull(const TkTextUndoStack stack); #endif /* __STDC_VERSION__ >= 199901L */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkTextUndo.h.
︙ | ︙ | |||
29 30 31 32 33 34 35 | #ifndef _TKTEXTUNDO #define _TKTEXTUNDO #include "tkBool.h" #include <stdint.h> | < < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #ifndef _TKTEXTUNDO #define _TKTEXTUNDO #include "tkBool.h" #include <stdint.h> /* * Our (private) stack type. */ struct TkTextUndoStack; typedef struct TkTextUndoStack * TkTextUndoStack; |
︙ | ︙ | |||
240 241 242 243 244 245 246 | * pushed. Returns an error (TCL_ERROR) if no undo (redo) action is possible. */ int TkTextUndoDoUndo(TkTextUndoStack stack); int TkTextUndoDoRedo(TkTextUndoStack stack); | | < < | 234 235 236 237 238 239 240 241 242 243 244 245 246 | * pushed. Returns an error (TCL_ERROR) if no undo (redo) action is possible. */ int TkTextUndoDoUndo(TkTextUndoStack stack); int TkTextUndoDoRedo(TkTextUndoStack stack); #ifdef TK_C99_INLINE_SUPPORT # define _TK_NEED_IMPLEMENTATION # include "tkTextUndoPriv.h" #endif #endif /* _TKTEXTUNDO */ /* vi:set ts=8 sw=4: */ |
Changes to generic/tkTextUndoPriv.h.
︙ | ︙ | |||
101 102 103 104 105 106 107 | inline bool TkTextUndoUndoStackIsFull(const TkTextUndoStack stack) { return !stack || (stack->maxUndoDepth > 0 && stack->undoDepth >= stack->maxUndoDepth); } inline bool TkTextUndoRedoStackIsFull(const TkTextUndoStack stack) | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | inline bool TkTextUndoUndoStackIsFull(const TkTextUndoStack stack) { return !stack || (stack->maxUndoDepth > 0 && stack->undoDepth >= stack->maxUndoDepth); } inline bool TkTextUndoRedoStackIsFull(const TkTextUndoStack stack) { return !stack || (stack->maxRedoDepth >= 0 && (int) stack->redoDepth >= stack->maxRedoDepth); } inline unsigned TkTextUndoCountCurrentUndoItems(const TkTextUndoStack stack) { assert(stack); return stack->current && !stack->doingUndo ? stack->current->data.arraySize : 0; } inline unsigned TkTextUndoCountCurrentRedoItems(const TkTextUndoStack stack) |
︙ | ︙ |
Changes to generic/tkTextWind.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "tkPort.h" #include "tkText.h" #include "tkTextTagSet.h" #include "tkTextUndo.h" #include <assert.h> | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include "tkPort.h" #include "tkText.h" #include "tkTextTagSet.h" #include "tkTextUndo.h" #include <assert.h> #ifdef NDEBUG # define DEBUG(expr) #else # define DEBUG(expr) expr #endif /* * Support of tk8.5. |
︙ | ︙ |
Changes to tests/text.test.
︙ | ︙ | |||
1462 1463 1464 1465 1466 1467 1468 | 12345 Line 4 bOy GIrl .#@? x_yz !@#$% Line 7" .t configure -state disabled .t delete 2.3 | | | 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 | 12345 Line 4 bOy GIrl .#@? x_yz !@#$% Line 7" .t configure -state disabled .t delete 2.3 .t get 2.0 2.end } -cleanup { destroy .t } -result {abcdefghijklm} test text-8.6 {TextWidgetCmd procedure, "delete" option} -setup { text .t } -body { .t insert 1.0 "Line 1 |
︙ | ︙ |
Changes to unix/Makefile.in.
︙ | ︙ | |||
944 945 946 947 948 949 950 | tkAtom.o: $(GENERIC_DIR)/tkAtom.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkAtom.c tkBind.o: $(GENERIC_DIR)/tkBind.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c tkBitField.o: $(GENERIC_DIR)/tkBitField.c | | | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | tkAtom.o: $(GENERIC_DIR)/tkAtom.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkAtom.c tkBind.o: $(GENERIC_DIR)/tkBind.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c tkBitField.o: $(GENERIC_DIR)/tkBitField.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitField.c tkBitmap.o: $(GENERIC_DIR)/tkBitmap.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitmap.c tkBusy.o: $(GENERIC_DIR)/tkBusy.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBusy.c |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | tkImgPhInstance.o: $(GENERIC_DIR)/tkImgPhInstance.c $(GENERIC_DIR)/tkImgPhoto.h $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhInstance.c tkOldTest.o: $(GENERIC_DIR)/tkOldTest.c $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkOldTest.c tkQTree.o: $(GENERIC_DIR)/tkQTree.c | | | | | | | | | | | | | | | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 | tkImgPhInstance.o: $(GENERIC_DIR)/tkImgPhInstance.c $(GENERIC_DIR)/tkImgPhoto.h $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhInstance.c tkOldTest.o: $(GENERIC_DIR)/tkOldTest.c $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkOldTest.c tkQTree.o: $(GENERIC_DIR)/tkQTree.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkQTree.c tkRangeList.o: $(GENERIC_DIR)/tkRangeList.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkRangeList.c tkIntSet.o: $(GENERIC_DIR)/tkIntSet.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkIntSet.c tkTest.o: $(GENERIC_DIR)/tkTest.c $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkTest.c tkText.o: $(GENERIC_DIR)/tkText.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c tkTextBTree.o: $(GENERIC_DIR)/tkTextBTree.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextBTree.c tkTextDisp.o: $(GENERIC_DIR)/tkTextDisp.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextDisp.c tkTextImage.o: $(GENERIC_DIR)/tkTextImage.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextImage.c tkTextIndex.o: $(GENERIC_DIR)/tkTextIndex.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextIndex.c tkTextLineBreak.o: $(GENERIC_DIR)/tkTextLineBreak.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextLineBreak.c tkTextMark.o: $(GENERIC_DIR)/tkTextMark.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextMark.c tkTextTag.o: $(GENERIC_DIR)/tkTextTag.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextTag.c tkTextTagSet.o: $(GENERIC_DIR)/tkTextTagSet.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextTagSet.c tkTextUndo.o: $(GENERIC_DIR)/tkTextUndo.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextUndo.c tkTextWind.o: $(GENERIC_DIR)/tkTextWind.c $(CC) -std=c99 -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextWind.c tkStubInit.o: $(GENERIC_DIR)/tkStubInit.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStubInit.c # Stub library binaries, these must be compiled for use in a shared library # even though they will be placed in a static archive |
︙ | ︙ |