Dear e-Reader Producers and Engineers

As an avid reader, here is what I expect to find in an e-reader.

Media support

The more the better, as long as it is a text media file. I do not need image support (as in galleries, photos), I do not need audio support (as in mp3, ogg), I do not need movie support (as in avi, mpg)! I want to store many books (pdfs, plain text, html, latex, man-pages), and read them. That’s it… Seriously… I really just want your e-reader for, you know, reading!

Fonts

Independent of media format, I want to be able to select my favorite font for reading. That also means, unless you have licensed every existing font and ship it with your device, I can drop a TTF (or some such) onto the reader and select it. I want to freely change the font size. Not between tiny and extremely large, but in 0 – ∞ points/pixels.

Text Flow

Again, independent of media format, I want the best possible text flow on the display. I don’t care about the layouter’s fancy ideas regarding paragraph length, indentation, margins and paper size. I’m not reading text on a letter-sized, A2, A3, A4, A5, whatever-size sheet of paper, I’m reading text on an e-ink display with a 5-10″ diagonal and X by Y pixels. So whatever text I’m reading, better be perfectly reflowed for the e-reader’s display.

Software Usability

I don’t need or want your super-special online bookstore, or super-special, super-wonderful synchronization crapware that only works on Windows 7. I want to drag-n-drop the files in my file explorer, HID USB Mass Storage Style that works anywhere, anytime, on any OS.

Since I want to read HTML documents, you’ll need to include a decent HTML render and browse component (hint: webkit). But stop right there, I do not want a full online browser, e-ink display refresh rates don’t make this a very usable or enjoyable experience.

Make it easy to search for a book title, really easy! Modern storage media will let me store thousands of books, a fact you so readily advertise. Showing me thousand books, ten books a page isn’t usable, it’s a cruel joke! I don’t need book covers or icons, I need titles, authors, categories, tags, bookmarks! I need a search that lets me find a certain book about ip_filter and nat setup on linux, a search that lets me find that fantastic recipe for chocolate macadamia cookies, as search that lets me find the one passage with that funny quote in that one book I can always only remember half of.

Don’t impose your tags and categories on me, let me use mine instead. I know much better than you, how I want organize my books (alphabetically by title? by date of release? by count of words? by file size?), so make as much information about a media file available as possible and let me decide what I want to see, when and where I want to see it.

Some bonus thoughts and tech tips on that: use a database like sqlite for metadata storage, add new documents and media info as discovered, scan in reasonable (or even better configurable) intervals for changes (some file systems have journals, if you used that, no need for intervals), create a GUI from browser component, render database information as HTML, make this easily customizable (use lighttpd and lua for scripting this and let us hackers access it).

Hardware Usability

While I do like the thought of note taking on such a device, any input method has so far appeared to be cumbersome. Tiny, cheap unresponsive alphanumeric keypads waste space, are uncomfortable and frustrating to use. Stylus input is laggy due to slow refresh rates and the reflective screen covering nullifies the readability comfort of e-ink displays. Touch displays have much the same problems as the Stylus based displays and add fingerprints and smudges to it. Thus your e-reader should not include note taking, unless you come up with a much better alternative to Touch and Stylus displays.

I do not need or want WiFi, 3G or some other wireless connection in my e-reader. I’m going to drop several hundred books on it, and not bother with it, until I’m through with most of them. If I need any more books or am out of battery, I’ll grab the micro USB cable and hook up the e-reader to my PC or laptop. Those people with social network dependency or constantly-online ADD are most likely not your target group, these people want “flash-n-bang” iPads, not “blink-blank-refresh” e-readers.

The less buttons, the better. By no means does this mean no buttons what-so-ever, though. It means some navigational buttons like a d-pad, and at-most one previous page button and one next-page button.

The casing should be made only from very durable and forgiving off-white plastic. Not black, not pink, not puce, not lime. And leave off any cheap chrome trimming, this only creates reflections and glares. I’m reading lots of text and I don’t want any distractions like absurd contrasts between the display area and casing. If you must absolutely add your device name, company logo and other silly stuff, put it on the back. I do not need to constantly see the name of the device or your company, I already chose and bought it. If you want others to see that stuff, the back is probably the perfect place, too. You know, because since most of the time the front with the display will be facing me, the back will be facing everything and everyone else.

Summary

Make me an e-reader that is only good for reading, storing and organizing lots of books in any form and nothing else. But make it do that extremely well.

Thank you!

Meet GMenu, Sibling of DMenu

I have been using wmii for quite some time now and right now can’t think of ever using a non tiling window manager ever again. Before wmii I tried dwm but didn’t quite like it as much as wmii.

But what I liked most about dwm and wmii is their “application launchers”: wimenu and dmenu. Actually they’re not really application launchers. All they really do, is read a list of items from STDIN and pop up a window where you can search and select the item you want. This (or whatever you typed) is then printed on STDOUT. It’s really trivial to create an application launching utility from these, basically just pipe ls /usr/bin to one of them, and then execute the resulting string. And did I mention they are both fast? Well, they are!

But they are also limited in ways I didn’t like. Wimenu displays it’s window either at the top edge or the bottom edge of the screen, and it displays the items in a horizontal list. Dmenu is similar, though it can display the items vertically, it will still span the whole screen width. I find horizontal lists hard to read, I prefer vertical lists. And while Dmenu can satisfy that, I would still prefer the window to be centered on the screen, a region I look at most of the time.

I spend some time reading the code of wimenu and dmenu, considering hacking them. But in the end, I decided against it. Both are written in plain C, no toolkit used, just basic Xlib. For the features I wanted to add, it was clear to me I would spend quite a bit of time implementing half a gui toolkit before I could even get to coding my desired features. And that’s when I decided to use GTK for my application, and hence I called it gmenu (as unimaginative as that is.)

You can check out gmenu at github.

Unbind/Rebind Ctrl+D in Gedit

After quite some googleing and experimenting I finally managed to change the behavior of Gedit and that annoying Ctrl+D shortcut. By default, pressing Ctrl+D deletes a line… very useful, I’m deleting lines all the time :roll-eyes:

To change this to something much more useful – like cutting the line and putting it into the clipboard – put the following into your ~/.gtkrc-2.0:

binding "override-ctrl-d" {
    bind "<ctrl>d" {
        "move-cursor" (display-line-ends, -1, 0)
        "move-cursor" (display-lines, 1, 1)
        "cut-clipboard" ()
    }
}
class "GeditView" binding :highest "override-ctrl-d"

To completely disable Ctrl+D, use the following instead:

binding "override-ctrl-d" {
    unbind "<ctrl>d"
}
class "GeditView" binding :highest "override-ctrl-d"

The important bit about these snippets is really just “class "GeditView" .... Now I just need to figure out how to remove the next useless key binding Ctrl+Shift+U…

Require, Include, Once, Autoload?

I have seen a few PHP performance tips lately that have me worried. A common tip found, is something along the lines of “Don’t use require_once/include_once” and also “Don’t use autoload.” The implications of following these tips are troublesome to say the least.
Read more of this post

Code Stutter

In all my experience as programmer (~9 years) I have contemplated, seen and created a few coding and naming conventions. But there was one kind of convention that always struck me as odd and lately as extremely annoying.
Read more of this post

PHP and PDO – Use it!

A lot of novice programmers exploring object orientation get their feet wet by implementing a database abstraction class. It’s a good learning assignment, but has no more use in production code ever since PHP introduced PDO.
Read more of this post

I’m learning Scala

Being bored I was browsing Wikipedia, reading about languages that use Java’s VM. I was reading the Groovy article, thinking that it looked interesting enough to start learning it. But then I got to the end where Groovy’s author, James Strachan, said:

I can honestly say if someone had shown me the Programming in Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I’d probably have never created Groovy.
Groovy Criticism

If even Groovy’s author thinks there is a better language, I thought I should just skip it and go read up on Scala. So first I read Wikipedia’s article on Scala, then I went over to the Scala language site for more. What I read there looked interesting enough and I added the Eclipse update site to my Eclipse installation, downloaded some of the PDFs in the documentation section, and started to play around with it.
Read more of this post

I want LISP but I don’t want LISP

LISP basically has everything I as a developer want. But somehow I just can’t bring myself to touch it with a ten-foot-pole. Maybe it’s the parenthesis ridden syntax, maybe it’s the functional paradigm, maybe it’s its mostly academic nature. Maybe it’s my preference for curly-brace languages, or my preference for object orientation. Maybe it’s those weird cons data structures and the equally weird car, cdr functions. Like LISP, Haskell and Erlang scare me. They have awesome concepts, programs can be mathematically proven to be correct, support parallel computing and more. Yet it’s that very mathematical nature that makes me uneasy. Math never held much fun or interest for me. It has always been a chore, a means to an end.
Read more of this post

ImageSlicer Progress…

The past two weeks I have been working on a small tool to slice images using Python, PIL and pygtk. I decided to use Glade for the user interface, and it’s great. It really simplifies coding GTK applications and lets me concentrate on handling events, writing callbacks. It is still necessary to know how GTK works to correctly create the interface and define signals and callbacks. But after that I just load the Glade XML file, fetch those widgets I’m really interested in (windows, buttons and menuitems mostly), connect handlers to the signals, show the main window and enter GTK’s main loop. As long as the widget names and signal names stay the same, I can now start trying out changing the user interface.

I want the ImageSlicer let the user create, move and resize rectangles over an image. I also wanted the display of the image and the rectangles to be zoomable. Since there isn’t any GTK widget that remotely does something like that, I had to come up with something. At first I thought, I’d just use some canvas component. I started by playing around with GnomeCanvas, but it didn’t have many features I needed and did have many features I didn’t need. Then I tried out GooCanvas, which at first seemed to be just what I needed. But then I noticed, it really isn’t suited to displaying images and working with them on a pixel level. While GooCanvas supports zooming, it will interpolate (blur, smooth) images and draw rectangles between pixels (which also blurs them). This is, because it really is meant to be used for displaying and modifing vector graphics. So I went back to creating my own solution.

I use a GtkDrawingArea for displaying the image and slice rectangles. I store the image as a GdkPixbuf, and draw only the visible area. I get the the visible area from two GtkAdjustments (one for the x axis, one for the y axis) which I also use for scrolling in a GtkScrolledWindow. For the zoom scale I also used a GtkAdjustment. I recalculate the visible width and height whenever the window size or the zoom changes and store that in the page_size property of the corresponding GtkAdjustment. I use GdkRectangles for the slice rectangles but I’ll probably change that to something else, since I also need to store more data with the slices like name, image type and options for the image type.

So far I have image loading, scrolling, zooming and creating slice rectangles done, but I’m having trouble with getting the pixel offset of the pointer correct once zoomed in. This results in some strange, wobbly behaviour when dragging or resizing slice rectangles. Once I have that fixed, I can continue with creating a user interface for setting properties of slices.

I really want to add support for gimp files (xcf), so the user can load a gimp file and enable/disable layers. I also want some way of monitoring images for changes, so they can be reloaded if they’re edited. I already thought up a basic undo/redo system but I’ll need to get a bit further along with the other issues before I know if it will work well.

Lua Userdata with user data

Sometimes I play around with Lua, and recently I decided it’s time to learn how to write modules in C/C++. I implemented a simple userdata with a few methods and property getter/setters. And while writing the Lua script to test the module, I noticed you could not set arbitrary properties on the userdata (of course not, it’s a userdata not a table). Then I started investigating, how this might be achived, yet every time I thought I had a solution it turned out it wouldn’t work, for some reason or other…

I was just about to give up, when I noticed a simple little paragraph in the Lua docs:

Pops a table from the stack and sets it as the new environment for the value at the given index. If the value at the given index is neither a function nor a thread nor a userdata, lua_setfenv returns 0. Otherwise it returns 1.

http://www.lua.org/manual/5.1/manual.html#lua_setfenv

I knew about this function and its getter equivalent (lua_getfenv) but always assumed the “f” in the name stood for “function”. I have no idea what it might stand for, but once the implication of the emphasized part hit me, it became clear! Every userdata can have its own environment table! And with two simple metatable functions for “__index” and “__newindex”, this environment table can be exposed to the Lua side and user properties/methods could be set!

And just after I had it implemented, I found a page in the lua-users wiki where it shows how to do just that (although it is not the main focus on the page)… I hate when that happens. :-(