873 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			873 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package androidx.constraintlayout.utils.widget;
 | |
| 
 | |
| import android.content.Context;
 | |
| import android.content.res.TypedArray;
 | |
| import android.graphics.Bitmap;
 | |
| import android.graphics.BitmapShader;
 | |
| import android.graphics.Canvas;
 | |
| import android.graphics.Matrix;
 | |
| import android.graphics.Outline;
 | |
| import android.graphics.Paint;
 | |
| import android.graphics.Path;
 | |
| import android.graphics.Rect;
 | |
| import android.graphics.RectF;
 | |
| import android.graphics.Shader;
 | |
| import android.graphics.Typeface;
 | |
| import android.graphics.drawable.Drawable;
 | |
| import android.text.Layout;
 | |
| import android.text.TextPaint;
 | |
| import android.util.AttributeSet;
 | |
| import android.util.Log;
 | |
| import android.util.TypedValue;
 | |
| import android.view.View;
 | |
| import android.view.ViewOutlineProvider;
 | |
| import androidx.constraintlayout.core.widgets.analyzer.BasicMeasure;
 | |
| import androidx.constraintlayout.motion.widget.Debug;
 | |
| import androidx.constraintlayout.motion.widget.FloatLayout;
 | |
| import androidx.constraintlayout.widget.R;
 | |
| import androidx.core.internal.view.SupportMenu;
 | |
| import androidx.core.view.GravityCompat;
 | |
| 
 | |
| /* loaded from: classes.dex */
 | |
