# Aligning text in drawer.writer

**URL:** <https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549>\
**Category:** Feature requests\
**Created:** [April 17, 2023, 5:57pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549 "2023-04-17T17:57:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![aahdee](https://avatars.discourse-cdn.com/v4/letter/a/d78d45/32.png) [@aahdee](https://openrndr.discourse.group/u/aahdee)\
**Post date:** [April 17, 2023, 5:57pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549/1 "2023-04-17T17:57:20Z")

</div>

Doing manual calculations for when I’d like to center to right align text can be frustrating, especially for longer paragraphs. Having it built into drawer.writer would be useful for text presentation and manipulation.  
For example, p5.js has a [textAlign](https://p5js.org/reference/#/p5/textAlign) function that allows you to place text to the left, center, or right of a given start point. They even go as far as vertical align, but I dont think thats nearly as useful as center and right align.

---

<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:** [April 18, 2023, 4:36pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549/2 "2023-04-18T16:36:23Z")

</div>

Hi! I took a first attempt at doing this. The idea is to pass uv coordinates to `drawer.text()` as a third argument. For instance `Vector2(0.5, 0.5)` would be used for aligning a text to the center. The `TextAlign` class contains some frequent locations (the typical 9 grid points).

![tests.TextAlign-2023-04-18-16.16.40](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/514e7ad6e38ca3b8699abe8d632c40abaddd1382.png)

```kotlin
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.Drawer
import org.openrndr.draw.Writer
import org.openrndr.draw.isolated
import org.openrndr.draw.loadFont
import org.openrndr.math.Vector2

fun main() = application {
    program {
        val word = "H|j"
        val font = loadFont("data/fonts/default.otf", 100.0, word.toSet())

        fun pos(u: Double, v: Double) = drawer.bounds.position(u, v)

        extend {
            drawer.clear(ColorRGBa.WHITE)
            drawer.fill = ColorRGBa.BLACK
            drawer.fontMap = font
            drawer.text(word, pos(1.0, 0.0), TextAlign.TOP_RIGHT)
            drawer.text(word, pos(0.0, 1.0), TextAlign.BOTTOM_LEFT)
            drawer.text(word, pos(1.0, 1.0), TextAlign.BOTTOM_RIGHT)
            drawer.text(word, pos(0.0, 0.0), TextAlign.TOP_LEFT)

            drawer.text(word, pos(0.5, 0.0), TextAlign.TOP)
            drawer.text(word, pos(0.5, 1.0), TextAlign.BOTTOM)
            drawer.text(word, pos(1.0, 0.5), TextAlign.RIGHT)
            drawer.text(word, pos(0.0, 0.5), TextAlign.LEFT)

            drawer.text(word, pos(0.5, 0.5), TextAlign.CENTER)

            drawer.stroke = ColorRGBa.BLACK.opacify(0.3)
            drawer.lineSegment(pos(0.5, 0.0), pos(0.5, 1.0))
            drawer.lineSegment(pos(0.0, 0.5), pos(1.0, 0.5))
        }
    }
}

/**
 * Text alignment presets
 */
class TextAlign {
    companion object {
        val CENTER = Vector2(0.5, 0.5)
        val LEFT = Vector2(0.0, 0.5)
        val RIGHT = Vector2(1.0, 0.5)
        val TOP = Vector2(0.5, 0.0)
        val BOTTOM = Vector2(0.5, 1.0)
        val TOP_LEFT = Vector2(0.0, 0.0)
        val TOP_RIGHT = Vector2(1.0, 0.0)
        val BOTTOM_LEFT = Vector2(0.0, 1.0)
        val BOTTOM_RIGHT = Vector2(1.0, 1.0)
    }
}

/**
 * A version of `Drawer.text()` accepting an [align] argument.
 */
private fun Drawer.text(txt: String, pos: Vector2, align: Vector2) {
    fontMap?.let { fm ->
        val writer = Writer(this)
        val off = Vector2(
            -writer.textWidth(txt) * align.x,
            fm.height * (1 - align.y)
        )
        text(txt, pos + off)
    }
}

```

I will think more about it. Also about multiline text.

---

<div class="post-metadata">

**Author:** ![aahdee](https://avatars.discourse-cdn.com/v4/letter/a/d78d45/32.png) [@aahdee](https://openrndr.discourse.group/u/aahdee)\
**Post date:** [April 21, 2023, 2:37pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549/3 "2023-04-21T14:37:54Z")

</div>

Thats a pretty good idea. I was playing around with overloading the `Writer.text` function and using a similar thought process as you, but it doesnt apply to all of the lines. Heres what I wrote before I stopped.

```auto
fun Writer.text(text: String, align: Vector2){                                      
    drawerRef?.fontMap?.let { fm ->                                                 
        val writer = Writer(drawerRef)                                              
        val off = Vector2(                                                          
            -writer.textWidth(text) * align.x,                                      
            fm.height * (1 - align.y)                                               
        )                                                                           
       box = Rectangle(box.x + off.x, box.y + off.y, box.width, box.height)         
                                                                                    
                                                                                    
       text(text)                                                                   
    }                                                                               
}                                                                                   

```

---

<div class="post-metadata">

**Author:** ![sidec](https://avatars.discourse-cdn.com/v4/letter/s/9fc29f/32.png) [@sidec](https://openrndr.discourse.group/u/sidec)\
**Post date:** [August 4, 2023, 7:36pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549/4 "2023-08-04T19:36:49Z")

</div>

this is so cool and solves the problem in so clever way that should find its way to the guide

---

<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:** [March 22, 2026, 12:28pm UTC](https://openrndr.discourse.group/t/aligning-text-in-drawer-writer/549/5 "2026-03-22T12:28:26Z")

</div>

It’s been a while since this was asked, but now there are powerful aligning features in

> **[orx/orx-text-writer at master · openrndr/orx](https://github.com/openrndr/orx/tree/master/orx-text-writer)**
>
> A growing library of assorted data structures, algorithms and utilities for OPENRNDR - openrndr/orx

🙂

 ![](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/fa5d696c02f2c11fe4f2e9377043961478490725.png)
