From d93a5f8ee6469ccc1bb0408286ec3041dd3f7b13 Mon Sep 17 00:00:00 2001 From: chengjunzhang61 Date: Wed, 8 Dec 2021 10:01:16 -0500 Subject: [PATCH] Create round text view --- markwon-round-textview/.gitignore | 1 + markwon-round-textview/build.gradle | 52 +++++ markwon-round-textview/consumer-rules.pro | 0 markwon-round-textview/proguard-rules.pro | 21 ++ .../boundarytext/ExampleInstrumentedTest.kt | 24 +++ .../src/main/AndroidManifest.xml | 5 + .../markdown/boundarytext/Extentions.kt | 25 +++ .../markdown/boundarytext/LayoutExtensions.kt | 75 +++++++ .../boundarytext/RoundedBgTextView.kt | 70 +++++++ .../TextRoundedBgAttributeReader.kt | 53 +++++ .../boundarytext/TextRoundedBgHelper.kt | 68 ++++++ .../boundarytext/TextRoundedBgRenderer.kt | 194 ++++++++++++++++++ .../src/main/res/drawable/rounded_text_bg.xml | 21 ++ .../res/drawable/rounded_text_bg_dark.xml | 21 ++ .../res/drawable/rounded_text_bg_left.xml | 22 ++ .../drawable/rounded_text_bg_left_dark.xml | 22 ++ .../main/res/drawable/rounded_text_bg_mid.xml | 20 ++ .../res/drawable/rounded_text_bg_mid_dark.xml | 20 ++ .../res/drawable/rounded_text_bg_right.xml | 22 ++ .../drawable/rounded_text_bg_right_dark.xml | 22 ++ .../src/main/res/values/attrs.xml | 11 + .../src/main/res/values/colors.xml | 6 + .../src/main/res/values/dimens.xml | 8 + .../src/main/res/values/styles.xml | 31 +++ .../markdown/boundarytext/ExampleUnitTest.kt | 17 ++ 25 files changed, 831 insertions(+) create mode 100644 markwon-round-textview/.gitignore create mode 100644 markwon-round-textview/build.gradle create mode 100644 markwon-round-textview/consumer-rules.pro create mode 100644 markwon-round-textview/proguard-rules.pro create mode 100644 markwon-round-textview/src/androidTest/java/io/noties/markdown/boundarytext/ExampleInstrumentedTest.kt create mode 100644 markwon-round-textview/src/main/AndroidManifest.xml create mode 100644 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/Extentions.kt create mode 100755 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/LayoutExtensions.kt create mode 100755 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/RoundedBgTextView.kt create mode 100755 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgAttributeReader.kt create mode 100755 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgHelper.kt create mode 100755 markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgRenderer.kt create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_dark.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_left.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_left_dark.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid_dark.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_right.xml create mode 100755 markwon-round-textview/src/main/res/drawable/rounded_text_bg_right_dark.xml create mode 100644 markwon-round-textview/src/main/res/values/attrs.xml create mode 100644 markwon-round-textview/src/main/res/values/colors.xml create mode 100644 markwon-round-textview/src/main/res/values/dimens.xml create mode 100644 markwon-round-textview/src/main/res/values/styles.xml create mode 100644 markwon-round-textview/src/test/java/io/noties/markdown/boundarytext/ExampleUnitTest.kt diff --git a/markwon-round-textview/.gitignore b/markwon-round-textview/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/markwon-round-textview/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/markwon-round-textview/build.gradle b/markwon-round-textview/build.gradle new file mode 100644 index 00000000..b255089c --- /dev/null +++ b/markwon-round-textview/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' +} + +android { + compileSdkVersion 31 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 31 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + + api project(':markwon-core') + + deps.with { + // add a compileOnly dependency, so if this artifact is present + // we will try to obtain a SpanFactory for a Strikethrough node and use + // it to be consistent with markdown (please note that we do not use markwon plugin + // for that in case if different implementation is used) + compileOnly it['commonmark-strikethrough'] + + testImplementation it['ix-java'] + } + + deps.test.with { + testImplementation it['junit'] + testImplementation it['robolectric'] + } +} \ No newline at end of file diff --git a/markwon-round-textview/consumer-rules.pro b/markwon-round-textview/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/markwon-round-textview/proguard-rules.pro b/markwon-round-textview/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/markwon-round-textview/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/markwon-round-textview/src/androidTest/java/io/noties/markdown/boundarytext/ExampleInstrumentedTest.kt b/markwon-round-textview/src/androidTest/java/io/noties/markdown/boundarytext/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..e9fc7c04 --- /dev/null +++ b/markwon-round-textview/src/androidTest/java/io/noties/markdown/boundarytext/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package io.noties.markdown.boundarytext + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("io.noties.markdown.boundarytext.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/AndroidManifest.xml b/markwon-round-textview/src/main/AndroidManifest.xml new file mode 100644 index 00000000..063beb55 --- /dev/null +++ b/markwon-round-textview/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/Extentions.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/Extentions.kt new file mode 100644 index 00000000..f5b418ed --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/Extentions.kt @@ -0,0 +1,25 @@ +package io.noties.markdown.boundarytext +import android.graphics.Canvas + +/** + *
+ *     author : NeXT
+ *     time   : 2018/12/11
+ *     desc   :
+ *     copy from: androidx.core.graphics.Canvas.kt
+ * 
+ */ + +inline fun Canvas.withTranslation( + x: Float = 0.0f, + y: Float = 0.0f, + block: Canvas.() -> Unit +) { + val checkpoint = save() + translate(x, y) + try { + block() + } finally { + restoreToCount(checkpoint) + } +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/LayoutExtensions.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/LayoutExtensions.kt new file mode 100755 index 00000000..765132c8 --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/LayoutExtensions.kt @@ -0,0 +1,75 @@ +package io.noties.markdown.boundarytext +import android.os.Build +import android.text.Layout + +// Extension functions for Layout object + +/** + * Android system default line spacing extra + */ +private const val DEFAULT_LINESPACING_EXTRA = 0f + +/** + * Android system default line spacing multiplier + */ +private const val DEFAULT_LINESPACING_MULTIPLIER = 1f + +/** + * Get the line bottom discarding the line spacing added. + */ +fun Layout.getLineBottomWithoutSpacing(line: Int): Int { + val lineBottom = getLineBottom(line) + val lastLineSpacingNotAdded = Build.VERSION.SDK_INT >= 19 + val isLastLine = line == lineCount - 1 + + val lineBottomWithoutSpacing: Int + val lineSpacingExtra = spacingAdd + val lineSpacingMultiplier = spacingMultiplier + val hasLineSpacing = lineSpacingExtra != DEFAULT_LINESPACING_EXTRA + || lineSpacingMultiplier != DEFAULT_LINESPACING_MULTIPLIER + + if (!hasLineSpacing || isLastLine && lastLineSpacingNotAdded) { + lineBottomWithoutSpacing = lineBottom + } else { + val extra: Float + if (lineSpacingMultiplier.compareTo(DEFAULT_LINESPACING_MULTIPLIER) != 0) { + val lineHeight = getLineHeight(line) + extra = lineHeight - (lineHeight - lineSpacingExtra) / lineSpacingMultiplier + } else { + extra = lineSpacingExtra + } + + lineBottomWithoutSpacing = (lineBottom - extra).toInt() + } + + return lineBottomWithoutSpacing +} + +/** + * Get the line height of a line. + */ +fun Layout.getLineHeight(line: Int): Int { + return getLineTop(line + 1) - getLineTop(line) +} + +/** + * Returns the top of the Layout after removing the extra padding applied by the Layout. + */ +fun Layout.getLineTopWithoutPadding(line: Int): Int { + var lineTop = getLineTop(line) + if (line == 0) { + lineTop -= topPadding + } + return lineTop +} + +/** + * Returns the bottom of the Layout after removing the extra padding applied by the Layout. + */ +fun Layout.getLineBottomWithoutPadding(line: Int): Int { + var lineBottom = getLineBottomWithoutSpacing(line) + if (line == lineCount - 1) { + lineBottom -= bottomPadding + } + return lineBottom +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/RoundedBgTextView.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/RoundedBgTextView.kt new file mode 100755 index 00000000..cdb9b468 --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/RoundedBgTextView.kt @@ -0,0 +1,70 @@ +package io.noties.markdown.boundarytext + +import android.content.Context +import android.graphics.Canvas +import android.text.Spanned +import android.util.AttributeSet +import android.widget.TextView + +/** + * A TextView that can draw rounded background to the portions of the text. See + * [TextRoundedBgHelper] for more information. + * + * See [TextRoundedBgAttributeReader] for supported attributes. + */ +class RoundedBgTextView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = android.R.attr.textViewStyle +) : TextView(context, attrs, defStyleAttr) { + + private lateinit var textRoundedBgHelper: TextRoundedBgHelper + private lateinit var attributeReader : TextRoundedBgAttributeReader + + private lateinit var mAttrs : AttributeSet + private var mTheme : String + + init { + mTheme = "light" + if (attrs != null) { + mAttrs = attrs + attributeReader = TextRoundedBgAttributeReader(context, mAttrs, mTheme) + textRoundedBgHelper = TextRoundedBgHelper( + horizontalPadding = attributeReader.horizontalPadding, + verticalPadding = attributeReader.verticalPadding, + drawable = attributeReader.drawable, + drawableLeft = attributeReader.drawableLeft, + drawableMid = attributeReader.drawableMid, + drawableRight = attributeReader.drawableRight + ) + } + + } + + fun setThemeChange(theme : String) { + mTheme = theme + attributeReader = TextRoundedBgAttributeReader(context, mAttrs, mTheme) + textRoundedBgHelper = TextRoundedBgHelper( + horizontalPadding = attributeReader.horizontalPadding, + verticalPadding = attributeReader.verticalPadding, + drawable = attributeReader.drawable, + drawableLeft = attributeReader.drawableLeft, + drawableMid = attributeReader.drawableMid, + drawableRight = attributeReader.drawableRight + ) + } + + fun setTextColorWith (textColor : Int){ + this.setTextColor(textColor) + } + + override fun onDraw(canvas: Canvas) { + // need to draw bg first so that text can be on top during super.onDraw() + if (text is Spanned && layout != null) { + canvas.withTranslation(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat()) { + textRoundedBgHelper.draw(canvas, text as Spanned, layout) + } + } + super.onDraw(canvas) + } +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgAttributeReader.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgAttributeReader.kt new file mode 100755 index 00000000..bd9307c6 --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgAttributeReader.kt @@ -0,0 +1,53 @@ +package io.noties.markdown.boundarytext + +import android.content.Context +import android.graphics.drawable.Drawable +import android.util.AttributeSet + +class TextRoundedBgAttributeReader(context: Context, attrs: AttributeSet?, theme : String) { + + val horizontalPadding: Int + val verticalPadding: Int + val drawable: Drawable + val drawableLeft: Drawable + val drawableMid: Drawable + val drawableRight: Drawable + + init { + var typedArray = context.obtainStyledAttributes( + attrs, + R.styleable.TextRoundedBgHelper, + 0, + R.style.RoundedBgTextView + ) + if(theme.equals("dark")){ + typedArray = context.obtainStyledAttributes( + attrs, + R.styleable.TextRoundedBgHelper, + 0, + R.style.RoundedBgTextDarkView + ) + } + horizontalPadding = typedArray.getDimensionPixelSize( + R.styleable.TextRoundedBgHelper_roundedTextHorizontalPadding, + 0 + ) + verticalPadding = typedArray.getDimensionPixelSize( + R.styleable.TextRoundedBgHelper_roundedTextVerticalPadding, + 0 + ) + drawable = typedArray.getDrawable( + R.styleable.TextRoundedBgHelper_roundedTextDrawable + )!! + drawableLeft = typedArray.getDrawable( + R.styleable.TextRoundedBgHelper_roundedTextDrawableLeft + )!! + drawableMid = typedArray.getDrawable( + R.styleable.TextRoundedBgHelper_roundedTextDrawableMid + )!! + drawableRight = typedArray.getDrawable( + R.styleable.TextRoundedBgHelper_roundedTextDrawableRight + )!! + typedArray.recycle() + } +} diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgHelper.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgHelper.kt new file mode 100755 index 00000000..cb9b8fc5 --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgHelper.kt @@ -0,0 +1,68 @@ +package io.noties.markdown.boundarytext + + +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.text.Layout +import android.text.Spanned +import io.noties.markwon.core.spans.CodeSpan + +class TextRoundedBgHelper( + val horizontalPadding: Int, + verticalPadding: Int, + drawable: Drawable, + drawableLeft: Drawable, + drawableMid: Drawable, + drawableRight: Drawable +) { + + private val singleLineRenderer: TextRoundedBgRenderer by lazy { + SingleLineRenderer( + horizontalPadding = horizontalPadding, + verticalPadding = verticalPadding, + drawable = drawable + ) + } + + private val multiLineRenderer: TextRoundedBgRenderer by lazy { + MultiLineRenderer( + horizontalPadding = horizontalPadding, + verticalPadding = verticalPadding, + drawableLeft = drawableLeft, + drawableMid = drawableMid, + drawableRight = drawableRight + ) + } + + /** + * Call this function during onDraw of another widget such as TextView. + * + * @param canvas Canvas to draw onto + * @param text + * @param layout Layout that contains the text + */ + fun draw(canvas: Canvas, text: Spanned, layout: Layout) { + // ideally the calculations here should be cached since they are not cheap. However, proper + // invalidation of the cache is required whenever anything related to text has changed. +// val spans = text.getSpans(0, text.length, Annotation::class.java) + val spans = text.getSpans(0, text.length, CodeSpan::class.java) + spans.forEach { span -> +// if (span.value.equals("rounded")) { + val spanStart = text.getSpanStart(span) + val spanEnd = text.getSpanEnd(span) + val startLine = layout.getLineForOffset(spanStart) + val endLine = layout.getLineForOffset(spanEnd) + + // start can be on the left or on the right depending on the language direction. + val startOffset = (layout.getPrimaryHorizontal(spanStart) + + -1 * layout.getParagraphDirection(startLine) * horizontalPadding).toInt() + // end can be on the left or on the right depending on the language direction. + val endOffset = (layout.getPrimaryHorizontal(spanEnd) + + layout.getParagraphDirection(endLine) * horizontalPadding).toInt() + + val renderer = if (startLine == endLine) singleLineRenderer else multiLineRenderer + renderer.draw(canvas, layout, startLine, endLine, startOffset, endOffset) +// } + } + } +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgRenderer.kt b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgRenderer.kt new file mode 100755 index 00000000..8bbe84a8 --- /dev/null +++ b/markwon-round-textview/src/main/java/io/noties/markdown/boundarytext/TextRoundedBgRenderer.kt @@ -0,0 +1,194 @@ +package io.noties.markdown.boundarytext + +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.text.Layout +import kotlin.math.max +import kotlin.math.min + +/** + * Base class for single and multi line rounded background renderers. + * + * @param horizontalPadding the padding to be applied to left & right of the background + * @param verticalPadding the padding to be applied to top & bottom of the background + */ +internal abstract class TextRoundedBgRenderer( + val horizontalPadding: Int, + val verticalPadding: Int +) { + + /** + * Draw the background that starts at the {@code startOffset} and ends at {@code endOffset}. + * + * @param canvas Canvas to draw onto + * @param layout Layout that contains the text + * @param startLine the start line for the background + * @param endLine the end line for the background + * @param startOffset the character offset that the background should start at + * @param endOffset the character offset that the background should end at + */ + abstract fun draw( + canvas: Canvas, + layout: Layout, + startLine: Int, + endLine: Int, + startOffset: Int, + endOffset: Int + ) + + /** + * Get the top offset of the line and add padding into account so that there is a gap between + * top of the background and top of the text. + * + * @param layout Layout object that contains the text + * @param line line number + */ + protected fun getLineTop(layout: Layout, line: Int): Int { + return layout.getLineTopWithoutPadding(line) - verticalPadding + } + + /** + * Get the bottom offset of the line and add padding into account so that there is a gap between + * bottom of the background and bottom of the text. + * + * @param layout Layout object that contains the text + * @param line line number + */ + protected fun getLineBottom(layout: Layout, line: Int): Int { + return layout.getLineBottomWithoutPadding(line) + verticalPadding + } +} + +/** + * Draws the background for text that starts and ends on the same line. + * + * @param horizontalPadding the padding to be applied to left & right of the background + * @param verticalPadding the padding to be applied to top & bottom of the background + * @param drawable the drawable used to draw the background + */ +internal class SingleLineRenderer( + horizontalPadding: Int, + verticalPadding: Int, + val drawable: Drawable +) : TextRoundedBgRenderer(horizontalPadding, verticalPadding) { + + override fun draw( + canvas: Canvas, + layout: Layout, + startLine: Int, + endLine: Int, + startOffset: Int, + endOffset: Int + ) { + val lineTop = getLineTop(layout, startLine) + val lineBottom = getLineBottom(layout, startLine) + // get min of start/end for left, and max of start/end for right since we don't + // the language direction + val left = min(startOffset, endOffset) + val right = max(startOffset, endOffset) + drawable.setBounds(left, lineTop, right, lineBottom) + drawable.draw(canvas) + } +} + +/** + * Draws the background for text that starts and ends on different lines. + * + * @param horizontalPadding the padding to be applied to left & right of the background + * @param verticalPadding the padding to be applied to top & bottom of the background + * @param drawableLeft the drawable used to draw left edge of the background + * @param drawableMid the drawable used to draw for whole line + * @param drawableRight the drawable used to draw right edge of the background + */ +internal class MultiLineRenderer( + horizontalPadding: Int, + verticalPadding: Int, + val drawableLeft: Drawable, + val drawableMid: Drawable, + val drawableRight: Drawable +) : TextRoundedBgRenderer(horizontalPadding, verticalPadding) { + + override fun draw( + canvas: Canvas, + layout: Layout, + startLine: Int, + endLine: Int, + startOffset: Int, + endOffset: Int + ) { + // draw the first line + val paragDir = layout.getParagraphDirection(startLine) + val lineEndOffset = if (paragDir == Layout.DIR_RIGHT_TO_LEFT) { + layout.getLineLeft(startLine) - horizontalPadding + } else { + layout.getLineRight(startLine) + horizontalPadding + }.toInt() + + var lineBottom = getLineBottom(layout, startLine) + var lineTop = getLineTop(layout, startLine) + drawStart(canvas, startOffset, lineTop, lineEndOffset, lineBottom) + + // for the lines in the middle draw the mid drawable + for (line in startLine + 1 until endLine) { + lineTop = getLineTop(layout, line) + lineBottom = getLineBottom(layout, line) + drawableMid.setBounds( + (layout.getLineLeft(line).toInt() - horizontalPadding), + lineTop, + (layout.getLineRight(line).toInt() + horizontalPadding), + lineBottom + ) + drawableMid.draw(canvas) + } + + val lineStartOffset = if (paragDir == Layout.DIR_RIGHT_TO_LEFT) { + layout.getLineRight(startLine) + horizontalPadding + } else { + layout.getLineLeft(startLine) - horizontalPadding + }.toInt() + + // draw the last line + lineBottom = getLineBottom(layout, endLine) + lineTop = getLineTop(layout, endLine) + + drawEnd(canvas, lineStartOffset, lineTop, endOffset, lineBottom) + } + + /** + * Draw the first line of a multiline annotation. Handles LTR/RTL. + * + * @param canvas Canvas to draw onto + * @param start start coordinate for the background + * @param top top coordinate for the background + * @param end end coordinate for the background + * @param bottom bottom coordinate for the background + */ + private fun drawStart(canvas: Canvas, start: Int, top: Int, end: Int, bottom: Int) { + if (start > end) { + drawableRight.setBounds(end, top, start, bottom) + drawableRight.draw(canvas) + } else { + drawableLeft.setBounds(start, top, end, bottom) + drawableLeft.draw(canvas) + } + } + + /** + * Draw the last line of a multiline annotation. Handles LTR/RTL. + * + * @param canvas Canvas to draw onto + * @param start start coordinate for the background + * @param top top position for the background + * @param end end coordinate for the background + * @param bottom bottom coordinate for the background + */ + private fun drawEnd(canvas: Canvas, start: Int, top: Int, end: Int, bottom: Int) { + if (start > end) { + drawableLeft.setBounds(end, top, start, bottom) + drawableLeft.draw(canvas) + } else { + drawableRight.setBounds(start, top, end, bottom) + drawableRight.draw(canvas) + } + } +} \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg.xml new file mode 100755 index 00000000..080efc4b --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_dark.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_dark.xml new file mode 100755 index 00000000..d4f9219a --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_dark.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left.xml new file mode 100755 index 00000000..a96b5596 --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left_dark.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left_dark.xml new file mode 100755 index 00000000..782c7193 --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_left_dark.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid.xml new file mode 100755 index 00000000..a3269897 --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid_dark.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid_dark.xml new file mode 100755 index 00000000..57b78b45 --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_mid_dark.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right.xml new file mode 100755 index 00000000..86576310 --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right_dark.xml b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right_dark.xml new file mode 100755 index 00000000..9a58993b --- /dev/null +++ b/markwon-round-textview/src/main/res/drawable/rounded_text_bg_right_dark.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/values/attrs.xml b/markwon-round-textview/src/main/res/values/attrs.xml new file mode 100644 index 00000000..298b366d --- /dev/null +++ b/markwon-round-textview/src/main/res/values/attrs.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/values/colors.xml b/markwon-round-textview/src/main/res/values/colors.xml new file mode 100644 index 00000000..596ae7e2 --- /dev/null +++ b/markwon-round-textview/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #EE6A6C + #F1F2F3 + #252627 + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/values/dimens.xml b/markwon-round-textview/src/main/res/values/dimens.xml new file mode 100644 index 00000000..caa8138b --- /dev/null +++ b/markwon-round-textview/src/main/res/values/dimens.xml @@ -0,0 +1,8 @@ + + + 6dp + 2dp + + 4dp + 1dp + \ No newline at end of file diff --git a/markwon-round-textview/src/main/res/values/styles.xml b/markwon-round-textview/src/main/res/values/styles.xml new file mode 100644 index 00000000..8223f706 --- /dev/null +++ b/markwon-round-textview/src/main/res/values/styles.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/markwon-round-textview/src/test/java/io/noties/markdown/boundarytext/ExampleUnitTest.kt b/markwon-round-textview/src/test/java/io/noties/markdown/boundarytext/ExampleUnitTest.kt new file mode 100644 index 00000000..09c6fbed --- /dev/null +++ b/markwon-round-textview/src/test/java/io/noties/markdown/boundarytext/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package io.noties.markdown.boundarytext + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file