| public class MotionLabel extends View implements FloatLayout {
 | |
|     private static final int MONOSPACE = 3;
 | |
|     private static final int SANS = 1;
 | |
|     private static final int SERIF = 2;
 | |
|     static String TAG = "MotionLabel";
 | |
|     private boolean mAutoSize;
 | |
|     private int mAutoSizeTextType;
 | |
|     float mBackgroundPanX;
 | |
|     float mBackgroundPanY;
 | |
|     private float mBaseTextSize;
 | |
|     private float mDeltaLeft;
 | |
|     private float mFloatHeight;
 | |
|     private float mFloatWidth;
 | |
|     private String mFontFamily;
 | |
|     private int mGravity;
 | |
|     private Layout mLayout;
 | |
|     boolean mNotBuilt;
 | |
|     Matrix mOutlinePositionMatrix;
 | |
|     private int mPaddingBottom;
 | |
|     private int mPaddingLeft;
 | |
|     private int mPaddingRight;
 | |
|     private int mPaddingTop;
 | |
|     TextPaint mPaint;
 | |
|     Path mPath;
 | |
|     RectF mRect;
 | |
|     float mRotate;
 | |
|     private float mRound;
 | |
|     private float mRoundPercent;
 | |
|     private int mStyleIndex;
 | |
|     Paint mTempPaint;
 | |
|     Rect mTempRect;
 | |
|     private String mText;
 | |
|     private Drawable mTextBackground;
 | |
|     private Bitmap mTextBackgroundBitmap;
 | |
|     private Rect mTextBounds;
 | |
|     private int mTextFillColor;
 | |
|     private int mTextOutlineColor;
 | |
|     private float mTextOutlineThickness;
 | |
|     private float mTextPanX;
 | |
|     private float mTextPanY;
 | |
|     private BitmapShader mTextShader;
 | |
|     private Matrix mTextShaderMatrix;
 | |
|     private float mTextSize;
 | |
|     private int mTextureEffect;
 | |
|     private float mTextureHeight;
 | |
|     private float mTextureWidth;
 | |
|     private CharSequence mTransformed;
 | |
|     private int mTypefaceIndex;
 | |
|     private boolean mUseOutline;
 | |
|     ViewOutlineProvider mViewOutlineProvider;
 | |
|     float mZoom;
 | |
|     Paint paintCache;
 | |
|     float paintTextSize;
 | |
| 
 | |
|     public float getRound() {
 | |
|         return this.mRound;
 | |
|     }
 | |
| 
 | |
|     public float getRoundPercent() {
 | |
|         return this.mRoundPercent;
 | |
|     }
 | |
| 
 | |
|     public float getScaleFromTextSize() {
 | |
|         return this.mBaseTextSize;
 | |
|     }
 | |
| 
 | |
|     public float getTextBackgroundPanX() {
 | |
|         return this.mBackgroundPanX;
 | |
|     }
 | |
| 
 | |
|     public float getTextBackgroundPanY() {
 | |
|         return this.mBackgroundPanY;
 | |
|     }
 | |
| 
 | |
|     public float getTextBackgroundRotate() {
 | |
|         return this.mRotate;
 | |
|     }
 | |
| 
 | |
|     public float getTextBackgroundZoom() {
 | |
|         return this.mZoom;
 | |
|     }
 | |
| 
 | |
|     public int getTextOutlineColor() {
 | |
|         return this.mTextOutlineColor;
 | |
|     }
 | |
| 
 | |
|     public float getTextPanX() {
 | |
|         return this.mTextPanX;
 | |
|     }
 | |
| 
 | |
|     public float getTextPanY() {
 | |
|         return this.mTextPanY;
 | |
|     }
 | |
| 
 | |
|     public float getTextureHeight() {
 | |
|         return this.mTextureHeight;
 | |
|     }
 | |
| 
 | |
|     public float getTextureWidth() {
 | |
|         return this.mTextureWidth;
 | |
|     }
 | |
| 
 | |
|     public void setScaleFromTextSize(float size) {
 | |
|         this.mBaseTextSize = size;
 | |
|     }
 | |
| 
 | |
|     public MotionLabel(Context context) {
 | |
|         super(context);
 | |
|         this.mPaint = new TextPaint();
 | |
|         this.mPath = new Path();
 | |
|         this.mTextFillColor = SupportMenu.USER_MASK;
 | |
|         this.mTextOutlineColor = SupportMenu.USER_MASK;
 | |
|         this.mUseOutline = false;
 | |
|         this.mRoundPercent = 0.0f;
 | |
|         this.mRound = Float.NaN;
 | |
|         this.mTextSize = 48.0f;
 | |
|         this.mBaseTextSize = Float.NaN;
 | |
|         this.mTextOutlineThickness = 0.0f;
 | |
|         this.mText = "Hello World";
 | |
|         this.mNotBuilt = true;
 | |
|         this.mTextBounds = new Rect();
 | |
|         this.mPaddingLeft = 1;
 | |
|         this.mPaddingRight = 1;
 | |
|         this.mPaddingTop = 1;
 | |
|         this.mPaddingBottom = 1;
 | |
|         this.mGravity = 8388659;
 | |
|         this.mAutoSizeTextType = 0;
 | |
|         this.mAutoSize = false;
 | |
|         this.mTextureHeight = Float.NaN;
 | |
|         this.mTextureWidth = Float.NaN;
 | |
|         this.mTextPanX = 0.0f;
 | |
|         this.mTextPanY = 0.0f;
 | |
|         this.paintCache = new Paint();
 | |
|         this.mTextureEffect = 0;
 | |
|         this.mBackgroundPanX = Float.NaN;
 | |
|         this.mBackgroundPanY = Float.NaN;
 | |
|         this.mZoom = Float.NaN;
 | |
|         this.mRotate = Float.NaN;
 | |
|         init(context, null);
 | |
|     }
 | |
| 
 | |
|     public MotionLabel(Context context, AttributeSet attrs) {
 | |
|         super(context, attrs);
 | |
|         this.mPaint = new TextPaint();
 | |
|         this.mPath = new Path();
 | |
|         this.mTextFillColor = SupportMenu.USER_MASK;
 | |
|         this.mTextOutlineColor = SupportMenu.USER_MASK;
 | |
|         this.mUseOutline = false;
 | |
|         this.mRoundPercent = 0.0f;
 | |
|         this.mRound = Float.NaN;
 | |
|         this.mTextSize = 48.0f;
 | |
|         this.mBaseTextSize = Float.NaN;
 | |
|         this.mTextOutlineThickness = 0.0f;
 | |
|         this.mText = "Hello World";
 | |
|         this.mNotBuilt = true;
 | |
|         this.mTextBounds = new Rect();
 | |
|         this.mPaddingLeft = 1;
 | |
|         this.mPaddingRight = 1;
 | |
|         this.mPaddingTop = 1;
 | |
|         this.mPaddingBottom = 1;
 | |
|         this.mGravity = 8388659;
 | |
|         this.mAutoSizeTextType = 0;
 | |
|         this.mAutoSize = false;
 | |
|         this.mTextureHeight = Float.NaN;
 | |
|         this.mTextureWidth = Float.NaN;
 | |
|         this.mTextPanX = 0.0f;
 | |
|         this.mTextPanY = 0.0f;
 | |
|         this.paintCache = new Paint();
 | |
|         this.mTextureEffect = 0;
 | |
|         this.mBackgroundPanX = Float.NaN;
 | |
|         this.mBackgroundPanY = Float.NaN;
 | |
|         this.mZoom = Float.NaN;
 | |
|         this.mRotate = Float.NaN;
 | |
|         init(context, attrs);
 | |
|     }
 | |
| 
 | |
|     public MotionLabel(Context context, AttributeSet attrs, int defStyleAttr) {
 | |
|         super(context, attrs, defStyleAttr);
 | |
|         this.mPaint = new TextPaint();
 | |
|         this.mPath = new Path();
 | |
|         this.mTextFillColor = SupportMenu.USER_MASK;
 | |
|         this.mTextOutlineColor = SupportMenu.USER_MASK;
 | |
|         this.mUseOutline = false;
 | |
|         this.mRoundPercent = 0.0f;
 | |
|         this.mRound = Float.NaN;
 | |
|         this.mTextSize = 48.0f;
 | |
|         this.mBaseTextSize = Float.NaN;
 | |
|         this.mTextOutlineThickness = 0.0f;
 | |
|         this.mText = "Hello World";
 | |
|         this.mNotBuilt = true;
 | |
|         this.mTextBounds = new Rect();
 | |
|         this.mPaddingLeft = 1;
 | |
|         this.mPaddingRight = 1;
 | |
|         this.mPaddingTop = 1;
 | |
|         this.mPaddingBottom = 1;
 | |
|         this.mGravity = 8388659;
 | |
|         this.mAutoSizeTextType = 0;
 | |
|         this.mAutoSize = false;
 | |
|         this.mTextureHeight = Float.NaN;
 | |
|         this.mTextureWidth = Float.NaN;
 | |
|         this.mTextPanX = 0.0f;
 | |
|         this.mTextPanY = 0.0f;
 | |
|         this.paintCache = new Paint();
 | |
|         this.mTextureEffect = 0;
 | |
|         this.mBackgroundPanX = Float.NaN;
 | |
|         this.mBackgroundPanY = Float.NaN;
 | |
|         this.mZoom = Float.NaN;
 | |
|         this.mRotate = Float.NaN;
 | |
|         init(context, attrs);
 | |
|     }
 | |
| 
 | |
|     private void init(Context context, AttributeSet attrs) {
 | |
|         setUpTheme(context, attrs);
 | |
|         if (attrs != null) {
 | |
|             TypedArray obtainStyledAttributes = getContext().obtainStyledAttributes(attrs, R.styleable.MotionLabel);
 | |
|             int indexCount = obtainStyledAttributes.getIndexCount();
 | |
|             for (int i = 0; i < indexCount; i++) {
 | |
|                 int index = obtainStyledAttributes.getIndex(i);
 | |
|                 if (index == R.styleable.MotionLabel_android_text) {
 | |
|                     setText(obtainStyledAttributes.getText(index));
 | |
|                 } else if (index == R.styleable.MotionLabel_android_fontFamily) {
 | |
|                     this.mFontFamily = obtainStyledAttributes.getString(index);
 | |
|                 } else if (index == R.styleable.MotionLabel_scaleFromTextSize) {
 | |
|                     this.mBaseTextSize = obtainStyledAttributes.getDimensionPixelSize(index, (int) this.mBaseTextSize);
 | |
|                 } else if (index == R.styleable.MotionLabel_android_textSize) {
 | |
|                     this.mTextSize = obtainStyledAttributes.getDimensionPixelSize(index, (int) this.mTextSize);
 | |
|                 } else if (index == R.styleable.MotionLabel_android_textStyle) {
 | |
|                     this.mStyleIndex = obtainStyledAttributes.getInt(index, this.mStyleIndex);
 | |
|                 } else if (index == R.styleable.MotionLabel_android_typeface) {
 | |
|                     this.mTypefaceIndex = obtainStyledAttributes.getInt(index, this.mTypefaceIndex);
 | |
|                 } else if (index == R.styleable.MotionLabel_android_textColor) {
 | |
|                     this.mTextFillColor = obtainStyledAttributes.getColor(index, this.mTextFillColor);
 | |
|                 } else if (index == R.styleable.MotionLabel_borderRound) {
 | |
|                     this.mRound = obtainStyledAttributes.getDimension(index, this.mRound);
 | |
|                     setRound(this.mRound);
 | |
|                 } else if (index == R.styleable.MotionLabel_borderRoundPercent) {
 | |
|                     this.mRoundPercent = obtainStyledAttributes.getFloat(index, this.mRoundPercent);
 | |
|                     setRoundPercent(this.mRoundPercent);
 | |
|                 } else if (index == R.styleable.MotionLabel_android_gravity) {
 | |
|                     setGravity(obtainStyledAttributes.getInt(index, -1));
 | |
|                 } else if (index == R.styleable.MotionLabel_android_autoSizeTextType) {
 | |
|                     this.mAutoSizeTextType = obtainStyledAttributes.getInt(index, 0);
 | |
|                 } else if (index == R.styleable.MotionLabel_textOutlineColor) {
 | |
|                     this.mTextOutlineColor = obtainStyledAttributes.getInt(index, this.mTextOutlineColor);
 | |
|                     this.mUseOutline = true;
 | |
|                 } else if (index == R.styleable.MotionLabel_textOutlineThickness) {
 | |
|                     this.mTextOutlineThickness = obtainStyledAttributes.getDimension(index, this.mTextOutlineThickness);
 | |
|                     this.mUseOutline = true;
 | |
|                 } else if (index == R.styleable.MotionLabel_textBackground) {
 | |
|                     this.mTextBackground = obtainStyledAttributes.getDrawable(index);
 | |
|                     this.mUseOutline = true;
 | |
|                 } else if (index == R.styleable.MotionLabel_textBackgroundPanX) {
 | |
|                     this.mBackgroundPanX = obtainStyledAttributes.getFloat(index, this.mBackgroundPanX);
 | |
|                 } else if (index == R.styleable.MotionLabel_textBackgroundPanY) {
 | |
|                     this.mBackgroundPanY = obtainStyledAttributes.getFloat(index, this.mBackgroundPanY);
 | |
|                 } else if (index == R.styleable.MotionLabel_textPanX) {
 | |
|                     this.mTextPanX = obtainStyledAttributes.getFloat(index, this.mTextPanX);
 | |
|                 } else if (index == R.styleable.MotionLabel_textPanY) {
 | |
|                     this.mTextPanY = obtainStyledAttributes.getFloat(index, this.mTextPanY);
 | |
|                 } else if (index == R.styleable.MotionLabel_textBackgroundRotate) {
 | |
|                     this.mRotate = obtainStyledAttributes.getFloat(index, this.mRotate);
 | |
|                 } else if (index == R.styleable.MotionLabel_textBackgroundZoom) {
 | |
|                     this.mZoom = obtainStyledAttributes.getFloat(index, this.mZoom);
 | |
|                 } else if (index == R.styleable.MotionLabel_textureHeight) {
 | |
|                     this.mTextureHeight = obtainStyledAttributes.getDimension(index, this.mTextureHeight);
 | |
|                 } else if (index == R.styleable.MotionLabel_textureWidth) {
 | |
|                     this.mTextureWidth = obtainStyledAttributes.getDimension(index, this.mTextureWidth);
 | |
|                 } else if (index == R.styleable.MotionLabel_textureEffect) {
 | |
|                     this.mTextureEffect = obtainStyledAttributes.getInt(index, this.mTextureEffect);
 | |
|                 }
 | |
|             }
 | |
|             obtainStyledAttributes.recycle();
 | |
|         }
 | |
|         setupTexture();
 | |
|         setupPath();
 | |
|     }
 | |
| 
 | |
|     Bitmap blur(Bitmap bitmapOriginal, int factor) {
 | |
|         Long.valueOf(System.nanoTime());
 | |
|         int width = bitmapOriginal.getWidth() / 2;
 | |
|         int height = bitmapOriginal.getHeight() / 2;
 | |
|         Bitmap createScaledBitmap = Bitmap.createScaledBitmap(bitmapOriginal, width, height, true);
 | |
|         for (int i = 0; i < factor && width >= 32 && height >= 32; i++) {
 | |
|             width /= 2;
 | |
|             height /= 2;
 | |
|             createScaledBitmap = Bitmap.createScaledBitmap(createScaledBitmap, width, height, true);
 | |
|         }
 | |
|         return createScaledBitmap;
 | |
|     }
 | |
| 
 | |
|     private void setupTexture() {
 | |
|         if (this.mTextBackground != null) {
 | |
|             this.mTextShaderMatrix = new Matrix();
 | |
|             int intrinsicWidth = this.mTextBackground.getIntrinsicWidth();
 | |
|             int intrinsicHeight = this.mTextBackground.getIntrinsicHeight();
 | |
|             if (intrinsicWidth <= 0 && (intrinsicWidth = getWidth()) == 0) {
 | |
|                 intrinsicWidth = Float.isNaN(this.mTextureWidth) ? 128 : (int) this.mTextureWidth;
 | |
|             }
 | |
|             if (intrinsicHeight <= 0 && (intrinsicHeight = getHeight()) == 0) {
 | |
|                 intrinsicHeight = Float.isNaN(this.mTextureHeight) ? 128 : (int) this.mTextureHeight;
 | |
|             }
 | |
|             if (this.mTextureEffect != 0) {
 | |
|                 intrinsicWidth /= 2;
 | |
|                 intrinsicHeight /= 2;
 | |
|             }
 | |
|             this.mTextBackgroundBitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
 | |
|             Canvas canvas = new Canvas(this.mTextBackgroundBitmap);
 | |
|             this.mTextBackground.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
 | |
|             this.mTextBackground.setFilterBitmap(true);
 | |
|             this.mTextBackground.draw(canvas);
 | |
|             if (this.mTextureEffect != 0) {
 | |
|                 this.mTextBackgroundBitmap = blur(this.mTextBackgroundBitmap, 4);
 | |
|             }
 | |
|             this.mTextShader = new BitmapShader(this.mTextBackgroundBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void adjustTexture(float l, float t, float r, float b) {
 | |
|         if (this.mTextShaderMatrix == null) {
 | |
|             return;
 | |
|         }
 | |
|         this.mFloatWidth = r - l;
 | |
|         this.mFloatHeight = b - t;
 | |
|         updateShaderMatrix();
 | |
|     }
 | |
| 
 | |
|     public void setGravity(int gravity) {
 | |
|         if ((gravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
 | |
|             gravity |= GravityCompat.START;
 | |
|         }
 | |
|         if ((gravity & 112) == 0) {
 | |
|             gravity |= 48;
 | |
|         }
 | |
|         if (gravity != this.mGravity) {
 | |
|             invalidate();
 | |
|         }
 | |
|         this.mGravity = gravity;
 | |
|         int i = gravity & 112;
 | |
|         if (i == 48) {
 | |
|             this.mTextPanY = -1.0f;
 | |
|         } else if (i != 80) {
 | |
|             this.mTextPanY = 0.0f;
 | |
|         } else {
 | |
|             this.mTextPanY = 1.0f;
 | |
|         }
 | |
|         int i2 = gravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK;
 | |
|         if (i2 != 3) {
 | |
|             if (i2 != 5) {
 | |
|                 if (i2 != 8388611) {
 | |
|                     if (i2 != 8388613) {
 | |
|                         this.mTextPanX = 0.0f;
 | |
|                         return;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             this.mTextPanX = 1.0f;
 | |
|             return;
 | |
|         }
 | |
|         this.mTextPanX = -1.0f;
 | |
|     }
 | |
| 
 | |
|     private float getHorizontalOffset() {
 | |
|         float f = Float.isNaN(this.mBaseTextSize) ? 1.0f : this.mTextSize / this.mBaseTextSize;
 | |
|         TextPaint textPaint = this.mPaint;
 | |
|         String str = this.mText;
 | |
|         return (((((Float.isNaN(this.mFloatWidth) ? getMeasuredWidth() : this.mFloatWidth) - getPaddingLeft()) - getPaddingRight()) - (f * textPaint.measureText(str, 0, str.length()))) * (this.mTextPanX + 1.0f)) / 2.0f;
 | |
|     }
 | |
| 
 | |
|     private float getVerticalOffset() {
 | |
|         float f = Float.isNaN(this.mBaseTextSize) ? 1.0f : this.mTextSize / this.mBaseTextSize;
 | |
|         Paint.FontMetrics fontMetrics = this.mPaint.getFontMetrics();
 | |
|         return ((((((Float.isNaN(this.mFloatHeight) ? getMeasuredHeight() : this.mFloatHeight) - getPaddingTop()) - getPaddingBottom()) - ((fontMetrics.descent - fontMetrics.ascent) * f)) * (1.0f - this.mTextPanY)) / 2.0f) - (f * fontMetrics.ascent);
 | |
|     }
 | |
| 
 | |
|     private void setUpTheme(Context context, AttributeSet attrs) {
 | |
|         TypedValue typedValue = new TypedValue();
 | |
|         context.getTheme().resolveAttribute(androidx.appcompat.R.attr.colorPrimary, typedValue, true);
 | |
|         TextPaint textPaint = this.mPaint;
 | |
|         int i = typedValue.data;
 | |
|         this.mTextFillColor = i;
 | |
|         textPaint.setColor(i);
 | |
|     }
 | |
| 
 | |
|     public void setText(CharSequence text) {
 | |
|         this.mText = text.toString();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     void setupPath() {
 | |
|         this.mPaddingLeft = getPaddingLeft();
 | |
|         this.mPaddingRight = getPaddingRight();
 | |
|         this.mPaddingTop = getPaddingTop();
 | |
|         this.mPaddingBottom = getPaddingBottom();
 | |
|         setTypefaceFromAttrs(this.mFontFamily, this.mTypefaceIndex, this.mStyleIndex);
 | |
|         this.mPaint.setColor(this.mTextFillColor);
 | |
|         this.mPaint.setStrokeWidth(this.mTextOutlineThickness);
 | |
|         this.mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
 | |
|         this.mPaint.setFlags(128);
 | |
|         setTextSize(this.mTextSize);
 | |
|         this.mPaint.setAntiAlias(true);
 | |
|     }
 | |
| 
 | |
|     void buildShape(float scale) {
 | |
|         if (this.mUseOutline || scale != 1.0f) {
 | |
|             this.mPath.reset();
 | |
|             String str = this.mText;
 | |
|             int length = str.length();
 | |
|             this.mPaint.getTextBounds(str, 0, length, this.mTextBounds);
 | |
|             this.mPaint.getTextPath(str, 0, length, 0.0f, 0.0f, this.mPath);
 | |
|             if (scale != 1.0f) {
 | |
|                 Log.v(TAG, Debug.getLoc() + " scale " + scale);
 | |
|                 Matrix matrix = new Matrix();
 | |
|                 matrix.postScale(scale, scale);
 | |
|                 this.mPath.transform(matrix);
 | |
|             }
 | |
|             Rect rect = this.mTextBounds;
 | |
|             rect.right--;
 | |
|             this.mTextBounds.left++;
 | |
|             this.mTextBounds.bottom++;
 | |
|             Rect rect2 = this.mTextBounds;
 | |
|             rect2.top--;
 | |
|             RectF rectF = new RectF();
 | |
|             rectF.bottom = getHeight();
 | |
|             rectF.right = getWidth();
 | |
|             this.mNotBuilt = false;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Override // android.view.View
 | |
|     public void layout(int l, int t, int r, int b) {
 | |
|         super.layout(l, t, r, b);
 | |
|         boolean isNaN = Float.isNaN(this.mBaseTextSize);
 | |
|         float f = isNaN ? 1.0f : this.mTextSize / this.mBaseTextSize;
 | |
|         this.mFloatWidth = r - l;
 | |
|         this.mFloatHeight = b - t;
 | |
|         if (this.mAutoSize) {
 | |
|             if (this.mTempRect == null) {
 | |
|                 this.mTempPaint = new Paint();
 | |
|                 this.mTempRect = new Rect();
 | |
|                 this.mTempPaint.set(this.mPaint);
 | |
|                 this.paintTextSize = this.mTempPaint.getTextSize();
 | |
|             }
 | |
|             Paint paint = this.mTempPaint;
 | |
|             String str = this.mText;
 | |
|             paint.getTextBounds(str, 0, str.length(), this.mTempRect);
 | |
|             int width = this.mTempRect.width();
 | |
|             int height = (int) (this.mTempRect.height() * 1.3f);
 | |
|             float f2 = (this.mFloatWidth - this.mPaddingRight) - this.mPaddingLeft;
 | |
|             float f3 = (this.mFloatHeight - this.mPaddingBottom) - this.mPaddingTop;
 | |
|             if (isNaN) {
 | |
|                 float f4 = width;
 | |
|                 float f5 = height;
 | |
|                 if (f4 * f3 > f5 * f2) {
 | |
|                     this.mPaint.setTextSize((this.paintTextSize * f2) / f4);
 | |
|                 } else {
 | |
|                     this.mPaint.setTextSize((this.paintTextSize * f3) / f5);
 | |
|                 }
 | |
|             } else {
 | |
|                 float f6 = width;
 | |
|                 float f7 = height;
 | |
|                 f = f6 * f3 > f7 * f2 ? f2 / f6 : f3 / f7;
 | |
|             }
 | |
|         }
 | |
|         if (this.mUseOutline || !isNaN) {
 | |
|             adjustTexture(l, t, r, b);
 | |
|             buildShape(f);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Override // androidx.constraintlayout.motion.widget.FloatLayout
 | |
|     public void layout(float l, float t, float r, float b) {
 | |
|         int i = (int) (l + 0.5f);
 | |
|         this.mDeltaLeft = l - i;
 | |
|         int i2 = (int) (r + 0.5f);
 | |
|         int i3 = i2 - i;
 | |
|         int i4 = (int) (b + 0.5f);
 | |
|         int i5 = (int) (0.5f + t);
 | |
|         int i6 = i4 - i5;
 | |
|         float f = r - l;
 | |
|         this.mFloatWidth = f;
 | |
|         float f2 = b - t;
 | |
|         this.mFloatHeight = f2;
 | |
|         adjustTexture(l, t, r, b);
 | |
|         if (getMeasuredHeight() != i6 || getMeasuredWidth() != i3) {
 | |
|             measure(View.MeasureSpec.makeMeasureSpec(i3, BasicMeasure.EXACTLY), View.MeasureSpec.makeMeasureSpec(i6, BasicMeasure.EXACTLY));
 | |
|             super.layout(i, i5, i2, i4);
 | |
|         } else {
 | |
|             super.layout(i, i5, i2, i4);
 | |
|         }
 | |
|         if (this.mAutoSize) {
 | |
|             if (this.mTempRect == null) {
 | |
|                 this.mTempPaint = new Paint();
 | |
|                 this.mTempRect = new Rect();
 | |
|                 this.mTempPaint.set(this.mPaint);
 | |
|                 this.paintTextSize = this.mTempPaint.getTextSize();
 | |
|             }
 | |
|             this.mFloatWidth = f;
 | |
|             this.mFloatHeight = f2;
 | |
|             Paint paint = this.mTempPaint;
 | |
|             String str = this.mText;
 | |
|             paint.getTextBounds(str, 0, str.length(), this.mTempRect);
 | |
|             float height = this.mTempRect.height() * 1.3f;
 | |
|             float f3 = (f - this.mPaddingRight) - this.mPaddingLeft;
 | |
|             float f4 = (f2 - this.mPaddingBottom) - this.mPaddingTop;
 | |
|             float width = this.mTempRect.width();
 | |
|             if (width * f4 > height * f3) {
 | |
|                 this.mPaint.setTextSize((this.paintTextSize * f3) / width);
 | |
|             } else {
 | |
|                 this.mPaint.setTextSize((this.paintTextSize * f4) / height);
 | |
|             }
 | |
|             if (this.mUseOutline || !Float.isNaN(this.mBaseTextSize)) {
 | |
|                 buildShape(Float.isNaN(this.mBaseTextSize) ? 1.0f : this.mTextSize / this.mBaseTextSize);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Override // android.view.View
 | |
|     protected void onDraw(Canvas canvas) {
 | |
|         float f = Float.isNaN(this.mBaseTextSize) ? 1.0f : this.mTextSize / this.mBaseTextSize;
 | |
|         super.onDraw(canvas);
 | |
|         if (!this.mUseOutline && f == 1.0f) {
 | |
|             canvas.drawText(this.mText, this.mDeltaLeft + this.mPaddingLeft + getHorizontalOffset(), this.mPaddingTop + getVerticalOffset(), this.mPaint);
 | |
|             return;
 | |
|         }
 | |
|         if (this.mNotBuilt) {
 | |
|             buildShape(f);
 | |
|         }
 | |
|         if (this.mOutlinePositionMatrix == null) {
 | |
|             this.mOutlinePositionMatrix = new Matrix();
 | |
|         }
 | |
|         if (this.mUseOutline) {
 | |
|             this.paintCache.set(this.mPaint);
 | |
|             this.mOutlinePositionMatrix.reset();
 | |
|             float horizontalOffset = this.mPaddingLeft + getHorizontalOffset();
 | |
|             float verticalOffset = this.mPaddingTop + getVerticalOffset();
 | |
|             this.mOutlinePositionMatrix.postTranslate(horizontalOffset, verticalOffset);
 | |
|             this.mOutlinePositionMatrix.preScale(f, f);
 | |
|             this.mPath.transform(this.mOutlinePositionMatrix);
 | |
|             if (this.mTextShader != null) {
 | |
|                 this.mPaint.setFilterBitmap(true);
 | |
|                 this.mPaint.setShader(this.mTextShader);
 | |
|             } else {
 | |
|                 this.mPaint.setColor(this.mTextFillColor);
 | |
|             }
 | |
|             this.mPaint.setStyle(Paint.Style.FILL);
 | |
|             this.mPaint.setStrokeWidth(this.mTextOutlineThickness);
 | |
|             canvas.drawPath(this.mPath, this.mPaint);
 | |
|             if (this.mTextShader != null) {
 | |
|                 this.mPaint.setShader(null);
 | |
|             }
 | |
|             this.mPaint.setColor(this.mTextOutlineColor);
 | |
|             this.mPaint.setStyle(Paint.Style.STROKE);
 | |
|             this.mPaint.setStrokeWidth(this.mTextOutlineThickness);
 | |
|             canvas.drawPath(this.mPath, this.mPaint);
 | |
|             this.mOutlinePositionMatrix.reset();
 | |
|             this.mOutlinePositionMatrix.postTranslate(-horizontalOffset, -verticalOffset);
 | |
|             this.mPath.transform(this.mOutlinePositionMatrix);
 | |
|             this.mPaint.set(this.paintCache);
 | |
|             return;
 | |
|         }
 | |
|         float horizontalOffset2 = this.mPaddingLeft + getHorizontalOffset();
 | |
|         float verticalOffset2 = this.mPaddingTop + getVerticalOffset();
 | |
|         this.mOutlinePositionMatrix.reset();
 | |
|         this.mOutlinePositionMatrix.preTranslate(horizontalOffset2, verticalOffset2);
 | |
|         this.mPath.transform(this.mOutlinePositionMatrix);
 | |
|         this.mPaint.setColor(this.mTextFillColor);
 | |
|         this.mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
 | |
|         this.mPaint.setStrokeWidth(this.mTextOutlineThickness);
 | |
|         canvas.drawPath(this.mPath, this.mPaint);
 | |
|         this.mOutlinePositionMatrix.reset();
 | |
|         this.mOutlinePositionMatrix.preTranslate(-horizontalOffset2, -verticalOffset2);
 | |
|         this.mPath.transform(this.mOutlinePositionMatrix);
 | |
|     }
 | |
| 
 | |
|     public void setTextOutlineThickness(float width) {
 | |
|         this.mTextOutlineThickness = width;
 | |
|         this.mUseOutline = true;
 | |
|         if (Float.isNaN(width)) {
 | |
|             this.mTextOutlineThickness = 1.0f;
 | |
|             this.mUseOutline = false;
 | |
|         }
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextFillColor(int color) {
 | |
|         this.mTextFillColor = color;
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextOutlineColor(int color) {
 | |
|         this.mTextOutlineColor = color;
 | |
|         this.mUseOutline = true;
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     private void setTypefaceFromAttrs(String familyName, int typefaceIndex, int styleIndex) {
 | |
|         Typeface typeface;
 | |
|         Typeface create;
 | |
|         if (familyName != null) {
 | |
|             typeface = Typeface.create(familyName, styleIndex);
 | |
|             if (typeface != null) {
 | |
|                 setTypeface(typeface);
 | |
|                 return;
 | |
|             }
 | |
|         } else {
 | |
|             typeface = null;
 | |
|         }
 | |
|         if (typefaceIndex == 1) {
 | |
|             typeface = Typeface.SANS_SERIF;
 | |
|         } else if (typefaceIndex == 2) {
 | |
|             typeface = Typeface.SERIF;
 | |
|         } else if (typefaceIndex == 3) {
 | |
|             typeface = Typeface.MONOSPACE;
 | |
|         }
 | |
|         if (styleIndex > 0) {
 | |
|             if (typeface == null) {
 | |
|                 create = Typeface.defaultFromStyle(styleIndex);
 | |
|             } else {
 | |
|                 create = Typeface.create(typeface, styleIndex);
 | |
|             }
 | |
|             setTypeface(create);
 | |
|             int i = (~(create != null ? create.getStyle() : 0)) & styleIndex;
 | |
|             this.mPaint.setFakeBoldText((i & 1) != 0);
 | |
|             this.mPaint.setTextSkewX((i & 2) != 0 ? -0.25f : 0.0f);
 | |
|             return;
 | |
|         }
 | |
|         this.mPaint.setFakeBoldText(false);
 | |
|         this.mPaint.setTextSkewX(0.0f);
 | |
|         setTypeface(typeface);
 | |
|     }
 | |
| 
 | |
|     public void setTypeface(Typeface tf) {
 | |
|         if (this.mPaint.getTypeface() != tf) {
 | |
|             this.mPaint.setTypeface(tf);
 | |
|             if (this.mLayout != null) {
 | |
|                 this.mLayout = null;
 | |
|                 requestLayout();
 | |
|                 invalidate();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public Typeface getTypeface() {
 | |
|         return this.mPaint.getTypeface();
 | |
|     }
 | |
| 
 | |
|     @Override // android.view.View
 | |
|     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 | |
|         int mode = View.MeasureSpec.getMode(widthMeasureSpec);
 | |
|         int mode2 = View.MeasureSpec.getMode(heightMeasureSpec);
 | |
|         int size = View.MeasureSpec.getSize(widthMeasureSpec);
 | |
|         int size2 = View.MeasureSpec.getSize(heightMeasureSpec);
 | |
|         this.mAutoSize = false;
 | |
|         this.mPaddingLeft = getPaddingLeft();
 | |
|         this.mPaddingRight = getPaddingRight();
 | |
|         this.mPaddingTop = getPaddingTop();
 | |
|         this.mPaddingBottom = getPaddingBottom();
 | |
|         if (mode != 1073741824 || mode2 != 1073741824) {
 | |
|             TextPaint textPaint = this.mPaint;
 | |
|             String str = this.mText;
 | |
|             textPaint.getTextBounds(str, 0, str.length(), this.mTextBounds);
 | |
|             if (mode != 1073741824) {
 | |
|                 size = (int) (this.mTextBounds.width() + 0.99999f);
 | |
|             }
 | |
|             size += this.mPaddingLeft + this.mPaddingRight;
 | |
|             if (mode2 != 1073741824) {
 | |
|                 int fontMetricsInt = (int) (this.mPaint.getFontMetricsInt(null) + 0.99999f);
 | |
|                 if (mode2 == Integer.MIN_VALUE) {
 | |
|                     fontMetricsInt = Math.min(size2, fontMetricsInt);
 | |
|                 }
 | |
|                 size2 = this.mPaddingTop + this.mPaddingBottom + fontMetricsInt;
 | |
|             }
 | |
|         } else if (this.mAutoSizeTextType != 0) {
 | |
|             this.mAutoSize = true;
 | |
|         }
 | |
|         setMeasuredDimension(size, size2);
 | |
|     }
 | |
| 
 | |
|     public void setRoundPercent(float round) {
 | |
|         boolean z = this.mRoundPercent != round;
 | |
|         this.mRoundPercent = round;
 | |
|         if (round != 0.0f) {
 | |
|             if (this.mPath == null) {
 | |
|                 this.mPath = new Path();
 | |
|             }
 | |
|             if (this.mRect == null) {
 | |
|                 this.mRect = new RectF();
 | |
|             }
 | |
|             if (this.mViewOutlineProvider == null) {
 | |
|                 ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() { // from class: androidx.constraintlayout.utils.widget.MotionLabel.1
 | |
|                     @Override // android.view.ViewOutlineProvider
 | |
|                     public void getOutline(View view, Outline outline) {
 | |
|                         outline.setRoundRect(0, 0, MotionLabel.this.getWidth(), MotionLabel.this.getHeight(), (Math.min(r3, r4) * MotionLabel.this.mRoundPercent) / 2.0f);
 | |
|                     }
 | |
|                 };
 | |
|                 this.mViewOutlineProvider = viewOutlineProvider;
 | |
|                 setOutlineProvider(viewOutlineProvider);
 | |
|             }
 | |
|             setClipToOutline(true);
 | |
|             int width = getWidth();
 | |
|             int height = getHeight();
 | |
|             float min = (Math.min(width, height) * this.mRoundPercent) / 2.0f;
 | |
|             this.mRect.set(0.0f, 0.0f, width, height);
 | |
|             this.mPath.reset();
 | |
|             this.mPath.addRoundRect(this.mRect, min, min, Path.Direction.CW);
 | |
|         } else {
 | |
|             setClipToOutline(false);
 | |
|         }
 | |
|         if (z) {
 | |
|             invalidateOutline();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void setRound(float round) {
 | |
|         if (Float.isNaN(round)) {
 | |
|             this.mRound = round;
 | |
|             float f = this.mRoundPercent;
 | |
|             this.mRoundPercent = -1.0f;
 | |
|             setRoundPercent(f);
 | |
|             return;
 | |
|         }
 | |
|         boolean z = this.mRound != round;
 | |
|         this.mRound = round;
 | |
|         if (round != 0.0f) {
 | |
|             if (this.mPath == null) {
 | |
|                 this.mPath = new Path();
 | |
|             }
 | |
|             if (this.mRect == null) {
 | |
|                 this.mRect = new RectF();
 | |
|             }
 | |
|             if (this.mViewOutlineProvider == null) {
 | |
|                 ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() { // from class: androidx.constraintlayout.utils.widget.MotionLabel.2
 | |
|                     @Override // android.view.ViewOutlineProvider
 | |
|                     public void getOutline(View view, Outline outline) {
 | |
|                         outline.setRoundRect(0, 0, MotionLabel.this.getWidth(), MotionLabel.this.getHeight(), MotionLabel.this.mRound);
 | |
|                     }
 | |
|                 };
 | |
|                 this.mViewOutlineProvider = viewOutlineProvider;
 | |
|                 setOutlineProvider(viewOutlineProvider);
 | |
|             }
 | |
|             setClipToOutline(true);
 | |
|             this.mRect.set(0.0f, 0.0f, getWidth(), getHeight());
 | |
|             this.mPath.reset();
 | |
|             Path path = this.mPath;
 | |
|             RectF rectF = this.mRect;
 | |
|             float f2 = this.mRound;
 | |
|             path.addRoundRect(rectF, f2, f2, Path.Direction.CW);
 | |
|         } else {
 | |
|             setClipToOutline(false);
 | |
|         }
 | |
|         if (z) {
 | |
|             invalidateOutline();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void setTextSize(float size) {
 | |
|         this.mTextSize = size;
 | |
|         Log.v(TAG, Debug.getLoc() + "  " + size + " / " + this.mBaseTextSize);
 | |
|         TextPaint textPaint = this.mPaint;
 | |
|         if (!Float.isNaN(this.mBaseTextSize)) {
 | |
|             size = this.mBaseTextSize;
 | |
|         }
 | |
|         textPaint.setTextSize(size);
 | |
|         buildShape(Float.isNaN(this.mBaseTextSize) ? 1.0f : this.mTextSize / this.mBaseTextSize);
 | |
|         requestLayout();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextBackgroundPanX(float pan) {
 | |
|         this.mBackgroundPanX = pan;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextBackgroundPanY(float pan) {
 | |
|         this.mBackgroundPanY = pan;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextBackgroundZoom(float zoom) {
 | |
|         this.mZoom = zoom;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextBackgroundRotate(float rotation) {
 | |
|         this.mRotate = rotation;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     private void updateShaderMatrix() {
 | |
|         float f = Float.isNaN(this.mBackgroundPanX) ? 0.0f : this.mBackgroundPanX;
 | |
|         float f2 = Float.isNaN(this.mBackgroundPanY) ? 0.0f : this.mBackgroundPanY;
 | |
|         float f3 = Float.isNaN(this.mZoom) ? 1.0f : this.mZoom;
 | |
|         float f4 = Float.isNaN(this.mRotate) ? 0.0f : this.mRotate;
 | |
|         this.mTextShaderMatrix.reset();
 | |
|         float width = this.mTextBackgroundBitmap.getWidth();
 | |
|         float height = this.mTextBackgroundBitmap.getHeight();
 | |
|         float f5 = Float.isNaN(this.mTextureWidth) ? this.mFloatWidth : this.mTextureWidth;
 | |
|         float f6 = Float.isNaN(this.mTextureHeight) ? this.mFloatHeight : this.mTextureHeight;
 | |
|         float f7 = f3 * (width * f6 < height * f5 ? f5 / width : f6 / height);
 | |
|         this.mTextShaderMatrix.postScale(f7, f7);
 | |
|         float f8 = width * f7;
 | |
|         float f9 = f5 - f8;
 | |
|         float f10 = f7 * height;
 | |
|         float f11 = f6 - f10;
 | |
|         if (!Float.isNaN(this.mTextureHeight)) {
 | |
|             f11 = this.mTextureHeight / 2.0f;
 | |
|         }
 | |
|         if (!Float.isNaN(this.mTextureWidth)) {
 | |
|             f9 = this.mTextureWidth / 2.0f;
 | |
|         }
 | |
|         this.mTextShaderMatrix.postTranslate((((f * f9) + f5) - f8) * 0.5f, (((f2 * f11) + f6) - f10) * 0.5f);
 | |
|         this.mTextShaderMatrix.postRotate(f4, f5 / 2.0f, f6 / 2.0f);
 | |
|         this.mTextShader.setLocalMatrix(this.mTextShaderMatrix);
 | |
|     }
 | |
| 
 | |
|     public void setTextPanX(float textPanX) {
 | |
|         this.mTextPanX = textPanX;
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextPanY(float textPanY) {
 | |
|         this.mTextPanY = textPanY;
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextureHeight(float mTextureHeight) {
 | |
|         this.mTextureHeight = mTextureHeight;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| 
 | |
|     public void setTextureWidth(float mTextureWidth) {
 | |
|         this.mTextureWidth = mTextureWidth;
 | |
|         updateShaderMatrix();
 | |
|         invalidate();
 | |
|     }
 | |
| }
 |