@@ -7,9 +7,12 @@ import android.graphics.Paint
77import android.graphics.drawable.Drawable
88import android.text.Editable
99import android.text.Spannable
10+ import android.text.style.DynamicDrawableSpan
1011import android.text.style.ImageSpan
12+ import android.text.style.ReplacementSpan
1113import androidx.core.content.res.ResourcesCompat
1214import io.github.karino2.kotlitex.view.MathExpressionSpan
15+ import java.lang.ref.WeakReference
1316import org.json.JSONObject
1417import org.oppia.android.util.R
1518import org.oppia.android.util.logging.ConsoleLogger
@@ -68,7 +71,8 @@ class MathTagHandler(
6871 content.rawLatex,
6972 lineHeight,
7073 type = if (useInlineRendering) INLINE_TEXT_IMAGE else BLOCK_IMAGE
71- )
74+ ),
75+ useInlineRendering
7276 )
7377 } else {
7478 MathExpressionSpan (
@@ -149,32 +153,45 @@ class MathTagHandler(
149153}
150154
151155/* * An [ImageSpan] that vertically centers a LaTeX drawable within the surrounding text. */
152- private class LatexImageSpan (drawable : Drawable ) : ImageSpan(drawable) {
156+ private class LatexImageSpan (
157+ private val drawable : Drawable ,
158+ private val isInline : Boolean
159+ ) : ReplacementSpan() {
160+ companion object {
161+ private const val INLINE_SHIFT_FACTOR = 0.9f // Adjust this value (0.2-0.4) as needed
162+ }
153163
154164 override fun getSize (
155165 paint : Paint ,
156166 text : CharSequence ,
157167 start : Int ,
158168 end : Int ,
159- fontMetricsInt : Paint .FontMetricsInt ?
169+ fm : Paint .FontMetricsInt ?
160170 ): Int {
161- val drawable = drawable
162- val rect = drawable.bounds
163-
164- fontMetricsInt?.let { fm ->
165- val paintMetrics = paint.fontMetricsInt
166- val fontHeight = paintMetrics.descent - paintMetrics.ascent
167- val drawableHeight = rect.bottom - rect.top
168- val centerY = paintMetrics.ascent + fontHeight / 2
169-
170- // Adjust font metrics to center the drawable vertically
171- fm.ascent = centerY - drawableHeight / 2
172- fm.top = fm.ascent
173- fm.bottom = centerY + drawableHeight / 2
174- fm.descent = fm.bottom
171+ val bounds = drawable.bounds
172+ val imageHeight = bounds.height()
173+ val paintMetrics = paint.fontMetricsInt
174+ val textHeight = paintMetrics.descent - paintMetrics.ascent
175+
176+ fm?.let { metrics ->
177+ if (isInline) {
178+ // Reserve space for inline shift
179+ val verticalShift = (imageHeight - textHeight) / 2 +
180+ (paintMetrics.descent * INLINE_SHIFT_FACTOR ).toInt()
181+ metrics.ascent = paintMetrics.ascent - verticalShift
182+ metrics.top = metrics.ascent
183+ metrics.descent = paintMetrics.descent + verticalShift
184+ metrics.bottom = metrics.descent
185+ } else {
186+ // Block mode calculations remain unchanged
187+ val totalHeight = (imageHeight * 1.2 ).toInt()
188+ metrics.ascent = - totalHeight / 2
189+ metrics.top = metrics.ascent
190+ metrics.descent = totalHeight / 2
191+ metrics.bottom = metrics.descent
192+ }
175193 }
176-
177- return rect.right
194+ return bounds.right
178195 }
179196
180197 override fun draw (
@@ -183,21 +200,28 @@ private class LatexImageSpan(drawable: Drawable) : ImageSpan(drawable) {
183200 start : Int ,
184201 end : Int ,
185202 x : Float ,
186- top : Int ,
187- y : Int ,
188- bottom : Int ,
203+ lineTop : Int ,
204+ baseline : Int ,
205+ lineBottom : Int ,
189206 paint : Paint
190207 ) {
191- val drawable = drawable
192208 canvas.save()
193209
194- // Calculate vertical centering
195- val paintMetrics = paint.fontMetricsInt
196- val fontHeight = paintMetrics.descent - paintMetrics.ascent
197- val centerY = y + paintMetrics.descent - fontHeight / 2
198- val transY = centerY - (drawable.bounds.bottom - drawable.bounds.top) / 2
210+ val imageHeight = drawable.bounds.height()
211+ val yPosition = when {
212+ isInline -> {
213+ // Apply downward shift for inline equations
214+ val textMidline = baseline - (paint.fontMetrics.descent - paint.fontMetrics.ascent) / 2
215+ val shiftOffset = (paint.fontMetricsInt.descent * INLINE_SHIFT_FACTOR ).toInt()
216+ textMidline - (imageHeight / 2 ) + shiftOffset
217+ }
218+ else -> {
219+ // Block mode remains centered
220+ lineTop + (lineBottom - lineTop - imageHeight) / 2
221+ }
222+ }
199223
200- canvas.translate(x, transY .toFloat())
224+ canvas.translate(x, yPosition .toFloat())
201225 drawable.draw(canvas)
202226 canvas.restore()
203227 }
0 commit comments