Doodlehash Reference Manual 0.0.2

Feedback Information

To report a bug or make a suggestion regarding the game, the editors, or this documentation, see the Doodlehash Project Page.


Table of Contents
Preface
What is this?
The API
Making a simple program
The Parts of the Doodlehash Face
The Drawing Order
Data files
Environment Variables
Connecting the SVG files together
Randomly colouring faces
Final Words
Copying This Manual

Preface

The idea for this library came from the www.robohash.org website. The artwork for this library came from worldlabel.com. Thank-you to www.worldlabel.com for putting their clip-art into the public domain so that free software projects like this one can use it.


What is this?

doodlehash, a C library that makes a random face from a string of text. You can use doodlehash to make an avatar from an email address. The idea is that you can use identifying text for a person to generate a random image.

doodlehash uses specially annotated SVG (Scalable Vector Graphic) files as input. Eyes, ears, nose, mouth, hair, etc are randomly chosen and coloured to make a unique face.

Here are some faces generated with doodlehash:

The many faces of doodlehash.

Figure 1.

It's fun and easy to add doodlehash to your program!


The API

The doodlehash interface is very simple:


#include <libdoodlehash/doodlehash.h>
int doodlehash_init();
GdkPixbuf* doodlehash_new_pixbuf(const gchar *text, guint32 height, guint32 width);
void doodlehash_term();
                

You give it some random text, as well as a desired height and width of the face, and doodlehash gives you back a randomly generated face on a GdkPixbuf. Call g_object_unref on the returned pixbuf when you're done with it.

There is a known bug in this version of the software: width must be the same as height for faces to be generated properly.

The init and term functions mostly equate to the same named functions inside librsvg2 (a run-time dependency of doodlehash). doodlehash_init does a little extra work of checking if it can see any data files -- it will return non-zero if it can't find any.


Making a simple program

hello-doodlehash.c:


#include <gtk/gtk.h>
#include <libdoodlehash/doodlehash.h>

int 
main (int argc, char **argv)
{
  int retval;
  gtk_init (&argc, &argv);
  retval = doodlehash_init ();
  if (retval != 0)
    return retval;

  GdkPixbuf *pixbuf = doodlehash_new_pixbuf ("foo", 512, 512);
  if (pixbuf)
    {
      gdk_pixbuf_save (pixbuf, "face.png", "png", NULL, NULL);
      g_object_unref (pixbuf);
    }

  doodlehash_term ();
  return 0;
}
                

Building and running hello-doodlehash.c:


$ gcc hello-doodlehash.c `pkg-config --cflags --libs gtk+-2.0 libdoodlehash-2.4 ` -o hello-doodlehash
$ ./hello-doodlehash
[various gtk warnings will be emitted]
$ eog face.png
        

Note that the doodlehash software needs to be built with --prefix=/usr so that the doodlehash pkg-config file gets installed into the right place.

The remainder of this document will describe how to change the behaviour of doodlehash. If you want to add a new mouth, or change a hairstyle, or if you just want to know how doodlehash works; then read on.


The Parts of the Doodlehash Face

Meet Carlos.

Figure 2.

His doodlehash face has many parts:


The Drawing Order

The drawing order of the parts of the face is hard-coded into the doodlehash library. There aren't any hints (yet) that can be passed to draw one object before or after another.

The drawing order is as follows:

  1. The head is drawn on a background of white.
  2. Cheeks.
  3. A nose.
  4. Eyes.
  5. Eyebrows.
  6. Spectacles.
  7. A Chin.
  8. A Mouth.
  9. A Moustache.
  10. Ears.
  11. Earrings.
  12. Hair.

The drawing order is important because it means that some facial objects will obscure others. It means that hair cannot go behind the head or the ears. But mostly it means good things like, earrings get drawn on ears; that fuzzy eyebrows obscure eyes; that a moustache obscures a mouth; and that eyeglasses can be transparent to see-through to the eyes.


Data files

Doodlehash looks for data files in /usr/share/doodlehash (again, this requires the software to be built with configure --prefix=/usr). This directory has a single subdirectory for each of the face parts:

Each of the subdirectories hold zero or more specially annotated (e.g. doodlehash-aware) SVG files.

Some of the face parts are implemented as left/right pairs of SVG files. The left graphic filename must have the -left.svg suffix, while the right-side graphic must have a -right.svg suffix. Doodlehash requires this naming convention to function properly.

The subdirectories that have these left/right pairs are:

Sometimes a particular part of the face is clearly male or female, and it doesn't always make sense to mix and match the parts. A big old Hulk Hogan moustache probably doesn't make a lot of sense on a head that has a pretty pink bow on it. Or maybe it does -- but Carlos wouldn't be comfortable with that.

SVG files that begin with m- are marked as being only applicable for male faces, while files that start with m- females only. By default all SVG files are applicable to both male and female.


Environment Variables

The doodlehash library knows about a single environment variable: DOODLEHASH_PATH.

Setting this environment variable makes doodlehash look for svg files at a different location. The various subdirectories (cheeks, chins, etc) will be expected at that location.


Connecting the SVG files together

The various parts of the face connect together in a straightforward manner:

The SVG files are specially annotated by naming rectangles. This is easily accomplished in an SVG editor like Inkscape. The following names are rectangle IDs that doodlehash recongizes:

The doodlehash library places the SVGs on top of each other according to where their connection points align. Imagine the connect-to-ear point in the earring SVG lining up with the connect-to-earring point in an ear SVG. Likewise the for connect-to-nose point in the head SVG lining up with the connect-to-head point in the nose SVG. Is this easy or what?

Beware that if the calculated upper-left corner of a face part has a negative subscript, it will not be drawn on the face.

Spectacles are connected at the point as the eyes. The dimensions of the spectacles SVG must be precisely the same as the eyes to be considered for random inclusion on the face. In this manner the doodlehash library is shown which eyes go with which spectacles.

A hair file must have the same dimensions as the head file to be considered for random inclusion on the face. In this manner the doodlehash library is shown which hair goes with which head.

Although the named SVG elements are rectangles, the point of the top-left corner is used when connecting face parts (and not the center of the rectangle).

Inkscape is your friend. You will be spending a lot time in Inkscape if you want to make your own set of faces. Placing hair can be difficult -- to make it easier, you can include a transparent generic head shape in your hair SVG files, and then work in outline-mode to place the hair in just the right place.

Try making your own mouth SVG file and add it to the doodlehash library of mouths! Maybe it's a big old frown, or maybe it's a mouth that's laughing.


Randomly colouring faces

Doodlehash allows for colour randomization, but they're not all that random. By default it won't generate faces with blond moustaches and black hair. And doodlehash also makes sure that the skin tones match. How does it do that?

Doodlehash knows about skin colour and hair colour. It knows which hair colours go with which skin colours. How does it know that? The colours are listed in each SVG file's metadata description. A single colour description line looks like this:


#000000 #000000 #FFFFFF #FFFFFF

There are four rgb colours in html hexadecimal notation. Other lines in the description that don't have this form are ignored by doodlehash. The first two colours refer to the stroke and fill colours for skin, and the last two colours refer to the stroke and fill colours for hair. So in this case we have skin that is black and hair that is white. This is one potential colour scheme for the SVG file it appears in.

Doodlehash tries to make sure that the following parts "go together": hair, ears, moustache, mouth, nose, eyebrows, chin and cheeks. All of these SVG files will need similar colour description lines in them, if you want the parts to "go together". If an SVG file does not have any colour description lines in it, it will be considered suitable for any colour scheme.

spectacles, and earrings can also have these colour description lines. The two sets of colours don't mean hair and skin though -- instead they are just colours that your spectacles and your earrings look good with.

After doodlehash does the hard work of finding the parts that look good together, it needs to change the colour of the SVG file. Doodlehash is told which parts to change the colour of by setting the stroke and fill colours to special doodlehash placeholder values.

Here are the four easy-to-remember placeholder colours:

  1. The skin stroke placeholder colour is: #d00dle (it says doodle).
  2. The skin fill placeholder colour is: #114511 (it says HASH, if you really squint).
  3. The hair stroke placeholder colour is: #f1dd1e (it says fiddle).
  4. The hair fill placeholder colour is: #00d1e5 (it says oodles).


Final Words

The default face parts do not include any cheeks, noses, ears, moustaches, spectacles, or earrings. This doesn't mean that they can't be used; they just lack proper artwork. The default heads have ears already on them because flawlessly lining up ears with many different heads seemed too time consuming.

Beware that adding one moustache will moustachio all randomly generated male faces. This can be addressed by adding a number of blank moustaches.

Try adding some spectacles. Make sure you a differently sized set of eyes, otherwise all of your randomly generated faces will be bespectacled.

Go forth and make some faces! Oh the faces we'll make. Enjoy!


Copying This Manual

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License (GFDL), Version 1.2 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You can find a copy of the GFDL at this link or in the file COPYING-DOCS distributed with this manual.

This manual is part of a collection of GNOME manuals distributed under the GFDL. If you want to distribute this manual separately from the collection, you can do so by adding a copy of the license to the manual, as described in section 6 of the license.

Many of the names used by companies to distinguish their products and services are claimed as trademarks. Where those names appear in any GNOME documentation, and the members of the GNOME Documentation Project are made aware of those trademarks, then the names are in capital letters or initial capital letters.

DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT ARE PROVIDED UNDER THE TERMS OF THE GNU FREE DOCUMENTATION LICENSE WITH THE FURTHER UNDERSTANDING THAT:

  1. DOCUMENT IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE DOCUMENT OR MODIFIED VERSION OF THE DOCUMENT IS FREE OF DEFECTS MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY, ACCURACY, AND PERFORMANCE OF THE DOCUMENT OR MODIFIED VERSION OF THE DOCUMENT IS WITH YOU. SHOULD ANY DOCUMENT OR MODIFIED VERSION PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL WRITER, AUTHOR OR ANY CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY DOCUMENT OR MODIFIED VERSION OF THE DOCUMENT IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER; AND

  2. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE AUTHOR, INITIAL WRITER, ANY CONTRIBUTOR, OR ANY DISTRIBUTOR OF THE DOCUMENT OR MODIFIED VERSION OF THE DOCUMENT, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER DAMAGES OR LOSSES ARISING OUT OF OR RELATING TO USE OF THE DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES.