On the Web

with Joe Blubaugh

My Country, Tis of TheeJul 21, 2020

Facism Wrapped in a Flag

I’ve spent a lot of time the last 3 years watching Umberto Eco’s sign’s of Ur-Facism manifest, and manifest, and manifest. I’ve seen a lot of things that I was raised to believe ~wouldn’t~ couldn’t happen here happen in sequence, with frightening speed. Out-of-control (willfully so) police beating and gassing people in the street, night after night after night. Destruction of public schools, along with requiring states fund religious schools. A Justice Department hell-bent on revenge for the President. Open xenophobia, brazen racism by members of congress. I thought we left that behind when Strom Thurmond finally died.

I worry about my wife, who holds a green card, and is thereby subject to the whims of immigration officers and state police who have an almost infinite number of crimes at their disposal. I worry for my co-worker Dan, a DACA kid who’s never done a thing wrong and still lives on unstable ground. I worry for everyone I know who opposes Donald Trump as his DoJ bends every law to its cruelest angle.

Looking back, you can see the seeds of these problems planted. Occupy Wall Street & Occupy Oakland happened during Barack Obama’s presidency, and protestors (including yours truly) were gassed and beaten by cops on more than one occasion. Expansive theories of executive power go back at least to John Yoo and the war on terror. John Yoo’s now sitting pretty at Berkeley and I wonder how he doesn’t get his car egged every day. Public Schools have been under assault for decades as standardized testing extends a widening grip on the entire system.

All of these seeds have been fertilized and nurtured by the fascists who prop up the President, and who will doubtless get sinecures at think tanks when they should be expelled from polite society and wind up unemployable. Even if we beat back the kudzu in November, I worry that we’ve passed a point of no return. Re-building after this can’t be about going back to before a mistake - it has to be going forward and changing our society.

Font MeasurementsJul 6, 2020

advance, kern, etc

TLDR;

I learned a bunch about rendering fonts and I thought it would be interesting to read about them from a programmer’s perspective. I gained a ton of empathy for type design and type-setting developers, as they work with a dizzying variety of screen resolutions, font styles, and a wide variety of device speeds to produce type that looks as good as it possibly can under harsh conditions.

Background

I’ve been working on a project involving a two-color e-ink screen. I’m drawing on the screen and that involves drawing text. The project is written in Go. There are common font-rendering librares like Cairo, which are written in C. I find compiling against C libraries like using cgo difficult and complex, so I was really interested in a Go-only solution.

Fortunately, Go supplies a decent image package right out of the box. Combined with the “semi official” font package, it seemed I could do everything I needed.

Unfortunately, I’ve selected some fonts that the most popular font-parsing package can’t handle. So I’m using a different package that can parse many more fonts, but until yesterday didn’t support any of the rendering functions required for drawing on images. In writing and submitting that code, I ended up learning a lot about how fonts are represented in files and what happens when they’re rendered.

I’m going to focus on laying out text left-to-right below. However, there are many languages that use right-to-left horizontal layouts, vertical layouts that go either left-to-right or right-to-left, and languages with alternating line directions. Many of the measurement concepts below apply but may need to be rotated or flipped from a horizontal left-to-right perspective.

Font-y terms

A font is a collection of glyphs - letters, numbers, symbols, ideograms, emojis (😭) that the font is able to draw.

A typeface is a collection of fonts that share a style. This can include italic, bold, or even serif & sans-serif variants.

A serif is that little slab at the bottom or top of a glyph. Here’s an example.

Fonts then, may be serif or sans-serif fonts, though there are other styles like Blackletter. This primarily applies to the Roman alphabet, and Roman-influenced alphabets. Chinese fonts have their own styles that are similar - Songti and Heiti

Serif/ Sans serif

Font metrics

The measurements described here are common to both manual typesetting and computer typesetting. Manual typesetting is very rare these days, but the terms originate from that practice.

The capital Q and lower-case e below both show their measurements.

Font measurements

The baseline is the line that all text on the line is laid-out relative to. For each rendered glyph there’s an “origin” point on the baseline.

The advance width is the space from a glyphs origin until the origin of the next glyph.

The ascent is the height of a glyph above the basline and the descent is the depth below the baseline. Many fonts also provide ascent and descent measurements that are the maximum of these values for all glyphs. This can help with line spacing.

The bearing of a glyph is the space between the glyph and its origin, or the origin of the next glyph.

Fonts are sized in units called points. There are 72 points per inch.

Special topic: Kerning

Kerning is the adjustment of glyph spacing based on glyph pairs. For example, WA is often kerned tighter than the default spacing to reduce the large diagonal line that you’d otherwise have between the two.

Kerning

Special topic: ligatures

In some fonts, multiple letters may be represented by a single glyph. In some fonts, fl or ff may be joined together so that the characters overlap.

