April 2019

Taste the rainbow...

Miyako Sono looks like a real sweettartheart:

Sadly, not the Nekomimi Era...

With the new emperor’s ascension scheduled for May 1st, the era name has been announced: 令和 (Reiwa).

(and the artists of Pixiv are hard at work designing Reiwa-chan…)

The most Thanko product ever...

Yes, it’s a smartphone-powered nose-hair trimmer.

Random cuteness

Just movin’ that Thanko pic down the page a bit…

"Oh, waitress..."

She clearly earns her tips.


Spring Cleaning

Just tidying up before I go on vacation…

Identifying as a liberal arts major...

“They told us we’d never use math after graduation, so I didn’t learn any.”


In reality, not many stories have 25 fully-fleshed-out characters in the first place, but in the ones that do, they’re generally too busy being part of the story to wave their diversity checkboxes in your face.

Unless the writer sucks, of course.


In fairness, this is a teenager, so he still has a chance to avoid a future in Tumblr’s SJW Vortex.

"Kenneth, what is the frequency?!"

I think this is the opposite of using a tinfoil hat to block the mind-control signals…

Surprisingly, the “Kenneth” attack may not have been an example of Dan Rather’s hobby of making up phony news stories; someone who later murdered an NBC employee claimed responsibility.

Weather Duck

If the duckie’s rockin’, it’s probably an earthquake.


Pixiv artist 'tomo'

How is it that I’m the only person following this artist? Seriously, the Grea pics alone ought to be worth a few hundred.


…never mind, Pixiv doesn’t display how many people follow another user, it’s how many users they follow. So, tomo only follows userid #11, aka Pixiv itself. I could have sworn there was a way to display follower count, but the API call that’s supposed to return that in pixivpi3 just returns your own followers. Maybe they locked it down.



Someone who actually needs an iPhone XS Max Plus Supreme…


Fun with PDFs...

While waiting on a fix for my Perl PDF font woes, I started thinking about some of the other long-standing issues I’ve had with PDF::API2. I actually use PDF::API2::Lite most of the time, with a few extra functions (like clip) merged back in, because I don’t need color spaces, bar codes, metadata, outlines, etc, etc. I just need all of the drawing functions and decent font handling, including proper subsetting in the output file.

Which it doesn’t do. Pro tip: the easiest way to clean up a PDF file full of cruft like giant embedded fonts is to run it through the ps2pdf utility supplied with Ghostscript. Despite the name, it works just fine as a pdf-to-pdf converter and optimizer.

Bottom line, PDF::API2 has been getting staler every year, and the font thing encouraged me to look elsewhere. Phil Perry is taking a stab at it with his fork PDF::Builder, but he’s still feeling his way around, and it’s a big job.

But I’ve written a lot of code over the years, and the PDF APIs I’ve looked at in other languages are either convoluted, limited in function (report writers and form fillers, mostly), just plain missing, and in at least one case commercial, and that generally applies to the other modules I rely on, too, like the Swiss Army Knife of date handling, DateTime.

By happy accident, I discovered that the Cairo library will generate PDF files, and integrates nicely with FreeType for robust font support, and they both have decent Perl modules. Being C libraries, they also have some performance advantages, but the most important thing they have is support.

Documentation and examples are pretty limited for the Perl modules, but I just finished successfully converting my calendar generator to use them, and it was only moderately annoying. The two biggest issues were that Cairo thinks (0,0) is the upper left corner, and that it only tracks one color in its graphics state, compared to PDF’s separate stroke and fill colors. Shimming around these problems added about 55 lines of code. Text positioning is improved thanks to Font::FreeType (and can be improved a lot more by exploiting the API fully), and output with embedded fonts is significantly smaller. Also, all my fonts work.

Now that I have a working example, I’ve started work on a wrapper module that works like PDF::API2::Lite, so that I can convert my old scripts by just editing a few lines at the top. Shouldn’t be too much work, and I’m tentatively calling it PDF::Cairo.

There’s also a Pango module for advanced text layout, but integrating that is definitely a “phase 2” item.


As far as I can tell, Pango offers the exact opposite of what I want, turning font lookup into a game where the penalty for guessing wrong is having all your text rendered in Verdana.

Bodacious Ryo-tas

Shattering the Rushuna barrier, it’s Ryoka Narusawa aka Ryotas, from Occultic;Nine. For the most part, fan artists are not exaggerating her bustline. Her huge tracts of land have huge tracts of land.

“She carried a pair of 44s. She also had a gun.”


Front toward enemy...


Elly Tran Ha

Elly Tran Ha is, um, fetching. Yeah, that’s the word.


Identifying as a full stack...

Stack Overflow has released their latest survey of straight white american male junior devs who ask questions about Javascript, Rust, and Redis. There, saved you a click.

Not a pick-up line...

I hope the DanMachi spinoffs eventually produce a story focused on second-tier adventurer Anakitty Autumn, who is apparently the only non-insane catgirl in that universe.

(screenshot from the mobile game)

Going fractal

Also known as “adding epicycles”, referring to a specific variety of scope creep where each decision in the project design opens an entirely new layer of crap to deal with.

It started with the idea of using Cairo to create PDF files using modern fonts that don’t work well with PDF::API2’s aging codebase. That pulled in Font::FreeType, and together they were enough to convert one of my simple-but-useful scripts, and seemed like 90% of what I needed to create a drop-in replacement for PDF::API2::Lite.

Except that I had to create an extra save/restore state stack to handle the fact that PDF has both a stroke color and a fill color, and Cairo only has one.

Also, Cairo doesn’t support the standard 35 PDF fonts, which are the standard PostScript printer fonts, which are Times, Helvetica, Symbol, etc. In fact, unless you load font files from disk, you’re limited to specifying the CSS2 generic fonts (“serif”, “sans-serif”, “monospace”), and wondering what it will decide that means each time you run your scripts.

So I need to support and/or supply free alternatives, such as the ones from URW that are used with Ghostscript, and Adobe’s Source Han Serif and Sans. And, yes, even if you do have the real fonts Adobe supplies with Acrobat, they’ll end up embedded in the output; PDF output is really kind of a sideline for Cairo, and honestly, I don’t think the authors expect anyone to own commercial fonts.

That should be enough, right? Except that in all of the Cairo documentation, the text-display methods are referred to as the “toy” API, and if you want to really use fonts for more than basic “this un-kerned string goes on the page at x,y”, you need to use a real layout engine like Pango.

Which doesn’t let you load arbitrary font files from disk, blowing up all the scaffolding I’ve just built around the assumption that Cairo’s FreeType support is supposed to actually be used.

Pango doesn’t just layout text, it uses span tags to mark up a string with font family, weight, etc, and uses Fontconfig to figure out what font you really wanted, quickly falling back all the way to the most generic font it can find on your computer, which on my Mac is Verdana.

So now it’s not enough to download a set of metrics-compatible OpenType fonts, I also need to create custom XML config files that override whatever else may be installed on a machine, and install them in a location that fontconfig is guaranteed to process first. XML, because there’s nothing like a text-based config parser that, by definition, must abort when it detects even the tiniest error.

There is a way to tell Pango to tell fontconfig to load a single font file from disk, but those methods aren’t exposed in the Perl Pango module. Which means I’d have to dig into the guts of how you link C libraries into Perl modules, add all the necessary functions and a set of tests, submit a patch to that project, wait for a release, and then at last C-ko would be mine!

Spoiler: yeah, not gonna happen.

By the way, it looks like no one has ever published a non-trivial example of how to use the Cairo, Pango, or Font::FreeType Perl modules, separately or together. Even a lot of the test code is little more than “yup, that called the C API and returned something”. Saying “see the C library web site” isn’t terribly Perl-y, given that everyone in the open source world has basically decided that automatically-generated API dumps are all the documentation anyone should ever need.

Which created Yet Another Problem, because it seems no one has ever even used the create_for_stream() method to render a PDF into memory and save it at the end. Which I need in order to transparently emulate PDF::API2::Lite’s saveas() method.

Therefore I present what is apparently the world’s first working Perl script that uses a Cairo PDF stream:

#!/usr/bin/env perl

use Cairo;

