JetBrains / skiko

Kotlin Multiplatform bindings to Skia
Apache License 2.0
1.82k stars 118 forks source link

Resizing window leads to text unclear and layout change. #961

Closed MrZhuKeXin closed 1 month ago

MrZhuKeXin commented 3 months ago

Problem Description:

When running SkiaAwtSample.

  1. On Windows 11(Ver.22631.3880), when running the demo program with Direct3D by default and resizing the window, the size of the text and text bounding boxes changes, and the text fluctuates between blurry and clear, and text may become blurry after adjusting the window.
  2. Switching to OpenGL(val skiaLayer = SkiaLayer(pixelGeometry = pixelGeometry, renderApi = GraphicsApi.OPENGL)) basically solves the problem, but the canvas update speed slows down, and the vertical position jumps when resizing the window vertically.

I also found that this issue occurs in Compose Multiplatform, affecting text rendering and general UI elements, usually when resizing the window.

Directx3D

https://github.com/user-attachments/assets/694d73bc-344b-43f4-b171-7b37d220863f

Comparison images showing the text clarity and blurriness after resizing the window:

Snipaste_2024-07-20_03-20-20

OpenGL

It can be observed that when resizing the window vertically, there is a deviation in the vertical coordinates. It seems to be caused by rounding errors in floating-point coordinates?

https://github.com/user-attachments/assets/d99ddcce-3505-46e3-a834-d51247e970da

Code

In the App.kt file of SkiaAwtSample, replace ClocksAwt with DemoRender.

package SkiaAwtSample.demo

import org.jetbrains.skia.*
import org.jetbrains.skia.paragraph.*
import org.jetbrains.skiko.*
import java.awt.event.MouseEvent
import java.awt.event.MouseMotionListener

open class DemoRender(private val scaleProvider: () -> Float) : SkikoRenderDelegate, MouseMotionListener {
    constructor(layer: SkiaLayer) : this({ layer.contentScale })

    private var frame = 0
    private var xpos = 0
    private var ypos = 0

    val pos = Point(50f, 100f)
    val text =
        """Welcome to the Jetpack Compose roadmap, outlining upcoming plans for Jetpack Compose. For completed features, please see release notes.These are the features that the team is currently thinking about and working on. This roadmap is shared with the best intent, however, it's not exhaustive and priorities might change as we learn more and continue to get feedback from you - our users.In Focus items are being worked on soon and are likely to land in an upcoming stable release. Backlog items are planned but not likely to land soon."""

    var pWidth = 300f

    val fontMgr = FontMgr.default
    private val fontCollection = FontCollection().apply {
        setDefaultFontManager(fontMgr)
    }
    private val boxPaint = Paint().apply {
        color = Color.RED
        mode = PaintMode.STROKE
        strokeWidth = 1f
        isAntiAlias = false
    }

    override fun onRender(canvas: Canvas, width: Int, height: Int, nanoTime: Long) {
        frame++
        val paragraphStyle = ParagraphStyle().apply {
            fontRastrSettings = FontRastrSettings(
                FontEdging.SUBPIXEL_ANTI_ALIAS,
                FontHinting.SLIGHT,
                true
            )
            textStyle = TextStyle().apply {
                color = Color.BLACK
                fontSize = 14f
                alignment = Alignment.LEFT
            }
        }
        val paragraph = ParagraphBuilder(style = paragraphStyle, fc = fontCollection)
            .addText(text)
            .build()
        paragraph.layout(pWidth)
        paragraph.paint(canvas, pos.x, pos.y)
        canvas.drawRect(Rect(pos.x, pos.y, pos.x + pWidth, pos.y + paragraph.height), boxPaint)
    }

    override fun mouseDragged(e: MouseEvent) {
    }

    override fun mouseMoved(e: MouseEvent) {
        xpos = e.x
        ypos = e.y
    }
}
okushnikov commented 1 month ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.