-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimage.c
143 lines (118 loc) · 2.52 KB
/
image.c
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fconv.h"
#include "conf.h"
static char current[20];
static glyph_t **image;
static int symbols = 0;
static void fill_glyph (char *s, int cnt)
{
int i;
if (symbols != 0)
free_image (image);
symbols = cnt;
if (strcmp (current, s))
strcpy (current, s);
image = malloc (symbols * sizeof (glyph_t *));
if (image == NULL) {
printf ("Not enough memory to process glyph\n");
exit (1);
}
for (i = 0; i < symbols; i++) {
image[i] = new_glyph ();
outline_glyph (current[i], image[i]);
}
}
static void normalize_glyph (void)
{
int i;
rect_t c;
double h;
double *aa = get_kern();
for (i = 0; i < symbols; i++) {
flip_hor_glyph (image[i]);
get_cbox (image[i], &c);
offset_glyph (image[i], -c.lt.x, -c.lt.y);
image[i]->adv = (c.rb.x - c.lt.x) * (1 + aa[i]);
h = c.rb.y - c.lt.y;
image[i]->dsc = h - image[i]->asc;
}
}
static void set_glyph_stops (void)
{
int i;
for (i = 0; i < symbols; i++)
set_ex_stop (image[i]);
}
static void get_unscaled_size (double *w, double *h)
{
double asc, dsc, adv;
int i;
asc = dsc = adv = 0;
for (i = 0; i < symbols; i++) {
adv += image[i]->adv;
asc = (image[i]->asc > asc) ? image[i]->asc : asc;
dsc = (image[i]->dsc > dsc) ? image[i]->dsc : dsc;
}
*w = adv;
*h = asc + dsc;
}
static void fit_image (glyph_t **tmp, double w, double h, double border)
{
double iw, ih;
double sx, sy, s;
int i;
double asc, adv;
get_unscaled_size (&iw, &ih);
w -= 2 * border;
h -= 2 * border;
sx = (w == 0) ? 1 : w / iw;
sy = (h == 0) ? 1 : h / ih;
s = (w == 0) ? sy : (h == 0) ? sx : (sx < sy) ? sx : sy;
asc = 0;
adv = border;
for (i = 0; i < symbols; i++) {
tmp[i] = duplicate_glyph (image[i]);
scale_glyph (tmp[i], s);
asc = (tmp[i]->asc > asc) ? tmp[i]->asc : asc;
}
for (i = 0; i < symbols; i++) {
offset_glyph (tmp[i], adv, asc - tmp[i]->asc + border);
adv += tmp[i]->adv;
}
}
int generate_glyph (char *s)
{
int i;
i = strlen (s);
if (i > 19) {
printf ("String is too long \n");
return 0;
}
if (strcmp (s, current)) {
fill_glyph (s, i);
normalize_glyph ();
set_glyph_stops ();
}
return i;
}
glyph_t ** get_scaled_image (double w, double h, double border)
{
glyph_t **tmp;
tmp = malloc (symbols * sizeof (glyph_t *));
if (tmp == NULL) {
printf ("Not enough memory to process glyph\n");
exit (1);
}
fit_image (tmp, w, h, border);
return tmp;
}
void free_image (glyph_t **g)
{
int i;
void *p = g;
for (i = 0; i < symbols; i++, g++)
free_glyph (*g);
free (p);
}