OLD | NEW |
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 | 627 |
628 Table* FindTable(std::vector<Table*>* tables, uint32_t tag) { | 628 Table* FindTable(std::vector<Table*>* tables, uint32_t tag) { |
629 for (Table* table : *tables) { | 629 for (Table* table : *tables) { |
630 if (table->tag == tag) { | 630 if (table->tag == tag) { |
631 return table; | 631 return table; |
632 } | 632 } |
633 } | 633 } |
634 return NULL; | 634 return NULL; |
635 } | 635 } |
636 | 636 |
637 // This is linear search, but could be changed to binary because we | |
638 // do have a guarantee that the tables are sorted by tag. But the total | |
639 // cpu time is expected to be very small in any case. | |
640 const Table* FindTable(const std::vector<Table>& tables, uint32_t tag) { | |
641 size_t n_tables = tables.size(); | |
642 for (size_t i = 0; i < n_tables; ++i) { | |
643 if (tables[i].tag == tag) { | |
644 return &tables[i]; | |
645 } | |
646 } | |
647 return NULL; | |
648 } | |
649 | |
650 // https://www.microsoft.com/typography/otspec/maxp.htm | |
651 bool ReadNumGlyphs(const Table* maxp_table, | |
652 const uint8_t* dst, size_t dst_length, | |
653 uint16_t* num_glyphs) { | |
654 if (PREDICT_FALSE(static_cast<uint64_t>(maxp_table->dst_offset + | |
655 maxp_table->dst_length) > dst_length)) { | |
656 return FONT_COMPRESSION_FAILURE(); | |
657 } | |
658 Buffer buffer(dst + maxp_table->dst_offset, maxp_table->dst_length); | |
659 // Skip 4 to reach 'maxp' numGlyphs | |
660 if (PREDICT_FALSE(!buffer.Skip(4) || !buffer.ReadU16(num_glyphs))) { | |
661 return FONT_COMPRESSION_FAILURE(); | |
662 } | |
663 return true; | |
664 } | |
665 | |
666 // Get numberOfHMetrics, https://www.microsoft.com/typography/otspec/hhea.htm | 637 // Get numberOfHMetrics, https://www.microsoft.com/typography/otspec/hhea.htm |
667 bool ReadNumHMetrics(const uint8_t* data, size_t data_size, | 638 bool ReadNumHMetrics(const uint8_t* data, size_t data_size, |
668 uint16_t* num_hmetrics) { | 639 uint16_t* num_hmetrics) { |
669 // Skip 34 to reach 'hhea' numberOfHMetrics | 640 // Skip 34 to reach 'hhea' numberOfHMetrics |
670 Buffer buffer(data, data_size); | 641 Buffer buffer(data, data_size); |
671 if (PREDICT_FALSE(!buffer.Skip(34) || !buffer.ReadU16(num_hmetrics))) { | 642 if (PREDICT_FALSE(!buffer.Skip(34) || !buffer.ReadU16(num_hmetrics))) { |
672 return FONT_COMPRESSION_FAILURE(); | 643 return FONT_COMPRESSION_FAILURE(); |
673 } | 644 } |
674 return true; | 645 return true; |
675 } | 646 } |
676 | 647 |
677 // x_min for glyph; https://www.microsoft.com/typography/otspec/glyf.htm | |
678 bool ReadGlyphXMin(Buffer* glyf_buff, Buffer* loca_buff, int16_t loca_format, | |
679 uint16_t index, int16_t* x_min) { | |
680 uint32_t offset1, offset2; | |
681 loca_buff->set_offset((loca_format == 0 ? 2 : 4) * index); | |
682 if (loca_format == 0) { | |
683 uint16_t tmp1, tmp2; | |
684 if (PREDICT_FALSE(!loca_buff->ReadU16(&tmp1) || | |
685 !loca_buff->ReadU16(&tmp2))) { | |
686 return FONT_COMPRESSION_FAILURE(); | |
687 } | |
688 // https://www.microsoft.com/typography/otspec/loca.htm | |
689 // "The actual local offset divided by 2 is stored." | |
690 offset1 = tmp1 * 2; | |
691 offset2 = tmp2 * 2; | |
692 } else if (PREDICT_FALSE(!loca_buff->ReadU32(&offset1) || | |
693 !loca_buff->ReadU32(&offset2))) { | |
694 return FONT_COMPRESSION_FAILURE(); | |
695 } | |
696 | |
697 if (offset1 != offset2) { | |
698 glyf_buff->set_offset(offset1 + 2); | |
699 if (!glyf_buff->ReadS16(x_min)) { | |
700 return FONT_COMPRESSION_FAILURE(); | |
701 } | |
702 } else { | |
703 *x_min = 0; | |
704 } | |
705 return true; | |
706 } | |
707 | |
708 // http://dev.w3.org/webfonts/WOFF2/spec/Overview.html#hmtx_table_format | 648 // http://dev.w3.org/webfonts/WOFF2/spec/Overview.html#hmtx_table_format |
709 bool ReconstructTransformedHmtx(const uint8_t* transformed_buf, | 649 bool ReconstructTransformedHmtx(const uint8_t* transformed_buf, |
710 size_t transformed_size, | 650 size_t transformed_size, |
711 uint16_t num_glyphs, | 651 uint16_t num_glyphs, |
712 uint16_t num_hmetrics, | 652 uint16_t num_hmetrics, |
713 const std::vector<int16_t>& x_mins, | 653 const std::vector<int16_t>& x_mins, |
714 uint32_t* checksum, | 654 uint32_t* checksum, |
715 WOFF2Out* out) { | 655 WOFF2Out* out) { |
716 Buffer hmtx_buff_in(transformed_buf, transformed_size); | 656 Buffer hmtx_buff_in(transformed_buf, transformed_size); |
717 | 657 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 } | 717 } |
778 | 718 |
779 *checksum = ComputeULongSum(&hmtx_table[0], hmtx_output_size); | 719 *checksum = ComputeULongSum(&hmtx_table[0], hmtx_output_size); |
780 if (PREDICT_FALSE(!out->Write(&hmtx_table[0], hmtx_output_size))) { | 720 if (PREDICT_FALSE(!out->Write(&hmtx_table[0], hmtx_output_size))) { |
781 return FONT_COMPRESSION_FAILURE(); | 721 return FONT_COMPRESSION_FAILURE(); |
782 } | 722 } |
783 | 723 |
784 return true; | 724 return true; |
785 } | 725 } |
786 | 726 |
787 uint32_t ComputeChecksum(const Table* table, const uint8_t* dst) { | |
788 return ComputeULongSum(dst + table->dst_offset, table->dst_length); | |
789 } | |
790 | |
791 const Table* FindTable(TtcFont ttc_font, const std::vector<Table>& tables, | |
792 uint32_t tag) { | |
793 for (const auto i : ttc_font.table_indices) { | |
794 if (tables[i].tag == tag) return &tables[i]; | |
795 } | |
796 return NULL; | |
797 } | |
798 | |
799 bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size, | 727 bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size, |
800 const uint8_t* src_buf, size_t src_size) { | 728 const uint8_t* src_buf, size_t src_size) { |
801 size_t uncompressed_size = dst_size; | 729 size_t uncompressed_size = dst_size; |
802 int ok = BrotliDecompressBuffer(src_size, src_buf, | 730 int ok = BrotliDecompressBuffer(src_size, src_buf, |
803 &uncompressed_size, dst_buf); | 731 &uncompressed_size, dst_buf); |
804 if (PREDICT_FALSE(!ok || uncompressed_size != dst_size)) { | 732 if (PREDICT_FALSE(!ok || uncompressed_size != dst_size)) { |
805 return FONT_COMPRESSION_FAILURE(); | 733 return FONT_COMPRESSION_FAILURE(); |
806 } | 734 } |
807 return true; | 735 return true; |
808 } | 736 } |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 hdr.uncompressed_size, | 1283 hdr.uncompressed_size, |
1356 &metadata, &hdr, i, out))) { | 1284 &metadata, &hdr, i, out))) { |
1357 return FONT_COMPRESSION_FAILURE(); | 1285 return FONT_COMPRESSION_FAILURE(); |
1358 } | 1286 } |
1359 } | 1287 } |
1360 | 1288 |
1361 return true; | 1289 return true; |
1362 } | 1290 } |
1363 | 1291 |
1364 } // namespace woff2 | 1292 } // namespace woff2 |
OLD | NEW |