hortont · blog · school

Fall 2010 Schedules

2010.08.24 in school



This is going to be a nice calm semester.



Matt's got a lot of manipulation to do, I guess. MAKE UP YOUR MIND!



I have no words except sorry for that one...

Horton Slab Writeup

2010.05.07 in code, school, and typography

Introduction

Don't expect this to be anything... it's just a bunch of relatively-disconnected words about what was going through my head at various times during the project, and how I fixed it, which I'm writing at the request of the professor. More or less...

Glyph shape

Each glyph is a Python class which, when instantiated, knows the properties of the glyph (weight, cap-height, slant, etc.). Using this information, it constructs the geometry of the glyph, which is made by combining two different primitives: line and circle. Both of these primitives can also be clipped by arbitrary polygons (this is how the C is constructed, for example: by taking a circle and clipping out a triangular wedge from it).

Geometry manipulation (basic boolean stuff; almost always either union, intersection, or difference) is done with the Shapely library, because I really didn't want to do that myself, as it's not very interesting.

Each glyph has a function which calculates its width relative to one em, information which is used heavily during the drawing phase.

The glyph shape function can be either very complicated (like, say, 2) or very simple, like that of the lowercase l:

    mainLine = Line(self.p(0.5, 1.0), self.p(0.5, 0.0),
                    self.weight(), serif=5)
    return [mainLine]


That's a very simple one. 2, in comparison, is about 50 lines long...

The line constructor that you see above takes three required arguments: the location of both endpoints, and the weight of the line to be drawn. The optional serif argument adds serifs, which we'll talk about later.

The 'p' function (I needed a really short name because I call it hundreds of times and wanted it to be neat - think of it as 'position') that I call there takes a percentage position (0.0 to 1.0) in x and y (measured from the bottom left, like things should be done) and turns it into coordinates in the glyph's coordinate space. p also takes another argument which determines whether it should consider the top of the glyph to be at the cap-height or the x-height.

Many of the glyphs have small adjustments that are made to the shape of the glyph as the weight changes, in order to correct for unpleasant effects.

So, the l above makes a line from the top, halfway across the glyph, to the bottom, halfway across the glyph, at the full weight of the glyph, with the 5th serif type, which will be described below.

You can look at the rest of the glyph functions on GitHub: Capitals, lowercase, numerals, punctuation.

Strange or Missing Glyphs

I added center-dot (for multiplication) and interrobang (at the request of my roommates) to the normal set of glyphs. My 0 is too wide, but I couldn't bring myself to make it an oval (or, more likely, similar to the shape of the 6 or 9). My angle-brackets are huge. HUGE! Maybe I'll fix them someday. I'm missing curly braces, because they'd be really annoying to draw. Much worse than 2, which was enough of a pain that I don't want to endure it again.

Serifs

Serifs are actually added by the line drawing logic - each character doesn't really need to know how to draw a serif, it just needs to know what kind of serif it wants, and asks politely for that. There are 6 kinds of serifs a glyph can ask for on one of its lines:

    0 - No serifs
    1 - A vertical half serif on one end of the line. (E)
    2 - A vertical half serif on both ends of the line. (T)
    3 - A full serif on one end of the line. (A)
    4 - A full serif on both ends of the line. (H)
    5 - A full serif on one end of the line, a half serif on the other. (l)
    6 - A half serif on one end of the line. (j)


The fact that glyphs don't know about serifs is neat, because it means we can turn off the serifs very easily, by just asking Line not to draw any! That's how we get the sans-serif variant, which isn't on the poster, but that's ok... it's just not as awesome.

Properties

PHI = 1.618... (golden ratio)

Fixed glyph properties are as follows:

    1 em = capHeight / PHI
    xHeight = capHeight / PHI


