Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.swmansion.enriched.markdown.renderer
import android.text.SpannableStringBuilder
import com.swmansion.enriched.markdown.parser.MarkdownASTNode
import com.swmansion.enriched.markdown.spans.BlockquoteSpan
import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_CONTAINER_BACKGROUND
import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE
import com.swmansion.enriched.markdown.utils.text.span.applyMarginBottom
import com.swmansion.enriched.markdown.utils.text.span.applyMarginTop
Expand Down Expand Up @@ -45,12 +46,14 @@ class BlockquoteRenderer(
.map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
.sortedBy { it.first }

// The Accent Bar Span covers the full range for visual continuity
// The accent bar span covers the full range for visual continuity.
// SPAN_FLAGS_CONTAINER_BACKGROUND keeps the blockquote fill under any
// inline chip/pill backgrounds on the same line.
builder.setSpan(
BlockquoteSpan(style, depth, factory.context, factory.styleCache),
start,
end,
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
SPAN_FLAGS_CONTAINER_BACKGROUND,
)

// Apply styling only to segments that are NOT nested quotes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.text.Layout
import android.text.Spanned
import android.text.TextPaint
import android.text.style.LeadingMarginSpan
import android.text.style.LineBackgroundSpan
import android.text.style.MetricAffectingSpan
import com.swmansion.enriched.markdown.renderer.BlockStyle
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
Expand All @@ -23,7 +24,8 @@ class BlockquoteSpan(
private val context: Context,
private val styleCache: SpanStyleCache,
) : MetricAffectingSpan(),
LeadingMarginSpan {
LeadingMarginSpan,
LineBackgroundSpan {
private val levelSpacing: Float = blockquoteStyle.borderWidth + blockquoteStyle.gapWidth
private val blockStyle =
BlockStyle(
Expand Down Expand Up @@ -60,8 +62,6 @@ class BlockquoteSpan(
// Essential check from original: only the deepest span draws to prevent over-rendering background
if (shouldSkipDrawing(text, start)) return

drawBackground(c, top, bottom, layout)

val borderPaint = configureBorderPaint()
val borderTop = top.toFloat()
val borderBottom = bottom.toFloat()
Expand All @@ -73,6 +73,23 @@ class BlockquoteSpan(
}
}

override fun drawBackground(
canvas: Canvas,
paint: Paint,
left: Int,
right: Int,
top: Int,
baseline: Int,
bottom: Int,
text: CharSequence,
start: Int,
end: Int,
lineNum: Int,
) {
if (shouldSkipDrawing(text, start)) return
drawBackground(canvas, left, top, bottom, right)
}

@SuppressLint("WrongConstant") // Result of mask is always valid: 0, 1, 2, or 3
private fun applyTextStyle(tp: TextPaint) {
tp.textSize = blockStyle.fontSize
Expand Down Expand Up @@ -123,12 +140,13 @@ class BlockquoteSpan(

private fun drawBackground(
c: Canvas,
left: Int,
top: Int,
bottom: Int,
layout: Layout?,
right: Int,
) {
val bgColor = blockquoteStyle.backgroundColor?.takeIf { it != Color.TRANSPARENT } ?: return
val backgroundPaint = configureBackgroundPaint(bgColor)
c.drawRect(0f, top.toFloat(), layout?.width?.toFloat() ?: 0f, bottom.toFloat(), backgroundPaint)
c.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), backgroundPaint)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
package com.swmansion.enriched.markdown.utils.text.span

import android.text.SpannableString
import android.text.Spanned

const val SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE = SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE

/**
* `SPAN_EXCLUSIVE_EXCLUSIVE` with the maximum span priority.
*
* Higher-priority spans are iterated — and therefore drawn — first, so any
* lower-priority span on the same line ends up painted *on top* visually.
* Use this for full-width container backgrounds (e.g. blockquote fill in
* [BlockquoteSpan]) that must sit under inline pill/chip backgrounds.
*/
Comment thread
xindixu marked this conversation as resolved.
const val SPAN_FLAGS_CONTAINER_BACKGROUND =
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE or Spanned.SPAN_PRIORITY
8 changes: 4 additions & 4 deletions apps/example/src/sampleMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Forests cover approximately **31% of the Earth's land surface**, providing habit

Forests are often called the *lungs of the Earth*. They absorb **carbon dioxide** and release oxygen through photosynthesis — a process essential for all life on our planet. A single mature tree can absorb up to \`48 pounds\` of CO₂ per year.

> In every walk with nature, one receives far more than he seeks.
> In every walk with nature, one receives far more than he seeks. \`test code\`
>
> — John Muir

Expand Down Expand Up @@ -136,7 +136,7 @@ class TreeNetwork {
this.trees = [];
this.fungalConnections = new Map();
}

connectTrees(tree1, tree2) {
// Trees share nutrients through mycorrhizal networks
this.fungalConnections.set(\`\${tree1.id}-\${tree2.id}\`, {
Expand Down Expand Up @@ -330,11 +330,11 @@ def detect_deforestation(region):
"""Monitor forest cover changes using satellite imagery"""
current_cover = satellite_imagery.get_forest_cover(region)
previous_cover = satellite_imagery.get_historical_cover(region, years_ago=1)

deforestation_rate = (previous_cover - current_cover) / previous_cover
if deforestation_rate > 0.05: # 5% threshold
alert_conservation_team(region, deforestation_rate)

return deforestation_rate
\`\`\`

Expand Down
Loading