Ligature

Font file formats

A very common text-rendering system on modern computers is Freetype. Windows is not included in that family. The common windows font-rendering system is ClearType.

Coordinate system

Font sizes themselves are expressed in “points”, and there are 72 of them in an inch. So you should expect a 72 pt font to take up about an inch from line-to-line.

However, computers don’t represent fonts that way. Each glyph in a font is represented by a set of “drawing instructions.” The instructions may specify “draw a line from A to B, then draw a cubic bezier from B to C, then draw another line from D to E.” These drawing instructions are represented on a single coordinate system, which is then scaled by the point size to create the final set of coordinates.

Font file coordinate systems use a special representation called “fixed point.” Because fonts need to represent sub-pixels, we can’t use whole integers. Why not use floating point numbers? At different scales, floating point numbers have different levels of precision. So font files use fixed-point representations for their various numbers. You can think of these as floats with a fixed precision. Several fixed-point formats are used in font files for kerning, glyphs etc. The glyph coordinates are written using “26.6” The integer part has twenty-six bits, and the fractional part has 6 bits, to fill the space of a 32-bit integer. This means that the resolution of the fractional part is 1/64. Here are some binary representations of numbers in fixed point:

Number Fixed-point
1 1.000000
1.5 1.100000
2.25 10.010000
5.75 101.110000
1 63/64 1.111111

So, to render a font on-screen, we need to put all of these pieces together:

  1. Take the string you need to render and get the coordinates for each glyph.
  2. Substitute ligatures where necessary, and adjust the spacing based on the kerning between glyphts.
  3. Create a pixel coordinate system based on the dots-per-inch (DPI) of the screen you’re rendering to. iPhone 11s have a DPI of 463 pixels per inch.
  4. Scale all the font coordinates (at 72 points per inch) by your screen grid (463 pixels per inch), using fixed-point math.

You may do all the above glyph-by-glyph, though you may have to “go back” to deal with ligatures.

Rasterization

Once you have the set of all font coordinates, you need to actually draw those dots on-screen. Some coordinates will be for fractional pixels, but we have an integer number of pixels. This is where “rasterization” comes in. Rasterization is done for just about anything displayed on a computer screen, from video games to text, to photos. In font rendering it involves shifting items to fill pixels, and adjusting colors so some pixels on the edge of letters are a lighter gray so the pixels appear partially filled.

Here’s an excellent site that explains a rasterizer for TrueType in greater detail.

Type rendering is a topic filled with nuance and artistry - the above only provides a simple summary. Some of the computer industry’s most talented graphics engineers have worked in this field for decades. Computer displays are now the place where westerners spend the majority of their reading time, so clear and attractive type on screens remains incredibly important.

InfluenceMay 30, 2020

Office Politics?

I got an email from an old co-worker the other day:

I was thinking about you and how you are a person I see as not being particularly embroiled in office politics, but also as having a lot of influence and knowing how and where to leverage it. I was curious if you had any words of advice for how you got to that place.

Of course I was happy to hear that I come off this way, and as I thought about how to reply, I found myself writing an essay.

So, about influence, and politics, and etc.

When most people say “office politics”, they seem to mean the “dark side” of relationships at a company. Who gets the boss’s ear? Who “wins” when there are decisions to be made? Who has their ear to the ground?

When people talk about influence and leveraging it, they’re talking about the “light side” of the same thing. Who shapes decisions? Who “makes things happen”? Who shifts behavior, changes the tone of the company?

Office politics and influence function in really similar ways: building relationships with your co-workers, building trust with them, and keeping lines of communication with them open. Most decisions are made before the decision gets made, so being around for those early conversations is where you can exercise leverage.

Some ways that I build relationships with co-workers:

  • private messages when they do something great.
  • always show up for those coffee chats and lunches. This is how you get to know people way outside your group. I have one lined up with our director of finance and a developer who lives in Europe. It's rare to get to talk with them both. If there isn't something like this at a job, it's usually pretty easy to kind-of start one.
  • not-too-frequent 1:1s with people in other teams. I have about 5 of these going, and I do them every 3 weeks. I try to vary the rotation enough from time-to-time. They're hard to drop, though! Be judicious.
  • ask people for help! most people love to feel helpful.

All of these have the advantage of being genuinely nice things to do! They make me feel good, they make my co-worker feel good. The hardest thing about them is making them happen when I have a lot of other stuff to do, or I’m feeling stressed out or distracted. But it really is a part of your job, especially as you grow into a leader in your team, organization, company.

I also work pretty hard to build trust. The best way I know to do this is to do your job as best as you can, and to be transparent with people. When you’re working on something hard, getting people’s opinion when the idea isn’t fully baked does a lot - you can get better ideas, and you show that you’re trusting a co-worker with something delicate, that you need and value their contribution. When things aren’t going smoothly, being straight with your boss

