font_rs/
font.rs

1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! A simple renderer for TrueType fonts
16
17use 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
76// TODO: be consistent, use newtype or one-field struct everywhere
77struct 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(); // insn_len
440        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            //println!("flag={:02x}, flags_ix={}, x_ix={}, ({}) y_ix={} ({})",
517            // flag, self.flags_ix, self.x_ix, self.data.get(self.x_ix), self.y_ix,
518            // self.data.get(self.y_ix));
519            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        // TODO: handle non-ARGS_ARE_XY_VALUES case
651        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                    //println!("n = {}", n);
727                    //let v = path_from_pts(p.by_ref().take(n)).collect::<Vec<_>>();
728                    //println!("size = {}", v.len());
729                    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                    //println!("component {} {:?}", glyph_index, affine);
735                    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                //dump_glyph(SimpleGlyph(s));
755                self.render_glyph_inner(&mut raster, &z, glyph.as_ref().unwrap());
756                //None
757                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        //println!("{}: {}", Tag(tag), table_data.len());
962        tables.insert(Tag(tag), table_data);
963    }
964    let head = Head(*tables.get(&Tag::from_str("head")).unwrap()); // todo: don't fail
965    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    //println!("version = {:x}", version);
983    Ok(f)
984}
985
986/*
987fn dump_glyph(g: Glyph) {
988    match g {
989        Glyph::Empty => println!("empty"),
990        Glyph::Simple(s) => {
991            //println!("{} contours", s.number_of_contours())
992            let mut p = s.points();
993            for n in s.contour_sizes() {
994                for _ in 0..n {
995                    println!("{:?}", p.next().unwrap());
996                }
997                println!("z");
998            }
999            let mut p = s.points();
1000            for n in s.contour_sizes() {
1001                for pathop in path_from_pts(p.by_ref().take(n)) {
1002                    println!("{:?}", pathop);
1003                }
1004            }
1005        },
1006        _ => println!("other")
1007    }
1008}
1009*/
1010
1011/*
1012fn dump(data: Vec<u8>) {
1013    println!("length is {}", data.len());
1014    match parse(&data) {
1015        Ok(font) => {
1016            println!("numGlyphs = {}", font.maxp.num_glyphs());
1017            for i in 0.. font.maxp.num_glyphs() {
1018                println!("glyph {}", i);
1019                match font.get_glyph(i) {
1020                    Some(g) => dump_glyph(g),
1021                    None => println!("glyph {} error", i)
1022                }
1023            }
1024        },
1025        _ => ()
1026    }
1027}
1028*/
1029
1030fn 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        // test for panics
1079        for i in 0..0x1ffff {
1080            font.lookup_glyph_id(i);
1081        }
1082    }
1083}