# Trouble with trying to align text

**URL:** <https://openrndr.discourse.group/t/trouble-with-trying-to-align-text/320>\
**Category:** Beginners\
**Created:** [January 12, 2022, 11:38pm UTC](https://openrndr.discourse.group/t/trouble-with-trying-to-align-text/320 "2022-01-12T23:38:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![JochemP](https://avatars.discourse-cdn.com/v4/letter/j/eada6e/32.png) [@JochemP](https://openrndr.discourse.group/u/JochemP)\
**Post date:** [January 12, 2022, 11:38pm UTC](https://openrndr.discourse.group/t/trouble-with-trying-to-align-text/320/1 "2022-01-12T23:38:29Z")

</div>

Im new to openrndr. Im trying to align text to center. I found this [openrndr-demos-span-2018/Text.kt at master · openrndr/openrndr-demos-span-2018 · GitHub](https://github.com/openrndr/openrndr-demos-span-2018/blob/master/src/main/kotlin/demos/Text.kt) but i dont know how to get this into a project. i tried creating a new project with the above url with git but it doesnt recognise the org.openrndr imports.

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [January 13, 2022, 11:29am UTC](https://openrndr.discourse.group/t/trouble-with-trying-to-align-text/320/2 "2022-01-13T11:29:23Z")

</div>

Hello and welcome to the forum 🙂

Thanks for posting that aligning example! I didn’t know about it.

Here’s an example usage:

```kotlin
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.*
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle

class Text(
    val drawer: Drawer,
    val text: String,
    url: String,
    size: Double
) {
    val font = FontImageMap.fromUrl(url, size)
    val writer = Writer(drawer)
    val height: Double
        get() {
            val isUpper = text.fold(true) { acc, char ->
                acc && (char.isUpperCase() || char.isDigit() || char.isWhitespace())
            }
            return if (isUpper) {
                font.height
            } else {
                font.height - font.descenderLength
            }
        }
    val width = font.let {
        drawer.fontMap = font
// println("""
// asc: ${font.ascenderLength}
// height: ${font.height}
// """.trimIndent())
        writer.textWidth(text)
    }

    private val fillRenderTarget by lazy {
        renderTarget(width.toInt(), height.toInt()) {
            colorBuffer()
        }
    }

    enum class HorizontalAlign {
        LEFT,
        CENTER,
        RIGHT
    }

    enum class VerticalAlign {
        ASCENDER,

        // XHEIGHT,
        BASELINE,
        DESCENDER,

        // CENTER_XHEIGHT,
        CENTER,
        CENTER_FULL,
        ;
    }

    fun align(
        horizontalAlign: HorizontalAlign,
        verticalAlign: VerticalAlign
    ): Vector2 {
        val deltaX = when (horizontalAlign) {
            HorizontalAlign.LEFT -> 0.0
            HorizontalAlign.CENTER -> -width / 2.0
            HorizontalAlign.RIGHT -> -width
        }
        val deltaY = when (verticalAlign) {
            VerticalAlign.BASELINE -> 0.0
            VerticalAlign.ASCENDER -> font.height
            /// Not sure if we need all these vertical alignment options
            VerticalAlign.CENTER -> font.height / 2.0
            VerticalAlign.CENTER_FULL -> ((font.ascenderLength + font.descenderLength) / 2.0)
            VerticalAlign.DESCENDER -> font.descenderLength
        }
        return Vector2(deltaX, deltaY)
    }

    // draws text stretched to the width and height of a target rectangle
    fun stretch(target: Rectangle, fn: Drawer.() -> Unit) {
        drawer.isolatedWithTarget(fillRenderTarget) {
            drawer.background(ColorRGBa.TRANSPARENT)
            drawer.ortho(fillRenderTarget)
            fn()
            draw(
                Vector2(0.0, 0.0),
                HorizontalAlign.LEFT,
                VerticalAlign.ASCENDER
            )
        }
        drawer.image(
            fillRenderTarget.colorBuffer(0),
            target.corner,
            target.width,
            target.height
        )
    }

    fun draw(
        position: Vector2,
        horizontalAlign: HorizontalAlign = HorizontalAlign.LEFT,
        verticalAlign: VerticalAlign = VerticalAlign.BASELINE
    ) {
        drawer.fontMap = font
        val alignment = align(horizontalAlign, verticalAlign)
        drawer.text(text, position + alignment)
    }

    fun explain(
        position: Vector2,
        horizontalAlign: HorizontalAlign = HorizontalAlign.LEFT,
        verticalAlign: VerticalAlign = VerticalAlign.BASELINE
    ) {

        drawer.fontMap = font
        val alignment = align(horizontalAlign, verticalAlign)
        val p = position + alignment

        // LEADING
        drawer.fill = ColorRGBa.PINK
        drawer.rectangle(p - Vector2(0.0, font.leading), width, font.leading)

        // ASC
        drawer.fill = ColorRGBa.BLUE.shade(0.5)
        drawer.rectangle(
            p - Vector2(0.0, font.ascenderLength),
            width,
            font.ascenderLength
        )

        // HEIGHT
        drawer.fill = ColorRGBa.GRAY
        drawer.rectangle(p - Vector2(0.0, font.height), width, font.height)

        // DESC
        drawer.fill = ColorRGBa.BLUE
        drawer.rectangle(p, width, -font.descenderLength)

        drawer.fill = ColorRGBa.BLACK
        drawer.text(text, p)
    }

}

fun main() = application {
    program {
        val t = Text(drawer, "hello", "file:data/fonts/default.otf", 100.0)
        extend {
            t.draw(
                drawer.bounds.center,
                Text.HorizontalAlign.CENTER,
                Text.VerticalAlign.CENTER
            )
        }
    }
}

```

To use this code I would first clone the `openrndr-template` repository and make sure that `TemplateProgram.kt` runs fine.

Then you can create a second `.kt` file with this content next to `TemplateProgram.kt`.  
Ideally you would move the `Text` class to its own file to have things better organized.

Let us know if you have trouble making it run.

ps. Ah it also assumes that you have a `data/fonts` folder containing the `default.otf` font.

---

<div class="post-metadata">

**Author:** ![JochemP](https://avatars.discourse-cdn.com/v4/letter/j/eada6e/32.png) [@JochemP](https://openrndr.discourse.group/u/JochemP)\
**Post date:** [January 13, 2022, 6:43pm UTC](https://openrndr.discourse.group/t/trouble-with-trying-to-align-text/320/3 "2022-01-13T18:43:56Z")

</div>

It works! Thank you for your help and for welcoming me.
