OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <ctype.h> | 8 #include <ctype.h> |
9 | 9 |
10 #include "SkData.h" | 10 #include "SkData.h" |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 uint16_t lastGlyphID) { | 577 uint16_t lastGlyphID) { |
578 SkDynamicMemoryWStream cmap; | 578 SkDynamicMemoryWStream cmap; |
579 if (multiByteGlyphs) { | 579 if (multiByteGlyphs) { |
580 append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); | 580 append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); |
581 } else { | 581 } else { |
582 append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1); | 582 append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1); |
583 } | 583 } |
584 append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs, | 584 append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs, |
585 firstGlyphID, lastGlyphID); | 585 firstGlyphID, lastGlyphID); |
586 append_cmap_footer(&cmap); | 586 append_cmap_footer(&cmap); |
587 sk_sp<SkData> cmapData(cmap.copyToData()); | 587 return sk_make_sp<SkPDFStream>( |
588 return sk_make_sp<SkPDFStream>(cmapData.get()); | 588 std::unique_ptr<SkStreamAsset>(cmap.detachAsStream())); |
589 } | 589 } |
590 | 590 |
591 #if defined (SK_SFNTLY_SUBSETTER) | |
592 static void sk_delete_array(const void* ptr, void*) { | |
593 // Use C-style cast to cast away const and cast type simultaneously. | |
594 delete[] (unsigned char*)ptr; | |
595 } | |
596 #endif | |
597 | |
598 #if defined(SK_SFNTLY_SUBSETTER) | |
599 static size_t get_subset_font_stream(const char* fontName, | |
600 const SkTypeface* typeface, | |
601 const SkTDArray<uint32_t>& subset, | |
602 SkPDFStream** fontStream) { | |
603 int ttcIndex; | |
604 std::unique_ptr<SkStreamAsset> fontData(typeface->openStream(&ttcIndex)); | |
605 SkASSERT(fontData); | |
606 if (!fontData) { | |
607 return 0; | |
608 } | |
609 | |
610 size_t fontSize = fontData->getLength(); | |
611 | |
612 // Read font into buffer. | |
613 SkPDFStream* subsetFontStream = nullptr; | |
614 SkTDArray<unsigned char> originalFont; | |
615 originalFont.setCount(SkToInt(fontSize)); | |
616 if (fontData->read(originalFont.begin(), fontSize) == fontSize) { | |
617 unsigned char* subsetFont = nullptr; | |
618 // sfntly requires unsigned int* to be passed in, as far as we know, | |
619 // unsigned int is equivalent to uint32_t on all platforms. | |
620 static_assert(sizeof(unsigned int) == sizeof(uint32_t), "unsigned_int_no t_32_bits"); | |
621 int subsetFontSize = SfntlyWrapper::SubsetFont(fontName, | |
622 originalFont.begin(), | |
623 fontSize, | |
624 subset.begin(), | |
625 subset.count(), | |
626 &subsetFont); | |
627 if (subsetFontSize > 0 && subsetFont != nullptr) { | |
628 SkAutoDataUnref data(SkData::NewWithProc(subsetFont, | |
629 subsetFontSize, | |
630 sk_delete_array, | |
631 nullptr)); | |
632 subsetFontStream = new SkPDFStream(data.get()); | |
633 fontSize = subsetFontSize; | |
634 } | |
635 } | |
636 if (subsetFontStream) { | |
637 *fontStream = subsetFontStream; | |
638 return fontSize; | |
639 } | |
640 fontData->rewind(); | |
641 | |
642 // Fail over: just embed the whole font. | |
643 *fontStream = new SkPDFStream(std::move(fontData)); | |
644 return fontSize; | |
645 } | |
646 #endif | |
647 | |
648 /////////////////////////////////////////////////////////////////////////////// | 591 /////////////////////////////////////////////////////////////////////////////// |
649 // class SkPDFGlyphSet | 592 // class SkPDFGlyphSet |
650 /////////////////////////////////////////////////////////////////////////////// | 593 /////////////////////////////////////////////////////////////////////////////// |
651 | 594 |
652 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { | 595 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { |
653 } | 596 } |
654 | 597 |
655 void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) { | 598 void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) { |
656 for (int i = 0; i < numGlyphs; ++i) { | 599 for (int i = 0; i < numGlyphs; ++i) { |
657 fBitSet.setBit(glyphIDs[i], true); | 600 fBitSet.setBit(glyphIDs[i], true); |
658 } | 601 } |
659 } | 602 } |
660 | 603 |
661 bool SkPDFGlyphSet::has(uint16_t glyphID) const { | 604 bool SkPDFGlyphSet::has(uint16_t glyphID) const { |
662 return fBitSet.isBitSet(glyphID); | 605 return fBitSet.isBitSet(glyphID); |
663 } | 606 } |
664 | 607 |
665 void SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const { | 608 void SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const { |
666 fBitSet.exportTo(glyphIDs); | 609 fBitSet.exportTo(glyphIDs); |
667 } | 610 } |
668 | 611 |
669 /////////////////////////////////////////////////////////////////////////////// | 612 /////////////////////////////////////////////////////////////////////////////// |
670 // class SkPDFGlyphSetMap | 613 // class SkPDFGlyphSetMap |
671 /////////////////////////////////////////////////////////////////////////////// | 614 /////////////////////////////////////////////////////////////////////////////// |
672 | 615 |
673 SkPDFGlyphSetMap::SkPDFGlyphSetMap() {} | 616 SkPDFGlyphSetMap::SkPDFGlyphSetMap() {} |
674 | 617 |
675 SkPDFGlyphSetMap::~SkPDFGlyphSetMap() { | 618 SkPDFGlyphSetMap::~SkPDFGlyphSetMap() { |
676 fMap.reset(); | 619 fMap.reset(); |
677 } | 620 } |
678 | 621 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1008 | 951 |
1009 SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, | 952 SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, |
1010 SkTypeface* typeface, | 953 SkTypeface* typeface, |
1011 const SkPDFGlyphSet* subset) | 954 const SkPDFGlyphSet* subset) |
1012 : SkPDFFont(info, typeface, nullptr) { | 955 : SkPDFFont(info, typeface, nullptr) { |
1013 this->populate(subset); | 956 this->populate(subset); |
1014 } | 957 } |
1015 | 958 |
1016 SkPDFCIDFont::~SkPDFCIDFont() {} | 959 SkPDFCIDFont::~SkPDFCIDFont() {} |
1017 | 960 |
961 #ifdef SK_SFNTLY_SUBSETTER | |
962 // if possible, make no copy. | |
963 static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) { | |
964 SkASSERT(stream); | |
965 (void)stream->rewind(); | |
966 SkASSERT(stream->hasLength()); | |
967 size_t size = stream->getLength(); | |
968 if (const void* base = stream->getMemoryBase()) { | |
969 SkData::ReleaseProc proc = | |
970 [](const void*, void* ctx) { delete (SkStream*)ctx; }; | |
971 return SkData::MakeWithProc(base, size, proc, stream.release()); | |
972 } | |
973 return SkData::MakeFromStream(stream.get(), size); | |
974 } | |
975 | |
976 static sk_sp<SkPDFObject> get_subset_font_stream( | |
977 std::unique_ptr<SkStreamAsset> fontAsset, | |
978 const SkTDArray<uint32_t>& subset, | |
979 const char* fontName) { | |
980 sk_sp<SkData> fontData(stream_to_data(std::move(fontAsset))); | |
981 unsigned char* subsetFont = nullptr; | |
982 // sfntly requires unsigned int* to be passed in, | |
983 // as far as we know, unsigned int is equivalent | |
984 // to uint32_t on all platforms. | |
985 static_assert(sizeof(unsigned) == sizeof(uint32_t), ""); | |
986 // TODO(halcanary): Use ttcIndex, not fontName. | |
987 int subsetFontSize = | |
988 SfntlyWrapper::SubsetFont(fontName, | |
989 fontData->bytes(), | |
990 fontData->size(), | |
991 subset.begin(), | |
992 subset.count(), | |
993 &subsetFont); | |
994 fontData = nullptr; // Release memory if necessary. | |
bungeman-skia
2016/07/27 20:15:59
Instead of doing this, can this be like
unsigned
hal.canary
2016/07/27 20:23:04
Done.
| |
995 SkASSERT(subsetFontSize > 0 || subsetFont == nullptr); | |
996 if (subsetFontSize > 0) { | |
bungeman-skia
2016/07/27 20:15:59
Can we reverse this so that less code goes into th
hal.canary
2016/07/27 20:23:04
Done.
| |
997 SkASSERT(subsetFont != nullptr); | |
998 auto subset = sk_make_sp<SkPDFStream>( | |
999 SkData::MakeWithProc( | |
1000 subsetFont, subsetFontSize, | |
1001 [](const void* p, void*) { | |
1002 delete[] (unsigned char*)p; | |
1003 }, nullptr)); | |
1004 subset->insertInt("Length1", subsetFontSize); | |
1005 return subset; | |
1006 } | |
1007 return nullptr; | |
1008 } | |
1009 #endif // SK_SFNTLY_SUBSETTER | |
1010 | |
1018 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, | 1011 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, |
1019 const SkTDArray<uint32_t>* subset) { | 1012 const SkTDArray<uint32_t>* subset) { |
1020 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 1013 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); |
1021 setFontDescriptor(descriptor.get()); | 1014 setFontDescriptor(descriptor.get()); |
1022 if (!addCommonFontDescriptorEntries(defaultWidth)) { | 1015 if (!addCommonFontDescriptorEntries(defaultWidth)) { |
1023 this->insertObjRef("FontDescriptor", std::move(descriptor)); | 1016 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
1024 return false; | 1017 return false; |
1025 } | 1018 } |
1026 SkASSERT(this->canEmbed()); | 1019 SkASSERT(this->canEmbed()); |
1027 | 1020 |
1028 switch (getType()) { | 1021 switch (getType()) { |
1029 case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 1022 case SkAdvancedTypefaceMetrics::kTrueType_Font: { |
1030 size_t fontSize = 0; | 1023 int ttcIndex; |
1031 #if defined(SK_SFNTLY_SUBSETTER) | 1024 std::unique_ptr<SkStreamAsset> fontAsset( |
1032 if (this->canSubset()) { | 1025 this->typeface()->openStream(&ttcIndex)); |
1033 sk_sp<SkPDFStream> fontStream; | 1026 SkASSERT(fontAsset); |
1034 SkPDFStream* rawStream = nullptr; | 1027 if (!fontAsset) { |
1035 fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), | 1028 return false; |
1036 typeface(), | 1029 } |
1037 *subset, | 1030 size_t fontSize = fontAsset->getLength(); |
1038 &rawStream); | 1031 SkASSERT(fontSize > 0); |
1039 if (0 == fontSize) { | 1032 if (fontSize == 0) { |
1040 return false; | 1033 return false; |
1041 } | 1034 } |
1042 if (rawStream) { | 1035 |
1043 fontStream.reset(rawStream); | 1036 #ifdef SK_SFNTLY_SUBSETTER |
1044 fontStream->insertInt("Length1", fontSize); | 1037 if (this->canSubset() && subset) { |
1045 descriptor->insertObjRef("FontFile2", std::move(fontStream)) ; | 1038 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( |
1039 std::move(fontAsset), *subset, fontInfo()->fFontName.c_s tr()); | |
1040 if (subsetStream) { | |
1041 descriptor->insertObjRef("FontFile2", std::move(subsetStream )); | |
1046 break; | 1042 break; |
1047 } | 1043 } |
1044 // If subsetting fails, fall back to original font data. | |
1045 fontAsset.reset(this->typeface()->openStream(&ttcIndex)); | |
1048 } | 1046 } |
1049 #endif | 1047 #endif // SK_SFNTLY_SUBSETTER |
1050 sk_sp<SkPDFSharedStream> fontStream; | 1048 auto fontStream = sk_make_sp<SkPDFSharedStream>(fontAsset.release()) ; |
1051 std::unique_ptr<SkStreamAsset> fontData( | |
1052 this->typeface()->openStream(nullptr)); | |
1053 SkASSERT(fontData); | |
1054 if (!fontData || 0 == fontData->getLength()) { | |
1055 return false; | |
1056 } | |
1057 fontSize = fontData->getLength(); | |
1058 SkASSERT(fontSize > 0); | |
1059 fontStream.reset(new SkPDFSharedStream(fontData.release())); | |
1060 fontStream->dict()->insertInt("Length1", fontSize); | 1049 fontStream->dict()->insertInt("Length1", fontSize); |
1061 descriptor->insertObjRef("FontFile2", std::move(fontStream)); | 1050 descriptor->insertObjRef("FontFile2", std::move(fontStream)); |
1062 break; | 1051 break; |
1063 } | 1052 } |
1064 case SkAdvancedTypefaceMetrics::kCFF_Font: | 1053 case SkAdvancedTypefaceMetrics::kCFF_Font: |
1065 case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 1054 case SkAdvancedTypefaceMetrics::kType1CID_Font: { |
1066 std::unique_ptr<SkStreamAsset> fontData( | 1055 std::unique_ptr<SkStreamAsset> fontData( |
1067 this->typeface()->openStream(nullptr)); | 1056 this->typeface()->openStream(nullptr)); |
1068 SkASSERT(fontData); | 1057 SkASSERT(fontData); |
1069 SkASSERT(fontData->getLength() > 0); | 1058 SkASSERT(fontData->getLength() > 0); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1200 SkASSERT(rawFontData->getLength() > 0); | 1189 SkASSERT(rawFontData->getLength() > 0); |
1201 if (!rawFontData || 0 == rawFontData->getLength()) { | 1190 if (!rawFontData || 0 == rawFontData->getLength()) { |
1202 return false; | 1191 return false; |
1203 } | 1192 } |
1204 sk_sp<SkData> fontData(handle_type1_stream(rawFontData.get(), &header, | 1193 sk_sp<SkData> fontData(handle_type1_stream(rawFontData.get(), &header, |
1205 &data, &trailer)); | 1194 &data, &trailer)); |
1206 if (fontData.get() == nullptr) { | 1195 if (fontData.get() == nullptr) { |
1207 return false; | 1196 return false; |
1208 } | 1197 } |
1209 SkASSERT(this->canEmbed()); | 1198 SkASSERT(this->canEmbed()); |
1210 auto fontStream = sk_make_sp<SkPDFStream>(fontData.get()); | 1199 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData)); |
1211 fontStream->insertInt("Length1", header); | 1200 fontStream->insertInt("Length1", header); |
1212 fontStream->insertInt("Length2", data); | 1201 fontStream->insertInt("Length2", data); |
1213 fontStream->insertInt("Length3", trailer); | 1202 fontStream->insertInt("Length3", trailer); |
1214 descriptor->insertObjRef("FontFile", std::move(fontStream)); | 1203 descriptor->insertObjRef("FontFile", std::move(fontStream)); |
1215 | 1204 |
1216 this->insertObjRef("FontDescriptor", std::move(descriptor)); | 1205 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
1217 | 1206 |
1218 return addCommonFontDescriptorEntries(defaultWidth); | 1207 return addCommonFontDescriptorEntries(defaultWidth); |
1219 } | 1208 } |
1220 | 1209 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1415 } | 1404 } |
1416 return *canon->fCanEmbedTypeface.set(id, canEmbed); | 1405 return *canon->fCanEmbedTypeface.set(id, canEmbed); |
1417 } | 1406 } |
1418 | 1407 |
1419 void SkPDFFont::drop() { | 1408 void SkPDFFont::drop() { |
1420 fTypeface = nullptr; | 1409 fTypeface = nullptr; |
1421 fFontInfo = nullptr; | 1410 fFontInfo = nullptr; |
1422 fDescriptor = nullptr; | 1411 fDescriptor = nullptr; |
1423 this->SkPDFDict::drop(); | 1412 this->SkPDFDict::drop(); |
1424 } | 1413 } |
OLD | NEW |