Skip to content

Commit b9b9fea

Browse files
committed
inline shift approach
1 parent cb120e1 commit b9b9fea

File tree

1 file changed

+53
-29
lines changed

1 file changed

+53
-29
lines changed

utility/src/main/java/org/oppia/android/util/parser/html/MathTagHandler.kt

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import android.graphics.Paint
77
import android.graphics.drawable.Drawable
88
import android.text.Editable
99
import android.text.Spannable
10+
import android.text.style.DynamicDrawableSpan
1011
import android.text.style.ImageSpan
12+
import android.text.style.ReplacementSpan
1113
import androidx.core.content.res.ResourcesCompat
1214
import io.github.karino2.kotlitex.view.MathExpressionSpan
15+
import java.lang.ref.WeakReference
1316
import org.json.JSONObject
1417
import org.oppia.android.util.R
1518
import 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

Comments
 (0)