📄 offsetmanager.java
字号:
| visible; } //{{{ Unrolled if((visible & (1L << (VISIBLE_SHIFT + 0))) != 0) virtualLineCounts[0] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 1))) != 0) virtualLineCounts[1] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 2))) != 0) virtualLineCounts[2] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 3))) != 0) virtualLineCounts[3] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 4))) != 0) virtualLineCounts[4] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 5))) != 0) virtualLineCounts[5] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 6))) != 0) virtualLineCounts[6] += numLines; if((visible & (1L << (VISIBLE_SHIFT + 7))) != 0) virtualLineCounts[7] += numLines; //}}} } //}}} moveGap(endLine,length,"contentInserted"); updatePositionsForInsert(offset,length); } //}}} //{{{ contentRemoved() method public void contentRemoved(int startLine, int offset, int numLines, int length) { //{{{ Update virtual line counts for(int i = 0; i < numLines; i++) { long info = lineInfo[startLine + i]; // Unrolled for max efficency if((info & (1L << (VISIBLE_SHIFT + 0))) != 0) virtualLineCounts[0]--; if((info & (1L << (VISIBLE_SHIFT + 1))) != 0) virtualLineCounts[1]--; if((info & (1L << (VISIBLE_SHIFT + 2))) != 0) virtualLineCounts[2]--; if((info & (1L << (VISIBLE_SHIFT + 3))) != 0) virtualLineCounts[3]--; if((info & (1L << (VISIBLE_SHIFT + 4))) != 0) virtualLineCounts[4]--; if((info & (1L << (VISIBLE_SHIFT + 5))) != 0) virtualLineCounts[5]--; if((info & (1L << (VISIBLE_SHIFT + 6))) != 0) virtualLineCounts[6]--; if((info & (1L << (VISIBLE_SHIFT + 7))) != 0) virtualLineCounts[7]--; } //}}} //{{{ Update line info and line context arrays if(numLines > 0) { moveGap(-1,0,"contentRemoved"); lineCount -= numLines; System.arraycopy(lineInfo,startLine + numLines,lineInfo, startLine,lineCount - startLine); System.arraycopy(lineContext,startLine + numLines,lineContext, startLine,lineCount - startLine); } //}}} moveGap(startLine,-length,"contentRemoved"); updatePositionsForRemove(offset,length); } //}}} //{{{ lineInfoChangedFrom() method public void lineInfoChangedFrom(int startLine) { moveGap(startLine,0,"lineInfoChangedFrom"); } //}}} //{{{ Private members /* {{{ Format of entires in line info array: * 0-31: end offset * 32-47: fold level * 48-55: visibility bit flags * 56: fold level valid flag * 57: context valid flag * 58-62: number of screen lines (currently unused, reserved for jEdit 4.1) * 63: reserved * * Having all the info packed into a long is not very OO and makes the * code somewhat more complicated, but it saves a lot of memory. * * The new document model has just 12 bytes of overhead per line. * LineContext instances are now internalized, so only a few should * actually be in the heap. * * In the old document model there were 5 objects per line, for a * total of about 100 bytes, plus a cached token list, which used * another 100 or so bytes. * }}}*/ private static final long END_MASK = 0x00000000ffffffffL; private static final long FOLD_LEVEL_MASK = 0x0000ffff00000000L; private static final int FOLD_LEVEL_SHIFT = 32; private static final long VISIBLE_MASK = 0x00ff000000000000L; private static final int VISIBLE_SHIFT = 48; private static final long FOLD_LEVEL_VALID_MASK = (1L<<56); private static final long CONTEXT_VALID_MASK = (1L<<57); private static final long SCREEN_LINES_MASK = 0x7c00000000000000L; private static final long SCREEN_LINES_SHIFT = 58; //{{{ Instance variables private Buffer buffer; private long[] lineInfo; private TokenMarker.LineContext[] lineContext; private int lineCount; private PosBottomHalf[] positions; private int positionCount; private int[] virtualLineCounts; /** * If -1, then there is no gap. * Otherwise, all lines from this line onwards need to have gapWidth * added to their end offsets. */ private int gapLine; private int gapWidth; //}}} //{{{ setLineEndOffset() method private final void setLineEndOffset(int line, int end) { lineInfo[line] = ((lineInfo[line] & ~(END_MASK | FOLD_LEVEL_VALID_MASK | CONTEXT_VALID_MASK)) | end); // what is the point of this -- DO NOT UNCOMMENT THIS IT // CAUSES A PERFORMANCE LOSS; nextLineRequested becomes true //lineContext[line] = null; } //}}} //{{{ moveGap() method private final void moveGap(int newGapLine, int newGapWidth, String method) { if(gapLine == -1) gapWidth = newGapWidth; else if(newGapLine == -1) { //if(gapWidth != 0) { //if(DEBUG && gapLine != lineCount) // System.err.println(method + ": update from " + gapLine + " to " + lineCount); for(int i = gapLine; i < lineCount; i++) setLineEndOffset(i,getLineEndOffset(i)); } gapWidth = newGapWidth; } else if(newGapLine < gapLine) { //if(gapWidth != 0) { //if(DEBUG && newGapLine != gapLine) // System.err.println(method + ": update from " + newGapLine + " to " + gapLine); for(int i = newGapLine; i < gapLine; i++) setLineEndOffset(i,getLineEndOffset(i) - gapWidth); } gapWidth += newGapWidth; } else //if(newGapLine >= gapLine) { //if(gapWidth != 0) { //if(DEBUG && gapLine != newGapLine) // System.err.println(method + ": update from " + gapLine + " to " + newGapLine); for(int i = gapLine; i < newGapLine; i++) setLineEndOffset(i,getLineEndOffset(i)); } gapWidth += newGapWidth; } if(newGapLine == lineCount) gapLine = -1; else gapLine = newGapLine; } //}}} //{{{ growPositionArray() method private void growPositionArray() { if(positions.length < positionCount + 1) { PosBottomHalf[] newPositions = new PosBottomHalf[ (positionCount + 1) * 2]; System.arraycopy(positions,0,newPositions,0,positionCount); positions = newPositions; } } //}}} //{{{ removePosition() method private synchronized void removePosition(PosBottomHalf bh) { int index = -1; for(int i = 0; i < positionCount; i++) { if(positions[i] == bh) { index = i; break; } } System.arraycopy(positions,index + 1,positions,index, positionCount - index - 1); positions[--positionCount] = null; } //}}} //{{{ updatePositionsForInsert() method private void updatePositionsForInsert(int offset, int length) { if(positionCount == 0) return; int start = getPositionAtOffset(offset); for(int i = start; i < positionCount; i++) { PosBottomHalf bh = positions[i]; if(bh.offset < offset) Log.log(Log.ERROR,this,"Screwed up: " + bh.offset); else bh.offset += length; } } //}}} //{{{ updatePositionsForRemove() method private void updatePositionsForRemove(int offset, int length) { if(positionCount == 0) return; int start = getPositionAtOffset(offset); for(int i = start; i < positionCount; i++) { PosBottomHalf bh = positions[i]; if(bh.offset < offset) Log.log(Log.ERROR,this,"Screwed up: " + bh.offset); else if(bh.offset < offset + length) bh.offset = offset; else bh.offset -= length; } } //}}} //{{{ getPositionAtOffset() method private int getPositionAtOffset(int offset) { int start = 0; int end = positionCount - 1; PosBottomHalf bh;loop: for(;;) { switch(end - start) { case 0: bh = positions[start]; if(bh.offset < offset) start++; break loop; case 1: bh = positions[end]; if(bh.offset < offset) { start = end + 1; } else { bh = positions[start]; if(bh.offset < offset) { start++; } } break loop; default: int pivot = (start + end) / 2; bh = positions[pivot]; if(bh.offset > offset) end = pivot - 1; else start = pivot + 1; break; } } return start; } //}}} //}}} //{{{ Inner classes //{{{ PosTopHalf class static class PosTopHalf implements Position { PosBottomHalf bh; //{{{ PosTopHalf constructor PosTopHalf(PosBottomHalf bh) { this.bh = bh; bh.ref(); } //}}} //{{{ getOffset() method public int getOffset() { return bh.offset; } //}}} //{{{ finalize() method public void finalize() { bh.unref(); } //}}} } //}}} //{{{ PosBottomHalf class class PosBottomHalf { int offset; int ref; //{{{ PosBottomHalf constructor PosBottomHalf(int offset) { this.offset = offset; } //}}} //{{{ ref() method void ref() { ref++; } //}}} //{{{ unref() method void unref() { if(--ref == 0) removePosition(this); } //}}} } //}}} //}}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -