Arnt Gulbrandsen
About meAbout this blog
2019-03-15

Email tracking pixel support

There once was a font called Smelvetica, a truly terrible prank based on Helvetica. There once was, because Monotype has sent a takedown notice for the git repo. Smelvetica was just like Helvetica except that its kerning was so bad that it was a feature. In fact, it was so bad that the font deserved a takedown notice. It deserved two.

There still exists a mail reader called Outlook, which my sort of people disliked twenty years ago, for good and bad reasons. One of the better reasons was that Outlook would implement harmful features. It still does. For example, it offers tracking pixel support, most often used via one-pixel images but Outlook offers other vectors too, including web fonts.

Bingo.

If you happen to have an old version of Smelvetica, don't like tracking pixels and suffer from a poor sense of humour, you can leverage it to send email that has terrible kerning if and only if the recipient's mail reader supports using web fonts in the way tracking needs. Here's an example of how to do it:

Date: …
From: …
Subject: A little gothic type
Mime-Version: 1.0
Content-Type: text/html

<html>
<link rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=UnifrakturCook:700">
<div style="font-family: UnifrakturCook;">
<p>Goth is great.
</div></html>

Since Smelvetica was taken down, I chose to use this font for the example, but the world of web fonts offers many other possibilities. Start looking here. Smelvetica was the best though — the result would look ordinary, yet somehow disturbingly wrong.

2019-03-09

Brexit

I make mistakes. I'm a programmer, half of what I do is giving birth to new bugs, and I hate it. So of course I try to improve that percentage. To identify and avoid error-prone routines, to interrupt mistakes before they've gone too far, etc.

Brexit scares me. Britain is an entire country with all the democratic mechanisms and institutions, with a long tradition, with no external pressure, with a full set of checks and balances, no lack of time or other resources except what they imposed on themselves. If experience, review, discussion or routines guard against mistakes, then noone should be more able to avoid big mistakes than Britain. Yet with just three weeks to go, they still seem headed for an utter mess. I can't bear to watch it.

2019-02-05

The young traveller's guide to Venice

Venice may quite possibly have the best-looking ambulances in the world.

It also has more of them than I'd expect for a city as small as Venice. Is it possible that the Italians keep a few extra to show off in front of young tourists?

When they're not racing stylishly through the city, the ambulances may be seen waiting in front of the hospital. The fireboats are (more…)

2019-01-23

static final volatile int foo = 1;

It's likely that my compiler treats foo as though it were just static final, and if you do not understand how a final volatile variable differs from a plain final, then congratulations.

The problem is that although people generally think of static final variables as constants, they aren't quite constant: foo is assigned its value early in the life of the application and can never be reassigned and, but if two or more classes reference each other, so that each class has to be initialised before the other, then code involved in that initialisation may see foo still being 0. This is usually an unpleasant surprise, found while debugging. volatile affects the visibility of the foo=1 assignment, and it probably forbids one of the things my compiler does to handle those loops.

I can fix it and I probably will, although I will not be highly motivated: It's a minor problem, and quite frankly, people whose code depends on the semantics of static final volatile ought to go for a walk in the park and reconsider that aspect of their design.

2019-01-17

I write a benchmark

Today I need to write a benchmark.

I have decided to reimplement HTML Tidy in a simple, approximate way. I chose this because:

Of course I realise that this won't be a very good as a benchmark. I chose it because I believe that Jsoup is the kind of code I need to handle well. If my code doesn't do well on Jsoup, then I need to fix it. I don't have the same feeling about specint and other well-known benchmarks. They try to be good, precise benchmarks, and they don't explicitly try to be typical java.

As a result this benchmark will be useful for me, and the cost of that is that its measured performance is imprecise for you.

2018-12-20

15000% improvement

I've been working on something that, I think, ought to perform 30%-200% better than the current solutions, depending on the workload and how the measurement mixes values for average/­typical/­best-case/­worst-case time and space. Some workloads might get more than 200% improvement, and I hope less than 30% will be rare.

The very first time I tried to measure the entire system, however, my measured result wasn't 30% improvement or 200%, it was a little over 15000%. Three zeroes. And I wasn't even trying to make a misleading benchmark — I just wanted to measure how well my code worked and I suppose I unconsciously concentrated on parts where the differences should show up clearly.

15000% certainly is a clear difference.

It's also totally meaningless. It measures something you'll never, ever do. However, it's a fantastically big number, I know that I was honest, and it has taught me that even if benchmark results are laughably unrealistic, it's not always because someone tried to brag or mislead. Maybe they are just myopic. Focused on the details of their work.

I've spoken harsh words about other people's benchmarks in the past. I don't think I will do that any more.

Update: 1500000‱.

Update: And the best way to represent it is with a logarithmic bar graph. Most people do not really understand a log scale, but the difference still looks very large and so the meaning is preserved. The label on the y axis makes it formally correct.

2018-12-11

A recipe for limoncello and marmalade

There are many limoncello recipes on the web, but so many are careless or incomplete that I add ours to the cacophony. Key points: You have to use the right kind of alcohol, you have to taste every day while you steep zest in alcohol, and the leftovers make lovely marmalade. Ingredients:

  • Alcohol (60-96%, not 40%)
  • Sugar (either white or light brown)
  • Water
  • Lemons
  • Pectin

For 1l of 96% alcohol, you should have 1-1.5kg of sugar, 2kg of lemons, and the amount of pectin depends on the lemons and your endurance. The amounts below assume 1l of 96% alcohol.

The reason that you can't start with 40% alcohol is that the end result has to contain about 32% alcohol in order to remain entirely fluid in the freezer, and the alcohol is mixed with a syrup. If the syrup is to reduce the alcohol content by only 8%, you would have to make it with just a few tablespoons of water, and you simply cannot dissolve enough sugar (more…)

2018-10-20

He's dead, but he won't lie down

Windows XP should be dead years ago, but but the number of web browsers using XP seems to not even decrease. And not at a negligible level, either, XP is used several times more than linux.

Progress is hard.