The horrors of Photoshop text rotation

Whilst having a good laugh at the Internet Explorer 8/Nickelback promotion this morning (submitted to Reddit with the amusing headline Lose-lose. Download Internet Explorer 8 get a Nickelback mp3.), I noticed the Mark of Photoshop:

IE8/Nickelback promotion text with dodgy rendering

You see it everywhere:

Photoshop text rotation from Richer Sounds promotional email

The reason is that, when you rotate text in Photoshop, it gets it wrong. Every time. Even in CS4:

Example of Photoshop rotating text incorrectly

There are ways to work around this bug, but it is a bug, and a pretty egregious one. I mean, how hard can it be? Well, not very, since just about every other program I’ve ever used can render text at an angle and do it properly without obvious rounding errors—and without costing the price of a decent upper-arm prosthesis. It’s high time Adobe fixed it.

For a piece of software that costs so much, Photoshop can be pretty disappointing. I guess Adobe can afford to coast when they’ve got such a captive market, but it’s a program that increasingly feels like new features are just being phoned in from the beach.

Dedication’s what you need, if you wanna be a Record Breaker

Last weekend, I, James, and about 850 others headed to Devonshire Square where we channelled the spirit of the late great Roy Castle and took part in a world record attempt.

We were trying to beat the record for the most Ukuleles played at one time by exceeding the previous record of 401 people, set in Stockholm in 2007. I already had a ukulele, and James’s friend B—, who was also taking part, lent him her old one (a pink flying V!).

The song for the occasion was the Beach Boys’ Sloop John B, played twice through to make it over five minutes long as required by the record. It’s a very easy song to play on ukulele, consisting of just three chords (C, G7 and F).

And we broke the record! All 851 of us. It was captured on video; see if you can spot me:

We should get certificates in due course. However, it doesn’t look as if the record will stand for very long: there’s another record attempt in Chicago in August. Maybe we’ll have to come back next year. Just please, no more Sloop John B. I’ve heard and played enough of that song for a while!

Liberating culture

The National Gallery houses the national collection of Western European painting from the 13th to the 19th centuries. It is on show 361 days a year, free of charge.

You can look at the collection online via a fancy zooming panning scrolling widget. It’s very clever, but the experience of peering at a painting through a tiny porthole (even on the ‘full screen’ version) isn’t the best one.

I don’t believe that our shared cultural heritage should be locked up behind browser widgets, so I took a look at reverse-engineering the system. That may sound controversial, but it’s actually completely in line with the Gallery’s stated aim of making its pictures available:

The Gallery aims to study and care for the collection, while encouraging the widest possible access to the pictures

Whether they actually believe their rhetoric, I don’t know. We’ll see!

Each painting is cut up into tiles at various resolutions to support panning and zooming. There’s a cursory effort at obfuscating the tile identifiers, via a little obfuscate function that turns the digits 0123456789 into vRfOdXapKz respectively and by mixing the parameters together in a strange order. But really, it’s fairly simple stuff. Knowing the size of the image, the size of a tile, and the zoom level, it’s trivial to fetch all the tiles.

Having got a set of tiles, stitching them together is a little harder. The full image can be very large (5,000 pixels on a side), and naïvely-written image processing libraries tend to use up all the available memory.

The solution I found that worked best was the montage command from ImageMagick. However, since it’s designed to work with tiles that are all the same shape, I had to do a bit of preprocessing on the truncated tiles at the right-hand and bottom edges to make them square beforehand, then crop the resultant image down to the desired size.

Having done all that, though, I can now pull down all the tiles and stitch them into a single beautiful image. I can now have high-quality offline copies of works of art to browse at my leisure, use as a desktop background, set as a screensaver, or just draw moustaches on.

The fact that you can now get these high-quality images does not, unfortunately, mean that you can do what you like with them. It may sound crazy, but, at least in the UK, copyright does apply to the photos, even though they may simply be reproductions of works made hundreds of years ago.

I’ve put my code on GitHub along with instructions. Some computing knowledge is required to use it, and it almost certainly won’t work on Windows in its current state.

Avoid death by lorry

I read the sad news today that, once again, a female cyclist has been seriously injured by a left-turning lorry.

No. Not sad. Tragic and eminently avoidable.

It happens a lot. Hence Velorution’s advice:

This is what we tell our customers:

Lesson Number One: Ladies: beware of left-turning HGVs.
Lesson Number Two: Never ever forget Lesson Number One.

So why are women disproportionately affected? A suppressed TfL report gives us a clue:

Women cyclists are far more likely to be killed by a lorry because, unlike men, they tend to obey red lights and wait at junctions in the driver’s blind spot, according to a study.

You really don’t want to do that. You’re going to be injured or killed. And yet the road layout and traffic laws encourage it. There’s an inviting green-tarmacked cycle lane down the nearside. There’s a red light stopping you right in the vehicle’s blind spot. Combine that with a long wheelbase and, frequently, railings, and you’ve created what Watchdog used to refer to as a potential deathtrap.

So what can be done about it? I can think of a few institutional actions right off:

  • Don’t paint cycle lanes where using them will place a cyclist in danger. These are attractive nuisances. They encourage dangerous undertaking. Cycle lanes are, in any case, generally potholed ghettos that relegate cyclists to a dangerous and disadvantaged position.
  • Put more labels on the backs of long-wheelbase vehicles like lorries and buses telling cyclists not to undertake them. In fact, make it the law that they all have them.
  • Remove railings from junctions.
  • Install advanced green lights for cyclists to allow them to accelerate out of danger before motor vehicles.
  • Reduce the speed limit to 20 mph in more places. This won’t affect the overall speed of traffic on most roads in central London.

As a cyclist, you can do a few things yourself:

  • Hang back from large vehicles. The best place to be is behind them. If passing them at lights, do so on the right and only when there is plenty of time and space.
  • Don’t be afraid to jump red lights where it’s safer to do so. This is particularly true of red lights on straight stretches, or where you are turning left. Don’t go cruising through like the light’s not there, but if you can safely move away before the heavy machinery around you starts up, do so. This is probably controversial. It’s also illegal. But in this case the law is not your friend.
  • Don’t hug the kerb. Where the road is narrow, claim the whole lane to prevent risky overtaking. This requires a certain level of stubbornness, but hey, if they’re beeping, they know exactly where you are.

But I’m really wondering what can be done to educate the cyclists who engage in risky undertaking.

Get your filthy hands off my Kernel methods

Using pre-existing libraries can save you development time. Unfortunately, the quality of Ruby plugins and gems can be highly variable.

Kernel#__method__ as defined in the aws-s3 gem:

