All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
commonMain.ru.casperix.multiplatform.text.impl.TextLayoutRender.kt Maven / Gradle / Ivy
package ru.casperix.multiplatform.text.impl
import ru.casperix.multiplatform.dimension
import ru.casperix.multiplatform.font.pixel.PixelFont
import ru.casperix.math.color.Color
import ru.casperix.math.color.Colors
import ru.casperix.math.quad_matrix.float32.Matrix3f
import ru.casperix.math.straight_line.float32.LineSegment2f
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.renderer.Renderer2D
import ru.casperix.renderer.material.SimpleMaterial
import ru.casperix.renderer.material.Texture
import ru.casperix.multiplatform.text.TextLayout
import ru.casperix.multiplatform.text.TextRenderConfig
import ru.casperix.renderer.vector.builder.VectorBuilder
import kotlin.math.roundToInt
@ExperimentalUnsignedTypes
object TextLayoutRender {
fun drawTextLayoutMetrics(
renderer: Renderer2D,
matrix: Matrix3f,
font: PixelFont,
layout: TextLayout
) = renderer.run {
val area = layout.getArea()
drawBox(Colors.BLACK.setAlpha(0.2f), area, matrix)
val lineThick = 1f
val alpha = 0.6f
layout.symbols.forEach { symbolLayout ->
val xAxis = symbolLayout.symbol.size.xAxis.toVector2f()
val baseLinePivot = symbolLayout.pivot
val ascentLine = LineSegment2f.byDelta(baseLinePivot - Vector2f(0f, font.metrics.ascent), xAxis)
val baseLine = LineSegment2f.byDelta(baseLinePivot, xAxis)
val descentLine = LineSegment2f.byDelta(baseLinePivot + Vector2f(0f, font.metrics.descent), xAxis)
val bottomLine = LineSegment2f.byDelta(baseLinePivot + Vector2f(0f, font.metrics.descent + font.metrics.leading), xAxis)
drawSegment(Colors.GREEN.setAlpha(alpha), matrix.transform(ascentLine), lineThick)
drawSegment(Colors.RED.setAlpha(alpha), matrix.transform(baseLine), lineThick)
drawSegment(Colors.BLUE.setAlpha(alpha), matrix.transform(descentLine), lineThick)
drawSegment(Colors.YELLOW.setAlpha(alpha), matrix.transform(bottomLine), lineThick)
}
}
fun drawTextLayout(
renderer: Renderer2D,
matrix: Matrix3f,
color: Color,
layout: TextLayout
) {
var lastAtlas: Texture? = null
var lastMaterial = SimpleMaterial()
val graphicList = layout.symbols.mapNotNull { symbolLayout ->
val graphic = symbolLayout.symbol.graphic
if (graphic != null) {
Pair(symbolLayout.pivot + symbolLayout.symbol.baselineOffset.toVector2f(), graphic)
} else null
}
val builder = VectorBuilder(hasPosition2 = true, hasTextureCoord = true)
graphicList.forEachIndexed { index, (position, pixelRegion) ->
val atlas = pixelRegion.atlas
val atlasSize = atlas.map.dimension().toVector2f()
val sizeFloat = pixelRegion.region.dimension.toVector2f()
val childMatrix = Matrix3f.translate(position)
val summaryMatrix = childMatrix * matrix
if (TextRenderConfig.textRoundToPixel) {
summaryMatrix.roundTranslate()
}
if (lastAtlas == null) {
lastMaterial = SimpleMaterial(color, albedoMap = atlas)
lastAtlas = atlas
} else if (lastAtlas != atlas) {
throw Exception("Please pack font with PixelFontPacker")
}
val tex00 = pixelRegion.region.min.toVector2f() / atlasSize
val tex11 = (pixelRegion.region.max + Vector2i.ONE).toVector2f() / atlasSize
val tex10 = Vector2f(tex11.x, tex00.y)
val tex01 = Vector2f(tex00.x, tex11.y)
val pos00 = summaryMatrix.transform(Vector2f.ZERO)
val pos10 = summaryMatrix.transform(sizeFloat.xAxis)
val pos11 = summaryMatrix.transform(sizeFloat)
val pos01 = summaryMatrix.transform(sizeFloat.yAxis)
builder.addQuad(pos00, pos10, pos11, pos01, tex00, tex10, tex11, tex01)
}
val material = lastMaterial
renderer.drawGraphic(builder.buildGraphic(material))
}
private fun Matrix3f.roundTranslate() {
data[6] = data[6].roundToInt().toFloat()
data[7] = data[7].roundToInt().toFloat()
}
}