Skip to content

Commit

Permalink
inline shift approach
Browse files Browse the repository at this point in the history
  • Loading branch information
manas-yu committed Jan 23, 2025
1 parent cb120e1 commit b9b9fea
Showing 1 changed file with 53 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import android.graphics.Paint
import android.graphics.drawable.Drawable
import android.text.Editable
import android.text.Spannable
import android.text.style.DynamicDrawableSpan
import android.text.style.ImageSpan
import android.text.style.ReplacementSpan
import androidx.core.content.res.ResourcesCompat
import io.github.karino2.kotlitex.view.MathExpressionSpan
import java.lang.ref.WeakReference
import org.json.JSONObject
import org.oppia.android.util.R
import org.oppia.android.util.logging.ConsoleLogger
Expand Down Expand Up @@ -68,7 +71,8 @@ class MathTagHandler(
content.rawLatex,
lineHeight,
type = if (useInlineRendering) INLINE_TEXT_IMAGE else BLOCK_IMAGE
)
),
useInlineRendering
)
} else {
MathExpressionSpan(
Expand Down Expand Up @@ -149,32 +153,45 @@ class MathTagHandler(
}

/** An [ImageSpan] that vertically centers a LaTeX drawable within the surrounding text. */
private class LatexImageSpan(drawable: Drawable) : ImageSpan(drawable) {
private class LatexImageSpan(
private val drawable: Drawable,
private val isInline: Boolean
) : ReplacementSpan() {
companion object {
private const val INLINE_SHIFT_FACTOR = 0.9f // Adjust this value (0.2-0.4) as needed
}

override fun getSize(
paint: Paint,
text: CharSequence,
start: Int,
end: Int,
fontMetricsInt: Paint.FontMetricsInt?
fm: Paint.FontMetricsInt?
): Int {
val drawable = drawable
val rect = drawable.bounds

fontMetricsInt?.let { fm ->
val paintMetrics = paint.fontMetricsInt
val fontHeight = paintMetrics.descent - paintMetrics.ascent
val drawableHeight = rect.bottom - rect.top
val centerY = paintMetrics.ascent + fontHeight / 2

// Adjust font metrics to center the drawable vertically
fm.ascent = centerY - drawableHeight / 2
fm.top = fm.ascent
fm.bottom = centerY + drawableHeight / 2
fm.descent = fm.bottom
val bounds = drawable.bounds
val imageHeight = bounds.height()
val paintMetrics = paint.fontMetricsInt
val textHeight = paintMetrics.descent - paintMetrics.ascent

fm?.let { metrics ->
if (isInline) {
// Reserve space for inline shift
val verticalShift = (imageHeight - textHeight) / 2 +
(paintMetrics.descent * INLINE_SHIFT_FACTOR).toInt()
metrics.ascent = paintMetrics.ascent - verticalShift
metrics.top = metrics.ascent
metrics.descent = paintMetrics.descent + verticalShift
metrics.bottom = metrics.descent
} else {
// Block mode calculations remain unchanged
val totalHeight = (imageHeight * 1.2).toInt()
metrics.ascent = -totalHeight / 2
metrics.top = metrics.ascent
metrics.descent = totalHeight / 2
metrics.bottom = metrics.descent
}
}

return rect.right
return bounds.right
}

override fun draw(
Expand All @@ -183,21 +200,28 @@ private class LatexImageSpan(drawable: Drawable) : ImageSpan(drawable) {
start: Int,
end: Int,
x: Float,
top: Int,
y: Int,
bottom: Int,
lineTop: Int,
baseline: Int,
lineBottom: Int,
paint: Paint
) {
val drawable = drawable
canvas.save()

// Calculate vertical centering
val paintMetrics = paint.fontMetricsInt
val fontHeight = paintMetrics.descent - paintMetrics.ascent
val centerY = y + paintMetrics.descent - fontHeight / 2
val transY = centerY - (drawable.bounds.bottom - drawable.bounds.top) / 2
val imageHeight = drawable.bounds.height()
val yPosition = when {
isInline -> {
// Apply downward shift for inline equations
val textMidline = baseline - (paint.fontMetrics.descent - paint.fontMetrics.ascent) / 2
val shiftOffset = (paint.fontMetricsInt.descent * INLINE_SHIFT_FACTOR).toInt()
textMidline - (imageHeight / 2) + shiftOffset
}
else -> {
// Block mode remains centered
lineTop + (lineBottom - lineTop - imageHeight) / 2
}
}

canvas.translate(x, transY.toFloat())
canvas.translate(x, yPosition.toFloat())
drawable.draw(canvas)
canvas.restore()
}
Expand Down

0 comments on commit b9b9fea

Please sign in to comment.