my $DATA;
my $surface = Cairo::PdfSurface->create_for_stream(
	sub {
		my ($whatever, $data) = @_;
		$DATA .= $data;
	"whatever", 320, 240,
my $pdf = Cairo::Context->create($surface);

$pdf->move_to(10, 48);

open(Out,'>:raw', "test.pdf");
print Out $DATA;
exit 0;

(if you just use the create() method that requires a file name, then you don’t have to flush, finish, or save your output at all; it just happens when the script exits)

But the fun never stops! Would you believe that there is no user documentation for the lookup strings used by Fontconfig? Everyone just copies the examples from the ‘user’ documentation that tells you all about the XML config format and very little about exactly what properties and constants you can specify:

Fontconfig provides a textual representation for patterns that the
library can both accept and generate. The representation is in three
parts, first a list of family names, second a list of point sizes and
finally a list of additional properties:

  <families>-<point sizes>:<name1>=<values1>:<name2>=<values2>...

Values in a list are separated with commas. The name needn't include
either families or point sizes; they can be elided. In addition, there
are symbolic constants that simultaneously indicate both a name and a
value. Here are some examples:

  Name                            Meaning
  Times-12                        12 point Times Roman
  Times-12:bold                   12 point Times Bold
  Courier:italic                  Courier Italic in the default size
  Monospace:matrix=1 .1 0 1       The users preferred monospace font
                                  with artificial obliquing

That’s all you get. Everywhere. The rest of the “user” documentation is about the zillions of XML config files that get parsed to decide what to do with these strings, which adds another half-dozen epicycles. The only complete documentation I can find on how these strings are parsed is the commentless source code in src/fcname.c. Maybe.

This is the kind of stuff that’s under the hood of desktop Linux, which is why everyone uses Windows and Mac.

Current Project Status

First script successfully converted using the PDF::API2::Lite compatibility methods. Well, except for the font-specific methods that I need to create a wrapper class for; I can get all the data I need from Cairo’s font_extents() and text_extents() methods, but those only return data for the current font at the current size, where the ones from PDF::API2 calculate them at load time for a size of 1 point. Not a huge issue, just another epicycle…


New epicycle: fonts lie. The text_extents() methods do the right thing, but the Cairo documentation confesses that many of the elements returned by font_extents() are the font designers’ opinion on the correct vertical sizes of the font. This has always annoyed me, so as part of building my wrapper class, I’m going to actually render representative characters into a recording surface in order to determine the precise values of ascender(), descender(), capheight(), xheight(), and fontbbox(). Also latin_baseline(), which can be pretty goofy in some kanji fonts.

World of Thighs

Surprisingly, this is not an online game like “World of Tanks” or “World of Warships” (yet). Instead, it’s a photography exhibition.

Think my sister will want to go with me? 😁

Steampunk Totoro

"Welcome Home"

Dear Amazon,

Why is this children’s toy wearing a bondage gag?

The Joy of Nacchi

Natsumi Abe grew up fast as the lead singer of the first generation of Morning Musume…

Vacation, all I ever wanted...

“Happiness is a warm server room.”

No, wait, that’s not right.

“Happiness is rooftop building maintenance that interrupts your server-room cooling, with portable chillers that just aren’t cutting it, followed by a surprise UPS failure that takes down all your servers. While you’re out of the country.”

Could be worse. Instead of canceling our visit to a temple flea market and a shrine festival this morning, it could have happened on Friday afternoon…

Craft Sake Week at Roppongi Hills is a brand-new event. We walked over from our hotel in Shiba, got there just before it opened at noon, chatted with the woman running the show (a charming New Zealander who wanted to make sure the limited foreign-language support she could offer was enough for people), and then spent the next four hours drinking glass after glass of really terrific saké.

Thanks to my sister’s well-honed talent for hitting it off with strangers anywhere in the world, we hooked up with a mother and daughter who were on the latter’s final Spring Break vacation before starting her Master’s program in Economics in London. After working our way through the available offerings, the four of us wandered over to the Kit-Kat Pairing Bar, which used “AI” (no actual AI were harmed by this marketing stunt) to pick the right combination of seasonal Kit-Kat and saké for each of us. Ally, the daughter, promptly cheated and ran through the questions again when she didn’t like the result. We approved.

All told, we spent over four hours drinking and chatting, leaving me drunk enough to feel it, and my far-less-massive sister well into wheeeee! territory. The walk back to the hotel involved much greeting of random pedestrians, a bit of stumbling and weaving, and some cat-herding on my part. The day ended early.

Next up, Saturday with penguins, gyoza, a shinkansen ride, and more gyoza (because our neighborhood tonkatsu curry udon joint was closed for the day).

Meanwhile, I watch our group’s Slack channel for news that the UPS is fixed and the folks on-site can bring up enough infrastructure for me to VPN in and do some sadly-necessary work.


Surprisingly clean recovery, although the UPS required a visit from an electrician to get it back online again, delaying things enough that we got to the flea market a bit later in the day, which made for a somewhat sweatier shopping experience (highs up to 78 this week in Kyoto, with humidity to match).

My knees, shins, calves, and right ankle are vigorously expressing their disapproval of all the walking, while my feet are just in a “we’ll get you for this later, dude” mood. All are responding nicely to a felbinac/menthol lotion I discovered on an earlier trip and picked up as soon as we got here.

Foodwise, we’ve struck out twice trying to visit the katsu curry udon place (pro tip: if you’re going to be closed for multiple days, don’t just put 本日 (“today”) on the sign apologizing for it and leave it up for several days).

Finding Tiger Gyoza Hall more than made up for it. The Pukkuri Gyoza in particular were so good that we were tempted to say “mata ashita” on the way out. And, yes, my sister hit it off with two charming older men who spoke decent English and drank heavily, and it turned out one of them had lived in both Chicago and San Jose. Despite being named “thousand winters”, he confessed to preferring Silicon Valley’s weather over Chicago.

(but we’re still going to try for the katsu curry udon again…)

Hey, at least she's got a cat

Run away!

Unrelated, my shins, calves, and ankles are still complaining about the stairs to the top of Himeji Castle…

"I'd thwip that!"

A better camera bag...

For this latest trip to Japan, I’m taking my Sony A6500 body, 18-105mm f/4 lens, a small flash, a Litra Pro LED light, and an ancient Minolta 100-200mm f/4.5 with E-mount adapter. For accessories, I’m taking a Sirui 3T-35 tabletop tripod (sturdy and versatile, with an Arca/Swiss-style mini ballhead), and a small color checker card. I’ll have my Ninja Reflector in the suitcase, in case we have a really scenic view out of one of our hotel rooms, but I don’t expect to pack it along unless we go to an aquarium or museum where everything’s under glass.

I spent some time a few months ago trying to figure out how exactly I was going to carry it all. I have (coughcough) “several” camera bags. The smallest of my Domke bags would be more than big enough for this modest loadout, but it has two flaws: it looks like a camera bag, and it’s not a good fit for a trip that involves more shopping than serious photography.

What would be ideal is something like my old PacSafe anti-theft laptop backback, but with a proper camera insert to keep everything organized and protected. There are a lot of things like that out on the market, but they all end up looking like camera bags, and most of them are at best half-decent at other things.

Then I found the Tenba BYOB 10 (Bring Your Own Bag) insert:

Careful measurement of my PacSafe backpack confirmed that it would snuggle inside, protecting my gear without adding significant weight, allowing me to carry a bag I already like. Win-win.

The best gyoza...

…is found in little side alleys. We already suspected this, but recent events have confirmed it.

Tenka Gyoza is dead; long live Tenpei Gyoza

It took us most of a week to get down to Osaka, only to discover that our favorite little third-floor hole-in-the-wall gyoza joint closed less than two weeks ago. We had gotten to Dotonbori around 1pm and checked to make sure her sign was still there, but since she didn’t open until 5, we didn’t go up until after we’d done our sightseeing and shopping.

Fortunately, there were two guys inside renovating for the new owner (sounds like it will just be a bar), and one of them knew that she’d retired and sold the place, and recommended we head back up toward Umeda station and try Tenpei.

We each devoured 50 hitokuchi (one-bite) gyoza too quickly to get a picture of them, but here’s their little English sign with a history of the place and the correct proportions for mixing up your own gyoza sauce:

I’d prefer to believe that the lady at the other place invented hitokuchi gyoza, but I’d need to spend a lot more time in Osaka researching the history of this most delicious incarnation of pan-fried dumplings. Tasty, tasty research.

If you want a higher filling-to-wrapper ratio, our other new find is a block up from Shijō off Karasuma in Kyoto, Tiger Gyoza Hall. They have a full menu for some reason, but if you just walk in and say “pukkuri gyoza, hakko”, you’ll be very happy. We’ve been there three times now, and I’m pretty sure there will be another visit before we leave town.

The unbelievably awesome teppanyaki restaurant Hanaroku deserves a post of its own…

Unrelated pro tip: if you use the new SmartEX app to purchase shinkansen tickets, guard that credit card with your life. If you somehow manage to lose the card (first time in my life…), you cannot pick up your tickets. At all.

The workaround is to use the app to cancel and resubmit your reservation with a different card, but this is not a practical solution when it’s the Friday afternoon where the entire country is going on vacation. The girl at the JR counter was politely apologetic, but didn’t think of what seemed obvious to me: have her place the order as soon as I hit the “cancel” button. Once we were synced up, we turned our keys and rebooked the same seats. Crisis averted, and there’s no sign that my card was used by anyone before I reported it lost.

"Well, hello kitty!"

Shieri Kurasawa (倉沢しえり) is quite the cutie. Born Christmas Eve, 1999, so “way too young for me but not a felony”.


The plural of anecdote is 'bullshit'

I’m a big fan of Trello, but the only reason to visit their blog is to check for new features. Unfortunately, they feel the need to pad it out with the sort of content-free content that makes workplace violence seem like a reasonable response.

Take this, for instance: “Here’s Proof That Office Layout Doesn’t Affect Productivity”.

Using the DeskTime time-tracking and productivity app, I examined people working in three different environments: an open office, a closed-space office, and a cubicle. It turns out that working in a closed office leads to just 4% more productivity than working in an open office (89.3% vs. 85.8%).

But here’s the kicker: the most productive setup (91.1%) of the trio was the bane of every modern worker’s existence—the dreaded cubicle.

This absolutely reeks. No sample size, no description of what type of work the “tracked” employees did, what industries they were in or even what countries, and no hint of how long this intern “studied” them, but she’s got proof that will put your foolish opinions in their place.

And her solutions? Forget office layout, and focus on art, plants, headphones, and blocking social media.

(and yes, I know her bio calls her “senior writer and content marketer”, but I used to work with a guy whose business cards said “Lord High Everything Else”, so I’m sticking with “intern”)

Coney Island Massacre

“Need a clue, take a clue,
 got a clue, leave a clue”