下面列出了android.text.TextPaint#getFontMetrics ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Constructs the generator and initializes the common members ignoring display density.
*
* @param iconWidthPx The width of the generated icon in pixels.
* @param iconHeightPx The height of the generated icon in pixels.
* @param cornerRadiusPx The radius of the corners in the icon in pixels.
* @param backgroundColor Color at which the rounded rectangle should be drawn.
* @param textSizePx Size at which the text should be drawn in pixels.
*/
public RoundedIconGenerator(int iconWidthPx, int iconHeightPx, int cornerRadiusPx,
int backgroundColor, float textSizePx) {
mIconWidthPx = iconWidthPx;
mIconHeightPx = iconHeightPx;
mCornerRadiusPx = cornerRadiusPx;
mBackgroundRect = new RectF(0, 0, mIconWidthPx, mIconHeightPx);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setColor(backgroundColor);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextSize(textSizePx);
FontMetrics textFontMetrics = mTextPaint.getFontMetrics();
mTextHeight = (float) Math.ceil(textFontMetrics.bottom - textFontMetrics.top);
mTextYOffset = -textFontMetrics.top;
}
private void init(Context context) {
this.context = context;
setBackgroundColor(Color.TRANSPARENT);
// 设置绘制flag的paint
paint = new Paint();
paint.setColor(patientColor);
paint.setAntiAlias(true);
// 设置绘制文字的paint
textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(ABTextUtil.sp2px(context, 12));
textPaint.setTextAlign(Paint.Align.CENTER);
textFontMetrics = textPaint.getFontMetrics();
}
private void init() {
dm = getResources().getDisplayMetrics();
dst_delete = new Rect();
dst_resize = new Rect();
dst_flipV = new Rect();
dst_top = new Rect();
localPaint = new Paint();
localPaint.setColor(getResources().getColor(R.color.red_e73a3d));
localPaint.setAntiAlias(true);
localPaint.setDither(true);
localPaint.setStyle(Paint.Style.STROKE);
localPaint.setStrokeWidth(2.0f);
mScreenwidth = dm.widthPixels;
mScreenHeight = dm.heightPixels;
mFontSize = mDefultSize;
mFontPaint = new TextPaint();
mFontPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mFontSize, dm));
mFontPaint.setColor(fontColor);
mFontPaint.setTextAlign(Paint.Align.CENTER);
mFontPaint.setAntiAlias(true);
fm = mFontPaint.getFontMetrics();
baseline = fm.descent - fm.ascent;
isInit = true;
mStr = defaultStr;
}
public TMReminderTagsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (mDensity == -1) {
initWith(context);
}
textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.rgb(255, 59, 68));
textPaint.setTextSize(dp2px(10));
bgPaint = new Paint();
bgPaint.setColor(Color.rgb(250, 211, 213));
tagsGap = dp2px(7);
hPadding = dp2px(3);
tagRect = new Rect();
textFontMetrics = textPaint.getFontMetrics();
}
/**
* Constructs the generator and initializes the common members ignoring display density.
*
* @param iconWidthPx The width of the generated icon in pixels.
* @param iconHeightPx The height of the generated icon in pixels.
* @param cornerRadiusPx The radius of the corners in the icon in pixels.
* @param backgroundColor Color at which the rounded rectangle should be drawn.
* @param textSizePx Size at which the text should be drawn in pixels.
*/
public RoundedIconGenerator(int iconWidthPx, int iconHeightPx, int cornerRadiusPx,
int backgroundColor, float textSizePx) {
mIconWidthPx = iconWidthPx;
mIconHeightPx = iconHeightPx;
mCornerRadiusPx = cornerRadiusPx;
mBackgroundRect = new RectF(0, 0, mIconWidthPx, mIconHeightPx);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setColor(backgroundColor);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextSize(textSizePx);
FontMetrics textFontMetrics = mTextPaint.getFontMetrics();
mTextHeight = (float) Math.ceil(textFontMetrics.bottom - textFontMetrics.top);
mTextYOffset = -textFontMetrics.top;
}
public void setLrcRow(@NonNull LrcRow lrcRow) {
if (lrcRow.getTime() != 0 && mCurLrcRow != null && mCurLrcRow.getTime() == lrcRow.getTime()) {
return;
}
mCurLrcRow = lrcRow;
stopAnimation();
// setText(mCurLrcRow.getContent());
TextPaint paint = getPaint();
if (paint == null) {
return;
}
String text = mCurLrcRow.getContent();
paint.getTextBounds(text, 0, text.length(), mTextRect);
float textWidth = mTextRect.width();
mOffsetY = (int) ((mTextRect.bottom + mTextRect.top - paint.getFontMetrics().bottom - paint
.getFontMetrics().top) / 2);
if (textWidth > getWidth()) {
//如果歌词宽度大于view的宽,则需要动态设置歌词的起始x坐标,以实现水平滚动
startScrollLrc(getWidth() - textWidth, (long) (mCurLrcRow.getTotalTime() * 0.85));
} else {
//如果歌词宽度小于view的宽,则让歌词居中显示
mCurTextXForHighLightLrc = (getWidth() - textWidth) / 2;
invalidate();
}
}
/**
* @param context The current Android's context.
* @param incognito Whether the title are for incognito mode.
* @param nullFaviconResourceId A drawable resource id of a default favicon.
*/
public TitleBitmapFactory(Context context, boolean incognito, int nullFaviconResourceId) {
mNullFaviconResourceId = nullFaviconResourceId;
Resources res = context.getResources();
int textColor = ApiCompatibilityUtils.getColor(res, incognito
? R.color.compositor_tab_title_bar_text_incognito
: R.color.compositor_tab_title_bar_text);
float textSize = res.getDimension(R.dimen.compositor_tab_title_text_size);
boolean fakeBoldText = res.getBoolean(R.bool.compositor_tab_title_fake_bold_text);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(textColor);
mTextPaint.setTextSize(textSize);
mTextPaint.setFakeBoldText(fakeBoldText);
mTextPaint.density = res.getDisplayMetrics().density;
FontMetrics textFontMetrics = mTextPaint.getFontMetrics();
mTextHeight = (float) Math.ceil(textFontMetrics.bottom - textFontMetrics.top);
mTextYOffset = -textFontMetrics.top;
mFaviconDimension = res.getDimensionPixelSize(R.dimen.compositor_tab_title_favicon_size);
mViewHeight = (int) Math.max(mFaviconDimension, mTextHeight);
int width = res.getDisplayMetrics().widthPixels;
int height = res.getDisplayMetrics().heightPixels;
mMaxWidth = (int) (TITLE_WIDTH_PERCENTAGE * Math.max(width, height));
// Set the favicon dimension here.
mFaviconDimension = Math.min(mMaxWidth, mFaviconDimension);
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
.getSpacingAdd());
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart,
lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
mLineY += textHeight;
}
}
public static Bitmap generateBitmap(String text,int textSizePx,int textColor){
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(textSizePx);
textPaint.setColor(textColor);
int width = (int) Math.ceil(textPaint.measureText(text));
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
int height = (int) Math.ceil(Math.abs(fontMetrics.bottom) + Math.abs(fontMetrics.top));
Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text,0,Math.abs(fontMetrics.ascent),textPaint);
return bitmap;
}
private void initView()
{
mPaint = new TextPaint();
mPaint.setTextSize(mTextSize);
mPaint.setTextAlign(Align.CENTER);
mPaint.setAntiAlias(true);
// 计算字体高度
FontMetrics fm = mPaint.getFontMetrics();
mTextHeight = (int) (fm.bottom - fm.top);
// 滚动动画
mLineAnimator = new ValueAnimator();
mLineAnimator.setIntValues(0, 100);
mLineAnimator.setDuration(mLineAnimDuration);
mLineAnimator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
int value = (Integer) animation.getAnimatedValue();
float percent = 1 - (float) value / 100;
mLineOffset = (int) (mAnimOffset * percent); // 更新偏移值,重绘View
invalidate();
}
});
}
private int getTextOffsetY(TextPaint paint, int gravity) {
int height = (int) (paint.getFontMetrics().descent - paint.getFontMetrics().ascent);
int offset = (int) (paint.getFontMetrics().descent + paint.getFontMetrics().ascent) / 2;
if ((gravity & Gravity.CENTER_VERTICAL) != 0) {
offset += height / 2;
} else if ((gravity & Gravity.BOTTOM) != 0) {
offset += height;
}
return offset;
}
public GestureUnlockView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GestureUnlockView, defStyleAttr, 0);
lines = a.getInteger(R.styleable.GestureUnlockView_guvLines, 3);
columns = a.getInteger(R.styleable.GestureUnlockView_guvColumns, 3);
radius = a.getDimensionPixelSize(R.styleable.GestureUnlockView_guvRadius, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 25, getResources().getDisplayMetrics()));
radiusInside = a.getDimensionPixelSize(R.styleable.GestureUnlockView_guvRadiusInside, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()));
circleColor = a.getColor(R.styleable.GestureUnlockView_guvCircleColor, Color.BLACK);
circleColorInside = a.getColor(R.styleable.GestureUnlockView_guvCircleColorInside, Color.GRAY);
circleLineWidth = a.getDimensionPixelOffset(R.styleable.GestureUnlockView_guvCircleLineWidth, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics()));
lineWidth = a.getDimensionPixelOffset(R.styleable.GestureUnlockView_guvLineWidth, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics()));
lineColor = a.getColor(R.styleable.GestureUnlockView_guvLineColor, Color.GRAY);
text = a.getString(R.styleable.GestureUnlockView_guvText);
textSuccess = a.getString(R.styleable.GestureUnlockView_guvTextSuccess);
textFailed = a.getString(R.styleable.GestureUnlockView_guvTextFailed);
textSize = a.getDimensionPixelSize(R.styleable.GestureUnlockView_guvTextSize, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));
textColor = a.getColor(R.styleable.GestureUnlockView_guvTextColor, Color.BLACK);
textPadding = a.getDimensionPixelSize(R.styleable.GestureUnlockView_guvTextPadding, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 55, getResources().getDisplayMetrics()));
padding = a.getDimensionPixelSize(R.styleable.GestureUnlockView_guvPadding, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));
colorSuccess = a.getColor(R.styleable.GestureUnlockView_guvColorSuccess, Color.GREEN);
colorFailed = a.getColor(R.styleable.GestureUnlockView_guvColorFailed, Color.RED);
a.recycle();
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(circleColor);
circlePaint.setStrokeWidth(circleLineWidth);
circlePaint.setStyle(Paint.Style.STROKE);
circleInsidePaint = new Paint();
circleInsidePaint.setAntiAlias(true);
circleInsidePaint.setColor(circleColorInside);
circleInsidePaint.setStyle(Paint.Style.FILL);
linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setColor(lineColor);
linePaint.setStrokeWidth(lineWidth);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeCap(Paint.Cap.ROUND);
linePaint.setStrokeJoin(Paint.Join.ROUND);
textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(textSize);
textPaint.setColor(textColor);
fm = textPaint.getFontMetrics();
fixPath = new Path();
movePath = new Path();
rects = new Rect[lines * columns];
for (int i = 0; i < lines * columns; i++)
rects[i] = new Rect();
pathIndexes = new ArrayList<>(rects.length);
curText = text;
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
// 返回绘制状态的资源ID数组表示视图的当前状态
paint.drawableState = getDrawableState();
// 对View上的内容进行测量后得到的View内容占据的宽度
// 前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);
// 否则你得到的结果和getWidth()得到的结果一样。
mViewWidth = getMeasuredWidth();
// 获取文本
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
// 获取用于显示当前文本的布局
Layout layout = getLayout();
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());
for (int i = 0; i < layout.getLineCount(); i++) {
// 返回文本中的指定行开头的偏移
int lineStart = layout.getLineStart(i);
// 返回文本中的指定行最后一个字符的偏移
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (line.equals("")) {
break;
}
if (i < layout.getLineCount() - 1) {
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
} else {
canvas.drawText(line, 0, mLineY, paint);
}
// 增加行高
mLineY += textHeight;
}
}
public static void drawMultilineText(Canvas c, StaticLayout textLayout,
float x, float y,
TextPaint paint,
MPPointF anchor, float angleDegrees) {
float drawOffsetX = 0.f;
float drawOffsetY = 0.f;
float drawWidth;
float drawHeight;
final float lineHeight = paint.getFontMetrics(mFontMetricsBuffer);
drawWidth = textLayout.getWidth();
drawHeight = textLayout.getLineCount() * lineHeight;
// Android sometimes has pre-padding
drawOffsetX -= mDrawTextRectBuffer.left;
// Android does not snap the bounds to line boundaries,
// and draws from bottom to top.
// And we want to normalize it.
drawOffsetY += drawHeight;
// To have a consistent point of reference, we always draw left-aligned
Paint.Align originalTextAlign = paint.getTextAlign();
paint.setTextAlign(Paint.Align.LEFT);
if (angleDegrees != 0.f) {
// Move the text drawing rect in a way that it always rotates around its center
drawOffsetX -= drawWidth * 0.5f;
drawOffsetY -= drawHeight * 0.5f;
float translateX = x;
float translateY = y;
// Move the "outer" rect relative to the anchor, assuming its centered
if (anchor.x != 0.5f || anchor.y != 0.5f) {
final FSize rotatedSize = getSizeOfRotatedRectangleByDegrees(
drawWidth,
drawHeight,
angleDegrees);
translateX -= rotatedSize.width * (anchor.x - 0.5f);
translateY -= rotatedSize.height * (anchor.y - 0.5f);
FSize.recycleInstance(rotatedSize);
}
c.save();
c.translate(translateX, translateY);
c.rotate(angleDegrees);
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
} else {
if (anchor.x != 0.f || anchor.y != 0.f) {
drawOffsetX -= drawWidth * anchor.x;
drawOffsetY -= drawHeight * anchor.y;
}
drawOffsetX += x;
drawOffsetY += y;
c.save();
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
}
paint.setTextAlign(originalTextAlign);
}
public static void drawMultilineText(Canvas c, StaticLayout textLayout,
float x, float y,
TextPaint paint,
MPPointF anchor, float angleDegrees) {
float drawOffsetX = 0.f;
float drawOffsetY = 0.f;
float drawWidth;
float drawHeight;
final float lineHeight = paint.getFontMetrics(mFontMetricsBuffer);
drawWidth = textLayout.getWidth();
drawHeight = textLayout.getLineCount() * lineHeight;
// Android sometimes has pre-padding
drawOffsetX -= mDrawTextRectBuffer.left;
// Android does not snap the bounds to line boundaries,
// and draws from bottom to top.
// And we want to normalize it.
drawOffsetY += drawHeight;
// To have a consistent point of reference, we always draw left-aligned
Paint.Align originalTextAlign = paint.getTextAlign();
paint.setTextAlign(Paint.Align.LEFT);
if (angleDegrees != 0.f) {
// Move the text drawing rect in a way that it always rotates around its center
drawOffsetX -= drawWidth * 0.5f;
drawOffsetY -= drawHeight * 0.5f;
float translateX = x;
float translateY = y;
// Move the "outer" rect relative to the anchor, assuming its centered
if (anchor.x != 0.5f || anchor.y != 0.5f) {
final FSize rotatedSize = getSizeOfRotatedRectangleByDegrees(
drawWidth,
drawHeight,
angleDegrees);
translateX -= rotatedSize.width * (anchor.x - 0.5f);
translateY -= rotatedSize.height * (anchor.y - 0.5f);
FSize.recycleInstance(rotatedSize);
}
c.save();
c.translate(translateX, translateY);
c.rotate(angleDegrees);
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
} else {
if (anchor.x != 0.f || anchor.y != 0.f) {
drawOffsetX -= drawWidth * anchor.x;
drawOffsetY -= drawHeight * anchor.y;
}
drawOffsetX += x;
drawOffsetY += y;
c.save();
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
}
paint.setTextAlign(originalTextAlign);
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
width = getMeasuredWidth();
Paint.FontMetrics fm = paint.getFontMetrics();
float firstHeight = getTextSize() - (fm.bottom - fm.descent + fm.ascent - fm.top);
int gravity = getGravity();
if ((gravity & 0x1000) == 0) { // 是否垂直居中
firstHeight = firstHeight + (textHeight - firstHeight) / 2;
}
int paddingTop = getPaddingTop();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
width = width - paddingLeft - paddingRight;
for (int i = 0; i < lines.size(); i++) {
float drawY = i * textHeight + firstHeight;
String line = lines.get(i);
// 绘画起始x坐标
float drawSpacingX = paddingLeft;
float gap = (width - paint.measureText(line));
float interval = gap / (line.length() - 1);
// 绘制最后一行
if (tailLines.contains(i)) {
interval = 0;
if (align == Align.ALIGN_CENTER) {
drawSpacingX += gap / 2;
} else if (align == Align.ALIGN_RIGHT) {
drawSpacingX += gap;
}
}
for (int j = 0; j < line.length(); j++) {
float drawX = paint.measureText(line.substring(0, j)) + interval * j;
canvas.drawText(line.substring(j, j + 1), drawX + drawSpacingX, drawY +
paddingTop + textLineSpaceExtra * i, paint);
}
}
}
private Bitmap createChipBitmap(RecipientEntry contact, TextPaint paint, Bitmap icon,
Drawable background) {
if (background == null) {
Log.w(TAG, "Unable to draw a background for the chips as it was never set");
return Bitmap.createBitmap(
(int) mChipHeight * 2, (int) mChipHeight, Bitmap.Config.ARGB_8888);
}
Rect backgroundPadding = new Rect();
background.getPadding(backgroundPadding);
// Ellipsize the text so that it takes AT MOST the entire width of the
// autocomplete text entry area. Make sure to leave space for padding
// on the sides.
int height = (int) mChipHeight;
// Since the icon is a square, it's width is equal to the maximum height it can be inside
// the chip.
int iconWidth = height - backgroundPadding.top - backgroundPadding.bottom;
float[] widths = new float[1];
paint.getTextWidths(" ", widths);
CharSequence ellipsizedText = ellipsizeText(createChipDisplayText(contact), paint,
calculateAvailableWidth() - iconWidth - widths[0] - backgroundPadding.left
- backgroundPadding.right);
int textWidth = (int) paint.measureText(ellipsizedText, 0, ellipsizedText.length());
// Make sure there is a minimum chip width so the user can ALWAYS
// tap a chip without difficulty.
// int width = Math.max(iconWidth * 2, textWidth + (mChipPadding * 2) + iconWidth
// + backgroundPadding.left + backgroundPadding.right);
int width = mIconPadding + icon.getWidth() + textWidth + mFontPadding * 2;
// Create the background of the chip.
Bitmap tmpBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(tmpBitmap);
// Draw the background drawable
background.setBounds(0, 0, width, height);
background.draw(canvas);
// Draw the text vertically aligned
paint.setColor(0xFF5C5C5C);
paint.setAntiAlias(true);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float textY = height / 2 - fontMetrics.descent + (fontMetrics.descent - fontMetrics.ascent) / 2;
getTextYOffset(ellipsizedText.toString(), paint, height);
canvas.drawText(ellipsizedText, 0, ellipsizedText.length(),
mIconPadding + icon.getWidth() + mFontPadding, textY, paint);
if (icon != null) {
// Draw the icon
canvas.drawBitmap(icon, mIconPadding, mChipHeight / 2 - icon.getHeight() / 2, paint);
}
return tmpBitmap;
}
public static void drawMultilineText(Canvas c, StaticLayout textLayout,
float x, float y,
TextPaint paint,
PointF anchor, float angleDegrees) {
float drawOffsetX = 0.f;
float drawOffsetY = 0.f;
float drawWidth;
float drawHeight;
final float lineHeight = paint.getFontMetrics(mFontMetricsBuffer);
drawWidth = textLayout.getWidth();
drawHeight = textLayout.getLineCount() * lineHeight;
// Android sometimes has pre-padding
drawOffsetX -= mDrawTextRectBuffer.left;
// Android does not snap the bounds to line boundaries,
// and draws from bottom to top.
// And we want to normalize it.
drawOffsetY += drawHeight;
// To have a consistent point of reference, we always draw left-aligned
Paint.Align originalTextAlign = paint.getTextAlign();
paint.setTextAlign(Paint.Align.LEFT);
if (angleDegrees != 0.f) {
// Move the text drawing rect in a way that it always rotates around its center
drawOffsetX -= drawWidth * 0.5f;
drawOffsetY -= drawHeight * 0.5f;
float translateX = x;
float translateY = y;
// Move the "outer" rect relative to the anchor, assuming its centered
if (anchor.x != 0.5f || anchor.y != 0.5f) {
final FSize rotatedSize = getSizeOfRotatedRectangleByDegrees(
drawWidth,
drawHeight,
angleDegrees);
translateX -= rotatedSize.width * (anchor.x - 0.5f);
translateY -= rotatedSize.height * (anchor.y - 0.5f);
}
c.save();
c.translate(translateX, translateY);
c.rotate(angleDegrees);
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
}
else {
if (anchor.x != 0.f || anchor.y != 0.f) {
drawOffsetX -= drawWidth * anchor.x;
drawOffsetY -= drawHeight * anchor.y;
}
drawOffsetX += x;
drawOffsetY += y;
c.save();
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
}
paint.setTextAlign(originalTextAlign);
}
public static void drawMultilineText(Canvas c, StaticLayout textLayout,
float x, float y,
TextPaint paint,
PointF anchor, float angleDegrees) {
float drawOffsetX = 0.f;
float drawOffsetY = 0.f;
float drawWidth;
float drawHeight;
final float lineHeight = paint.getFontMetrics(mFontMetricsBuffer);
drawWidth = textLayout.getWidth();
drawHeight = textLayout.getLineCount() * lineHeight;
// Android sometimes has pre-padding
drawOffsetX -= mDrawTextRectBuffer.left;
// Android does not snap the bounds to line boundaries,
// and draws from bottom to top.
// And we want to normalize it.
drawOffsetY += drawHeight;
// To have a consistent point of reference, we always draw left-aligned
Paint.Align originalTextAlign = paint.getTextAlign();
paint.setTextAlign(Paint.Align.LEFT);
if (angleDegrees != 0.f) {
// Move the text drawing rect in a way that it always rotates around its center
drawOffsetX -= drawWidth * 0.5f;
drawOffsetY -= drawHeight * 0.5f;
float translateX = x;
float translateY = y;
// Move the "outer" rect relative to the anchor, assuming its centered
if (anchor.x != 0.5f || anchor.y != 0.5f) {
final FSize rotatedSize = getSizeOfRotatedRectangleByDegrees(
drawWidth,
drawHeight,
angleDegrees);
translateX -= rotatedSize.width * (anchor.x - 0.5f);
translateY -= rotatedSize.height * (anchor.y - 0.5f);
}
c.save();
c.translate(translateX, translateY);
c.rotate(angleDegrees);
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
} else {
if (anchor.x != 0.f || anchor.y != 0.f) {
drawOffsetX -= drawWidth * anchor.x;
drawOffsetY -= drawHeight * anchor.y;
}
drawOffsetX += x;
drawOffsetY += y;
c.save();
c.translate(drawOffsetX, drawOffsetY);
textLayout.draw(c);
c.restore();
}
paint.setTextAlign(originalTextAlign);
}
/**
* @param context The current Android's context.
* @param incognito Whether the title are for incognito mode.
* @param nullFaviconResourceId A drawable resource id of a default favicon.
*/
public TitleBitmapFactory(Context context, boolean incognito, int nullFaviconResourceId) {
mNullFaviconResourceId = nullFaviconResourceId;
Resources res = context.getResources();
int textColor = ApiCompatibilityUtils.getColor(res, incognito
? R.color.compositor_tab_title_bar_text_incognito
: R.color.compositor_tab_title_bar_text);
int shadowColor = ApiCompatibilityUtils.getColor(res, incognito
? R.color.compositor_tab_title_bar_shadow_incognito
: R.color.compositor_tab_title_bar_shadow);
int shadowXOffset = res.getDimensionPixelOffset(incognito
? R.dimen.compositor_tab_title_bar_shadow_x_offset_incognito
: R.dimen.compositor_tab_title_bar_shadow_x_offset);
int shadowYOffset = res.getDimensionPixelOffset(incognito
? R.dimen.compositor_tab_title_bar_shadow_y_offset_incognito
: R.dimen.compositor_tab_title_bar_shadow_y_offset);
float textSize = res.getDimension(R.dimen.compositor_tab_title_text_size);
boolean fakeBoldText = res.getBoolean(R.bool.compositor_tab_title_fake_bold_text);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(textColor);
if (shadowXOffset != 0 && shadowYOffset != 0) {
mTextPaint.setShadowLayer(0.001f, shadowXOffset, shadowYOffset, shadowColor);
}
mTextPaint.setTextSize(textSize);
mTextPaint.setFakeBoldText(fakeBoldText);
mTextPaint.density = res.getDisplayMetrics().density;
FontMetrics textFontMetrics = mTextPaint.getFontMetrics();
mTextHeight = (float) Math.ceil(textFontMetrics.bottom - textFontMetrics.top);
mTextYOffset = -textFontMetrics.top;
mFaviconDimension = res.getDimensionPixelSize(R.dimen.compositor_tab_title_favicon_size);
mViewHeight = (int) Math.max(mFaviconDimension, mTextHeight);
int width = res.getDisplayMetrics().widthPixels;
int height = res.getDisplayMetrics().heightPixels;
mMaxWidth = (int) (TITLE_WIDTH_PERCENTAGE * Math.max(width, height));
// Set the favicon dimension here.
mFaviconDimension = Math.min(mMaxWidth, mFaviconDimension);
}