Advertisement
Guest User

Untitled

a guest
Apr 9th, 2020
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 5.11 KB | None | 0 0
  1. package coffee.injected.latte.view.engine
  2.  
  3. import coffee.injected.latte.util.Color
  4. import coffee.injected.latte.util.Corners
  5. import coffee.injected.latte.view.engine.texture.Texture
  6. import coffee.injected.latte.view.engine.texture.TextureStitcher
  7. import coffee.injected.latte.view.engine.texture.TexturedRectRenderer
  8. import coffee.injected.latte.view.engine.texture.VertexTessellator
  9. import coffee.injected.latte.view.part.RectAttributes
  10. import coffee.injected.latte.view.part.RectViewPart
  11. import java.lang.Float.min
  12. import kotlin.math.cos
  13. import kotlin.math.max
  14. import kotlin.math.sin
  15.  
  16. class TessellatingRectRenderer(val tessellator: VertexTessellator) : ViewPartRenderer<RectViewPart, RectAttributes> {
  17.  
  18.     override fun render(part: RectViewPart, attributes: RectAttributes, context: ViewRenderContext) {
  19.         val x = context.translateX + part.contentRegion.x
  20.         val y = context.translateY + part.contentRegion.y
  21.         val w = part.contentRegion.width
  22.         val h = part.contentRegion.height
  23.  
  24.         val color = attributes.color.value
  25.         val texture = attributes.texture.value
  26.         val stitcher = if (texture != null) attributes.textureStitcher.value else TextureStitcher.ATTACH
  27.         val corners = attributes.cornerRadius.value
  28.  
  29.         if (color.alpha > 0) {
  30.             tessellator.setup(texture)
  31.  
  32.             val renderer = Renderer(tessellator, x, y, color, corners, texture)
  33.             stitcher.draw(renderer, w, h, texture?.width ?: w, texture?.height ?: h)
  34.  
  35.             tessellator.end()
  36.         }
  37.     }
  38.  
  39.     private class Renderer(
  40.         val tessellator: VertexTessellator,
  41.         val rootX: Float,
  42.         val rootY: Float,
  43.         val color: Color,
  44.         val corners: Corners<Float>,
  45.         val texture: Texture?
  46.     ) : TexturedRectRenderer {
  47.  
  48.         override fun drawRect(
  49.             x: Float, y: Float, width: Float, height: Float, tx: Float, ty: Float, tw: Float, th: Float,
  50.             radius1: Boolean, radius2: Boolean, radius3: Boolean, radius4: Boolean
  51.         ) {
  52.             val red = color.red
  53.             val green = color.green
  54.             val blue = color.blue
  55.             val alpha = color.alpha
  56.  
  57.             fun vertex(cx: Float, cy: Float) {
  58.                 val u = texture?.u(tx + tw * (cx - x) / width) ?: 0f
  59.                 val v = texture?.u(ty + th * (cy - y) / height) ?: 0f
  60.  
  61.                 tessellator.vertex(rootX + cx, rootY + cy, red, green, blue, alpha, u, v)
  62.             }
  63.  
  64.             fun rect(x1: Float, y1: Float, x2: Float, y2: Float) {
  65.                 vertex(x1, y1)
  66.                 vertex(x2, y1)
  67.                 vertex(x1, y2)
  68.                 vertex(x2, y1)
  69.                 vertex(x1, y2)
  70.                 vertex(x2, y2)
  71.             }
  72.  
  73.             fun angle(x: Float, y: Float, radius: Float, start: Int, steps: Int = 5) {
  74.                 val step = 90f / steps
  75.                 val stepRad = Math.toRadians(step.toDouble())
  76.                 var angle = Math.toRadians(start.toDouble())
  77.  
  78.                 for (i in 0..steps) {
  79.                     val x1 = x + radius * cos(angle).toFloat()
  80.                     val y1 = y + radius * sin(angle).toFloat()
  81.                     vertex(x1, y1)
  82.  
  83.                     if (i < steps) {
  84.                         vertex(x, y)
  85.                         if (i != 0) vertex(x1, y1)
  86.                     }
  87.  
  88.                     angle += stepRad
  89.                 }
  90.             }
  91.  
  92.             val x1 = x
  93.             val y1 = y
  94.             val x2 = x + width
  95.             val y2 = y + height
  96.  
  97.             val maxRadius = min(width / 2, height / 2)
  98.             val r1 = if (radius1) corners.topLeft.coerceAtMost(maxRadius) else 0f
  99.             val r2 = if (radius2) corners.topRight.coerceAtMost(maxRadius) else 0f
  100.             val r3 = if (radius3) corners.bottomRight.coerceAtMost(maxRadius) else 0f
  101.             val r4 = if (radius4) corners.bottomLeft.coerceAtMost(maxRadius) else 0f
  102.  
  103.             val cy1 = y1 + max(r1, r2)
  104.             val cy2 = y2 - max(r3, r4)
  105.  
  106.             // render top plate and corners
  107.             if (r1 != 0f || r2 != 0f) {
  108.                 val cx1 = x1 + r1
  109.                 val cx2 = x2 - r2
  110.  
  111.                 rect(cx1, y1, cx2, cy1)
  112.  
  113.                 if (r1 != r2) {
  114.                     if (r1 > r2) rect(cx2, y1 + r2, x2, cy1)
  115.                     else rect(x1, y1 + r1, cx1, cy1)
  116.                 }
  117.  
  118.                 if (r1 != 0f) angle(cx1, y1 + r1, r1, 180)
  119.                 if (r2 != 0f) angle(cx2, y1 + r2, r2, 270)
  120.             }
  121.  
  122.             // render bottom plate and corners
  123.             if (r3 != 0f || r4 != 0f) {
  124.                 val cx1 = x1 + r4
  125.                 val cx2 = x2 - r3
  126.  
  127.                 rect(cx1, cy2, cx2, y2)
  128.  
  129.                 if (r3 != r4) {
  130.                     if (r4 > r3) rect(cx2, cy2, x2, y2 - r3)
  131.                     else rect(x1, cy2, cx1, y2 - r4)
  132.                 }
  133.  
  134.                 if (r4 != 0f) angle(cx1, y2 - r4, r4, 90)
  135.                 if (r3 != 0f) angle(cx2, y2 - r3, r3, 0)
  136.             }
  137.  
  138.             //render center plate
  139.             if (cy1 < cy2) {
  140.                 rect(x1, cy1, x2, cy2)
  141.             }
  142.         }
  143.  
  144.     }
  145.  
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement