1use std::collections::HashMap;
18use std::fmt;
19use std::fmt::{Debug, Display, Formatter};
20use std::result::Result;
21
22use geom::{affine_pt, Affine, Point};
23use raster::Raster;
24
25#[derive(PartialEq, Eq, Hash)]
26struct Tag(u32);
27
28impl Tag {
29 fn from_str(s: &str) -> Tag {
30 Tag(get_u32(s.as_bytes(), 0).unwrap())
31 }
32}
33
34impl Display for Tag {
35 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
36 let &Tag(tag) = self;
37 let buf = vec![
38 ((tag >> 24) & 0xff) as u8,
39 ((tag >> 16) & 0xff) as u8,
40 ((tag >> 8) & 0xff) as u8,
41 (tag & 0xff) as u8,
42 ];
43 f.write_str(&String::from_utf8(buf).unwrap())
44 }
45}
46
47fn get_u16(data: &[u8], off: usize) -> Option<u16> {
48 if off + 1 > data.len() {
49 None
50 } else {
51 Some(((data[off] as u16) << 8) | data[off + 1] as u16)
52 }
53}
54
55fn get_i16(data: &[u8], off: usize) -> Option<i16> {
56 get_u16(data, off).map(|x| x as i16)
57}
58
59fn get_f2_14(data: &[u8], off: usize) -> Option<f32> {
60 get_i16(data, off).map(|x| x as f32 * (1.0 / (1 << 14) as f32))
61}
62
63fn get_u32(data: &[u8], off: usize) -> Option<u32> {
64 if off + 3 > data.len() {
65 None
66 } else {
67 Some(
68 ((data[off] as u32) << 24)
69 | ((data[off + 1] as u32) << 16)
70 | ((data[off + 2] as u32) << 8)
71 | data[off + 3] as u32,
72 )
73 }
74}
75
76struct Head<'a>(&'a [u8]);
78
79impl<'a> Head<'a> {
80 fn index_to_loc_format(&self) -> i16 {
81 get_i16(self.0, 50).unwrap()
82 }
83
84 fn units_per_em(&self) -> u16 {
85 get_u16(self.0, 18).unwrap()
86 }
87}
88
89struct Maxp<'a> {
90 data: &'a [u8],
91}
92
93impl<'a> Maxp<'a> {
94 fn num_glyphs(&self) -> u16 {
95 get_u16(self.data, 4).unwrap()
96 }
97}
98
99struct Loca<'a>(&'a [u8]);
100
101impl<'a> Loca<'a> {
102 fn get_off(&self, glyph_ix: u16, fmt: i16) -> Option<u32> {
103 if fmt != 0 {
104 get_u32(self.0, glyph_ix as usize * 4)
105 } else {
106 get_u16(self.0, glyph_ix as usize * 2).map(|raw| raw as u32 * 2)
107 }
108 }
109}
110
111struct EncodingRecord<'a>(&'a [u8]);
112
113impl<'a> EncodingRecord<'a> {
114 fn get_platform_id(&self) -> u16 {
115 get_u16(self.0, 0).unwrap()
116 }
117
118 fn get_encoding_id(&self) -> u16 {
119 get_u16(self.0, 2).unwrap()
120 }
121
122 fn get_offset(&self) -> u32 {
123 get_u32(self.0, 4).unwrap()
124 }
125}
126
127impl<'a> Debug for EncodingRecord<'a> {
128 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
129 f.debug_struct("EncodingRecord")
130 .field("platformID", &self.get_platform_id())
131 .field("encodingID", &self.get_encoding_id())
132 .field("offset", &self.get_offset())
133 .finish()
134 }
135}
136
137struct Encoding<'a>(&'a [u8]);
138
139impl<'a> Encoding<'a> {
140 fn get_format(&self) -> u16 {
141 get_u16(self.0, 0).unwrap()
142 }
143
144 fn get_length(&self) -> u16 {
145 get_u16(self.0, 2).unwrap()
146 }
147
148 fn get_language(&self) -> u16 {
149 get_u16(self.0, 4).unwrap()
150 }
151}
152
153impl<'a> Debug for Encoding<'a> {
154 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
155 f.debug_struct("Encoding")
156 .field("format", &self.get_format())
157 .field("length", &self.get_length())
158 .field("language", &self.get_language())
159 .finish()
160 }
161}
162
163struct EncodingFormat4<'a>(&'a [u8]);
164
165impl<'a> EncodingFormat4<'a> {
166 fn get_format(&self) -> u16 {
167 get_u16(self.0, 0).unwrap()
168 }
169
170 fn get_length(&self) -> u16 {
171 get_u16(self.0, 2).unwrap()
172 }
173
174 fn get_language(&self) -> u16 {
175 get_u16(self.0, 4).unwrap()
176 }
177
178 fn get_seg_count_x_2(&self) -> u16 {
179 get_u16(self.0, 6).unwrap()
180 }
181
182 fn get_seg_count(&self) -> u16 {
183 self.get_seg_count_x_2() / 2
184 }
185
186 fn get_search_range(&self) -> u16 {
187 get_u16(self.0, 8).unwrap()
188 }
189
190 fn get_entry_selector(&self) -> u16 {
191 get_u16(self.0, 10).unwrap()
192 }
193
194 fn get_range_shift(&self) -> u16 {
195 get_u16(self.0, 12).unwrap()
196 }
197
198 fn get_u16_vec(&self, start_position: u16, count: u16) -> Vec<u16> {
199 let mut result = vec![];
200 let mut vec_position = start_position;
201 let limit = vec_position + 2 * count;
202 while vec_position < limit {
203 result.push(get_u16(self.0, vec_position as usize).unwrap());
204 vec_position += 2;
205 }
206 result
207 }
208
209 fn get_i16_vec(&self, start_position: u16, count: u16) -> Vec<i16> {
210 let mut result = vec![];
211 let mut vec_position = start_position;
212 let limit = vec_position + 2 * count;
213 while vec_position < limit {
214 result.push(get_i16(self.0, vec_position as usize).unwrap());
215 vec_position += 2;
216 }
217 result
218 }
219
220 fn get_end_counts_position() -> u16 {
221 14
222 }
223
224 fn get_end_counts(&self) -> Vec<u16> {
225 let seg_count = self.get_seg_count();
226 self.get_u16_vec(Self::get_end_counts_position(), seg_count)
227 }
228
229 fn get_start_counts_position(seg_count: u16) -> u16 {
230 Self::get_end_counts_position() + 2 + 2 * seg_count
231 }
232
233 fn get_start_counts(&self) -> Vec<u16> {
234 let seg_count = self.get_seg_count();
235 self.get_u16_vec(Self::get_start_counts_position(seg_count), seg_count)
236 }
237
238 fn get_id_deltas_position(seg_count: u16) -> u16 {
239 Self::get_start_counts_position(seg_count) + 2 * seg_count
240 }
241
242 fn get_id_deltas(&self) -> Vec<i16> {
243 let seg_count = self.get_seg_count();
244 self.get_i16_vec(Self::get_id_deltas_position(seg_count), seg_count)
245 }
246
247 fn get_id_range_offset_position(seg_count: u16) -> u16 {
248 Self::get_id_deltas_position(seg_count) + 2 * seg_count
249 }
250
251 fn get_id_range_offsets(&self) -> Vec<u16> {
252 let seg_count = self.get_seg_count();
253 self.get_u16_vec(Self::get_id_range_offset_position(seg_count), seg_count)
254 }
255
256 fn extract_glyph_id(
257 &self, code_point: u16, start_value: u16, seg_count: u16, seg_index: u16,
258 ) -> Option<u16> {
259 let data = self.0;
260 let seg_index_pos = 2 * seg_index;
261 let id_range_offset_pos = Self::get_id_range_offset_position(seg_count) + seg_index_pos;
262 let id_range_offset_value = get_u16(data, id_range_offset_pos as usize).unwrap();
263 let id_delta_pos = Self::get_id_deltas_position(seg_count) + seg_index_pos;
264 let id_delta = get_i16(data, id_delta_pos as usize).unwrap();
265 if id_range_offset_value == 0 {
266 Some((code_point as i16 + id_delta) as u16)
267 } else {
268 let delta = (code_point - start_value) * 2;
269 let pos = id_range_offset_pos.wrapping_add(delta) + id_range_offset_value;
270 let glyph_array_value = get_u16(data, pos as usize).unwrap();
271 if glyph_array_value == 0 {
272 return None;
273 }
274 let glyph_index = (glyph_array_value as i16).wrapping_add(id_delta);
275 Some(glyph_index as u16)
276 }
277 }
278
279 pub fn lookup_glyph_id(&self, code_point: u16) -> Option<u16> {
280 let end_counts_position = Self::get_end_counts_position();
281 let seg_count = self.get_seg_count();
282 let mut size = seg_count - 1;
283 let mut index = size / 2;
284 while size > 0 {
285 let search = end_counts_position + index * 2;
286 let end_value = get_u16(self.0, search as usize).unwrap();
287 if end_value >= code_point {
288 let start_pos = Self::get_start_counts_position(seg_count) + 2 * index;
289 let start_value = get_u16(self.0, start_pos as usize).unwrap();
290 if start_value > code_point {
291 size /= 2;
292 index -= size;
293 } else {
294 return self.extract_glyph_id(code_point, start_value, seg_count, index);
295 }
296 } else {
297 size /= 2;
298 index += size;
299 }
300 }
301 None
302 }
303}
304
305impl<'a> Debug for EncodingFormat4<'a> {
306 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
307 f.debug_struct("EncodingFormat4")
308 .field("format", &self.get_format())
309 .field("length", &self.get_length())
310 .field("language", &self.get_language())
311 .field("segCountX2", &self.get_seg_count_x_2())
312 .field("searchRange", &self.get_search_range())
313 .field("entrySelector", &self.get_entry_selector())
314 .field("rangeShift", &self.get_range_shift())
315 .field("endCounts", &self.get_end_counts())
316 .field("startCounts", &self.get_start_counts())
317 .field("idDeltas", &self.get_id_deltas())
318 .field("idRangeOffsets", &self.get_id_range_offsets())
319 .finish()
320 }
321}
322
323struct Cmap<'a>(&'a [u8]);
324
325impl<'a> Cmap<'a> {
326 fn get_version(&self) -> u16 {
327 get_u16(self.0, 0).unwrap()
328 }
329
330 fn get_num_tables(&self) -> u16 {
331 get_u16(self.0, 2).unwrap()
332 }
333
334 fn get_encoding_record(&self, index: u16) -> Option<EncodingRecord<'a>> {
335 if index >= self.get_num_tables() {
336 return None;
337 }
338 let enc_offset = (index * 8 + 4) as usize;
339 let encoding_data = &self.0[enc_offset as usize..(enc_offset + 12) as usize];
340 Some(EncodingRecord(encoding_data))
341 }
342
343 fn get_encoding_records(&self) -> Vec<EncodingRecord> {
344 let mut encodings = vec![];
345 for i in 0..self.get_num_tables() {
346 encodings.push(self.get_encoding_record(i).unwrap());
347 }
348 encodings
349 }
350
351 fn get_encoding(&self, index: u16) -> Option<Encoding<'a>> {
352 if index >= self.get_num_tables() {
353 return None;
354 }
355 let record = self.get_encoding_record(index).unwrap();
356 let subtable_len = get_u16(self.0, (record.get_offset() + 2) as usize).unwrap() as u32;
357 let encoding_data =
358 &self.0[record.get_offset() as usize..(record.get_offset() + subtable_len) as usize];
359 Some(Encoding(encoding_data))
360 }
361
362 fn get_encoding_format_4_at(&self, index: u16) -> Option<EncodingFormat4<'a>> {
363 let encoding = self.get_encoding(index);
364 if encoding.is_none() || encoding.unwrap().get_format() != 4 {
365 return None;
366 }
367 let record = self.get_encoding_record(index).unwrap();
368 let subtable_len = get_u16(self.0, (record.get_offset() + 2) as usize).unwrap() as u32;
369 let encoding_data =
370 &self.0[record.get_offset() as usize..(record.get_offset() + subtable_len) as usize];
371 Some(EncodingFormat4(encoding_data))
372 }
373
374 fn get_encodings(&self) -> Vec<Encoding> {
375 let mut encodings = vec![];
376 for i in 0..self.get_num_tables() {
377 encodings.push(self.get_encoding(i).unwrap());
378 }
379 encodings
380 }
381
382 pub fn find_format_4_encoding(&self) -> Option<u16> {
383 for index in 0..self.get_num_tables() {
384 let encoding = self.get_encoding(index);
385 if let Some(encoding) = encoding {
386 if encoding.get_format() == 4 {
387 return Some(index);
388 }
389 }
390 }
391 None
392 }
393}
394
395impl<'a> Debug for Cmap<'a> {
396 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
397 f.debug_struct("Cmap")
398 .field("version", &self.get_version())
399 .field("numTables", &self.get_num_tables())
400 .field("encodingRecords", &self.get_encoding_records())
401 .field("encodings", &self.get_encodings())
402 .finish()
403 }
404}
405
406fn get_bbox_raw(data: &[u8]) -> (i16, i16, i16, i16) {
407 (
408 get_i16(data, 2).unwrap(),
409 get_i16(data, 4).unwrap(),
410 get_i16(data, 6).unwrap(),
411 get_i16(data, 8).unwrap(),
412 )
413}
414
415enum Glyph<'a> {
416 Empty,
417 Simple(SimpleGlyph<'a>),
418 Compound(CompoundGlyph<'a>),
419}
420
421struct SimpleGlyph<'a> {
422 data: &'a [u8],
423}
424
425impl<'a> SimpleGlyph<'a> {
426 fn number_of_contours(&self) -> i16 {
427 get_i16(self.data, 0).unwrap()
428 }
429
430 fn bbox(&self) -> (i16, i16, i16, i16) {
431 get_bbox_raw(self.data)
432 }
433
434 fn points(&self) -> GlyphPoints<'a> {
435 let data = self.data;
436 let n_contours = self.number_of_contours();
437 let insn_len_off = 10 + 2 * n_contours as usize;
438 let n_points = get_u16(data, insn_len_off - 2).unwrap() as usize + 1;
439 let insn_len = get_u16(data, insn_len_off).unwrap(); let flags_ix = insn_len_off + insn_len as usize + 2;
441 let mut flags_size = 0;
442 let mut x_size = 0;
443 let mut points_remaining = n_points;
444 while points_remaining > 0 {
445 let flag = data[flags_ix as usize + flags_size];
446 let repeat_count = if (flag & 8) == 0 {
447 1
448 } else {
449 flags_size += 1;
450 data[flags_ix as usize + flags_size] as usize + 1
451 };
452 flags_size += 1;
453 match flag & 0x12 {
454 0x02 | 0x12 => x_size += repeat_count,
455 0x00 => x_size += 2 * repeat_count,
456 _ => (),
457 }
458 points_remaining -= repeat_count;
459 }
460 let x_ix = flags_ix + flags_size;
461 let y_ix = x_ix + x_size;
462 GlyphPoints {
463 data: data,
464 x: 0,
465 y: 0,
466 points_remaining: n_points,
467 last_flag: 0,
468 flag_repeats_remaining: 0,
469 flags_ix: flags_ix,
470 x_ix: x_ix,
471 y_ix: y_ix,
472 }
473 }
474
475 fn contour_sizes(&self) -> ContourSizes {
476 let n_contours = self.number_of_contours();
477 ContourSizes {
478 data: self.data,
479 contours_remaining: n_contours as usize,
480 ix: 10,
481 offset: -1,
482 }
483 }
484}
485
486struct GlyphPoints<'a> {
487 data: &'a [u8],
488 x: i16,
489 y: i16,
490 points_remaining: usize,
491 last_flag: u8,
492 flag_repeats_remaining: u8,
493 flags_ix: usize,
494 x_ix: usize,
495 y_ix: usize,
496}
497
498impl<'a> Iterator for GlyphPoints<'a> {
499 type Item = (bool, i16, i16);
500 fn next(&mut self) -> Option<(bool, i16, i16)> {
501 if self.points_remaining == 0 {
502 None
503 } else {
504 if self.flag_repeats_remaining == 0 {
505 self.last_flag = self.data[self.flags_ix];
506 if (self.last_flag & 8) == 0 {
507 self.flags_ix += 1;
508 } else {
509 self.flag_repeats_remaining = self.data[self.flags_ix + 1];
510 self.flags_ix += 2;
511 }
512 } else {
513 self.flag_repeats_remaining -= 1;
514 }
515 let flag = self.last_flag;
516 match flag & 0x12 {
520 0x02 => {
521 self.x -= self.data[self.x_ix] as i16;
522 self.x_ix += 1;
523 }
524 0x00 => {
525 self.x += get_i16(self.data, self.x_ix).unwrap();
526 self.x_ix += 2;
527 }
528 0x12 => {
529 self.x += self.data[self.x_ix] as i16;
530 self.x_ix += 1;
531 }
532 _ => (),
533 }
534 match flag & 0x24 {
535 0x04 => {
536 self.y -= self.data[self.y_ix] as i16;
537 self.y_ix += 1;
538 }
539 0x00 => {
540 self.y += get_i16(self.data, self.y_ix).unwrap();
541 self.y_ix += 2;
542 }
543 0x24 => {
544 self.y += self.data[self.y_ix] as i16;
545 self.y_ix += 1;
546 }
547 _ => (),
548 }
549 self.points_remaining -= 1;
550 Some(((self.last_flag & 1) != 0, self.x, self.y))
551 }
552 }
553
554 fn size_hint(&self) -> (usize, Option<usize>) {
555 (
556 self.points_remaining as usize,
557 Some(self.points_remaining as usize),
558 )
559 }
560}
561
562struct ContourSizes<'a> {
563 data: &'a [u8],
564 contours_remaining: usize,
565 ix: usize,
566 offset: i32,
567}
568
569impl<'a> Iterator for ContourSizes<'a> {
570 type Item = usize;
571 fn next(&mut self) -> Option<(usize)> {
572 if self.contours_remaining == 0 {
573 None
574 } else {
575 let ret = get_u16(self.data, self.ix).unwrap() as i32 - self.offset;
576 self.offset += ret;
577 self.ix += 2;
578 self.contours_remaining -= 1;
579 Some(ret as usize)
580 }
581 }
582
583 fn size_hint(&self) -> (usize, Option<usize>) {
584 (self.contours_remaining, Some(self.contours_remaining))
585 }
586}
587
588struct CompoundGlyph<'a> {
589 data: &'a [u8],
590}
591
592struct Components<'a> {
593 data: &'a [u8],
594 more: bool,
595 ix: usize,
596}
597
598const ARG_1_AND_2_ARE_WORDS: u16 = 1;
599const WE_HAVE_A_SCALE: u16 = 1 << 3;
600const MORE_COMPONENTS: u16 = 1 << 5;
601const WE_HAVE_AN_X_AND_Y_SCALE: u16 = 1 << 6;
602const WE_HAVE_A_TWO_BY_TWO: u16 = 1 << 7;
603
604impl<'a> Iterator for Components<'a> {
605 type Item = (u16, Affine);
606 fn next(&mut self) -> Option<(u16, Affine)> {
607 if !self.more {
608 return None;
609 }
610 let flags = get_u16(self.data, self.ix).unwrap();
611 self.ix += 2;
612 let glyph_index = get_u16(self.data, self.ix).unwrap();
613 self.ix += 2;
614 let arg1;
615 let arg2;
616 if (flags & ARG_1_AND_2_ARE_WORDS) != 0 {
617 arg1 = get_i16(self.data, self.ix).unwrap();
618 self.ix += 2;
619 arg2 = get_i16(self.data, self.ix).unwrap();
620 self.ix += 2;
621 } else {
622 arg1 = self.data[self.ix] as i16;
623 self.ix += 1;
624 arg2 = self.data[self.ix] as i16;
625 self.ix += 1;
626 }
627 let mut a = 1.0;
628 let mut b = 0.0;
629 let mut c = 0.0;
630 let mut d = 1.0;
631 if (flags & WE_HAVE_A_TWO_BY_TWO) != 0 {
632 a = get_f2_14(self.data, self.ix).unwrap();
633 self.ix += 2;
634 b = get_f2_14(self.data, self.ix).unwrap();
635 self.ix += 2;
636 c = get_f2_14(self.data, self.ix).unwrap();
637 self.ix += 2;
638 d = get_f2_14(self.data, self.ix).unwrap();
639 self.ix += 2;
640 } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0 {
641 a = get_f2_14(self.data, self.ix).unwrap();
642 self.ix += 2;
643 d = get_f2_14(self.data, self.ix).unwrap();
644 self.ix += 2;
645 } else if (flags & WE_HAVE_A_SCALE) != 0 {
646 a = get_f2_14(self.data, self.ix).unwrap();
647 self.ix += 2;
648 d = a;
649 }
650 let x = arg1 as f32;
652 let y = arg2 as f32;
653 let z = Affine::new(a, b, c, d, x, y);
654 self.more = (flags & MORE_COMPONENTS) != 0;
655 Some((glyph_index, z))
656 }
657}
658
659impl<'a> CompoundGlyph<'a> {
660 fn bbox(&self) -> (i16, i16, i16, i16) {
661 get_bbox_raw(self.data)
662 }
663
664 fn components(&self) -> Components {
665 Components {
666 data: self.data,
667 ix: 10,
668 more: true,
669 }
670 }
671}
672
673pub struct Font<'a> {
674 _version: u32,
675 _tables: HashMap<Tag, &'a [u8]>,
676 head: Head<'a>,
677 maxp: Maxp<'a>,
678 cmap: Option<Cmap<'a>>,
679 loca: Option<Loca<'a>>,
680 glyf: Option<&'a [u8]>,
681 encoding_index: Option<u16>,
682}
683
684struct Metrics {
685 l: i32,
686 t: i32,
687 r: i32,
688 b: i32,
689}
690
691impl Metrics {
692 fn width(&self) -> usize {
693 (self.r - self.l) as usize
694 }
695
696 fn height(&self) -> usize {
697 (self.b - self.t) as usize
698 }
699}
700
701impl<'a> Font<'a> {
702 fn metrics_and_affine(
703 &self, xmin: i16, ymin: i16, xmax: i16, ymax: i16, size: u32,
704 ) -> (Metrics, Affine) {
705 let ppem = self.head.units_per_em();
706 let scale = (size as f32) / (ppem as f32);
707 let l = (xmin as f32 * scale).floor() as i32;
708 let t = (ymax as f32 * -scale).floor() as i32;
709 let r = (xmax as f32 * scale).ceil() as i32;
710 let b = (ymin as f32 * -scale).ceil() as i32;
711 let metrics = Metrics {
712 l: l,
713 t: t,
714 r: r,
715 b: b,
716 };
717 let z = Affine::new(scale, 0.0, 0.0, -scale, -l as f32, -t as f32);
718 (metrics, z)
719 }
720
721 fn render_glyph_inner(&self, raster: &mut Raster, z: &Affine, glyph: &Glyph) {
722 match *glyph {
723 Glyph::Simple(ref s) => {
724 let mut p = s.points();
725 for n in s.contour_sizes() {
726 draw_path(raster, z, &mut path_from_pts(p.by_ref().take(n)));
730 }
731 }
732 Glyph::Compound(ref c) => {
733 for (glyph_index, affine) in c.components() {
734 let concat = Affine::concat(z, &affine);
736 if let Some(component_glyph) = self.get_glyph(glyph_index) {
737 self.render_glyph_inner(raster, &concat, &component_glyph);
738 }
739 }
740 }
741 _ => {
742 println!("unhandled glyph case");
743 }
744 }
745 }
746
747 pub fn render_glyph(&self, glyph_id: u16, size: u32) -> Option<GlyphBitmap> {
748 let glyph = self.get_glyph(glyph_id);
749 match glyph {
750 Some(Glyph::Simple(ref s)) => {
751 let (xmin, ymin, xmax, ymax) = s.bbox();
752 let (metrics, z) = self.metrics_and_affine(xmin, ymin, xmax, ymax, size);
753 let mut raster = Raster::new(metrics.width(), metrics.height());
754 self.render_glyph_inner(&mut raster, &z, glyph.as_ref().unwrap());
756 Some(GlyphBitmap {
758 width: metrics.width(),
759 height: metrics.height(),
760 left: metrics.l,
761 top: metrics.t,
762 data: raster.get_bitmap(),
763 })
764 }
765 Some(Glyph::Compound(ref c)) => {
766 let (xmin, ymin, xmax, ymax) = c.bbox();
767 let (metrics, z) = self.metrics_and_affine(xmin, ymin, xmax, ymax, size);
768 let mut raster = Raster::new(metrics.width(), metrics.height());
769 self.render_glyph_inner(&mut raster, &z, glyph.as_ref().unwrap());
770 Some(GlyphBitmap {
771 width: metrics.width(),
772 height: metrics.height(),
773 left: metrics.l,
774 top: metrics.t,
775 data: raster.get_bitmap(),
776 })
777 }
778 _ => {
779 println!("glyph {} error", glyph_id);
780 None
781 }
782 }
783 }
784
785 fn get_glyph(&self, glyph_ix: u16) -> Option<Glyph> {
786 if glyph_ix >= self.maxp.num_glyphs() {
787 return None;
788 }
789 let fmt = self.head.index_to_loc_format();
790 match self.loca {
791 Some(ref loca) => match (
792 loca.get_off(glyph_ix, fmt),
793 loca.get_off(glyph_ix + 1, fmt),
794 self.glyf,
795 ) {
796 (Some(off0), Some(off1), Some(glyf)) => if off0 == off1 {
797 Some(Glyph::Empty)
798 } else {
799 let glyph_data = &glyf[off0 as usize..off1 as usize];
800 if get_i16(glyph_data, 0) == Some(-1) {
801 Some(Glyph::Compound(CompoundGlyph { data: glyph_data }))
802 } else {
803 Some(Glyph::Simple(SimpleGlyph { data: glyph_data }))
804 }
805 },
806 (_, _, _) => None,
807 },
808 None => None,
809 }
810 }
811
812 pub fn lookup_glyph_id(&self, code_point: u32) -> Option<u16> {
813 match self.encoding_index {
814 Some(encoding_index) => {
815 if code_point > u16::max_value() as u32 {
816 return None;
817 }
818
819 self.cmap
820 .as_ref()
821 .unwrap()
822 .get_encoding_format_4_at(encoding_index)
823 .unwrap()
824 .lookup_glyph_id(code_point as u16)
825 }
826 None => None,
827 }
828 }
829}
830
831#[derive(Debug)]
832enum PathOp {
833 MoveTo(Point),
834 LineTo(Point),
835 QuadTo(Point, Point),
836}
837
838use self::PathOp::{LineTo, MoveTo, QuadTo};
839
840struct BezPathOps<T> {
841 inner: T,
842 first_oncurve: Option<Point>,
843 first_offcurve: Option<Point>,
844 last_offcurve: Option<Point>,
845 alldone: bool,
846 closing: bool,
847}
848
849fn path_from_pts<T: Iterator>(inner: T) -> BezPathOps<T> {
850 BezPathOps {
851 inner: inner,
852 first_oncurve: None,
853 first_offcurve: None,
854 last_offcurve: None,
855 alldone: false,
856 closing: false,
857 }
858}
859
860impl<I> Iterator for BezPathOps<I>
861where
862 I: Iterator<Item = (bool, i16, i16)>,
863{
864 type Item = PathOp;
865 fn next(&mut self) -> Option<PathOp> {
866 loop {
867 if self.closing {
868 if self.alldone {
869 return None;
870 } else {
871 match (self.first_offcurve, self.last_offcurve) {
872 (None, None) => {
873 self.alldone = true;
874 return Some(LineTo(self.first_oncurve.unwrap()));
875 }
876 (None, Some(last_offcurve)) => {
877 self.alldone = true;
878 return Some(QuadTo(last_offcurve, self.first_oncurve.unwrap()));
879 }
880 (Some(first_offcurve), None) => {
881 self.alldone = true;
882 return Some(QuadTo(first_offcurve, self.first_oncurve.unwrap()));
883 }
884 (Some(first_offcurve), Some(last_offcurve)) => {
885 self.last_offcurve = None;
886 return Some(QuadTo(
887 last_offcurve,
888 Point::lerp(0.5, &last_offcurve, &first_offcurve),
889 ));
890 }
891 }
892 }
893 } else {
894 match self.inner.next() {
895 None => {
896 self.closing = true;
897 }
898 Some((oncurve, x, y)) => {
899 let p = Point::new(x, y);
900 if self.first_oncurve.is_none() {
901 if oncurve {
902 self.first_oncurve = Some(p);
903 return Some(MoveTo(p));
904 } else {
905 match self.first_offcurve {
906 None => self.first_offcurve = Some(p),
907 Some(first_offcurve) => {
908 let midp = Point::lerp(0.5, &first_offcurve, &p);
909 self.first_oncurve = Some(midp);
910 self.last_offcurve = Some(p);
911 return Some(MoveTo(midp));
912 }
913 }
914 }
915 } else {
916 match (self.last_offcurve, oncurve) {
917 (None, false) => self.last_offcurve = Some(p),
918 (None, true) => return Some(LineTo(p)),
919 (Some(last_offcurve), false) => {
920 self.last_offcurve = Some(p);
921 return Some(QuadTo(
922 last_offcurve,
923 Point::lerp(0.5, &last_offcurve, &p),
924 ));
925 }
926 (Some(last_offcurve), true) => {
927 self.last_offcurve = None;
928 return Some(QuadTo(last_offcurve, p));
929 }
930 }
931 }
932 }
933 }
934 }
935 }
936 }
937}
938
939#[derive(Debug)]
940pub enum FontError {
941 Invalid,
942}
943
944pub fn parse(data: &[u8]) -> Result<Font, FontError> {
945 if data.len() < 12 {
946 return Err(FontError::Invalid);
947 }
948 let version = get_u32(data, 0).unwrap();
949 let num_tables = get_u16(data, 4).unwrap() as usize;
950 let _search_range = get_u16(data, 6).unwrap();
951 let _entry_selector = get_u16(data, 8).unwrap();
952 let _range_shift = get_u16(data, 10).unwrap();
953 let mut tables = HashMap::new();
954 for i in 0..num_tables {
955 let header = &data[12 + i * 16..12 + (i + 1) * 16];
956 let tag = get_u32(header, 0).unwrap();
957 let _check_sum = get_u32(header, 4).unwrap();
958 let offset = get_u32(header, 8).unwrap();
959 let length = get_u32(header, 12).unwrap();
960 let table_data = &data[offset as usize..(offset + length) as usize];
961 tables.insert(Tag(tag), table_data);
963 }
964 let head = Head(*tables.get(&Tag::from_str("head")).unwrap()); let maxp = Maxp {
966 data: *tables.get(&Tag::from_str("maxp")).unwrap(),
967 };
968 let loca = tables.get(&Tag::from_str("loca")).map(|&data| Loca(data));
969 let glyf = tables.get(&Tag::from_str("glyf")).map(|&data| data);
970 let cmap = tables.get(&Tag::from_str("cmap")).map(|&data| Cmap(data));
971 let encoding_index = cmap.as_ref().and_then(|cmap| cmap.find_format_4_encoding());
972 let f = Font {
973 _version: version,
974 _tables: tables,
975 head: head,
976 maxp: maxp,
977 loca: loca,
978 cmap: cmap,
979 glyf: glyf,
980 encoding_index: encoding_index,
981 };
982 Ok(f)
984}
985
986fn draw_path<I: Iterator<Item = PathOp>>(r: &mut Raster, z: &Affine, path: &mut I) {
1031 let mut lastp = Point::new(0i16, 0i16);
1032 for op in path {
1033 match op {
1034 MoveTo(p) => lastp = p,
1035 LineTo(p) => {
1036 r.draw_line(&affine_pt(z, &lastp), &affine_pt(z, &p));
1037 lastp = p
1038 }
1039 QuadTo(p1, p2) => {
1040 r.draw_quad(
1041 &affine_pt(z, &lastp),
1042 &affine_pt(z, &p1),
1043 &affine_pt(z, &p2),
1044 );
1045 lastp = p2;
1046 }
1047 }
1048 }
1049}
1050
1051pub struct GlyphBitmap {
1052 pub width: usize,
1053 pub height: usize,
1054 pub left: i32,
1055 pub top: i32,
1056 pub data: Vec<u8>,
1057}
1058
1059#[cfg(test)]
1060mod tests {
1061
1062 use font::parse;
1063
1064 static FONT_DATA: &'static [u8] =
1065 include_bytes!("../fonts/notomono-hinted/NotoMono-Regular.ttf");
1066
1067 #[test]
1068 fn test_cmap_format_4() {
1069 let font = parse(&FONT_DATA).unwrap();
1070 let cmap = font.cmap.as_ref().unwrap();
1071 assert!(cmap.get_encoding_record(cmap.get_num_tables()).is_none());
1072 assert!(cmap.get_encoding(cmap.get_num_tables()).is_none());
1073 assert_eq!(font.lookup_glyph_id('A' as u32).unwrap(), 36);
1074 assert_eq!(font.lookup_glyph_id(0x3c8).unwrap(), 405);
1075 assert_eq!(font.lookup_glyph_id(0xfffd).unwrap(), 589);
1076 assert_eq!(font.lookup_glyph_id(0x232B).is_none(), true);
1077 assert_eq!(font.lookup_glyph_id(0x1000232B).is_none(), true);
1078 for i in 0..0x1ffff {
1080 font.lookup_glyph_id(i);
1081 }
1082 }
1083}