10 #define MIN(a, b) ((a) < (b) ? (a) : (b))
11 #define MAX(a, b) ((a) > (b) ? (a) : (b))
12 #define LIMIT(n, a, b) ((n) < (a) ? (a) : ((n) > (b) ? (b) : (n)))
14 static FT_Library library
;
15 static FT_Face fn
[NFONTS
];
16 static int fn_desc
[NFONTS
];
17 static int fn_bold
[NFONTS
];
18 static int fn_hint
[NFONTS
];
19 static int fn_sc
[NFONTS
];
20 static int fn_sr
[NFONTS
];
23 static int glyphload(FT_Face face
, int c
, int autohint
)
25 int flags
= FT_LOAD_RENDER
;
27 flags
|= FT_LOAD_FORCE_AUTOHINT
;
28 return !FT_Get_Char_Index(face
, c
) ||
29 FT_Load_Char(face
, c
, flags
);
32 static int facedescender(FT_Face face
)
34 char *s
= "gy_pj/\\|Q";
37 if (!glyphload(face
, *s
, 0))
38 ret
= MAX(ret
, face
->glyph
->bitmap
.rows
-
39 face
->glyph
->bitmap_top
);
43 int mkfn_font(char *path
, char *spec
)
45 FT_Face
*face
= &fn
[fn_cnt
];
49 if (FT_New_Face(library
, path
, 0, face
))
51 while (spec
&& *spec
) {
53 fn_hint
[fn_cnt
] = atoi(spec
+ 1);
55 fn_bold
[fn_cnt
] = atoi(spec
+ 1);
57 vdpi
= atoi(spec
+ 1);
59 fn_sc
[fn_cnt
] = atof(spec
+ 1);
61 fn_sr
[fn_cnt
] = atof(spec
+ 1);
63 hdpi
= atoi(spec
+ 1);
65 size
= atof(spec
+ 1);
66 if (isdigit((unsigned char) spec
[0]))
69 while (*spec
&& strchr("0123456789.-+", (unsigned char) *spec
))
72 if (FT_Set_Char_Size(*face
, 0, size
* 64, hdpi
, vdpi
))
74 fn_desc
[fn_cnt
] = facedescender(*face
);
79 static void fn_embolden(unsigned char *bits
, int rows
, int cols
)
83 for (i
= 0; i
< rows
; i
++) {
84 for (j
= cols
- n
; j
>= 0; j
--) {
85 int idx
= i
* cols
+ j
;
87 for (k
= 0; k
< n
; k
++)
88 if (bits
[idx
+ k
] > val
)
90 bits
[idx
+ n
- 1] = val
;
95 int mkfn_bitmap(char *dst
, int c
, int rows
, int cols
)
97 unsigned char *bits
= (void *) dst
;
98 int sr
, sc
; /* the starting and the number of rows in bits */
99 int nr
, nc
; /* the starting and the number of cols in bits */
100 int br
; /* the starting column of glyph bitmap */
101 int bc
; /* the starting row of glyph bitmap */
102 int bw
; /* the number of columns in glyph bitmap */
107 for (i
= 0; i
< fn_cnt
; i
++) {
108 if (!glyphload(fn
[i
], c
& ~DWCHAR
, fn_hint
[i
])) {
118 bc
= c
& DWCHAR
? cols
: 0;
119 nc
= LIMIT(face
->glyph
->bitmap
.width
- bc
, 0, cols
);
120 sc
= LIMIT(face
->glyph
->bitmap_left
- bc
+ fn_sc
[i
], 0, cols
- nc
);
121 sr
= rows
+ fn_sr
[i
] - fn_desc
[i
] - face
->glyph
->bitmap_top
;
123 sr
= LIMIT(sr
, 0, rows
);
124 nr
= MIN(rows
- sr
, face
->glyph
->bitmap
.rows
- br
);
125 memset(bits
, 0, rows
* cols
);
126 src
= face
->glyph
->bitmap
.buffer
;
127 bw
= face
->glyph
->bitmap
.pitch
;
128 if (face
->glyph
->bitmap
.pixel_mode
== FT_PIXEL_MODE_MONO
) {
129 for (i
= 0; i
< nr
; i
++) {
130 for (j
= 0; j
< nc
; j
++) {
131 int num
= (br
+ i
) * bw
* 8 + bc
+ j
;
132 int val
= src
[num
/ 8] & (1 << (7 - num
% 8));
133 bits
[(i
+ sr
) * cols
+ j
+ sc
] = val
? 255 : 0;
138 for (i
= 0; i
< nr
; i
++)
139 memcpy(&bits
[(sr
+ i
) * cols
+ sc
], src
+ (br
+ i
) * bw
+ bc
, nc
);
141 fn_embolden(bits
, rows
, cols
);
145 void mkfn_dim(int *r
, int *c
)
147 *r
= fn
[0]->size
->metrics
.height
>> 6;
148 *c
= fn
[0]->size
->metrics
.max_advance
>> 6;
153 FT_Init_FreeType(&library
);
159 for (i
= 0; i
< fn_cnt
; i
++)
161 FT_Done_FreeType(library
);