The defaults for variable glyph properties are as follows:

    weight = 3 (this is a unitless measure, where ultralight = 0.5 and heavy = 7)
    slanted = False (not really italic, it's more slanted than anything)
    outlined = False (this was more for testing, but turned it into outlines)
    color = Black (obvious)
    serifed = True (whether or not Line should draw serifs for this glyph)
    autoKern = True (you'll see, in a bit)


Italic

The italic variant isn't nearly as neat as all the rest, it's just made quite literally by shearing the character with Cairo while it's being drawn. Not interesting, not particularly awesome, but it worked out OK. There's a pretty good chance it will break the consistency of inter-word spacing, but I'm not totally sure how to fix that (without doing the shearing beforehand, with Shapely... or manually).

Weights

Technically, you can generate glyphs of whatever weight you want, because it's all procedurally generated. However, I blessed a few weights so that I didn't have to look at/tweak more than a few weights:

    Ultralight = 0.5
    Light = 2.0
    Regular = 3.0
    Bold = 5.0
    Heavy = 7.0


Kerning

Kerning was a stickling point for the first few days. At that point, I was just throwing glyphs down and advancing the x position by the reported width of the glyph. We all know why this doesn't work, though, with the AV pair being the classic example.

So, instead, I wrote an optical autokerner in a few lines of Python. It works by placing the two glyphs on a plane and shifting them back and forth until it finds the boundary where they're just touching, then adds the correct amount of kerning. There's a kerning table which gives adjustments relative to this value, but it only has a handful of entries (one case which was particularly problematic was +=, where the bar of the plus slid directly into the middle slot of the equal-sign, kerning them way too tightly). It could probably do with a few entries, but after all this, I didn't have a lot of time to work on the kerning table, and I didn't really think it looked terrible - at least not enough to worry about.

There's another issue with the optical autokerning: punctuation. Tiny little dots don't autokern well at all; also, quotes don't ever collide with lowercase letters, so that breaks things too... So I added a per-glyph override which instead kerns based on the bounding box of the glyph extended to basically-infinity in the vertical direction. This mostly fixes the problems with punctuation.

The autokerner is really quite slow (as you might expect), especially for large blocks of text, so there's a disk-based cache that stores the kerning values between runs. You have to delete it if you change the glyph shape, or your kerning will be horribly wrong. Also, the cache is per-capHeight-per-weight (as kerning values change slightly), so if you change the capHeight or weight, get ready to wait again...

Layout

The space character is also a glyph - it's a square block which is special-cased to not be drawn at all in the drawing logic. This fixed a lot of trouble I was having when advancing words in the "stupid" way (just adding some amount of x-advance each time you see a space character), where the space between the words ended up varying significantly, which was really tripping up reading.

My line-breaking algorithm is horribly primitive: it just draws words at a time; when it gets to each word, it checks to see if it's past the edge of the layout box. If it is, it moves down by the leading and moves back to the left side of the box. This is a problem mostly because it means the last word on a line could be (and usually is) extending beyond the right side of the layout box. Also, it creates really crappy right rag unless you pay a lot of attention, because it's really not aware of the idea of rag.

If I had a ton more time, I'd implement Knuth's famous line-breaking algorithm (the one TeX uses), which is pretty much ideal, but since I don't have that kind of time, I decided against writing a poor knockoff. I've heard it's not actually that complicated, but... relative terms...

Input Format

The main program takes an XML file with a very simple format. For example, you can see the one that makes the description of the various weights that's on the poster here.

There are only a few tags defined:

    u, l, r, b, h = Weight (ultralight, light, regular, bold, heavy)
    i = Slanted/Italic
    br = Newline
    textbox (attributes x, y, size, width, height) = A reflowing text container
    leading, tracking, size (attribute px) = Obvious text properties
    color (attributes r, g, b, a) = Obvious color properties
    sans, serif = Turn on/off serifs


More Stuff

If you have any questions, feel free to email me.

The code is all open-source, under the relatively permissive 2-clause BSD license, which basically just says you can do what you want with it as long as you keep my copyright header around... (the terms are in LICENSE in the source directory, but they're exactly the same as all of the gazillions of other BSD projects out there). The code is here.

Libraries/Thanks

Python
GEOS + Shapely
Cairo + PyCairo
ElementTree

Orbitals, Particles, a Font, and some Sheeple

2010.04.29 in code, school, and typography

Apparently the semester's nearly over, or so I've been told (repeatedly. naggingly.)! In any case, I've gotten a lot more done on some things than I expected, and a lot less on others... it's always hard to predict how the semester will go.

A Font

For Typography, I've been working on the font + renderer + autokerner that I just wrote about the other day. I won't post any more pictures, just scroll down a little further to see that post!

Orbitals

For Parallel Programming, I've been working on a atomic orbital simulation, using OpenCL to evaluate the electron probability density function for a hydrogen atom at many, many points. It makes nice smooth images like this:



It's showing approximately a 20x speedup, moving from Zoe's CPU to GPU (Core i7 @ 2x2.66/3.33GHz to a NVIDIA GeForce 330M GT). The move from Zoe's CPU to Jayne's GPU (the 4890) is even more awesome; it's something like 40x faster!

Eventually (soon), I'm going to make an animation with it, and then it's time to write a paper!

Particles

For Advanced Computer Graphics, I've been working on a particle system simulator that uses (surprise!) OpenCL to simulate tons and tons of particles at once (millions, anyway). And render them, attractively (the renderer is still in its infancy). And it comes with a tool to design them, too (also incomplete).

I don't have any really interesting examples to show now, because I just got emitters to work. Below is a picture of something like 1,000,000 particles being blown away from the origin by two "simple"-type forces (they just push outward from a point, with inverse-square falloff).



And a video (which will only work if you're using a very recent Chrome or Safari, probably) of the same simulation, though with only 128K points. This simulation really isn't interesting because there's nothing complicated going on. I've got gravity working, which is a gazillion times more interesting and more complicated, but I'll post pictures and video of that some other day (it's also much, much slower).

It also turns out that the overhead of OpenCL isn't worth it for simple forces; it significantly speeds up complex (O(n^2)) forces like gravity (I'm aware of many ways to speed up n-body simulation, I just haven't had a chance to implement them yet), but for O(n) forces like below, it really only provides a tiny-to-near-zero gain.



Sheeple

All of this (plus normal coursework) leaves less time than desired for other things, but I still manage to occasionally put a few hours in to work on Sheeple. I feel bad that I don't have tons of time for RCOS work, though I will note that all of these projects are open source (all of them are under the 2-clause BSD license except Sheeple, which is GPLv3), so the general idea of promoting/using/writing OSS is still there :-)

I recently wrote and pushed a partial implementation of a Google Contacts backend for Sheeple. It's a lot smaller (and nicer, since it's written in Vala), and it's what I'd like to use for the time being while developing the UI and backend stuff, since it's a lot easier to change.

Another thing that contributes to slow Sheeple development is that everything now takes place in a VM; I don't have a native Linux install anymore, and I consider that a good thing. I've gotten sick of wasting time with a broken system, and I'm just not going to do that anymore - I don't care enough nor have enough time to spend to fix things, and I'm just generally all-around much happier in OS X. So both of my machines are running OS X, and I'm pretty sure that's how it's going to stay for the foreseeable future.

I should thank Moorthy and Sean O'Sullivan for putting up with me, and for constructing RCOS and keeping it alive. I wrote a long bit about what I think about RCOS and the people involved a few months ago, and that all still stands. Given this semester's overload (which will likely continue next semester) and how RCOS has worked out within this semester, I find it somewhat likely that I'm not going to participate next semester; I feel guilty about being paid to do much less work than I feel like I should be doing. I'll still hang around, certainly, and I'll (obviously) still write OSS, I'll even happily talk about stuff I'm working on, but the absence of that feeling of guilt/obligation/deadline (and also the ability to bounce between projects as I feel like it) will be quite the load off.

Horton Slab?!

2010.04.26 in school and typography

I've spent the last almost-exactly-one week working on my final project for Typography. During the first class, back in January, I decided that I'd try to put together a font for my final project.

I didn't get started as early as I perhaps should have, mostly because I have other final projects I've been working on all semester, so I decided to take this last week off from other projects and just concentrate on this.

Of course, there was no way anyone was going to get me to sit in a room with FontLab for hours on end (it's a horrible program), so I had to come up with something different to do, to make it an interesting project. I eventually decided to try a somewhat different approach: a procedurally-generated font.

Horton Slab (and its sans-serif variant, which you won't see here today) is implemented in Python; each glyph is a separate class with knowledge of its properties, and constructs its geometry from this knowledge. This means that — given enough care — you can automatically generate quite reasonable alternative faces (at different weights, with italics, with or without serifs, etc), reducing design time significantly.

Most of the ratios in the font are derived from phi, the golden ratio. The ratio of cap-height to x-height, serif thickness to stem thickness, height of the crossbar in A, E, F, G, H, etc. to the cap-height, the depth of the middle of M, and many, many other things. This isn't as strict as it could be, but I sometimes sacrificed phi-ness (the original guiding design property) for readability or beauty.

I also implemented a relatively primitive layout engine and an autokerner. There are only a few entries in my kerning overrides table (something like 10) — it turns out that a very simple approach to optical kerning actually works somewhat well.

All of the code is available on GitHub as always, and under a BSD license.

Everything you see below was designed in a silly XML-based markup that my layout engine accepts, and clicking on them will open the straight-out-of-engine PDF.



All of the glyphs I have at the moment:



Some pseudo-Latin filler text:



And a classic Sagan quote:

Typography : Computer Modern

2010.02.05 in school and typography



A little something I made for our first Typography project: the double-slit experiment out of Computer Modern characters. Click on it to view the rest of the project...

Jumpin' Right In!

2010.01.26 in school

Already getting to work! Mondays, Wednesdays, and Thursdays are going to be really boring, Tuesdays and Fridays are going to be really long but really, really awesome.



That's the output of my first graphics project (the "getting GL set up" project, nothing particularly annoying).

Finished this week's homework today; yay! Tomorrow is a day to relax (no Bio lab this week), hang out, get concert tickets, watch the Apple keynote, and do a phone interview for my Mathematica certification. FUN!

Spring 2010 Schedules

2010.01.21 in school

Luckily, 9 AM Biology is a test section, which only happens a few times a year!



Out With The Old!

2009.12.13 in school

Fall semester is over! That's 5/8; just three to go!

I finished the Programming Languages final at 3:00 or so on Friday, stood up, and walked not only out of the DCC, but out of the semester, too! There's a little bit of cleanup left (a final in AI on Thursday, primarily), but after that I'm homeward bound.

I guess I'll say a few things about each class, since that seems to be the thing to do...

Intro to AI was — unless I'm way off base, which doesn't seem likely — the easiest full-sized class I've taken at RPI. The assignments were easy (and even relatively fun) — straight out of AIMA, implement in whatever language you choose, spend two weeks on it. That gave plenty of time to overdo the assignments, which doesn't seem to have phased/angered the professor. The tests weren't too bad; the first one was a little surprising (I came out of it thinking it was either the easiest test I'd taken here, or that I'd missed something vital and failed it, and ended up with a B), and the second is on Thursday.

Programming Languages is an interesting beast. A bunch of ex-Cary people took it along with me (as well as Mike, who dropped the class a week or two in, and has to take it some other semester); a good number of the ones I've talked to about it since believe (along with myself) that the class as it stands should be scrapped, in its entirety. I'm not sure I can/should totally explain why, just that the class is a mess and needs a rethink. It's a good idea — certainly! — to teach various paradigms and languages; I'm not completely convinced it's a good idea to use the professor's pet language to do so. Drop Erlang in in place of SALSA, a Scheme or a Lisp and/or Haskell in place of Oz, keep Prolog; this would help make the class a lot more real-world useful (I can't believe I'm putting Lisp, Erlang, and Haskell in a sentence about real-world usefulness...) without sacrificing (at all) the various lessons about language design and use (except the ones about how things should not be done, in the last few weeks). The other problems (the real ones)... I'll leave for people who take the class to discover on their own!

Intermediate Video was awesome. Well... there was a lot of strange contained within the videos we watched in class, but I suppose that comes with the territory! The awesome part was two things: a) getting to spend time working on video again (I bought FCS a few years back and have been upgrading it every once in a while since then; I don't get to use it very often these days, though), and b) the class. It was a tiny class; there were only nine of us! The nice part about it was that everybody got along; they made someone who didn't belong (me) feel like he fit right in, even if he sometimes took issue with being asked to find meaning in things which clearly didn't have any (I'm cool with art-for-art's sake, but leave it there, and don't try to make that sort of art have meaning!). And I had a lot of fun with the three projects during the course of the semester.

Quasars and Cosmology doesn't even count. One credit, no work (literally). Sit down for an hour once a week and look at pretty pictures of space. Awesome!

Machine Learning was really tough. It's yet another case of me distinctly lacking math experience (multivar and linear algebra, mostly, in this case, but there was also the fact that most of the calc I've studied has (yay!) rotted out of my brain). It sounds like it's going to have quite the curve, too, which is good! There was a lot of cool stuff in this class; it's the only CS course this semester where you could see something you were writing really work. I now know (and have implemented) a dozen different ways to classify digits from the USPS zipcode database — that's always fun! It was nice to not have any tests to speak of, but the homeworks were killer, and a very large chunk of the book (which is currently being co-written by the professor) never ended up getting posted to the website.

On the slate for next semester: Introductory Biology (YUCK, but that finishes my science requirement), Typography (I love being a fake EMAC), Parallel Programming, Advanced Computer Graphics (Cutler again!), and Intro to Economics (I need to take a bunch of humanities stuff, I figure ECON will go better than PSYC or PHIL).

α ↔ ω : The End

2009.12.10 in school and video

Today marked the end of a somewhat awesome semester of Intermediate Video; with that, of course, marked the end of our final projects.

I've got a lot of stories to tell about this project, but very little time right now to tell them! There's a big test that I need to do well on tomorrow (the last one was during the week I was out sick; I ended up taking it right after I got better, to not-so-great-effect), as well as a lovely RCOS presentation that I need to prepare. So, stories later.

For now, there's a copy of the video at YouTube (I apologize for the bars and tone; the professor requires them, and I forgot to remove them before uploading; jump to 0:30 to skip them!). Watch it in HD!

Or, if you're adventurous (and have a lot of time), there's a 400+MB H.264@720p version on Jayne. (not currently available)

The music (which I made overnight last night, in Logic, and isn't very good) is around, too.

It was a fun video to make, anyway! I'm not sure what I'm going to do with the data; the RAWs are wayyyyy too big to keep around, but the Apple Intermediate files are only a few gigabytes, so I might (should) keep them.