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
|
#include <stdio.h>
#include <string.h>
#include "encoding.h"
#include "fm.h"
#include "glyph.h"
#include "utils.h"
static void encoding_write_glyph(int index, struct glyph *glyph,
encoding_type type, FILE *fp);
/**
* Write font encoding file
*
* \param savein Location to save in
* \param name The font name
* \param ctx Conversion context
* \param type File format to use - 0 = full; 1 = sparse
* \param callback Progress callback function
*/
ttf2f_result encoding_write(const char *savein, const char *name,
ttf2f_ctx *ctx, encoding_type type,
void (*callback)(int progress))
{
FILE *output;
struct glyph *g;
size_t i;
char out[1024];
snprintf(out, 1024, "%s" DIR_SEP "Encoding", savein);
if ((output = fopen(out, "w+")) == NULL)
return TTF2F_RESULT_OPEN;
fprintf(output, "%% Encoding file for font '%s'\n\n", name);
/* Write latin1 first */
for (i = 0; i != N_ELEMENTS(ctx->latin1tab); i++) {
if (ctx->latin1tab[i] == NULL) {
if (type == ENCODING_TYPE_NORMAL) {
fprintf(output, "/.notdef\n");
}
} else {
encoding_write_glyph(i, ctx->latin1tab[i],
type, output);
ctx->latin1tab[i]->done_encoding = 1;
}
}
/* Then the rest, skipping the ones we've already written */
for (i = 0; i != ctx->nglyphs; i++) {
g = &ctx->glyphs[i];
callback(i * 100 / ctx->nglyphs);
ttf2f_poll(1);
if (g->done_encoding == 0) {
encoding_write_glyph(i + N_ELEMENTS(ctx->latin1tab),
g, type, output);
g->done_encoding = 1;
}
}
fclose(output);
return TTF2F_RESULT_OK;
}
void encoding_write_glyph(int index, struct glyph *glyph,
encoding_type type, FILE *fp)
{
if (type == ENCODING_TYPE_SPARSE) {
if (glyph->name != 0) {
/* .notdef is implicit */
if (strcmp(glyph->name, ".notdef") != 0) {
fprintf(fp, "%4.4X;%s;COMMENT\n", index,
glyph->name);
}
} else if (glyph->code != (unsigned int) -1) {
if (glyph->code < 0x10000) {
/* Use uniXXXX for BMP codepoints */
fprintf(fp, "%4.4X;uni%04X;COMMENT\n", index,
glyph->code);
} else {
/* Use uXXXXX - uXXXXXXXX otherwise */
fprintf(fp, "%4.4X;u%X;COMMENT\n", index,
glyph->code);
}
} else {
fprintf(fp, "# Skipping %4.4X\n", index);
}
} else {
if (glyph->name != 0) {
fprintf(fp, "/%s\n", glyph->name);
} else if (glyph->code != (unsigned int) -1) {
if (glyph->code < 0x10000) {
/* Use /uniXXXX for BMP codepoints */
fprintf(fp, "/uni%4.4X\n", glyph->code);
} else {
/* Use /uXXXXX - /uXXXXXXXX otherwise.
* These are supported since FM 3.53.
* FM 3.43 - 3.52 (inclusive) understood
* /uniXXXXYYYY, where XXXX and YYYY were
* a UTF-16 surrogate pair. We have never
* emitted such things and support for
* them was removed in FM 3.53 with the
* introduction of support for the /u form.
* Thus, take the easy option and rely on
* noone running a UCS FM earlier than 3.53
* expecting astral codepoints to work.
*/
fprintf(fp, "/u%X\n", glyph->code);
}
} else {
fprintf(fp, "/.notdef\n");
}
}
}
|