unless (RUBY_VERSION[0,3] == '1.9')
  module Kernel
    def __method__
      /\`([^\']+)\'/.match(caller(1).first)[1].to_sym
    end 
    # ...
  end
end

Kernel#__method__ as defined in the facets gem:

module Kernel
  def __method__(depth = 0)
    caller[depth][/`([^']+)'/, 1]
  end if RUBY_VERSION <= '1.8.7'
  # ...
end

Can you guess what happens when both are loaded?

One definition wins. Something breaks.

So which one is right?

Neither.

Please don’t write code like this.

Thoughts on the future of the iPlayer Downloader

Because it’s there—attributed to George Mallory, on being asked, Why do you want to climb Mt. Everest?

I had great fun working out how to download programmes from the iPlayer, fighting against the BBC’s cat and mouse games. I loved the controversy and notoriety. But I’m thinking about abandoning the iPlayer Downloader project for a number of reasons.

  • I feel that I succeeded in what I set out to achieve. I wanted to make it possible to download programmes, but I don’t really need to. Building the downloader was an enjoyable exercise, but it’s not scratching my itch.
  • The GUI is very limited, and I’m not really motivated to address that, or to give users the features they’re asking for. Similarly, I don’t take bug reports very seriously.
  • I’ve got other new projects to work on that are better ways to spend my free time.
  • There are other programmes that will do the same and more.

The code will still be there. I recently moved it to Github, so it’s easier than ever to fork it, and I might even pull the changes. What I’m proposing to do is to abandon responsibility for keeping it up to date or adding new features.

A lot of people keep asking if my program can download HD content. It can’t. But I know a program that can: get_iplayer. It doesn’t make sense to me to duplicate that work.

Anyway, at the moment, it’s just something I’m thinking about. I’d welcome your feedback.

Things you can’t do in an iPhone application

When Apple announced the iPhone SDK, I expressed my mistrust of the walled garden in no uncertain terms. The feedback was pretty overwhelmingly negative. Apple fans generally don’t like criticism, and my use of metonymy seemed to touch a particular nerve.

Personally, I wouldn’t build an iPhone application with your seed capital: I can’t see how anyone would base a business model on the inscrutable whims of the gnomes of Cupertino. And I’ve got to admit that I’ve slightly enjoyed the Schadenfreude of seeing the pain that developers have suffered at the hands of Apple’s opaque and arbitrary application vetting process, because I feel a bit vindicated. That may well make me a bad person, but I’ll live with it. I also hope that the outcry of disgruntled developers will make the concept of a single gatekeeper less palatable in future. I want to see the App Store model wither. No, that’s not true. I want the concept of one single exclusive App Store to die. I want this experiment in cut down computing to fail. Hard.

The last two days have brought another couple of examples of incomprehensible reasons for rejection, so here’s a list of things you can’t do in an iPhone application:

  1. Allow anyone to read books that are on the internet, because the internet contains porn (if badly bowdlerised Victorian translations of the Kama Sutra count as porn).
  2. Celebrate Israeli independence and/or whistle.
  3. Display the word ‘fuck’, even if it was typed in by the Apple tester himself or came from the internet
  4. Provide functionality that Apple thinks it owns, such as fetching podcasts or email.
  5. Interact with an application that could be used to download unlawful copies of copyrighted material
  6. Use a development framework that would allow you to write cross-platform phone applications.

Of course, one category that seems to suffer no such restrictions is that of the flatulence simulator.

Anyway, I expect irate responses to this piece as well. So let me make one thing clear: Apple can indeed legally do what it likes (more’s the pity). But, developers, if you choose to hitch your wagon to their horse, don’t complain where you’re led. I, for one, won’t have any sympathy for you.

I know that the iPhone is a lovely platform. I know that the development tools are very good (at least by the standards of mobile phone development). I know that having someone else handle charging and billing is convenient. But the fact that the yoke is padded in velvet doesn’t make it any less constricting. Whether to submit to it is your choice.

tl;dr: I told you so.

European Democracy

I’ve got to admit, I’ve never paid much attention to the European Parliament. To be honest, I don’t think many people do; the turnout in European elections here in the UK is very low.

But a couple of things have recently changed that. The first was the fact that the European Parliament (hereafter EP) elections are coming up next month; the second was the controversial Telecoms Packet. We hear very little about what gets discussed in the EP, so I went to their website to find out. I was utterly astonished by what I found.

The EP website is clunky, and it’s a bit hard to find the information you’re after, but that’s not really the problem. Have a look at a debate and you’ll see what’s wrong: every contribution is recorded in the speaker’s original language:

The verbatim report of proceedings of each sitting (often referred to by its French abbreviation, CRE) is published (Rule 173 of the Rules of Procedure) and contains the speeches made in plenary, in the original language.

OK, I can read French, Dutch, German, Spanish, and Italian well enough to catch the gist. But I don’t understand Polish, or Latvian, or Bulgarian, or Greek, or Hungarian, or …. In fact, I doubt that there’s a single person alive who can speak all twenty-three working languages of the European Union. In other words, no one can understand what’s going on unless they were actually there.

The odd thing is that, whilst debates are simultaneously translated, these translations never seem to make it into the official record. This is, surely, no way to run a democracy. I thought this was all pretty scandalous.

A little later, I realised that I could actually do something about it. Google’s translation service can handle almost all the EU languages (all except Irish, I think). I know how to make websites, and how to scrape data off other websites. I had signed up for the Yahoo-sponsored 24-hour Open Hack Day last weekend, and decided that opening up the European Parliament should be my project. I roped in Julian Burgess as a collaborator, and we roughly bolted together a website to prove that it was possible.

Inspired by TheyWorkForYou.com and TheyWorkForYou.co.nz, we called it TheyWorkFor.EU

Check out the debates, and see what your EU representatives have been discussing! At present, we’ve only scraped a couple of days of debates, but we’ve proven both that it’s a workable idea and that Google’s translations are pretty good.

We won a Guardian-sponsored prize for Best Government Hack, which was both gratifying and amusing, considering that Julian works for The Times!

My hope is that I can get it into workable shape before the next session opens, so that the next session of the European Parliament takes place in a more open environment than it has done in the past.

Phone support matters

I’ve got a phone line in my new flat at last. I had wondered whether I could manage without a fixed line, but the latency and spottiness of 3G data connections has convinced me that I still need some old-skool copper for a decent internet experience.

Since the local exchange (Bermondsey) has terrible contention on the BT ADSL network, I wanted to use an LLU operator—that is, one who has their own equipment in the exchange, and who doesn’t rely on BT for any more than the last mile (or two) of wire.

I’d heard good things about both Be and O2, who share the same hardware and backbone but operate as separate companies. I started off at Be’s website, and typed in my phone number. (Web developers will want to point and laugh at the form that says ‘Copy & paste is not permitted in this field’; view the source for full humorous impact.) The computer said:

Unfortunately Be is not available in your area yet.

That’s not true: I know for a fact that they have equipment at the Bermondsey exchange.

So I phoned them, and got through to an offshore call centre somewhere I couldn’t quite identify. The person I spoke to was charming and competent, but that’s all. She was able to tell me that there was an existing account associated with the number, but couldn’t take it any further.

On a whim, I decided to see what O2’s website had to say:

Order already exists against this number in system.

Despite the geeky terseness of the message, it was at least accurate, unlike Be’s website which appears to make the cardinal sin of catching any error and assuming that it’s the most common one.

Right next to it, they had a free phone number, so I called them. This time, I got through to a Scottish chap who was actually able to help me. He went to talk to a manager to work out how to deal with the unusual situation. He called me back on the same number to verify that it was correct—having taken a mobile number first, just in case. He submitted a request to BT, gave me a case number, and told me to call back if I haven’t heard back by Saturday.

This wasn’t an offshore/onshore issue per se—it was one of initiative, and I’m sure that the way that call centres are managed and their staff evaluated is at least as important as any other factor. The fact remains, though, that whereas Be’s phone support wasn’t able to break out and handle this odd case, O2’s was. And that’s why I’ll be signing up with them for ADSL service.

Once they’ve sorted out this minor problem, that is.

More responsive web browsing on 3G/UMTS via dnsmasq on Ubuntu

One of the downsides to moving house is the complete loss of internet access for an extended period. Yes, technically, you can get it switched over seamlessly. In my case, though, the previous tenant hadn’t even cancelled his phone service, so it’s been a lot more long-winded and painful. I should have a phone line again by Wednesday (after 3 calls to BT, the last of which took 20 minutes). 48 hours after that, I’ll be able to order ADSL, the provision of which takes five working days.

But this is the UK, where former incumbent state operators still work on soviet bureaucracy timescales (c.f. Royal Mail).

I’d anticipated this cascade of incompetence, so I pre-emptively purchased a 3G UMTS dongle (a little Huawei USB device the size of a butane lighter) and bandwidth package. For £100, I got both the device and 12 GB to be used at any time over a period of 12 months. That’s a pretty reasonable offer that fits my expected usage pattern well. Also, £100 is small beer in the context of all the thieving bastards taking advantage of my change of address to screw me over.

So hurrah for modern technologies! Except … 3G is slow. Not in raw data transfer terms—it’s actually faster than the overly-contended ADSL connection was at my old place—but the latency is painful.

Web browsing entails lots of DNS queries to look up (resolve) the address of a page—to say that google.com is 209.85.171.100, for example. Firefox, rightly, doesn’t cache this information. It defers to the operating system. The operating system, also rightly, defers to the local DNS server. Under normal circumstances, this is close enough (in four dimensions) that you don’t notice the tiny amount of extra time taken to resolve DNS queries.

On my 3G dongle, though, it can easily take up to a second to return a response.

There’s a second problem, too, in that 3’s DHCP service doesn’t always seem to return DNS information. You can fix this by appending known-good DNS servers to /etc/resolv.conf, but it’s a hassle.

To summarise: I need a local DNS server that always knows where to look upstream. I took some information from Local DNS Cache for Faster Browsing with the caveat that, at least according to the dnsmasq community documentation, dnsmasq interferes with Network Manager. Here’s my solution. I’ve used OpenDNS for this example, as their DNS servers should work for anybody.

Install the dnsmasq-base and resolvconf packages:

sudo apt-get install dnsmasq-base resolvconf

Edit /etc/dnsmasq.conf to contain:

listen-address=127.0.01

and

resolv-file=/etc/resolv.conf.upstream

You can find commented-out lines with the left-hand values; uncomment them and add the right-hand side to each.

Create a file in /etc/resolv.conf.upstream containing just:

nameserver 208.67.222.222
nameserver 208.67.220.220

Use other DNS servers if you prefer.

Finally, uncomment/modify one line in /etc/dhcp3/dhclient.conf:

prepend domain-name-servers 127.0.0.1;

Restart dnsmasq:

sudo /etc/init.d/dnsmasq restart

Reconnect to your internet connection, and try typing dig google.com into the terminal a few times. After the first lookup, it should be very fast.

There’s one wrinkle: in 8.04, NetworkManager ignores all DNS settings for 3G connections, and sets resolv.conf to whatver the DHCP server returned, bypassing the local server. The best solution I’ve found so far is to edit /etc/network/interfaces and configure ppp0:

iface ppp0
  dns-nameservers 127.0.0.1