7 ms·
Is your Ruby-based terminal source online? I'd love to see it.
by brainbag 3y ago
Is your Ruby-based terminal source online? I'd love to see it.
- vidarh 3y agoNo current version, but I'm preparing it. But actually, to see a really ridiculously minimalist start, this was my starting point, which used a tiny C extension to do the X rendering (though it optimistically included a dummy class intended to be the start for the Ruby X backend). It's awfully limited, and awfully broken, but it shows how little it takes to be able to start writing: https://github.com/vidarh/rubyterm https://github.com/vidarh/rubyterm It's totally useless for anything other that testing or expanding on, but it was the starting point for the terminal I now run every day, and I'll be updating that repo as I clean up my current version at some point. The current version uses this for a pure Ruby (no Xlib) X11 client implementation: https://github.com/vidarh/ruby-x11 https://github.com/vidarh/ruby-x11 And this pure-Ruby TrueType font renderer (I did the Ruby conversion; the C code it's based on was not mine, and is a beautiful example of compact C - look up libschrift) as I got tired of using the bitmap fonts and didn't want to add a FreeType dependency (the renderer is ~500 lines of code): https://github.com/vidarh/skrift https://github.com/vidarh/skrift
- kragen 3y agoi look forward to seeing it! the simple, approachable truetype implementation is very exciting already! i didn't know about libschrift, but one third the code makes Skrift three times as approachable do you have an output sample like https://github.com/tomolt/libschrift/raw/master/resources/demo-screenshot.png https://github.com/tomolt/libschrift/raw/master/resources/de...?
- vidarh 3y agoI really should just reproduce that output in its entirety for direct comparison. If it does not produce pixel for pixel identical output it's a bug. But here is the first pass of code that uses the same approach to integrate it with X and use Xrender to output the rendered glyphs: https://github.com/vidarh/skrift-x11 https://github.com/vidarh/skrift-x11 (EDIT: Fixed the issue below) Note that the example contains a hard coded visual. I need to push a fix for that - it was last updated before I added support to the X11 client to look up the visual. In it's current form it probably won't work for you. Will see if I can push a fix for that today.
- kragen 3y agonice! probably magenta on a red background is undesirable, though; maybe switch to colors with better contrasts, or add a border or drop shadow, or just postprocess with a zero-phase high-pass filter i hate x11 visuals and in https://gitlab.com/kragen/bubbleos/blob/master/yeso/yeso-xlib.c https://gitlab.com/kragen/bubbleos/blob/master/yeso/yeso-xli... i just assume that everything is 32-bit bgra. i need to get around to fixing that at some point what do you think an idiomatic ruby binding for yeso would look like? so far i only have lua, c, and python bindings, which are described in https://gitlab.com/kragen/bubbleos/blob/master/yeso/README.md https://gitlab.com/kragen/bubbleos/blob/master/yeso/README.m.... my ruby experience is both limited (only a few thousand lines of code) and over a decade ago
- vidarh 3y agoYeah, the colour choices were pretty random, I need to clean it up. X11 visuals are severely annoying. I get they made sense in the 80's and 90's - I spent time in computer labs where the machines ranged from monochrome to SGI Indy's, with 8-bit palette, and 15 and 16 bit direct color displays in between, but I'm all for just assuming 32-bit bgra is available these days. Any server supporting XRender needs to support it anyway as it's one of the standard formats for XRender. (I don't know if you've looked at the XRender library code, though, but one of the things that made me facepalm was that even though it requires a handful of standard visuals, the new Xrender call that returns the visuals for Xrender does not just return a list of the handful of standard formats as part of the response - you need to filter the full list of visuals and match them to depths and bit masks... Not that it's a lot of code, but it just so aggravatingly pointless) > what do you think an idiomatic ruby binding for yeso would look like? I think a bit of a mix between the Python and Lua would get you pretty close. Don't look at "my" X11 client for idiomatic Ruby :) It was "inherited" from an older client, and it's very closely following the protocol more so than idiomatic Ruby, and I'll eventually try to massage it into something nicer. To take your examples, we'd probably want to use blocks. E.g. I could see the munching squares example looking something like this in Ruby: def munch(t, fb) fb.each_row do |y| fb.each_col do |x| fb[x,y] = ... end end end You could also use the approach you use more directly, and I'm sure nobody would think that was weird either: def much (t,fb) fb.each_row do |y, p| fb.each_col do |x| p[x] = ... end end end For the main bit, "new" will always directly return the window, but it's not unreasonable to then either `yield self if block_given?` in the constructor to allow similar code to your Python version: Yeso::Window.new(...) do |w| .. and so on; end or wrap that in a class method: Yeso::Window.create(...) do |w| (0..).each {|t| w.frame {|fb| much(t,fb) } } end (Endless infinite range is "new" since 2.6) The class method vs. constructor only really buys you that you can make it slightly harder to accidentally keep the object around since you can prevent it from being directly returned. I think overall that's probably the most common approach even when the constructor supports taking a block directly.
- vidarh 3y agoAlso to add that one thing that really inspired me with libschrift is the realization that Trutetype is conceptually really simple. Most of the code is parsing the annoying format. The actual rendering - as long as you don't deal with hinting, is just a matter of rasterising lines and quadratic bezier curves. Handly OpenType then adds cubic bezier. If, on the other hand, you want colour emojis, you need to implement a subset of SVG (though the subset is small).. Yikes. You get 90% for 10% of the effort... As usual, I guess. Part of me want to see how far down full emoji font support can be golfed, but another part of me feels that's downright masochism.
- kragen 3y agoi guess hinting is less important today than it was in the days of monochrome 1152×900 21" monitors and sub-mebibyte framebuggers where you couldn't do antialiasing (and maybe you can do a decent job of blind "hinting" with smarter dsp algorithms, gradient descent, and orders of magnitude more cpu, and just ignore the tt hints virtual machine) well-defined subsets of svg are a pretty interesting thing; i feel like a smol computing system might benefit from using something like that as its base graphical layer for things like fonts and windows; then a font engine can delegate the rasterizing down to the svg layer 'how far can we golf an svg subset' might be a good rough description of vpri's nile and gezira https://news.ycombinator.com/item?id=10535364 https://news.ycombinator.com/item?id=10535364 parsing annoying formats is what https://github.com/abiggerhammer/hammer https://github.com/abiggerhammer/hammer is for; we were able to get it to parse pdf. unfortunately it's not pure ruby. the smallest i've been able to get a peg parser library is http://canonical.org/~kragen/sw/dev3/tack.py http://canonical.org/~kragen/sw/dev3/tack.py which is 27 lines of python, but i'm not sure it can be reasonably extended to do the kind of binary parsing that hammer does without balooning in size
- vidarh 3y agoSimilar thoughts on hinting - it's "good enough" for me on full HD w/just the antialiasing. With respect to automatic hinting, as I understand it Freetype has autohinting based on heuristics as hints in the fonts are often poor, but I haven't looked at how complex the auto hinter is. Thanks for the nile and gezira link - it'd be fun to handle the emoji fonts too, at least as an addon... Hammer looks interesting. I'm right in the middle of yet another parser combinator library in Ruby, but focused on text (it annoyed me that the Ruby Toml parser pulled in a 1500 line dependency for several hundreds of lines of excessively verbose parser definition for a grammar that can be defined in ca 50 lines) and frankly more an excuse to toy with refinements to see if I can get closer to BNF for specifying it. I might have a look at hammer for inspiration for ways to shrink the ttf parser later.