From 2adc20fd3034a03aeadebfc0e0cfd9e51ee3a20f Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Fri, 26 Dec 2025 07:58:48 +0100 Subject: [PATCH] Kotlin Fill --- .../github/mikephil/charting/utils/Fill.java | 309 ------------------ .../github/mikephil/charting/utils/Fill.kt | 244 ++++++++++++++ 2 files changed, 244 insertions(+), 309 deletions(-) delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.kt diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.java b/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.java deleted file mode 100644 index 6f18697e7..000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.java +++ /dev/null @@ -1,309 +0,0 @@ -package com.github.mikephil.charting.utils; - -import android.graphics.Canvas; -import android.graphics.LinearGradient; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import static com.github.mikephil.charting.utils.UtilsKtKt.getSDKInt; - -public class Fill { - public enum Type { - EMPTY, COLOR, LINEAR_GRADIENT, DRAWABLE - } - - public enum Direction { - DOWN, UP, RIGHT, LEFT - } - - /** - * the type of fill - */ - private Type mType = Type.EMPTY; - - /** - * the color that is used for filling - */ - @Nullable - private Integer mColor = null; - - private Integer mFinalColor = null; - - /** - * the drawable to be used for filling - */ - @Nullable - protected Drawable mDrawable; - - @Nullable - private int[] mGradientColors; - - @Nullable - private float[] mGradientPositions; - - /** - * transparency used for filling - */ - private int mAlpha = 255; - - public Fill() { - } - - public Fill(int color) { - this.mType = Type.COLOR; - this.mColor = color; - calculateFinalColor(); - } - - public Fill(int startColor, int endColor) { - this.mType = Type.LINEAR_GRADIENT; - this.mGradientColors = new int[]{startColor, endColor}; - } - - public Fill(@NonNull int[] gradientColors) { - this.mType = Type.LINEAR_GRADIENT; - this.mGradientColors = gradientColors; - } - - public Fill(@NonNull int[] gradientColors, @NonNull float[] gradientPositions) { - this.mType = Type.LINEAR_GRADIENT; - this.mGradientColors = gradientColors; - this.mGradientPositions = gradientPositions; - } - - public Fill(@NonNull Drawable drawable) { - this.mType = Type.DRAWABLE; - this.mDrawable = drawable; - } - - public Type getType() { - return mType; - } - - public void setType(Type type) { - this.mType = type; - } - - @Nullable - public Integer getColor() { - return mColor; - } - - public void setColor(int color) { - this.mColor = color; - calculateFinalColor(); - } - - public int[] getGradientColors() { - return mGradientColors; - } - - public void setGradientColors(int[] colors) { - this.mGradientColors = colors; - } - - public float[] getGradientPositions() { - return mGradientPositions; - } - - public void setGradientPositions(float[] positions) { - this.mGradientPositions = positions; - } - - public void setGradientColors(int startColor, int endColor) { - this.mGradientColors = new int[]{startColor, endColor}; - } - - public int getAlpha() { - return mAlpha; - } - - public void setAlpha(int alpha) { - this.mAlpha = alpha; - calculateFinalColor(); - } - - private void calculateFinalColor() { - if (mColor == null) { - mFinalColor = null; - } else { - int alpha = (int) Math.floor(((mColor >> 24) / 255.0) * (mAlpha / 255.0) * 255.0); - mFinalColor = (alpha << 24) | (mColor & 0xffffff); - } - } - - public void fillRect(Canvas c, Paint paint, - float left, float top, float right, float bottom, - Direction gradientDirection, float mRoundedBarRadius) { - switch (mType) { - case EMPTY: - return; - - case COLOR: { - if (mFinalColor == null) { - return; - } - - if (isClipPathSupported()) { - int save = c.save(); - - c.clipRect(left, top, right, bottom); - c.drawColor(mFinalColor); - - c.restoreToCount(save); - } else { - // save - Paint.Style previous = paint.getStyle(); - int previousColor = paint.getColor(); - - // set - paint.setStyle(Paint.Style.FILL); - paint.setColor(mFinalColor); - - c.drawRoundRect(new RectF(left, top, right, bottom), mRoundedBarRadius, mRoundedBarRadius, paint); - - // restore - paint.setColor(previousColor); - paint.setStyle(previous); - } - } - break; - - case LINEAR_GRADIENT: { - if (mGradientColors == null) { - return; - } - - LinearGradient gradient = new LinearGradient( - (int) (gradientDirection == Direction.RIGHT - ? right - : left), - (int) (gradientDirection == Direction.UP - ? bottom - : top), - (int) (gradientDirection == Direction.RIGHT - ? left - : gradientDirection == Direction.LEFT - ? right - : left), - (int) (gradientDirection == Direction.UP - ? top - : gradientDirection == Direction.DOWN - ? bottom - : top), - mGradientColors, - mGradientPositions, - android.graphics.Shader.TileMode.MIRROR); - - paint.setShader(gradient); - - c.drawRoundRect(new RectF(left, top, right, bottom), mRoundedBarRadius, mRoundedBarRadius, paint); - } - break; - - case DRAWABLE: { - if (mDrawable == null) { - return; - } - - mDrawable.setBounds((int) left, (int) top, (int) right, (int) bottom); - mDrawable.draw(c); - } - break; - } - } - - public void fillPath(Canvas c, Path path, Paint paint, - @Nullable RectF clipRect) { - switch (mType) { - case EMPTY: - return; - - case COLOR: { - if (mFinalColor == null) { - return; - } - - if (clipRect != null && isClipPathSupported()) { - int save = c.save(); - - c.clipPath(path); - c.drawColor(mFinalColor); - - c.restoreToCount(save); - } else { - // save - Paint.Style previous = paint.getStyle(); - int previousColor = paint.getColor(); - - // set - paint.setStyle(Paint.Style.FILL); - paint.setColor(mFinalColor); - - c.drawPath(path, paint); - - // restore - paint.setColor(previousColor); - paint.setStyle(previous); - } - } - break; - - case LINEAR_GRADIENT: { - if (mGradientColors == null) { - return; - } - - LinearGradient gradient = new LinearGradient( - 0, - 0, - c.getWidth(), - c.getHeight(), - mGradientColors, - mGradientPositions, - android.graphics.Shader.TileMode.MIRROR); - - paint.setShader(gradient); - - c.drawPath(path, paint); - } - break; - - case DRAWABLE: { - if (mDrawable == null) { - return; - } - - ensureClipPathSupported(); - - int save = c.save(); - c.clipPath(path); - - mDrawable.setBounds( - clipRect == null ? 0 : (int) clipRect.left, - clipRect == null ? 0 : (int) clipRect.top, - clipRect == null ? c.getWidth() : (int) clipRect.right, - clipRect == null ? c.getHeight() : (int) clipRect.bottom); - mDrawable.draw(c); - - c.restoreToCount(save); - } - break; - } - } - - private boolean isClipPathSupported() { - return getSDKInt() >= 18; - } - - private void ensureClipPathSupported() { - if (getSDKInt() < 18) { - throw new RuntimeException("Fill-drawables not (yet) supported below API level 18, this code was run on API level ${getSDKInt()}"); - } - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.kt new file mode 100644 index 000000000..770203e4a --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Fill.kt @@ -0,0 +1,244 @@ +package com.github.mikephil.charting.utils + +import android.graphics.Canvas +import android.graphics.LinearGradient +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF +import android.graphics.Shader +import android.graphics.drawable.Drawable +import kotlin.math.floor + +open class Fill { + enum class Type { + EMPTY, COLOR, LINEAR_GRADIENT, DRAWABLE + } + + enum class Direction { + DOWN, UP, RIGHT, LEFT + } + + /** + * the type of fill + */ + var type: Type = Type.EMPTY + + /** + * the color that is used for filling + */ + private var mColor: Int? = null + + private var mFinalColor: Int? = null + + /** + * the drawable to be used for filling + */ + protected var drawable: Drawable? = null + + var gradientColors: IntArray = IntArray(0) + + var gradientPositions: FloatArray = FloatArray(0) + + /** + * transparency used for filling + */ + private var mAlpha = 255 + + constructor(startColor: Int, endColor: Int) { + this.type = Type.LINEAR_GRADIENT + this.gradientColors = intArrayOf(startColor, endColor) + } + + var color: Int? + get() = mColor + set(color) { + this.mColor = color + calculateFinalColor() + } + + fun setGradientColors(startColor: Int, endColor: Int) { + this.gradientColors = intArrayOf(startColor, endColor) + } + + var alpha: Int + get() = mAlpha + set(alpha) { + this.mAlpha = alpha + calculateFinalColor() + } + + private fun calculateFinalColor() { + if (mColor == null) { + mFinalColor = null + } else { + val alpha = floor(((mColor!! shr 24) / 255.0) * (mAlpha / 255.0) * 255.0).toInt() + mFinalColor = (alpha shl 24) or (mColor!! and 0xffffff) + } + } + + fun fillRect( + c: Canvas, paint: Paint, + left: Float, top: Float, right: Float, bottom: Float, + gradientDirection: Direction?, mRoundedBarRadius: Float + ) { + when (this.type) { + Type.EMPTY -> return + + Type.COLOR -> { + if (mFinalColor == null) { + return + } + + if (this.isClipPathSupported) { + val save = c.save() + + c.clipRect(left, top, right, bottom) + c.drawColor(mFinalColor!!) + + c.restoreToCount(save) + } else { + // save + val previous = paint.getStyle() + val previousColor = paint.getColor() + + // set + paint.setStyle(Paint.Style.FILL) + paint.setColor(mFinalColor!!) + + c.drawRoundRect(RectF(left, top, right, bottom), mRoundedBarRadius, mRoundedBarRadius, paint) + + // restore + paint.setColor(previousColor) + paint.setStyle(previous) + } + } + + Type.LINEAR_GRADIENT -> { + val gradient = LinearGradient( + (if (gradientDirection == Direction.RIGHT) + right + else + left).toInt().toFloat(), + (if (gradientDirection == Direction.UP) + bottom + else + top).toInt().toFloat(), + (if (gradientDirection == Direction.RIGHT) + left + else + if (gradientDirection == Direction.LEFT) + right + else + left).toInt().toFloat(), + (if (gradientDirection == Direction.UP) + top + else + if (gradientDirection == Direction.DOWN) + bottom + else + top).toInt().toFloat(), + this.gradientColors, + this.gradientPositions, + Shader.TileMode.MIRROR + ) + + paint.setShader(gradient) + + c.drawRoundRect(RectF(left, top, right, bottom), mRoundedBarRadius, mRoundedBarRadius, paint) + } + + Type.DRAWABLE -> { + if (drawable == null) { + return + } + + drawable!!.setBounds(left.toInt(), top.toInt(), right.toInt(), bottom.toInt()) + drawable!!.draw(c) + } + } + } + + fun fillPath( + c: Canvas, path: Path, paint: Paint, + clipRect: RectF? + ) { + when (this.type) { + Type.EMPTY -> return + + Type.COLOR -> { + if (mFinalColor == null) { + return + } + + if (clipRect != null && this.isClipPathSupported) { + val save = c.save() + + c.clipPath(path) + c.drawColor(mFinalColor!!) + + c.restoreToCount(save) + } else { + // save + val previous = paint.getStyle() + val previousColor = paint.getColor() + + // set + paint.setStyle(Paint.Style.FILL) + paint.setColor(mFinalColor!!) + + c.drawPath(path, paint) + + // restore + paint.setColor(previousColor) + paint.setStyle(previous) + } + } + + Type.LINEAR_GRADIENT -> { + val gradient = LinearGradient( + 0f, + 0f, + c.getWidth().toFloat(), + c.getHeight().toFloat(), + this.gradientColors, + this.gradientPositions, + Shader.TileMode.MIRROR + ) + + paint.setShader(gradient) + + c.drawPath(path, paint) + } + + Type.DRAWABLE -> { + if (drawable == null) { + return + } + + ensureClipPathSupported() + + val save = c.save() + c.clipPath(path) + + drawable!!.setBounds( + if (clipRect == null) 0 else clipRect.left.toInt(), + if (clipRect == null) 0 else clipRect.top.toInt(), + if (clipRect == null) c.getWidth() else clipRect.right.toInt(), + if (clipRect == null) c.getHeight() else clipRect.bottom.toInt() + ) + drawable!!.draw(c) + + c.restoreToCount(save) + } + } + } + + private val isClipPathSupported: Boolean + get() = getSDKInt() >= 18 + + private fun ensureClipPathSupported() { + if (getSDKInt() < 18) { + throw RuntimeException("Fill-drawables not (yet) supported below API level 18, this code was run on API level \${getSDKInt()}") + } + } +}