“That’s not one of meat’s many uses.”
— Ben, from Full Throttle…or at least “not ready for prime time”.
It seems I wasn’t quite correct in my assessment of why my MacBook was sluggish. Full-disk encryption was indeed having a visible effect on performance, but even after turning it back off, I’ve still been seeing some pretty awful performance… after a few days of uptime.
There are two primary symptoms, both connected to filesystem performance: first, Time Machine backups take progressively longer each time (no matter how much data is being backed up), until it starts reporting that a typical 300MB backup will take more than an hour; and second, image-heavy web sites start loading very slowly, with JPEGs showing up ‘blocky’ while they’re rendering. If I don’t reboot when I detect these two issues (usually after about four days of uptime), then I’ll start having difficulty mounting and unmounting external devices and network volumes, and Disk Utility will show a SPoD. I’ve had to disable automatic backups, because I can’t put it to sleep until they finish (Time Machine will cheerfully corrupt your backup history if you disconnect from the file server while it’s running).
My recent vacation makes it difficult to be sure, since I turned the MacBook off after every use, instead of my usual “leave it up until it crashes”, but I think this is specific to the OS 10.14.4 release.
With all the problems they’re having with hardware and software, it seems the old cliché about “there’s no I in TEAM” could be rewritten as “there’s no QA in APPLE”.
Related, when I do reboot, the first thing I do is open top in a
Terminal window and wait a minute or two until the load drops from ~50
to under 5; then I kick off a backup and start working.
After a lot more testing, it seems that APFS is only responsible for about a third of the slowdown. The rest is coming from the TCP stack. Rebooting is still the only fix; I’ve tried switching between wired and wireless, changing out the USB-C ethernet adapter (I have like five brands of them, between home and office), manually resetting the interfaces, etc, etc.
If I work completely offline, local I/O still slows down over a few days, but if I’m online, network I/O gets worse faster. Still a problem after the 10.14.5 update, and I’m thinking it’s specific to the 12-inch MacBook hardware, since I don’t see it at all on the 15-inch MacBook Pro that’s usually on the other side of the kitchen table.
[Back over the net to you, Brickmuppet!]
Mixed in with the fan artists at Pixiv are a lot of pros, posting excerpts from the various games, manga, and light novels they do work for. Browsing the 仕事絵 tag is a good way to find quality cheesecake.
At this rate, I’ll never run out of cheesecake to post. Can’t say that’s a bad thing. Names when I get a chance.

Here. Needs a full test suite and a bunch of examples before I throw it up on Github/CPAN, but I’m pretty happy with the functionality.
I think if I were exploring another scripting language, I’d look for Cairo and FreeType support, and then I’d port this module over. A bit of work up front, but less hassle than dealing with the quirks and limitations of another implementation.
Stripped of comments and documentation, it’s just about 1,500 lines of code, half of which is in the main PDF::Cairo package. Quite a bit of it is PDF::API2 compatibility, which I could jettison when porting to another language, so it would be pretty quick.
Usage is quite straightforward:
use PDF::Cairo qw(cm);
$pdf = PDF::Cairo->new(
file => "output.pdf",
paper => "a4",
landscape => 1,
);
$font = $pdf->loadfont('Times-Bold');
$pdf->move(cm(2), cm(4));
$pdf->fillcolor('red');
$pdf->setfont($font, 32);
$pdf->print("Hamburgefontsiv");
$image = $pdf->loadimage("logo.png");
$pdf->showimage($image, cm(5), cm(5),
scale => 0.5, rotate => 45);
$pdf->write;
Honestly, the thing that took the longest was dredging up the schoolboy trig to get it to rotate images from the lower-left corner instead of the upper-left. Cairo’s inverted coordinate system makes sense on-screen, not so much in print.
I was very selective about what I pulled in from Pango. It’s a peculiar library that simultaneously gives you more control over text layout while removing control over font selection. You can precisely position each glyph in a Unicode string, but have no idea what it will look like on the page. Some of this it inherits from Fontconfig, which is a giant hairy mess of XML configuration files, but they’ve layered their own clunky parser on top of that.
For instance, on my Mac, I have four styles of the typeface family
Hoefler Text installed: Regular, Italic, Black, and Black Italic.
Using the Fontconfig tool fc-match, I can select them with the
string ‘Hoefler Text’ optionally followed by ‘:bold’, ‘:italic’, or
‘:bold:italic’. Using Pango’s pango-list tool, I discover that the
correct incantation there is to request ‘Hoefler Text Small-Caps’,
with the words ‘Bold’ and ‘Italic’ optionally added in that order
after ‘Text’.
Leave out the ‘Small-Caps’, and I get Verdana (well, technically I get
Hoefler Text Ornaments, which then falls back to Verdana because
that font doesn’t actually have any alphanumeric characters in it).
Use it, and I get the right font, but without small caps. Try to
request real small caps (which it has), using the
variant='smallcaps' attribute, and I still don’t get small caps
(despite the documentation, I’m not sure that works at all). I have no
idea how to fix this, or if it’s even possible.
I made the Pango support optional, because it takes a full two seconds to initialize the first layout on my laptop. By comparison, my calendar generator takes less than a second to create a 10-year, 59-page calendar.
Unfortunately, while I was porting one of my other old scripts to use
as an example, libfreetype segfaulted in FT_Set_Transform. Didn’t
matter what font I loaded, there was just something about that script
that triggered it.
After some painstaking debugging, it looks like I have two
workarounds. First, render the text as a Pango layout, which avoids
calling Freetype directly from Cairo. Second, use the
create_for_stream() method to initialize the PDF surface and
explicitly save the file at the end, rather than use the standard
create() method that takes a file name up front and auto-saves when
the script exits. That last bit seems to be where the bug is being
triggered.
Ironically, this is how my PDF::API2 compatibility methods work, so a direct port of the old script works fine, and it doesn’t crash until I try to update it to use what seemed to be the recommended method (pun intended).
For now, I’ve commented out the use of create(), and added an
explicit write() method to dump the PDF file to disk. I’ll test
again when Homebrew catches up to the current Cairo release.
I’ve refreshed the tarball about a dozen times now, as I add examples and come across bugs and little niggling issues in the APIs. I’ve pretty much rewritten half of the Box module as I’ve started using it more aggressively in simplifying the calculations in my examples.
I’d say that I’m just about ready to stick a fork in it, write the
test cases, and release, but then I thought of another epicycle:
rendering SVG files as vectors. Currently, the only way to import
existing graphical data is as fonts with FreeType or bitmapped images
with Imagemagick’s convert
tool.
I’ve used the custom font trick before to load illustrations into a program that didn’t support them, but I’d rather import SVG directly. Because ImageMagick supports rasterizing vector formats, I can already place an SVG into a PDF, but only as a bitmap.
But it turns out that librsvg is already designed to do exactly what I want: render an SVG into a Cairo context. There’s just not a maintained Perl module that links to it. I can’t say that I’ve always wanted to figure out how to write XS glue, but since my needs are very simple, I think I can dodge that bullet and create a simple API with SWIG.
Looking at the RSVG API, I think all I really need to do is:
Pass a filename to rsvg_handle_new_from_file(), save the result.
Pass that to rsvg_handle_render_cairo() along with a Cairo
handle.
Profit!
I’m not even sure I need rsvg_handle_free(); the memory should be
reclaimed when the Perl variables go out of scope, or worst case, when
the script exits.
It looks like SWIG is not going to be easier than XS. Oh, well.
Mocha is a relatively prolific creator of detailed non-cheesecake scenes, often set in places that have been abandoned or reclaimed by nature.
But not always…