[go: up one dir, main page]

Menu

[72b583]: / tests / c / ligexperts.c  Maximize  Restore  History

Download this file

151 lines (143 with data), 7.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#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);
}