Another way that I build trust and credibility is calling attention to issues that affect “everybody” - but always offering to help make the improvement happen, or even do initial legwork to offer an idea for a solution. This makes it clear that you’re doing more than complaining; that you genuinely want things to improve and you want to be part of that.

Finally, asking for hard feedback, and giving hard feedback are important skills for building trust. The asking is much harder to do, and. I don’t agree with everything in the book - even maybe less than half of it - but Radical Candor helped reshape my ideas about trust. I think the book goes too far, but being able to give criticism honestly and with respect is crucia. Even more important is being ready to receive it without rejecting it or saying “yea, but”. Living with it. Thinking about it. Then accepting the parts that are true and rejecting the parts that are undermining you. If you get sexist feedback, throw it in the garbage and note how much you can trust that person.

So, how is that different from office politics? It’s not just tone, but tone is a big part of it. It’s about genuinely wanting good for other people and for yourself. It’s about character, and about honesty. It’s about genuinely wanting good things for yourself, your co-workers and your company, and striving to make that happen.

Influence is definitely related to competence, but also to prioritization. You’ll be more influential if you’re addressing real needs that people care about - especially your bosses. If they’re good bosses, this is both easy and not morally perilous.

Unfortunately, none of this holds up when you’re surrounded by people of ill will. In that sort of situation, find the other people of good character in your workplace and keep your head down. If you can get out, get out. Don’t spend your energy trying to change people who show you they can’t be trusted.

An aside about conflict:

Every so often, influence doesn't work this way and you have to stick your neck out. Again, the tone is really important here. In our two big meetings after the layoffs, I directly asked our CEO and my VP some uncomfortable questions about how decisions about who was being laid off and how the layoffs were communicated. I followed up with more direct feedback in private conversations. I think this made a difference in how decisions will happen in the future and in gave my co-workers a better picture of what happened. The way I made those conversations work was by communicating respect for my bosses as people as early as I could in the conversation, and assuming good will by them.

About assuming good will - it’s complicated, but important. The key point is that by assuming good will, you’re able to get more honest and less-defensive communication with someone, even if they’re acting with ill will. That doesn’t mean avoid confrontation, but it means approaching confrontation as though it’s based on either conflicting priorities or mistakes rather than malice. This is a key conflict skill that I wish I’d developed so much sooner! Life would have been better. After the conversation you draw your own conclusions about whether you’ve been dealt with honestly and you can choose your next steps with good information. When good will is real, things will often change for the better as a result of the conflict.

This all sounds very high minded. In writing it, I’ve noticed many ways that I fall short of these ideals. But it feels right as a roadmap.

LuckyMay 22, 2020

Really Lucky

We went through layoffs at work recently. Like a lot of companies, the belt is tightening, and the bathtub drain is getting blugged. I’m lucky to have not been laid off. Lucky again - this is the third “surprise” layoff where I’ve kept my job. I’m batting 1.000 but I know my number has to come up sometime.


I graduated from college in 2009, 9 months into the Great Financial Crisis. I was lucky to get into a good graduate school on a stipend that paid my rent, and even luckier to be leaving undergraduate without student debt. I was lucky that when I needed to quit graduate school I could find a government job.


I was lucky to go to a particular concert, meet a particular person, and lucky that we fell in love. Lucky that the US Government didn’t fuck around with her life and we were able to stay here in California.


I’m lucky to be living through this epidemic in good health, with plenty of food and a functioning society.


Count your blessings.

Fast is a FeatureMay 19, 2020

Slow software destroys flow

We all use dozens of pieces of software a day - email clients, web browser, email clients inside web browsers. Cameras and chat, digital art tools and spreadsheets. We switch between them dozens of times, and when we really get into a task, when can sometimes achieve a state of flow, a state of satisfying and effective effort that lets us accomplish more than we thought and enjoy it all the way.

But then you add another layer to your Photoshop project, or attach a picture to an email. The beachball starts spinning, the text box gets laggy, and you start thinking about opening that Twitter tab again.

This is one of the reasons I still use vim after all these years. Even in large software projects with plugins for syntax highlighting, autocomplete and build-on-save, the navigation and input remain quick. But not always - vim on my home computer feels faster and more responsive than my work computer, because I’m asking it to do less. When compared to a product like IntelliJ/GoLand, it’s like a car against a horse. Very few editors are both as fast and as capable, and I can thereby keep going as long as the work requires.

Every time your software lags, it’s a chance for your user to lose their state. Every time you make them move the mouse to open a menu, they have to go away from their task. Put your menus in context with the work, not in a toolbar. Make your software as quick and as smooth as possible. This is what makes people love software, not flashy features.

Beef Barley Mushroom SoupJan 15, 2018

Fast Food for Slow Days

