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} |