/// <summary> /// Make a layout for the transformed text (password transformation /// being the primary example of a transformation) /// that will be updated as the base text is changed. /// </summary> /// <remarks> /// Make a layout for the transformed text (password transformation /// being the primary example of a transformation) /// that will be updated as the base text is changed. /// If ellipsize is non-null, the Layout will ellipsize the text /// down to ellipsizedWidth. /// * /// *@hide /// </remarks> public DynamicLayout(java.lang.CharSequence @base, java.lang.CharSequence display , android.text.TextPaint paint, int width, android.text.Layout.Alignment?align, android.text.TextDirectionHeuristic textDir, float spacingmult, float spacingadd , bool includepad, android.text.TextUtils.TruncateAt?ellipsize_1, int ellipsizedWidth ) : base((ellipsize_1 == null) ? display : (display is android.text.Spanned) ? new android.text.Layout.SpannedEllipsizer(display) : new android.text.Layout.Ellipsizer (display), paint, width, align, textDir, spacingmult, spacingadd) { mBase = @base; mDisplay = display; if (ellipsize_1 != null) { mInts = new android.text.PackedIntVector(COLUMNS_ELLIPSIZE); mEllipsizedWidth = ellipsizedWidth; mEllipsizeAt = ellipsize_1; } else { mInts = new android.text.PackedIntVector(COLUMNS_NORMAL); mEllipsizedWidth = width; mEllipsizeAt = null; } mObjects = new android.text.PackedObjectVector <android.text.Layout.Directions>(1); mIncludePad = includepad; if (ellipsize_1 != null) { android.text.Layout.Ellipsizer e = (android.text.Layout.Ellipsizer)getText(); e.mLayout = this; e.mWidth = ellipsizedWidth; e.mMethod = ellipsize_1; mEllipsize = true; } // Initial state is a single line with 0 characters (0 to 0), // with top at 0 and bottom at whatever is natural, and // undefined ellipsis. int[] start; if (ellipsize_1 != null) { start = new int[COLUMNS_ELLIPSIZE]; start[ELLIPSIS_START] = ELLIPSIS_UNDEFINED; } else { start = new int[COLUMNS_NORMAL]; } android.text.Layout.Directions[] dirs = new android.text.Layout.Directions[] { DIRS_ALL_LEFT_TO_RIGHT }; android.graphics.Paint.FontMetricsInt fm = paint.getFontMetricsInt(); int asc = fm.ascent; int desc = fm.descent; start[DIR] = DIR_LEFT_TO_RIGHT << DIR_SHIFT; start[TOP] = 0; start[DESCENT] = desc; mInts.insertAt(0, start); start[TOP] = desc - asc; mInts.insertAt(1, start); mObjects.insertAt(0, dirs); // Update from 0 characters to whatever the real text is reflow(@base, 0, 0, @base.Length); if (@base is android.text.Spannable) { if (mWatcher == null) { mWatcher = new android.text.DynamicLayout.ChangeWatcher(this); } // Strip out any watchers for other DynamicLayouts. android.text.Spannable sp = (android.text.Spannable)@base; android.text.DynamicLayout.ChangeWatcher[] spans = sp.getSpans <android.text.DynamicLayout .ChangeWatcher>(0, sp.Length); { for (int i = 0; i < spans.Length; i++) { sp.removeSpan(spans[i]); } } sp.setSpan(mWatcher, 0, @base.Length, android.text.SpannedClass.SPAN_INCLUSIVE_INCLUSIVE | (PRIORITY << android.text.SpannedClass.SPAN_PRIORITY_SHIFT)); } }
/// <summary> /// Returns null if not boring; the width, ascent, and descent in the /// provided Metrics object (or a new one if the provided one was null) /// if boring. /// </summary> /// <remarks> /// Returns null if not boring; the width, ascent, and descent in the /// provided Metrics object (or a new one if the provided one was null) /// if boring. /// </remarks> /// <hide></hide> public static android.text.BoringLayout.Metrics isBoring(java.lang.CharSequence text , android.text.TextPaint paint, android.text.TextDirectionHeuristic textDir, android.text.BoringLayout .Metrics metrics) { char[] temp = android.text.TextUtils.obtain(500); int length = text.Length; bool boring = true; { for (int i = 0; i < length; i += 500) { int j = i + 500; if (j > length) { j = length; } android.text.TextUtils.getChars(text, i, j, temp, 0); int n = j - i; { for (int a = 0; a < n; a++) { char c = temp[a]; if (c == '\n' || c == '\t' || c >= FIRST_RIGHT_TO_LEFT) { boring = false; goto outer_break; } } } if (textDir != null && textDir.isRtl(temp, 0, n)) { boring = false; goto outer_break; } } outer_continue :; } outer_break :; android.text.TextUtils.recycle(temp); if (boring && text is android.text.Spanned) { android.text.Spanned sp = (android.text.Spanned)text; object[] styles = sp.getSpans <android.text.style.ParagraphStyle>(0, length); if (styles.Length > 0) { boring = false; } } if (boring) { android.text.BoringLayout.Metrics fm = metrics; if (fm == null) { fm = new android.text.BoringLayout.Metrics(); } android.text.TextLine line = android.text.TextLine.obtain(); line.set(paint, text, 0, length, android.text.Layout.DIR_LEFT_TO_RIGHT, android.text.Layout .DIRS_ALL_LEFT_TO_RIGHT, false, null); fm.width = (int)android.util.FloatMath.ceil(line.metrics(fm)); android.text.TextLine.recycle(line); return(fm); } else { return(null); } }
/// <summary>Analyzes text for bidirectional runs.</summary> /// <remarks>Analyzes text for bidirectional runs. Allocates working buffers.</remarks> internal virtual void setPara(java.lang.CharSequence text, int start, int end, android.text.TextDirectionHeuristic textDir) { mText = text; mTextStart = start; int len = end - start; mLen = len; mPos = 0; if (mWidths == null || mWidths.Length < len) { mWidths = new float[[email protected](len)]; } if (mChars == null || mChars.Length < len) { mChars = new char[[email protected](len)]; } android.text.TextUtils.getChars(text, start, end, mChars, 0); if (text is android.text.Spanned) { android.text.Spanned spanned = (android.text.Spanned)text; android.text.style.ReplacementSpan[] spans = spanned.getSpans <android.text.style.ReplacementSpan >(start, end); { for (int i = 0; i < spans.Length; i++) { int startInPara = spanned.getSpanStart(spans[i]) - start; int endInPara = spanned.getSpanEnd(spans[i]) - start; { for (int j = startInPara; j < endInPara; j++) { mChars[j] = '\uFFFC'; } } } } } if ((textDir == android.text.TextDirectionHeuristics.LTR || textDir == android.text.TextDirectionHeuristics .FIRSTSTRONG_LTR || textDir == android.text.TextDirectionHeuristics.ANYRTL_LTR) && android.text.TextUtils.doesNotNeedBidi(mChars, 0, len)) { mDir = android.text.Layout.DIR_LEFT_TO_RIGHT; mEasy = true; } else { if (mLevels == null || mLevels.Length < len) { mLevels = new byte[[email protected](len)]; } int bidiRequest; if (textDir == android.text.TextDirectionHeuristics.LTR) { bidiRequest = android.text.Layout.DIR_REQUEST_LTR; } else { if (textDir == android.text.TextDirectionHeuristics.RTL) { bidiRequest = android.text.Layout.DIR_REQUEST_RTL; } else { if (textDir == android.text.TextDirectionHeuristics.FIRSTSTRONG_LTR) { bidiRequest = android.text.Layout.DIR_REQUEST_DEFAULT_LTR; } else { if (textDir == android.text.TextDirectionHeuristics.FIRSTSTRONG_RTL) { bidiRequest = android.text.Layout.DIR_REQUEST_DEFAULT_RTL; } else { bool isRtl = textDir.isRtl(mChars, 0, len); bidiRequest = isRtl ? android.text.Layout.DIR_REQUEST_RTL : android.text.Layout.DIR_REQUEST_LTR; } } } } mDir = android.text.AndroidBidi.bidi(bidiRequest, mChars, mLevels, len, false); mEasy = false; } }
/// <summary>Returns null if not boring; the width, ascent, and descent if boring.</summary> /// <remarks>Returns null if not boring; the width, ascent, and descent if boring.</remarks> /// <hide></hide> public static android.text.BoringLayout.Metrics isBoring(java.lang.CharSequence text , android.text.TextPaint paint, android.text.TextDirectionHeuristic textDir) { return(isBoring(text, paint, textDir, null)); }