Skip to content

Commit

Permalink
updating tests
Browse files Browse the repository at this point in the history
  • Loading branch information
manas-yu committed Jan 25, 2025
1 parent b9b9fea commit 5e99381
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ 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 @@ -154,44 +151,56 @@ class MathTagHandler(

/** An [ImageSpan] that vertically centers a LaTeX drawable within the surrounding text. */
private class LatexImageSpan(
private val drawable: Drawable,
private val isInline: Boolean
) : ReplacementSpan() {
imageDrawable: Drawable?,
private val isInlineMode: Boolean
) : ImageSpan(imageDrawable ?: createEmptyDrawable()) {

companion object {
private const val INLINE_SHIFT_FACTOR = 0.9f // Adjust this value (0.2-0.4) as needed
private const val INLINE_VERTICAL_SHIFT_RATIO = 0.9f

private fun createEmptyDrawable(): Drawable {
return object : Drawable() {
override fun draw(canvas: Canvas) {}
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(colorFilter: android.graphics.ColorFilter?) {}
override fun getOpacity(): Int = android.graphics.PixelFormat.TRANSPARENT

init {
setBounds(0, 0, 1, 1)
}
}
}
}

override fun getSize(
paint: Paint,
text: CharSequence,
start: Int,
end: Int,
fm: Paint.FontMetricsInt?
fontMetrics: Paint.FontMetricsInt?
): Int {
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 drawableBounds = drawable.bounds
val imageHeight = drawableBounds.height()
val textMetrics = paint.fontMetricsInt
val textHeight = textMetrics.descent - textMetrics.ascent

fontMetrics?.let { metrics ->
if (isInlineMode) {
val verticalShift = (imageHeight - textHeight) / 2 +
(paintMetrics.descent * INLINE_SHIFT_FACTOR).toInt()
metrics.ascent = paintMetrics.ascent - verticalShift
(textMetrics.descent * INLINE_VERTICAL_SHIFT_RATIO).toInt()
metrics.ascent = textMetrics.ascent - verticalShift
metrics.top = metrics.ascent
metrics.descent = paintMetrics.descent + verticalShift
metrics.descent = textMetrics.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 bounds.right
return drawableBounds.right
}

override fun draw(
Expand All @@ -208,20 +217,17 @@ private class LatexImageSpan(
canvas.save()

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
}
val yOffset = if (isInlineMode) {
val metrics = paint.fontMetricsInt
val ascent = metrics.ascent.toFloat()
val descent = metrics.descent.toFloat()
val expectedCenterY = baseline.toFloat() + (ascent + descent) / 2f
expectedCenterY - (imageHeight / 2f)
} else {
lineTop.toFloat() + (lineBottom - lineTop - imageHeight) / 2f
}

canvas.translate(x, yPosition.toFloat())
canvas.translate(x, yOffset)
drawable.draw(canvas)
canvas.restore()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ class MathTagHandlerTest {

val metrics = paint.fontMetricsInt
val y = 100
val expectedCenterY = y + (metrics.descent + metrics.ascent) / 2f

imageSpans[0].draw(
mockCanvas,
Expand All @@ -168,17 +167,20 @@ class MathTagHandlerTest {
200,
paint
)
// The canvas should be translated to center the drawable vertically

val textHeight = (metrics.descent - metrics.ascent).toFloat()
val textMidline = y.toFloat() - (textHeight / 2f)
val verticalShift = metrics.descent * 0.9f
val drawable = imageSpans[0].drawable
val expectedTranslation = textMidline + verticalShift - (drawable.bounds.height() / 2f)

// The translation should position the drawable centered around the text baseline
verify(mockCanvas).save()
verify(mockCanvas).translate(
eq(0f),
capture(floatCaptor)
)
// The translation should position the drawable centered around the text baseline
val drawable = imageSpans[0].drawable
val expectedTranslation = expectedCenterY - (drawable.bounds.height() / 2)
assertThat(floatCaptor.value).isWithin(1f).of(expectedTranslation)

verify(mockCanvas).restore()
}

Expand Down Expand Up @@ -233,6 +235,7 @@ class MathTagHandlerTest {
val lineHeight = paint.textSize * 1.2f
assertThat(totalHeight.toFloat()).isLessThan(lineHeight)
}

@Test
fun testParseHtml_emptyString_doesNotIncludeImageSpan() {
val parsedHtml =
Expand Down

0 comments on commit 5e99381

Please sign in to comment.