public void chooseHeight( CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm, TextPaint paint) { int size = mSize; if (paint != null) { size *= paint.density; } if (fm.bottom - fm.top < size) { fm.top = fm.bottom - size; fm.ascent = fm.ascent - size; } else { if (sProportion == 0) { /* * Calculate what fraction of the nominal ascent the height * of a capital letter actually is, so that we won't reduce * the ascent to less than that unless we absolutely have * to. */ Paint p = new Paint(); p.setTextSize(100); Rect r = new Rect(); p.getTextBounds("ABCDEFG", 0, 7, r); sProportion = (r.top) / p.ascent(); } int need = (int) Math.ceil(-fm.top * sProportion); if (size - fm.descent >= need) { /* * It is safe to shrink the ascent this much. */ fm.top = fm.bottom - size; fm.ascent = fm.descent - size; } else if (size >= need) { /* * We can't show all the descent, but we can at least show * all the ascent. */ fm.top = fm.ascent = -need; fm.bottom = fm.descent = fm.top + size; } else { /* * Show as much of the ascent as we can, and no descent. */ fm.top = fm.ascent = -size; fm.bottom = fm.descent = 0; } } }
@Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { if (fm != null) { int cy = (fm.ascent + fm.descent) / 2; fm.ascent = Math.min(fm.ascent, cy - mHeight / 2); fm.descent = Math.max(fm.descent, cy + mHeight / 2); fm.top = Math.min(fm.top, fm.ascent); fm.bottom = Math.max(fm.bottom, fm.descent); } return mWidth; }
@Override public int getSize( Paint paint, CharSequence charSequence, int start, int end, Paint.FontMetricsInt fm) { if (fm != null) { // WTF??? fm.ascent = -Screen.dp(21 + 3); fm.descent = Screen.dp(10 + 3); fm.top = fm.ascent; fm.bottom = fm.descent; } return (int) textPaint.measureText(userText) + Screen.dp(24 + 8); }
@Override public int getSize( Paint paint, CharSequence charSequence, int start, int end, Paint.FontMetricsInt fm) { padding = (int) paint.measureText(" ") / 3; if (fm != null) { fm.ascent = originalMetrics.ascent; fm.descent = originalMetrics.descent; fm.top = originalMetrics.top; fm.bottom = originalMetrics.bottom; } return size + padding * 2; }
@Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { if (fm == null) { fm = new Paint.FontMetricsInt(); } int sz = super.getSize(paint, text, start, end, fm); int offset = AndroidUtilities.dp(6); int w = (fm.bottom - fm.top) / 2; fm.top = -w - offset; fm.bottom = w - offset; fm.ascent = -w - offset; fm.leading = 0; fm.descent = w - offset; return sz; }
public int getSize( Paint paint, CharSequence charSequence, int i, int i2, Paint.FontMetricsInt fm) { prepView(); if (fm != null) { // We need to make sure the layout allots enough space for the view int height = view.getMeasuredHeight(); int need = height - (fm.descent - fm.ascent); if (need > 0) { int ascent = need / 2; // This makes sure the text drawing area will be tall enough for the view fm.descent += need - ascent; fm.ascent -= ascent; fm.bottom += need - ascent; fm.top -= need / 2; } } return view.getRight(); }
/** * Renders and/or measures a directional run of text on a single line. Unlike {@link * #drawUniformRun}, this can render runs that cross style boundaries. Returns the signed advance * width, if requested. * * <p> * * <p>The x position is the leading edge of the text. In a right-to-left paragraph, this will be * to the right of the text to be drawn. Paint should not have an Align value other than LEFT or * positioning will isCancelled confused. * * <p> * * <p>This optimizes for unstyled text and so workPaint might not be modified by this call. * * <p> * * <p>The returned advance width will be < 0 if the paragraph direction is right-to-left. */ private static float drawDirectionalRun( Canvas canvas, CharSequence text, int start, int end, int dir, boolean runIsRtl, float x, int top, int y, int bottom, Paint.FontMetricsInt fmi, TextPaint paint, TextPaint workPaint, boolean needWidth) { // XXX: It looks like all calls to this API match dir and runIsRtl, so // having both parameters is redundant and confusing. // fast path for unstyled text if (!(text instanceof Spanned)) { float ret = 0; if (runIsRtl) { CharSequence tmp = TextUtils.getReverse(text, start, end); // XXX: this assumes getReverse doesn't tweak the length of // the text int tmpend = end - start; if (canvas != null || needWidth) { ret = paint.measureText(tmp, 0, tmpend); } if (canvas != null) { canvas.drawText(tmp, 0, tmpend, x - ret, y, paint); } } else { if (needWidth) { ret = paint.measureText(text, start, end); } if (canvas != null) { canvas.drawText(text, start, end, x, y, paint); } } if (fmi != null) { paint.getFontMetricsInt(fmi); } return ret * dir; // Layout.DIR_RIGHT_TO_LEFT == -1 } float ox = x; int minAscent = 0, maxDescent = 0, minTop = 0, maxBottom = 0; Spanned sp = (Spanned) text; Class<?> division; if (canvas == null) { division = MetricAffectingSpan.class; } else { division = CharacterStyle.class; } int next; for (int i = start; i < end; i = next) { next = sp.nextSpanTransition(i, end, division); // XXX: if dir and runIsRtl were not the same, this would onDraw // spans in the wrong order, but no one appears to call it this // way. x += drawUniformRun( canvas, sp, i, next, dir, runIsRtl, x, top, y, bottom, fmi, paint, workPaint, needWidth || next != end); if (fmi != null) { if (fmi.ascent < minAscent) { minAscent = fmi.ascent; } if (fmi.descent > maxDescent) { maxDescent = fmi.descent; } if (fmi.top < minTop) { minTop = fmi.top; } if (fmi.bottom > maxBottom) { maxBottom = fmi.bottom; } } } if (fmi != null) { if (start == end) { paint.getFontMetricsInt(fmi); } else { fmi.ascent = minAscent; fmi.descent = maxDescent; fmi.top = minTop; fmi.bottom = maxBottom; } } return x - ox; }