Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(519)

Side by Side Diff: src/pdf/SkPDFFont.cpp

Issue 842253003: SkPDFCanon (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: did you mean struct here? Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFGraphicState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkGlyphCache.h" 11 #include "SkGlyphCache.h"
12 #include "SkPaint.h" 12 #include "SkPaint.h"
13 #include "SkPDFCatalog.h" 13 #include "SkPDFCatalog.h"
14 #include "SkPDFCanon.h"
14 #include "SkPDFDevice.h" 15 #include "SkPDFDevice.h"
15 #include "SkPDFFont.h" 16 #include "SkPDFFont.h"
16 #include "SkPDFFontImpl.h" 17 #include "SkPDFFontImpl.h"
17 #include "SkPDFStream.h" 18 #include "SkPDFStream.h"
18 #include "SkPDFTypes.h" 19 #include "SkPDFTypes.h"
19 #include "SkPDFUtils.h" 20 #include "SkPDFUtils.h"
20 #include "SkRefCnt.h" 21 #include "SkRefCnt.h"
21 #include "SkScalar.h" 22 #include "SkScalar.h"
22 #include "SkStream.h" 23 #include "SkStream.h"
23 #include "SkTypefacePriv.h" 24 #include "SkTypefacePriv.h"
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 * Resources are canonicalized and uniqueified by pointer so there has to be 735 * Resources are canonicalized and uniqueified by pointer so there has to be
735 * some additional state indicating which subset of the font is used. It 736 * some additional state indicating which subset of the font is used. It
736 * must be maintained at the page granularity and then combined at the document 737 * must be maintained at the page granularity and then combined at the document
737 * granularity. a) change SkPDFFont to fill in its state on demand, kind of 738 * granularity. a) change SkPDFFont to fill in its state on demand, kind of
738 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each 739 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each
739 * page/pdf device. c) in the document, retrieve the per font glyph usage 740 * page/pdf device. c) in the document, retrieve the per font glyph usage
740 * from each page and combine it and ask for a resource with that subset. 741 * from each page and combine it and ask for a resource with that subset.
741 */ 742 */
742 743
743 SkPDFFont::~SkPDFFont() { 744 SkPDFFont::~SkPDFFont() {
744 SkAutoMutexAcquire lock(CanonicalFontsMutex()); 745 {
745 int index = -1; 746 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex());
746 for (int i = 0 ; i < CanonicalFonts().count() ; i++) { 747 SkPDFCanon::GetCanon().removeFont(this);
747 if (CanonicalFonts()[i].fFont == this) {
748 index = i;
749 }
750 }
751
752 SkDEBUGCODE(int indexFound;)
753 SkASSERT(index == -1 ||
754 (Find(fTypeface->uniqueID(),
755 fFirstGlyphID,
756 &indexFound) &&
757 index == indexFound));
758 if (index >= 0) {
759 CanonicalFonts().removeShuffle(index);
760 } 748 }
761 fResources.unrefAll(); 749 fResources.unrefAll();
762 } 750 }
763 751
764 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 752 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
765 SkTSet<SkPDFObject*>* newResourceObjects) { 753 SkTSet<SkPDFObject*>* newResourceObjects) {
766 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); 754 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects);
767 } 755 }
768 756
769 SkTypeface* SkPDFFont::typeface() { 757 SkTypeface* SkPDFFont::typeface() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 return i; 798 return i;
811 } 799 }
812 glyphIDs[i] -= (fFirstGlyphID - 1); 800 glyphIDs[i] -= (fFirstGlyphID - 1);
813 } 801 }
814 802
815 return numGlyphs; 803 return numGlyphs;
816 } 804 }
817 805
818 // static 806 // static
819 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { 807 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
820 SkAutoMutexAcquire lock(CanonicalFontsMutex());
821
822 SkAutoResolveDefaultTypeface autoResolve(typeface); 808 SkAutoResolveDefaultTypeface autoResolve(typeface);
823 typeface = autoResolve.get(); 809 typeface = autoResolve.get();
810 const uint32_t fontID = typeface->uniqueID();
824 811
825 const uint32_t fontID = typeface->uniqueID(); 812 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex());
826 int relatedFontIndex; 813 SkPDFFont* relatedFont;
827 if (Find(fontID, glyphID, &relatedFontIndex)) { 814 SkPDFFont* pdfFont =
828 CanonicalFonts()[relatedFontIndex].fFont->ref(); 815 SkPDFCanon::GetCanon().findFont(fontID, glyphID, &relatedFont);
829 return CanonicalFonts()[relatedFontIndex].fFont; 816 if (pdfFont) {
817 return SkRef(pdfFont);
830 } 818 }
831 819
832 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics; 820 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics;
833 SkPDFDict* relatedFontDescriptor = NULL; 821 SkPDFDict* relatedFontDescriptor = NULL;
834 if (relatedFontIndex >= 0) { 822 if (relatedFont) {
835 SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont; 823 fontMetrics.reset(SkSafeRef(relatedFont->fontInfo()));
836 fontMetrics.reset(relatedFont->fontInfo());
837 SkSafeRef(fontMetrics.get());
838 relatedFontDescriptor = relatedFont->getFontDescriptor(); 824 relatedFontDescriptor = relatedFont->getFontDescriptor();
839 825
840 // This only is to catch callers who pass invalid glyph ids. 826 // This only is to catch callers who pass invalid glyph ids.
841 // If glyph id is invalid, then we will create duplicate entries 827 // If glyph id is invalid, then we will create duplicate entries
842 // for TrueType fonts. 828 // for TrueType fonts.
843 SkAdvancedTypefaceMetrics::FontType fontType = 829 SkAdvancedTypefaceMetrics::FontType fontType =
844 fontMetrics.get() ? fontMetrics.get()->fType : 830 fontMetrics.get() ? fontMetrics.get()->fType :
845 SkAdvancedTypefaceMetrics::kOther_Font; 831 SkAdvancedTypefaceMetrics::kOther_Font;
846 832
847 if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font || 833 if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
848 fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 834 fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
849 CanonicalFonts()[relatedFontIndex].fFont->ref(); 835 return SkRef(relatedFont);
850 return CanonicalFonts()[relatedFontIndex].fFont;
851 } 836 }
852 } else { 837 } else {
853 SkAdvancedTypefaceMetrics::PerGlyphInfo info; 838 SkAdvancedTypefaceMetrics::PerGlyphInfo info;
854 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; 839 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo;
855 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 840 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
856 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); 841 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo);
857 #if !defined (SK_SFNTLY_SUBSETTER) 842 #if !defined (SK_SFNTLY_SUBSETTER)
858 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 843 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
859 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); 844 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
860 #endif 845 #endif
861 fontMetrics.reset( 846 fontMetrics.reset(
862 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); 847 typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
863 #if defined (SK_SFNTLY_SUBSETTER) 848 #if defined (SK_SFNTLY_SUBSETTER)
864 if (fontMetrics.get() && 849 if (fontMetrics.get() &&
865 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { 850 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
866 // Font does not support subsetting, get new info with advance. 851 // Font does not support subsetting, get new info with advance.
867 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 852 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
868 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); 853 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
869 fontMetrics.reset( 854 fontMetrics.reset(
870 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); 855 typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
871 } 856 }
872 #endif 857 #endif
873 } 858 }
874 859
875 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, 860 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID,
876 relatedFontDescriptor); 861 relatedFontDescriptor);
877 FontRec newEntry(font, fontID, font->fFirstGlyphID); 862 SkPDFCanon::GetCanon().addFont(font, fontID, font->fFirstGlyphID);
878 CanonicalFonts().push(newEntry);
879 return font; // Return the reference new SkPDFFont() created. 863 return font; // Return the reference new SkPDFFont() created.
880 } 864 }
881 865
882 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { 866 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
883 return NULL; // Default: no support. 867 return NULL; // Default: no support.
884 } 868 }
885 869
886 // static
887 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() {
888 SkPDFFont::CanonicalFontsMutex().assertHeld();
889 static SkTDArray<FontRec> gCanonicalFonts;
890 return gCanonicalFonts;
891 }
892
893 SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
894 // static
895 SkBaseMutex& SkPDFFont::CanonicalFontsMutex() {
896 return gCanonicalFontsMutex;
897 }
898
899 // static
900 bool SkPDFFont::Find(uint32_t fontID, uint16_t glyphID, int* index) {
901 // TODO(vandebo): Optimize this, do only one search?
902 FontRec search(NULL, fontID, glyphID);
903 *index = CanonicalFonts().find(search);
904 if (*index >= 0) {
905 return true;
906 }
907 search.fGlyphID = 0;
908 *index = CanonicalFonts().find(search);
909 return false;
910 }
911
912 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, 870 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
913 SkTypeface* typeface, 871 SkTypeface* typeface,
914 SkPDFDict* relatedFontDescriptor) 872 SkPDFDict* relatedFontDescriptor)
915 : SkPDFDict("Font"), 873 : SkPDFDict("Font"),
916 fTypeface(ref_or_default(typeface)), 874 fTypeface(ref_or_default(typeface)),
917 fFirstGlyphID(1), 875 fFirstGlyphID(1),
918 fLastGlyphID(info ? info->fLastGlyphID : 0), 876 fLastGlyphID(info ? info->fLastGlyphID : 0),
919 fFontInfo(SkSafeRef(info)), 877 fFontInfo(SkSafeRef(info)),
920 fDescriptor(SkSafeRef(relatedFontDescriptor)) { 878 fDescriptor(SkSafeRef(relatedFontDescriptor)) {
921 if (info == NULL || 879 if (info == NULL ||
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 } 985 }
1028 986
1029 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { 987 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) {
1030 // Single byte glyph encoding supports a max of 255 glyphs. 988 // Single byte glyph encoding supports a max of 255 glyphs.
1031 fFirstGlyphID = glyphID - (glyphID - 1) % 255; 989 fFirstGlyphID = glyphID - (glyphID - 1) % 255;
1032 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { 990 if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
1033 fLastGlyphID = fFirstGlyphID + 255 - 1; 991 fLastGlyphID = fFirstGlyphID + 255 - 1;
1034 } 992 }
1035 } 993 }
1036 994
1037 bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const {
1038 if (fFontID != b.fFontID) {
1039 return false;
1040 }
1041 if (fFont != NULL && b.fFont != NULL) {
1042 return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID &&
1043 fFont->fLastGlyphID == b.fFont->fLastGlyphID;
1044 }
1045 if (fGlyphID == 0 || b.fGlyphID == 0) {
1046 return true;
1047 }
1048
1049 if (fFont != NULL) {
1050 return fFont->fFirstGlyphID <= b.fGlyphID &&
1051 b.fGlyphID <= fFont->fLastGlyphID;
1052 } else if (b.fFont != NULL) {
1053 return b.fFont->fFirstGlyphID <= fGlyphID &&
1054 fGlyphID <= b.fFont->fLastGlyphID;
1055 }
1056 return fGlyphID == b.fGlyphID;
1057 }
1058
1059 SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID)
1060 : fFont(font),
1061 fFontID(fontID),
1062 fGlyphID(glyphID) {
1063 }
1064
1065 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { 995 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
1066 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { 996 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) {
1067 return; 997 return;
1068 } 998 }
1069 SkAutoTUnref<SkPDFStream> pdfCmap( 999 SkAutoTUnref<SkPDFStream> pdfCmap(
1070 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, 1000 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset,
1071 multiByteGlyphs(), firstGlyphID(), 1001 multiByteGlyphs(), firstGlyphID(),
1072 lastGlyphID())); 1002 lastGlyphID()));
1073 addResource(pdfCmap.get()); 1003 addResource(pdfCmap.get());
1074 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); 1004 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 1417
1488 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); 1418 insert("FontBBox", makeFontBBox(bbox, 1000))->unref();
1489 insertInt("FirstChar", 1); 1419 insertInt("FirstChar", 1);
1490 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); 1420 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1);
1491 insert("Widths", widthArray.get()); 1421 insert("Widths", widthArray.get());
1492 insertName("CIDToGIDMap", "Identity"); 1422 insertName("CIDToGIDMap", "Identity");
1493 1423
1494 populateToUnicodeTable(NULL); 1424 populateToUnicodeTable(NULL);
1495 return true; 1425 return true;
1496 } 1426 }
1427
1428 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont,
1429 uint32_t existingFontID,
1430 uint16_t existingGlyphID,
1431 uint32_t searchFontID,
1432 uint16_t searchGlyphID) {
1433 if (existingFontID != searchFontID) {
1434 return SkPDFFont::kNot_Match;
1435 }
1436 if (existingGlyphID == 0 || searchGlyphID == 0) {
1437 return SkPDFFont::kExact_Match;
1438 }
1439 if (existingFont != NULL) {
1440 return (existingFont->fFirstGlyphID <= searchGlyphID &&
1441 searchGlyphID <= existingFont->fLastGlyphID)
1442 ? SkPDFFont::kExact_Match
1443 : SkPDFFont::kRelated_Match;
1444 }
1445 return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match
1446 : SkPDFFont::kRelated_Match;
1447 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFGraphicState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698