?? tktextbtree.c
字號(hào):
* Starting and stopping segments are in the same line; mark the * search as over immediately if the second segment is after the * first. */ if (index1Ptr->charIndex <= backOne.charIndex) { searchPtr->linesLeft = 0; } }}/* *---------------------------------------------------------------------- * * TkBTreeNextTag -- * * Once a tag search has begun, successive calls to this procedure * return successive tag toggles. Note: it is NOT SAFE to call this * procedure if characters have been inserted into or deleted from * the B-tree since the call to TkBTreeStartSearch. * * Results: * The return value is 1 if another toggle was found that met the * criteria specified in the call to TkBTreeStartSearch; in this * case searchPtr->curIndex gives the toggle's position and * searchPtr->curTagPtr points to its segment. 0 is returned if * no more matching tag transitions were found; in this case * searchPtr->curIndex is the same as searchPtr->stopIndex. * * Side effects: * Information in *searchPtr is modified to update the state of the * search and indicate where the next tag toggle is located. * *---------------------------------------------------------------------- */intTkBTreeNextTag(searchPtr) register TkTextSearch *searchPtr; /* Information about search in * progress; must have been set up by * call to TkBTreeStartSearch. */{ register TkTextSegment *segPtr; register Node *nodePtr; register Summary *summaryPtr; if (searchPtr->linesLeft <= 0) { goto searchOver; } /* * The outermost loop iterates over lines that may potentially contain * a relevant tag transition, starting from the current segment in * the current line. */ segPtr = searchPtr->nextPtr; while (1) { /* * Check for more tags on the current line. */ for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) { if (segPtr == searchPtr->lastPtr) { goto searchOver; } if (((segPtr->typePtr == &tkTextToggleOnType) || (segPtr->typePtr == &tkTextToggleOffType)) && (searchPtr->allTags || (segPtr->body.toggle.tagPtr == searchPtr->tagPtr))) { searchPtr->segPtr = segPtr; searchPtr->nextPtr = segPtr->nextPtr; searchPtr->tagPtr = segPtr->body.toggle.tagPtr; return 1; } searchPtr->curIndex.charIndex += segPtr->size; } /* * See if there are more lines associated with the current parent * node. If so, go back to the top of the loop to search the next * one. */ nodePtr = searchPtr->curIndex.linePtr->parentPtr; searchPtr->curIndex.linePtr = searchPtr->curIndex.linePtr->nextPtr; searchPtr->linesLeft--; if (searchPtr->linesLeft <= 0) { goto searchOver; } if (searchPtr->curIndex.linePtr != NULL) { segPtr = searchPtr->curIndex.linePtr->segPtr; searchPtr->curIndex.charIndex = 0; continue; } if (nodePtr == searchPtr->tagPtr->tagRootPtr) { goto searchOver; } /* * Search across and up through the B-tree's node hierarchy looking * for the next node that has a relevant tag transition somewhere in * its subtree. Be sure to update linesLeft as we skip over large * chunks of lines. */ while (1) { while (nodePtr->nextPtr == NULL) { if (nodePtr->parentPtr == NULL || nodePtr->parentPtr == searchPtr->tagPtr->tagRootPtr) { goto searchOver; } nodePtr = nodePtr->parentPtr; } nodePtr = nodePtr->nextPtr; for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL; summaryPtr = summaryPtr->nextPtr) { if ((searchPtr->allTags) || (summaryPtr->tagPtr == searchPtr->tagPtr)) { goto gotNodeWithTag; } } searchPtr->linesLeft -= nodePtr->numLines; } /* * At this point we've found a subtree that has a relevant tag * transition. Now search down (and across) through that subtree * to find the first level-0 node that has a relevant tag transition. */ gotNodeWithTag: while (nodePtr->level > 0) { for (nodePtr = nodePtr->children.nodePtr; ; nodePtr = nodePtr->nextPtr) { for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL; summaryPtr = summaryPtr->nextPtr) { if ((searchPtr->allTags) || (summaryPtr->tagPtr == searchPtr->tagPtr)) { goto nextChild; } } searchPtr->linesLeft -= nodePtr->numLines; if (nodePtr->nextPtr == NULL) { panic("TkBTreeNextTag found incorrect tag summary info."); } } nextChild: continue; } /* * Now we're down to a level-0 node that contains a line that contains * a relevant tag transition. Set up line information and go back to * the beginning of the loop to search through lines. */ searchPtr->curIndex.linePtr = nodePtr->children.linePtr; searchPtr->curIndex.charIndex = 0; segPtr = searchPtr->curIndex.linePtr->segPtr; if (searchPtr->linesLeft <= 0) { goto searchOver; } continue; } searchOver: searchPtr->linesLeft = 0; searchPtr->segPtr = NULL; return 0;}/* *---------------------------------------------------------------------- * * TkBTreePrevTag -- * * Once a tag search has begun, successive calls to this procedure * return successive tag toggles in the reverse direction. * Note: it is NOT SAFE to call this * procedure if characters have been inserted into or deleted from * the B-tree since the call to TkBTreeStartSearch. * * Results: * The return value is 1 if another toggle was found that met the * criteria specified in the call to TkBTreeStartSearch; in this * case searchPtr->curIndex gives the toggle's position and * searchPtr->curTagPtr points to its segment. 0 is returned if * no more matching tag transitions were found; in this case * searchPtr->curIndex is the same as searchPtr->stopIndex. * * Side effects: * Information in *searchPtr is modified to update the state of the * search and indicate where the next tag toggle is located. * *---------------------------------------------------------------------- */intTkBTreePrevTag(searchPtr) register TkTextSearch *searchPtr; /* Information about search in * progress; must have been set up by * call to TkBTreeStartSearch. */{ register TkTextSegment *segPtr, *prevPtr; register TkTextLine *linePtr, *prevLinePtr; register Node *nodePtr, *node2Ptr, *prevNodePtr; register Summary *summaryPtr; int charIndex; int pastLast; /* Saw last marker during scan */ int linesSkipped; if (searchPtr->linesLeft <= 0) { goto searchOver; } /* * The outermost loop iterates over lines that may potentially contain * a relevant tag transition, starting from the current segment in * the current line. "nextPtr" is maintained as the last segment in * a line that we can look at. */ while (1) { /* * Check for the last toggle before the current segment on this line. */ charIndex = 0; if (searchPtr->lastPtr == NULL) { /* * Search back to the very beginning, so pastLast is irrelevent. */ pastLast = 1; } else { pastLast = 0; } for (prevPtr = NULL, segPtr = searchPtr->curIndex.linePtr->segPtr ; segPtr != NULL && segPtr != searchPtr->nextPtr; segPtr = segPtr->nextPtr) { if (((segPtr->typePtr == &tkTextToggleOnType) || (segPtr->typePtr == &tkTextToggleOffType)) && (searchPtr->allTags || (segPtr->body.toggle.tagPtr == searchPtr->tagPtr))) { prevPtr = segPtr; searchPtr->curIndex.charIndex = charIndex; } if (segPtr == searchPtr->lastPtr) { prevPtr = NULL; /* Segments earlier than last don't count */ pastLast = 1; } charIndex += segPtr->size; } if (prevPtr != NULL) { if (searchPtr->linesLeft == 1 && !pastLast) { /* * We found a segment that is before the stopping index. * Note that it is OK if prevPtr == lastPtr. */ goto searchOver; } searchPtr->segPtr = prevPtr; searchPtr->nextPtr = prevPtr; searchPtr->tagPtr = prevPtr->body.toggle.tagPtr; return 1; } searchPtr->linesLeft--; if (searchPtr->linesLeft <= 0) { goto searchOver; } /* * See if there are more lines associated with the current parent * node. If so, go back to the top of the loop to search the previous * one. */ nodePtr = searchPtr->curIndex.linePtr->parentPtr; for (prevLinePtr = NULL, linePtr = nodePtr->children.linePtr; linePtr != NULL && linePtr != searchPtr->curIndex.linePtr; prevLinePtr = linePtr, linePtr = linePtr->nextPtr) { /* empty loop body */ ; } if (prevLinePtr != NULL) { searchPtr->curIndex.linePtr = prevLinePtr; searchPtr->nextPtr = NULL; continue; } if (nodePtr == searchPtr->tagPtr->tagRootPtr) { goto searchOver; } /* * Search across and up through the B-tree's node hierarchy looking * for the previous node that has a relevant tag transition somewhere in * its subtree. The search and line counting is trickier with/out * back pointers. We'll scan all the nodes under a parent up to * the current node, searching all of them for tag state. The last * one we find, if any, is recorded in prevNodePtr, and any nodes * past prevNodePtr that don't have tag state increment linesSkipped. */ while (1) { for (prevNodePtr = NULL, linesSkipped = 0, node2Ptr = nodePtr->parentPtr->children.nodePtr ; node2Ptr != nodePtr; node2Ptr = node2Ptr->nextPtr) { for (summaryPtr = node2Ptr->summaryPtr; summaryPtr != NULL; summaryPtr = summaryPtr->nextPtr) { if ((searchPtr->allTags) || (summaryPtr->tagPtr == searchPtr->tagPtr)) { prevNodePtr = node2Ptr; linesSkipped = 0; goto keepLooking; } } linesSkipped += node2Ptr->numLines; keepLooking: continue; } if (prevNodePtr != NULL) { nodePtr = prevNodePtr; searchPtr->linesLeft -= linesSkipped; goto gotNodeWithTag; } nodePtr = nodePtr->parentPtr; if (nodePtr->parentPtr == NULL || nodePtr == searchPtr->tagPtr->tagRootPtr) { goto searchOver; } } /* * At this point we've found a subtree that has a relevant tag * transition. Now search down (and across) through that subtree * to find the last level-0 node that has a relevant tag transition. */ gotNodeWithTag: while (nodePtr->level > 0) { for (linesSkipped = 0, prevNodePtr = NULL, nodePtr = nodePtr->children.nodePtr; nodePtr != NULL ; nodePtr = nodePtr->nextPtr) { for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL; summaryPtr = summaryPtr->nextPtr) { if ((searchPtr->allTags) || (summaryPtr->tagPtr == searchPtr->tagPtr)) { prevNodePtr = nodePtr; linesSkipped = 0; goto keepLooking2; } } linesSkipped += nodePtr->numLines; keepLooking2: continue; } if (prevNodePtr == NULL) { panic("TkBTreePrevTag found incorrect tag summary info."); } searchPtr->linesLeft -= linesSkipped; nodePtr = prevNodePtr; } /* * Now we're down to a level-0 node that contains a line that contains * a relevant tag transition. Set up line information and go back to * the beginning of the loop to search through lines. We start with * the last line below the node. */ for (prevLinePtr = NULL, linePtr = nodePtr->children.linePtr; linePtr != NULL ; prevLinePtr = linePtr, linePtr = linePtr->nextPtr) { /* empty loop body */ ; } searchPtr->curIndex.linePtr = prevLinePtr; searchPtr->curIndex.charIndex = 0; if (searchPtr->linesLeft <= 0) { goto searchOver; } continue; } searchOver: searchPtr->linesLeft = 0; searchPtr->segPtr = NULL; return 0;}/* *---------------------------------------------------------------------- * * TkBTreeCharTagged -- * * Determine whether a particular character has a particular tag. * * Results: * The return value is 1 if the given tag is in effect at the * character given by linePtr and ch, and 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */intTkBTreeCharTagged(indexPtr, tagPtr) TkTextIndex *indexPtr; /* Indicates a character position at * which to check for a tag. */ TkTextTag *tagPtr; /* Tag of interest. */{ register Node *nodePtr; register TkTextLine *siblingLinePtr; register TkTextSegment *segPtr; TkTextSegment *toggleSegPtr; int toggles, index; /* * Check for toggles for the tag in indexPtr's line but before * indexPtr. If there is one, its type indicates whether or * not the character is tagged. */ toggleSegPtr = NULL; for (index = 0, segPtr = indexPtr->linePtr->segPtr; (index + segPtr->size) <= indexPtr->charIndex; index += segPtr->size, segPtr = segPtr->nextPtr) { if (((segPtr->typePtr == &tkTextToggleOnType) || (segPtr->typePtr == &tkTextToggleOffType)) && (segPtr->body.toggle.tagPtr == tagPtr)) { toggleSegPtr = segPtr; } } if (toggleSegPtr != NULL) { return (toggleSegPtr->typePtr == &tkTextToggleOnType); } /* * No toggle in this line. Look for toggles for the tag in lines * that are predecessors of indexPtr->linePtr but under the same * level-0 node. */ for (siblingLinePtr = indexPtr->linePtr->parentPtr->children.linePtr; siblingLinePtr != indexPtr->linePtr; siblingLinePtr = siblingLinePtr->nextPtr) { for (segPtr = siblingLinePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { if (((segPtr->typePtr == &tkTextToggleOnType) || (segP
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -