#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <libps/pslib.h>
#ifdef MEMORY_DEBUGGING
#include <libps/pslib-mp.h>
#endif

void errorhandler(PSDoc *p, int error, const char *str, void *data) {
	fprintf(stderr, "PSLib: %s\n", str);
}

int main() {
	PSDoc *psdoc;
	int antiqua;
	float leftmargin = 100.0;
	int leftchars, pos = 0;
	char *text =
	  "This file is trying to show some of the possibilities of pslib when "
		"it comes to fonts, ligatures, kerning, input, and output encoding. "
		"For those not familiar "
		"with typography or type setting systems like TeX, it is not "
		"understandable at first sight, why thinks must be this complicated. "
		"Well, I have to admit myself, it isn't easy to grasp, how a letter "
		"typed on your keyboard finally ends up in your PostScript document "
		"and looks like you expected it to be. Let's have a look at the steps "
		"inbetween."
		"\n\n"
		"Task: Create a document containing a single number '1'"
		"\n\n"
		"That sounds like something easily achievable and it actually is. "
		"All you need to do is to call PS_show() and pass the string \"1\". "
		"Althought this appears to be quite forward, internally, pslib has "
		"to perform several tasks." 
		"\n\n"
		"First it takes the '1' from the passed string which must be in one of "
		"pslib's supported input encodings (currently iso-8859-1 and iso-8859-2). "
		"To be more precise, what is passed to PS_show() is actually a sequence "
		"of bytes (in this case only one byte) followed by a trailing null byte. "
		"PS_show() reads a 0x31 and since it assumes it be iso-8859-1 encoded, "
		"this must be a 'one' which is the official name. The next step is to "
		"check if this, so called glyph name, is available in the current font. "
		"There is a good chance that it is, because most fonts provide such a "
		"glyph. What was done with the input encoding is now reversed using the "
		"font encoding vector, which is a mapping between glyph names and an eight "
		"bit number. The byte stored for the glyph 'one' will be written to "
		"the PostScript file together with the font encoding vector. It could "
		"well be, that the hexadecimal number 0x31 is written to the file, but "
		"it may also be any other 8 bit number. This way "
		"the PostScript interpreter will be able to read the byte, look up its "
		"glyph name in the font encoding vector, and get the glyph outline from "
		"the font for actually drawing the glyph."
		"If you think this is too complicated, I can assure you, there is not "
		"better way, without sacrifying flexibility. Actually there is still "
		"a limitation, because of both the input and font encoding vector cannot "
		"contain more then 256 characters/glyphs. Typesetting a paragraph with a "
		"mixture of many different chars is almost impossible, unless you change "
		"the font encoding vector all the times, not talking about limitations "
		"in the set of possible chars supported by the input encoding."
		"\n\n"
		"Once you understood this process you can easily tweak it. For example, "
		"you don't want to use the regular arabic 1 but the roman 1. First of "
		"all you need a font containing a roman one, e.g. Linux Libertine. "
		"Its glyph name is 'romanone'. "
		"\n\n"
		"Another nice feature of pslib is support for ligatures. Ligatures are "
		"actually nothing more than replacement glyphs for a combination of "
		"glyphs. One populare ligatur is called 'fi' which is a replacement for "
		"a 'f' followed by an 'i'. Typographycally, such a ligature looks nicer "
		"than a 'f' and an 'i'. Ligatures appear to be a threadend species, "
		"because many word processors do not care about them and fonts often do "
		"only provide some very standard ligatures like 'fi', 'ff' and 'fl'. "
		"pslib uses a ligature whenever one is available."
		"\n\n"
		"The already mentioned font Linux Libertine has many ligatures, just like "
		"some old german fonts which traditionally make great use of ligatures. "
		"Ligatures may not be limited to two characters, there are variants "
		"with three characters like the 'sch' in the font 'Alte Schwabacher'. "
		"This ligature is made of 's' and 'ch', with 'ch' itself being a "
		"ligature of 'c' and 'h'. pslib supports all these and even ligatures "
		"made of n chars if there are any. There is just one think you have to "
		"take care of. The ligature glyph must be in the font encoding vector, "
		"otherwise pslib doesn't know which byte code has to be written into "
		"the PostScript file and it will take a '?' instead of disolve the "
		"ligature in recent versions (>= 0.4.0). "
		"\n\n"
		"Ligatures are not only from a typographical point of view of interest. "
		"They are very helpful if your input encoding does not contain certain "
		"characters like the long or short 's' in old german. Typing an 's' "
		"means either a long or a short s. Whatever it is, the other one is not "
		"reachable unless you tweak your input encoding. The solution is to "
		"create a ligature of e.g. ':' and 's' which ends up to be the e.g. "
		"long s. So, whenever you type ':s' the long s will appear in the output. "
		"Linux Libertine has a nice glyph showing the Linux penguin. What, if you "
		"like to "
		"put it into your running text of a paragraph. Again, tweak the input "
		"encoding (better don't mess with it), or create a ligature made of "
		"two chars, how about 'l' and 'x'?"
		"\n\n"
    "You may keep asking yourself how to tell pslib about this new ligatures. "
		"In the past, there was only one way to create new ligatures, by specify "
		"an encoding vector when loading the font. This file not just contains "
		"the font encoding vector but can also define new ligatures. Check for "
		"examples in the file 'AlteSchwabacher.enc'. Since version 0.4.0 of pslib "
		"there is function PS_add_ligature() which was initially provided to "
		"create ligatures for Type3  fonts, but can also be used to add new "
		"ligatures to Type1 fonts loaded from an afm file. "
		;

	PS_boot();
#ifdef MEMORY_DEBUGGING
	PS_mp_init();
#endif

#ifdef MEMORY_DEBUGGING
	psdoc = PS_new2(errorhandler, PS_mp_malloc, PS_mp_realloc, PS_mp_free, NULL);
#else
	psdoc = PS_new();
#endif
	PS_open_file(psdoc, "ligexperts.ps");
	PS_set_info(psdoc, "Creator", __FILE__);
	PS_set_info(psdoc, "Author", "Uwe Steinmann");
	PS_set_info(psdoc, "Title", "Ligatures for experts");
	PS_set_info(psdoc, "Keywords", "Font, Ligatures");
	PS_set_info(psdoc, "BoundingBox", "0 0 596 842");

	PS_set_parameter(psdoc, "SearchPath", "/usr/share/fonts/type1/linux-libertine");
	antiqua = PS_findfont(psdoc, "LinLibertine_Re-2.6.9RO", "", 1);

	do {
		PS_begin_page(psdoc, 596, 842);
		PS_setfont(psdoc, antiqua, 10.0);
		PS_set_value(psdoc, "leading", 15.0);
		PS_set_value(psdoc, "parindent", 15.0);
		leftchars = PS_show_boxed(psdoc, &text[pos], leftmargin, 100, 400, 680, "justify", NULL);
		pos = strlen(text) - leftchars;
		PS_end_page(psdoc);
	} while(leftchars > 0);

	PS_deletefont(psdoc, antiqua);
	PS_close(psdoc);
	PS_delete(psdoc);
#ifdef MEMORY_DEBUGGING 
	PS_mp_list_unfreed();
#endif  
	PS_shutdown();
	exit(0);
}
