private void reflow(java.lang.CharSequence s, int where, int before, int after) { if (s != mBase) { return; } java.lang.CharSequence text = mDisplay; int len = text.Length; // seek back to the start of the paragraph int find = android.text.TextUtils.lastIndexOf(text, '\n', where - 1); if (find < 0) { find = 0; } else { find = find + 1; } { int diff = where - find; before += diff; after += diff; where -= diff; } // seek forward to the end of the paragraph int look = android.text.TextUtils.indexOf(text, '\n', where + after); if (look < 0) { look = len; } else { look++; } // we want the index after the \n int change = look - (where + after); before += change; after += change; // seek further out to cover anything that is forced to wrap together if (text is android.text.Spanned) { android.text.Spanned sp = (android.text.Spanned)text; bool again; do { again = false; object[] force = sp.getSpans <android.text.style.WrapTogetherSpan>(where, where + after); { for (int i = 0; i < force.Length; i++) { int st = sp.getSpanStart(force[i]); int en = sp.getSpanEnd(force[i]); if (st < where) { again = true; int diff = where - st; before += diff; after += diff; where -= diff; } if (en > where + after) { again = true; int diff = en - (where + after); before += diff; after += diff; } } } }while (again); } // find affected region of old layout int startline = getLineForOffset(where); int startv = getLineTop(startline); int endline = getLineForOffset(where + before); if (where + after == len) { endline = getLineCount(); } int endv = getLineTop(endline); bool islast = (endline == getLineCount()); // generate new layout for affected text android.text.StaticLayout reflowed; lock (sLock) { reflowed = sStaticLayout; sStaticLayout = null; } if (reflowed == null) { reflowed = new android.text.StaticLayout(null); } else { reflowed.prepare(); } reflowed.generate(text, where, where + after, getPaint(), getWidth(), getAlignment (), getTextDirectionHeuristic(), getSpacingMultiplier(), getSpacingAdd(), false, true, mEllipsizedWidth, mEllipsizeAt); int n = reflowed.getLineCount(); // If the new layout has a blank line at the end, but it is not // the very end of the buffer, then we already have a line that // starts there, so disregard the blank line. if (where + after != len && reflowed.getLineStart(n - 1) == where + after) { n--; } // remove affected lines from old layout mInts.deleteAt(startline, endline - startline); mObjects.deleteAt(startline, endline - startline); // adjust offsets in layout for new height and offsets int ht = reflowed.getLineTop(n); int toppad = 0; int botpad = 0; if (mIncludePad && startline == 0) { toppad = reflowed.getTopPadding(); mTopPadding = toppad; ht -= toppad; } if (mIncludePad && islast) { botpad = reflowed.getBottomPadding(); mBottomPadding = botpad; ht += botpad; } mInts.adjustValuesBelow(startline, START, after - before); mInts.adjustValuesBelow(startline, TOP, startv - endv + ht); // insert new layout int[] ints; if (mEllipsize) { ints = new int[COLUMNS_ELLIPSIZE]; ints[ELLIPSIS_START] = ELLIPSIS_UNDEFINED; } else { ints = new int[COLUMNS_NORMAL]; } android.text.Layout.Directions[] objects = new android.text.Layout.Directions[1]; { for (int i_1 = 0; i_1 < n; i_1++) { ints[START] = reflowed.getLineStart(i_1) | (reflowed.getParagraphDirection(i_1) << DIR_SHIFT) | (reflowed.getLineContainsTab(i_1) ? TAB_MASK : 0); int top = reflowed.getLineTop(i_1) + startv; if (i_1 > 0) { top -= toppad; } ints[TOP] = top; int desc = reflowed.getLineDescent(i_1); if (i_1 == n - 1) { desc += botpad; } ints[DESCENT] = desc; objects[0] = reflowed.getLineDirections(i_1); if (mEllipsize) { ints[ELLIPSIS_START] = reflowed.getEllipsisStart(i_1); ints[ELLIPSIS_COUNT] = reflowed.getEllipsisCount(i_1); } mInts.insertAt(startline + i_1, ints); mObjects.insertAt(startline + i_1, objects); } } lock (sLock) { sStaticLayout = reflowed; reflowed.finish(); } }
private void reflow(java.lang.CharSequence s, int where, int before, int after) { if (s != mBase) { return; } java.lang.CharSequence text = mDisplay; int len = text.Length; // seek back to the start of the paragraph int find = android.text.TextUtils.lastIndexOf(text, '\n', where - 1); if (find < 0) { find = 0; } else { find = find + 1; } { int diff = where - find; before += diff; after += diff; where -= diff; } // seek forward to the end of the paragraph int look = android.text.TextUtils.indexOf(text, '\n', where + after); if (look < 0) { look = len; } else { look++; } // we want the index after the \n int change = look - (where + after); before += change; after += change; // seek further out to cover anything that is forced to wrap together if (text is android.text.Spanned) { android.text.Spanned sp = (android.text.Spanned)text; bool again; do { again = false; object[] force = sp.getSpans<android.text.style.WrapTogetherSpan>(where, where + after); { for (int i = 0; i < force.Length; i++) { int st = sp.getSpanStart(force[i]); int en = sp.getSpanEnd(force[i]); if (st < where) { again = true; int diff = where - st; before += diff; after += diff; where -= diff; } if (en > where + after) { again = true; int diff = en - (where + after); before += diff; after += diff; } } } } while (again); } // find affected region of old layout int startline = getLineForOffset(where); int startv = getLineTop(startline); int endline = getLineForOffset(where + before); if (where + after == len) { endline = getLineCount(); } int endv = getLineTop(endline); bool islast = (endline == getLineCount()); // generate new layout for affected text android.text.StaticLayout reflowed; lock (sLock) { reflowed = sStaticLayout; sStaticLayout = null; } if (reflowed == null) { reflowed = new android.text.StaticLayout(null); } else { reflowed.prepare(); } reflowed.generate(text, where, where + after, getPaint(), getWidth(), getAlignment (), getTextDirectionHeuristic(), getSpacingMultiplier(), getSpacingAdd(), false, true, mEllipsizedWidth, mEllipsizeAt); int n = reflowed.getLineCount(); // If the new layout has a blank line at the end, but it is not // the very end of the buffer, then we already have a line that // starts there, so disregard the blank line. if (where + after != len && reflowed.getLineStart(n - 1) == where + after) { n--; } // remove affected lines from old layout mInts.deleteAt(startline, endline - startline); mObjects.deleteAt(startline, endline - startline); // adjust offsets in layout for new height and offsets int ht = reflowed.getLineTop(n); int toppad = 0; int botpad = 0; if (mIncludePad && startline == 0) { toppad = reflowed.getTopPadding(); mTopPadding = toppad; ht -= toppad; } if (mIncludePad && islast) { botpad = reflowed.getBottomPadding(); mBottomPadding = botpad; ht += botpad; } mInts.adjustValuesBelow(startline, START, after - before); mInts.adjustValuesBelow(startline, TOP, startv - endv + ht); // insert new layout int[] ints; if (mEllipsize) { ints = new int[COLUMNS_ELLIPSIZE]; ints[ELLIPSIS_START] = ELLIPSIS_UNDEFINED; } else { ints = new int[COLUMNS_NORMAL]; } android.text.Layout.Directions[] objects = new android.text.Layout.Directions[1]; { for (int i_1 = 0; i_1 < n; i_1++) { ints[START] = reflowed.getLineStart(i_1) | (reflowed.getParagraphDirection(i_1) << DIR_SHIFT) | (reflowed.getLineContainsTab(i_1) ? TAB_MASK : 0); int top = reflowed.getLineTop(i_1) + startv; if (i_1 > 0) { top -= toppad; } ints[TOP] = top; int desc = reflowed.getLineDescent(i_1); if (i_1 == n - 1) { desc += botpad; } ints[DESCENT] = desc; objects[0] = reflowed.getLineDirections(i_1); if (mEllipsize) { ints[ELLIPSIS_START] = reflowed.getEllipsisStart(i_1); ints[ELLIPSIS_COUNT] = reflowed.getEllipsisCount(i_1); } mInts.insertAt(startline + i_1, ints); mObjects.insertAt(startline + i_1, objects); } } lock (sLock) { sStaticLayout = reflowed; reflowed.finish(); } }