Hey, @guzba and me have done a bunch more work on Pixie that is pretty cool to share.
For those that don't know, Pixie is a pure Nim 2D graphics library (think image file loading, editing, paths, SVG etc). Now we've added really deep support for text.
I already have a repo for rendering text called Typography but as Pixie became more mature I decided to integrate text layout and rendering into Pixie instead of a separate repo. We've also improved text handling even more.
Features:
Examples:
import pixie
let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
font.size = 20
let text = "Typesetting is the arrangement and composition of text in graphic design and publishing in both digital and traditional medias."
image.fillText(font.typeset(text, bounds = vec2(180, 180)), vec2(10, 10))
image.writeFile("examples/text.png")
import pixie
let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
let font = readFont("tests/fonts/Ubuntu-Regular_1.ttf")
proc style(font: Font, size: float32, color: ColorRGBA): Font =
result = font
result.size = size
result.paint.color = color
let spans = @[
newSpan("verb [with object] ", font.style(12, rgba(200, 200, 200, 255))),
newSpan("strallow\n", font.style(36, rgba(0, 0, 0, 255))),
newSpan("\nstral·low\n", font.style(13, rgba(0, 127, 244, 255))),
newSpan("\n1. free (something) from restrictive restrictions \"the regulations are intended to strallow changes in public policy\" ",
font.style(14, rgba(80, 80, 80, 255)))
]
image.fillText(typeset(spans, bounds = vec2(180, 180)), vec2(10, 10))
image.writeFile("examples/text_spans.png")
I'm not sure since I never did something of this scope. All the other neovim GUI's look quite complicated too.
Totally a neovim UI would be really cool. You have everything, its just how fancy you want it to be? Some one made the UI using SDL: https://github.com/etorth/libnvc, its definitely possible.
Pixie would have everything you would need at this point to draw things. Maybe use staticglfw for input?
How do you use it with glfw? Can pixie render onto an opengl context?
When i was making a vim GUI (not neovim) last year i settled on stb_truetype for text. I think it's a lot more primitive than your text renderer here though. Would it be possible to mix it with normal opengl code?
You can see in the demo.nim how to make real time apps with pixie: https://github.com/treeform/pixie/blob/master/src/pixie/demo.nim
It just has a pixie image called screen and it transfers it to a texture every frame. It uses GLFW for windowing and input.
Here are examples of where demo is used: https://github.com/treeform/bumpy/blob/master/examples/convexhull.nim https://github.com/treeform/bumpy/blob/master/examples/circle2circle.nim
I should probably include a real-time example.
I use staticglfw because I maintain it: https://github.com/treeform/staticglfw
Yes use fillText to draw some text to an image then send that image to an open openGL texture.
At first I focused on having a text atlas to manage. In this texture-text-atlas every letter-font-size had its own square. But problems with text atlas quickly explodes, subpixel versions, Chinese characters, what if text is rotated. Meanwhile our text render got really fast, we could render anything very quickly and text does not change that often.
We found it faster to just draw whole paragraphs of text then send them over to a texture and only redraw the texture when text changes.
Thank you!
But really we changed some minor APIs and now stuff breaks compatibility. We plan to have many versions.
I'm happy to see the integration with typography. Congrats the project reaches 2.0.
I would suggest writing a blog post to introduce this library. You can share the link on Hacker News so that more people can know your work and nim.
Hey @jyapayne, I made the demo work on high DPI screens: https://github.com/treeform/pixie/pull/197
They key to high DPI is to know your DPI scaling and scaling everything appropriately, including the mouse position.
Let me know if that works for you?