Deleted Added
full compact
vt_font.c (259016) vt_font.c (262861)
1/*-
2 * Copyright (c) 2009 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Ed Schouten under sponsorship from the
6 * FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Ed Schouten under sponsorship from the
6 * FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/vt/vt_font.c 256145 2013-10-08 12:40:04Z ray $");
31__FBSDID("$FreeBSD: stable/10/sys/dev/vt/vt_font.c 262861 2014-03-06 18:30:56Z jhb $");
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/malloc.h>
36#include <sys/refcount.h>
37#include <sys/systm.h>
38
39#include <dev/vt/vt.h>
40
41static MALLOC_DEFINE(M_VTFONT, "vtfont", "vt font");
42
43/* Some limits to prevent abnormal fonts from being loaded. */
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/malloc.h>
36#include <sys/refcount.h>
37#include <sys/systm.h>
38
39#include <dev/vt/vt.h>
40
41static MALLOC_DEFINE(M_VTFONT, "vtfont", "vt font");
42
43/* Some limits to prevent abnormal fonts from being loaded. */
44#define VTFONT_MAXMAPPINGS 1024
45#define VTFONT_MAXGLYPHSIZE 262144
44#define VTFONT_MAXMAPPINGS 8192
45#define VTFONT_MAXGLYPHSIZE 1048576
46#define VTFONT_MAXDIMENSION 128
47
48static uint16_t
49vtfont_bisearch(const struct vt_font_map *map, unsigned int len, uint32_t src)
50{
51 int min, mid, max;
52
53 min = 0;

--- 27 unchanged lines hidden (view full) ---

81}
82
83const uint8_t *
84vtfont_lookup(const struct vt_font *vf, term_char_t c)
85{
86 uint32_t src;
87 uint16_t dst;
88 size_t stride;
46#define VTFONT_MAXDIMENSION 128
47
48static uint16_t
49vtfont_bisearch(const struct vt_font_map *map, unsigned int len, uint32_t src)
50{
51 int min, mid, max;
52
53 min = 0;

--- 27 unchanged lines hidden (view full) ---

81}
82
83const uint8_t *
84vtfont_lookup(const struct vt_font *vf, term_char_t c)
85{
86 uint32_t src;
87 uint16_t dst;
88 size_t stride;
89 unsigned int normal_map;
90 unsigned int bold_map;
89
91
92 /*
93 * No support for printing right hand sides for CJK fullwidth
94 * characters. Simply print a space and assume that the left
95 * hand side describes the entire character.
96 */
90 src = TCHAR_CHARACTER(c);
97 src = TCHAR_CHARACTER(c);
98 if (TCHAR_FORMAT(c) & TF_CJK_RIGHT) {
99 normal_map = VFNT_MAP_NORMAL_RIGHT;
100 bold_map = VFNT_MAP_BOLD_RIGHT;
101 } else {
102 normal_map = VFNT_MAP_NORMAL;
103 bold_map = VFNT_MAP_BOLD;
104 }
105
91 if (TCHAR_FORMAT(c) & TF_BOLD) {
106 if (TCHAR_FORMAT(c) & TF_BOLD) {
92 dst = vtfont_bisearch(vf->vf_bold, vf->vf_bold_length, src);
107 dst = vtfont_bisearch(vf->vf_map[bold_map],
108 vf->vf_map_count[bold_map], src);
93 if (dst != 0)
94 goto found;
95 }
109 if (dst != 0)
110 goto found;
111 }
96 dst = vtfont_bisearch(vf->vf_normal, vf->vf_normal_length, src);
112 dst = vtfont_bisearch(vf->vf_map[normal_map],
113 vf->vf_map_count[normal_map], src);
97
98found:
99 stride = howmany(vf->vf_width, 8) * vf->vf_height;
100 return (&vf->vf_bytes[dst * stride]);
101}
102
103struct vt_font *
104vtfont_ref(struct vt_font *vf)
105{
106
107 refcount_acquire(&vf->vf_refcount);
108 return (vf);
109}
110
111void
112vtfont_unref(struct vt_font *vf)
113{
114
115found:
116 stride = howmany(vf->vf_width, 8) * vf->vf_height;
117 return (&vf->vf_bytes[dst * stride]);
118}
119
120struct vt_font *
121vtfont_ref(struct vt_font *vf)
122{
123
124 refcount_acquire(&vf->vf_refcount);
125 return (vf);
126}
127
128void
129vtfont_unref(struct vt_font *vf)
130{
131 unsigned int i;
114
115 if (refcount_release(&vf->vf_refcount)) {
132
133 if (refcount_release(&vf->vf_refcount)) {
116 free(vf->vf_normal, M_VTFONT);
117 free(vf->vf_bold, M_VTFONT);
134 for (i = 0; i < VFNT_MAPS; i++)
135 free(vf->vf_map[i], M_VTFONT);
118 free(vf->vf_bytes, M_VTFONT);
119 free(vf, M_VTFONT);
120 }
121}
122
123static int
124vtfont_validate_map(struct vt_font_map *vfm, unsigned int length,
136 free(vf->vf_bytes, M_VTFONT);
137 free(vf, M_VTFONT);
138 }
139}
140
141static int
142vtfont_validate_map(struct vt_font_map *vfm, unsigned int length,
125 unsigned int nglyphs)
143 unsigned int glyph_count)
126{
127 unsigned int i, last = 0;
128
129 for (i = 0; i < length; i++) {
130 /* Not ordered. */
131 if (i > 0 && vfm[i].vfm_src <= last)
132 return (EINVAL);
133 /*
134 * Destination extends amount of glyphs.
135 */
144{
145 unsigned int i, last = 0;
146
147 for (i = 0; i < length; i++) {
148 /* Not ordered. */
149 if (i > 0 && vfm[i].vfm_src <= last)
150 return (EINVAL);
151 /*
152 * Destination extends amount of glyphs.
153 */
136 if (vfm[i].vfm_dst >= nglyphs ||
137 vfm[i].vfm_dst + vfm[i].vfm_len >= nglyphs)
154 if (vfm[i].vfm_dst >= glyph_count ||
155 vfm[i].vfm_dst + vfm[i].vfm_len >= glyph_count)
138 return (EINVAL);
139 last = vfm[i].vfm_src + vfm[i].vfm_len;
140 }
141
142 return (0);
143}
144
145int
146vtfont_load(vfnt_t *f, struct vt_font **ret)
147{
156 return (EINVAL);
157 last = vfm[i].vfm_src + vfm[i].vfm_len;
158 }
159
160 return (0);
161}
162
163int
164vtfont_load(vfnt_t *f, struct vt_font **ret)
165{
148 size_t glyphsize;
166 size_t glyphsize, mapsize;
149 struct vt_font *vf;
150 int error;
167 struct vt_font *vf;
168 int error;
169 unsigned int i;
151
152 /* Make sure the dimensions are valid. */
153 if (f->width < 1 || f->height < 1)
154 return (EINVAL);
155 if (f->width > VTFONT_MAXDIMENSION || f->height > VTFONT_MAXDIMENSION)
156 return (E2BIG);
157
158 /* Not too many mappings. */
170
171 /* Make sure the dimensions are valid. */
172 if (f->width < 1 || f->height < 1)
173 return (EINVAL);
174 if (f->width > VTFONT_MAXDIMENSION || f->height > VTFONT_MAXDIMENSION)
175 return (E2BIG);
176
177 /* Not too many mappings. */
159 if (f->nnormal > VTFONT_MAXMAPPINGS || f->nbold > VTFONT_MAXMAPPINGS)
160 return (E2BIG);
178 for (i = 0; i < VFNT_MAPS; i++)
179 if (f->map_count[i] > VTFONT_MAXMAPPINGS)
180 return (E2BIG);
161
162 /* Character 0 must always be present. */
181
182 /* Character 0 must always be present. */
163 if (f->nglyphs < 1)
183 if (f->glyph_count < 1)
164 return (EINVAL);
165
184 return (EINVAL);
185
166 glyphsize = howmany(f->width, 8) * f->height * f->nglyphs;
186 glyphsize = howmany(f->width, 8) * f->height * f->glyph_count;
167 if (glyphsize > VTFONT_MAXGLYPHSIZE)
168 return (E2BIG);
169
170 /* Allocate new font structure. */
187 if (glyphsize > VTFONT_MAXGLYPHSIZE)
188 return (E2BIG);
189
190 /* Allocate new font structure. */
171 vf = malloc(sizeof *vf, M_VTFONT, M_WAITOK);
172 vf->vf_normal = malloc(f->nnormal * sizeof(struct vt_font_map),
173 M_VTFONT, M_WAITOK);
174 vf->vf_bold = malloc(f->nbold * sizeof(struct vt_font_map),
175 M_VTFONT, M_WAITOK);
191 vf = malloc(sizeof *vf, M_VTFONT, M_WAITOK | M_ZERO);
176 vf->vf_bytes = malloc(glyphsize, M_VTFONT, M_WAITOK);
177 vf->vf_height = f->height;
178 vf->vf_width = f->width;
192 vf->vf_bytes = malloc(glyphsize, M_VTFONT, M_WAITOK);
193 vf->vf_height = f->height;
194 vf->vf_width = f->width;
179 vf->vf_normal_length = f->nnormal;
180 vf->vf_bold_length = f->nbold;
181 vf->vf_refcount = 1;
182
195 vf->vf_refcount = 1;
196
183 /* Copy in data. */
184 error = copyin(f->normal, vf->vf_normal,
185 vf->vf_normal_length * sizeof(struct vt_font_map));
186 if (error)
187 goto bad;
188 error = copyin(f->bold, vf->vf_bold,
189 vf->vf_bold_length * sizeof(struct vt_font_map));
190 if (error)
191 goto bad;
197 /* Allocate, copy in, and validate mappings. */
198 for (i = 0; i < VFNT_MAPS; i++) {
199 vf->vf_map_count[i] = f->map_count[i];
200 if (f->map_count[i] == 0)
201 continue;
202 mapsize = f->map_count[i] * sizeof(struct vt_font_map);
203 vf->vf_map[i] = malloc(mapsize, M_VTFONT, M_WAITOK);
204 error = copyin(f->map[i], vf->vf_map[i], mapsize);
205 if (error)
206 goto bad;
207 error = vtfont_validate_map(vf->vf_map[i], vf->vf_map_count[i],
208 f->glyph_count);
209 if (error)
210 goto bad;
211 }
212
213 /* Copy in glyph data. */
192 error = copyin(f->glyphs, vf->vf_bytes, glyphsize);
193 if (error)
194 goto bad;
195
214 error = copyin(f->glyphs, vf->vf_bytes, glyphsize);
215 if (error)
216 goto bad;
217
196 /* Validate mappings. */
197 error = vtfont_validate_map(vf->vf_normal, vf->vf_normal_length,
198 f->nglyphs);
199 if (error)
200 goto bad;
201 error = vtfont_validate_map(vf->vf_bold, vf->vf_bold_length,
202 f->nglyphs);
203 if (error)
204 goto bad;
205
206 /* Success. */
207 *ret = vf;
208 return (0);
209
210bad: vtfont_unref(vf);
211 return (error);
212}
218 /* Success. */
219 *ret = vf;
220 return (0);
221
222bad: vtfont_unref(vf);
223 return (error);
224}