This is adapted from Tom Lacalamita’s Pressure Cookers for Dummies, but you should use the Serious Eats method of browning stew beef in one large piece, then cubing it before cooking, for better results.

Ingredients

  • 1/2 lb stew meat
  • 3 carrots, thinly sliced
  • 3 stalks of celery, sliced
  • 1/2 lb of mixed mushrooms, trimmed and quartered
  • 1 cup barley
  • 2 or 3 bay leaves
  • 8 cups of liquid, stock preferred
  • Chopped parsley

Steps

  1. Cook onion in oil until fragrant
  2. Add the meat and cook until browned. Remove and chop into small cubes.
  3. Add the carrots, celery, barley, mushrooms, meat, stock, and bay leaf to the pressure cooker.
  4. Bring o high heat and cook for 20 minutes. Release pressure with the quick release method.
  5. Add parsley, and season the soup with salt and pepper before serving.

Ricotta ChickenJan 15, 2018

Butter Chicken without butter

The secret here is that you can replace the Butter in Butter Chicken with just about any high-fat dairy product. Ricotta, sour cream, greek yogurt will all work. They change the flavor of the dish, but they’re all good variations.

This is adapted from a recipe in Tom Lacalamita’s Pressure Cookers for Dummies

Ingredients

  • 1.5 lbs chicken, cubed
  • 1 onion, minced
  • 1 Tbsp minced ginger
  • 2 tsp garam masala
  • 1 small chili, minced
  • 6 oz tomato paste
  • 2 cups chicken broth
  • 2 Tbsp minced cilantro or parsley
  • 1/2 - 2/3 cup high-fat dairy. Butter chicken is 1/2 cup cream, 3 tbsp butter. Limes for serving.

Steps

  1. Salt and pepper the chicken.
  2. Cook onion, ginger, chili and garam over high heat in oil, until browned.
  3. Add the chicken and brown in spices. Add the broth and tomato paste, stir to deglaze the pan.
  4. Bring the pressure cooker to high heat and cook for 8 minutes. Release pressure with a quick-release method.
  5. Over low hit, stir in the dairy. Serve over white rice, and squeeze fresh lime juice just before serving.

Pressure Cooker Red Beans and RiceJan 15, 2018

Didn't Miss Her

Red beans and rice is simple, fast and good. Use a good hot sauce, use more seasoning than you think you’ll need. This recipe scales well - 2 or 3 cups of beans will fill most normal pressure cookers.

Ingredients

  • 2 cups of red beans
  • 1 large onion
  • 1 head garlic
  • 1 cup chopped celery
  • 1 cup chopped carrots
  • 1 14.5 oz can of diced tomatoes
  • 2 tsp hot sauce
  • 2 or 3 bay leaves
  • 1 smoked ham hock or 3 strips of bacon or 1 can of (gasp!) spam, etc
  • 4 cups of water
  • 1/2 lb of andouille or other smoked sausage
  • salt to taste (around 1 or 2 Tbsp)

Steps

  1. Rinse the beans, and let them soak while you do the other prep.
  2. Chop the onion and garlic. Saute in olive oil until fragrant. Add the carrots, tomatoes, hot sauce, and bay leaf. Cook for 2 or 3 minutes. Add the ham hock, beans, water.
  3. Bring pressure cooker to high pressure, cook for 20 minutes. Release pressure via “natural release”. If beans are still hard, cook another 5 minutes.
  4. Add sausage, salt and pepper. Cook with cover off until desired thickness is reached, about 5 to 10 minutes.
  5. Serve over white rice.

MicheladaDec 10, 2017

My favorite version of this

Originally from Ever in Transit, this is the best tasting version of the drink to me. I like to use the tomato juice from a can of peeled plum tomatoes. I use the whole tomatoes to make sauce, and keep the juice to make two micheladas with.

Ingredients

  1. Lager beer
  2. Tomato Juice
  3. 3-4 splashes Tapatio
  4. splash of worcestershire sauce
  5. splash of soy sauce
  6. juice of one lime or lemon

Roberta's Pizza DoughDec 10, 2017

Quicker Rise, Soft crust

Pizza

Originally from the NYT, makes enough for two pizzas.

Ingredients

  • 306 grams of flour (50/50 00 and bread, or 100% AP)
  • 2 grams of active dry yeast
  • 4 grams olive oil
  • 8 grams of fine sea salt
  • 200 g of tap water

Steps

  1. Combine flour and salt in mixing bowl
  2. Combine water, oil, and yeast in mixing cup. Add to dry ingredients and knead until incorporated. Let rest 15 minutes.
  3. Knead dough about 3 minutes. Works well with a dough hook.
  4. Divide dough in half and shape into two balls. Cover with a damp kitchen towel.
  5. Let rise. 3 to 4 hours at room temperature, or 8 to 24 hours in the fridge.
  6. Shape, top, and cook.