1 17 18 19 20 package org.apache.fop.pdf; 21 22 import java.awt.geom.Rectangle2D ; 24 import java.io.FileNotFoundException ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.net.MalformedURLException ; 28 import java.util.BitSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import javax.xml.transform.Source ; 33 import javax.xml.transform.stream.StreamSource ; 34 35 import org.apache.commons.io.IOUtils; 37 import org.apache.commons.io.output.ByteArrayOutputStream; 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 41 import org.apache.fop.fonts.CIDFont; 43 import org.apache.fop.fonts.CustomFont; 44 import org.apache.fop.fonts.Typeface; 45 import org.apache.fop.fonts.FontDescriptor; 46 import org.apache.fop.fonts.FontMetrics; 47 import org.apache.fop.fonts.FontType; 48 import org.apache.fop.fonts.LazyFont; 49 import org.apache.fop.fonts.MultiByteFont; 50 import org.apache.fop.fonts.truetype.FontFileReader; 51 import org.apache.fop.fonts.truetype.TTFSubSetFile; 52 import org.apache.fop.fonts.type1.PFBData; 53 import org.apache.fop.fonts.type1.PFBParser; 54 import org.apache.xmlgraphics.xmp.Metadata; 55 56 59 public class PDFFactory { 60 61 private PDFDocument document; 62 63 private Log log = LogFactory.getLog(PDFFactory.class); 64 65 70 public PDFFactory(PDFDocument document) { 71 this.document = document; 72 } 73 74 78 public final PDFDocument getDocument() { 79 return this.document; 80 } 81 82 83 84 91 public PDFRoot makeRoot(PDFPages pages) { 92 PDFRoot pdfRoot = new PDFRoot(++this.document.objectcount, pages); 94 pdfRoot.setDocument(getDocument()); 95 getDocument().addTrailerObject(pdfRoot); 96 return pdfRoot; 97 } 98 99 104 public PDFPages makePages() { 105 PDFPages pdfPages = new PDFPages(++(this.document.objectcount)); 106 pdfPages.setDocument(getDocument()); 107 getDocument().addTrailerObject(pdfPages); 108 return pdfPages; 109 } 110 111 116 public PDFResources makeResources() { 117 PDFResources pdfResources = new PDFResources(++this.document.objectcount); 118 pdfResources.setDocument(getDocument()); 119 getDocument().addTrailerObject(pdfResources); 120 return pdfResources; 121 } 122 123 129 protected PDFInfo makeInfo(String prod) { 130 131 135 PDFInfo pdfInfo = new PDFInfo(); 136 pdfInfo.setProducer(prod); 138 getDocument().registerObject(pdfInfo); 139 return pdfInfo; 140 } 141 142 148 public PDFMetadata makeMetadata(Metadata meta, boolean readOnly) { 149 PDFMetadata pdfMetadata = new PDFMetadata(meta, readOnly); 150 getDocument().registerObject(pdfMetadata); 151 return pdfMetadata; 152 } 153 154 158 public PDFOutputIntent makeOutputIntent() { 159 PDFOutputIntent outputIntent = new PDFOutputIntent(); 160 getDocument().registerObject(outputIntent); 161 return outputIntent; 162 } 163 164 176 public PDFPage makePage(PDFResources resources, 177 int pageWidth, int pageHeight, int pageIndex) { 178 179 183 PDFPage page = new PDFPage(resources, 184 pageWidth, pageHeight, pageIndex); 185 186 getDocument().assignObjectNumber(page); 187 getDocument().getPages().addPage(page); 188 return page; 189 } 190 191 202 public PDFPage makePage(PDFResources resources, 203 int pageWidth, int pageHeight) { 204 return makePage(resources, pageWidth, pageHeight, -1); 205 } 206 207 208 209 266 public PDFFunction makeFunction(int theFunctionType, List theDomain, 267 List theRange, List theSize, 268 int theBitsPerSample, int theOrder, 269 List theEncode, List theDecode, 270 StringBuffer theFunctionDataStream, 271 List theFilter) { 272 PDFFunction function = new PDFFunction(theFunctionType, theDomain, 274 theRange, theSize, 275 theBitsPerSample, theOrder, 276 theEncode, theDecode, 277 theFunctionDataStream, 278 theFilter); 279 280 PDFFunction oldfunc = getDocument().findFunction(function); 281 if (oldfunc == null) { 282 getDocument().registerObject(function); 283 } else { 284 function = oldfunc; 285 } 286 return (function); 287 } 288 289 315 public PDFFunction makeFunction(int theFunctionType, List theDomain, 316 List theRange, List theCZero, 317 List theCOne, 318 double theInterpolationExponentN) { PDFFunction function = new PDFFunction(theFunctionType, theDomain, 320 theRange, theCZero, theCOne, 321 theInterpolationExponentN); 322 PDFFunction oldfunc = getDocument().findFunction(function); 323 if (oldfunc == null) { 324 getDocument().registerObject(function); 325 } else { 326 function = oldfunc; 327 } 328 return (function); 329 } 330 331 367 public PDFFunction makeFunction(int theFunctionType, List theDomain, 368 List theRange, List theFunctions, 369 List theBounds, 370 List theEncode) { 371 373 PDFFunction function = new PDFFunction(theFunctionType, theDomain, 374 theRange, theFunctions, 375 theBounds, theEncode); 376 377 PDFFunction oldfunc = getDocument().findFunction(function); 378 if (oldfunc == null) { 379 getDocument().registerObject(function); 380 } else { 381 function = oldfunc; 382 } 383 return (function); 384 } 385 386 396 public PDFFunction makeFunction(int theNumber, int theFunctionType, 397 List theDomain, List theRange, 398 StringBuffer theFunctionDataStream) { 399 PDFFunction function = new PDFFunction(theFunctionType, theDomain, 401 theRange, 402 theFunctionDataStream); 403 404 PDFFunction oldfunc = getDocument().findFunction(function); 405 if (oldfunc == null) { 406 getDocument().registerObject(function); 407 } else { 408 function = oldfunc; 409 } 410 return (function); 411 412 } 413 414 415 416 439 public PDFShading makeShading(PDFResourceContext res, int theShadingType, 440 PDFDeviceColorSpace theColorSpace, 441 List theBackground, List theBBox, 442 boolean theAntiAlias, List theDomain, 443 List theMatrix, 444 PDFFunction theFunction) { 445 PDFShading shading = new PDFShading(theShadingType, 447 theColorSpace, theBackground, 448 theBBox, theAntiAlias, theDomain, 449 theMatrix, theFunction); 450 451 PDFShading oldshad = getDocument().findShading(shading); 452 if (oldshad == null) { 453 getDocument().registerObject(shading); 454 } else { 455 shading = oldshad; 456 } 457 458 if (res != null) { 460 res.getPDFResources().addShading(shading); 461 } else { 462 getDocument().getResources().addShading(shading); 463 } 464 465 return (shading); 466 } 467 468 491 public PDFShading makeShading(PDFResourceContext res, int theShadingType, 492 PDFDeviceColorSpace theColorSpace, 493 List theBackground, List theBBox, 494 boolean theAntiAlias, List theCoords, 495 List theDomain, PDFFunction theFunction, 496 List theExtend) { 497 PDFShading shading = new PDFShading(theShadingType, 499 theColorSpace, theBackground, 500 theBBox, theAntiAlias, theCoords, 501 theDomain, theFunction, 502 theExtend); 503 504 PDFShading oldshad = getDocument().findShading(shading); 505 if (oldshad == null) { 506 getDocument().registerObject(shading); 507 } else { 508 shading = oldshad; 509 } 510 511 if (res != null) { 512 res.getPDFResources().addShading(shading); 513 } else { 514 getDocument().getResources().addShading(shading); 515 } 516 517 return (shading); 518 } 519 520 544 public PDFShading makeShading(PDFResourceContext res, int theShadingType, 545 PDFDeviceColorSpace theColorSpace, 546 List theBackground, List theBBox, 547 boolean theAntiAlias, 548 int theBitsPerCoordinate, 549 int theBitsPerComponent, 550 int theBitsPerFlag, List theDecode, 551 PDFFunction theFunction) { 552 PDFShading shading = new PDFShading(theShadingType, 554 theColorSpace, theBackground, 555 theBBox, theAntiAlias, 556 theBitsPerCoordinate, 557 theBitsPerComponent, 558 theBitsPerFlag, theDecode, 559 theFunction); 560 561 PDFShading oldshad = getDocument().findShading(shading); 562 if (oldshad == null) { 563 getDocument().registerObject(shading); 564 } else { 565 shading = oldshad; 566 } 567 568 if (res != null) { 569 res.getPDFResources().addShading(shading); 570 } else { 571 getDocument().getResources().addShading(shading); 572 } 573 574 return (shading); 575 } 576 577 599 public PDFShading makeShading(PDFResourceContext res, int theShadingType, 600 PDFDeviceColorSpace theColorSpace, 601 List theBackground, List theBBox, 602 boolean theAntiAlias, 603 int theBitsPerCoordinate, 604 int theBitsPerComponent, List theDecode, 605 int theVerticesPerRow, 606 PDFFunction theFunction) { 607 PDFShading shading = new PDFShading(theShadingType, 609 theColorSpace, theBackground, 610 theBBox, theAntiAlias, 611 theBitsPerCoordinate, 612 theBitsPerComponent, theDecode, 613 theVerticesPerRow, theFunction); 614 615 PDFShading oldshad = getDocument().findShading(shading); 616 if (oldshad == null) { 617 getDocument().registerObject(shading); 618 } else { 619 shading = oldshad; 620 } 621 622 if (res != null) { 623 res.getPDFResources().addShading(shading); 624 } else { 625 getDocument().getResources().addShading(shading); 626 } 627 628 return (shading); 629 } 630 631 632 633 649 public PDFPattern makePattern(PDFResourceContext res, int thePatternType, PDFResources theResources, int thePaintType, int theTilingType, 651 List theBBox, double theXStep, 652 double theYStep, List theMatrix, 653 List theXUID, StringBuffer thePatternDataStream) { 654 PDFPattern pattern = new PDFPattern(theResources, 1, 656 thePaintType, theTilingType, 657 theBBox, theXStep, theYStep, 658 theMatrix, theXUID, 659 thePatternDataStream); 660 661 PDFPattern oldpatt = getDocument().findPattern(pattern); 662 if (oldpatt == null) { 663 getDocument().registerObject(pattern); 664 } else { 665 pattern = oldpatt; 666 } 667 668 if (res != null) { 669 res.getPDFResources().addPattern(pattern); 670 } else { 671 getDocument().getResources().addPattern(pattern); 672 } 673 674 return (pattern); 675 } 676 677 688 public PDFPattern makePattern(PDFResourceContext res, 689 int thePatternType, PDFShading theShading, 690 List theXUID, StringBuffer theExtGState, 691 List theMatrix) { 692 PDFPattern pattern = new PDFPattern(2, theShading, 693 theXUID, theExtGState, theMatrix); 694 695 PDFPattern oldpatt = getDocument().findPattern(pattern); 696 if (oldpatt == null) { 697 getDocument().registerObject(pattern); 698 } else { 699 pattern = oldpatt; 700 } 701 702 if (res != null) { 703 res.getPDFResources().addPattern(pattern); 704 } else { 705 getDocument().getResources().addPattern(pattern); 706 } 707 708 return (pattern); 709 } 710 711 722 public PDFPattern makeGradient(PDFResourceContext res, boolean radial, 723 PDFDeviceColorSpace theColorspace, 724 List theColors, List theBounds, 725 List theCoords, List theMatrix) { 726 PDFShading myShad; 727 PDFFunction myfunky; 728 PDFFunction myfunc; 729 List theCzero; 730 List theCone; 731 PDFPattern myPattern; 732 double interpolation = (double)1.000; 734 List theFunctions = new java.util.ArrayList (); 735 736 int currentPosition; 737 int lastPosition = theColors.size() - 1; 738 739 740 744 for (currentPosition = 0; currentPosition < lastPosition; 745 currentPosition++) { PDFColor currentColor = 747 (PDFColor)theColors.get(currentPosition); 748 PDFColor nextColor = (PDFColor)theColors.get(currentPosition 749 + 1); 750 if (getDocument().getColorSpace() 752 != currentColor.getColorSpace()) { 753 currentColor.setColorSpace( 754 getDocument().getColorSpace()); 755 } 756 757 if (getDocument().getColorSpace() 758 != nextColor.getColorSpace()) { 759 nextColor.setColorSpace( 760 getDocument().getColorSpace()); 761 } 762 763 theCzero = currentColor.getVector(); 764 theCone = nextColor.getVector(); 765 766 myfunc = makeFunction(2, null, null, theCzero, theCone, 767 interpolation); 768 769 theFunctions.add(myfunc); 770 771 } 773 myfunky = makeFunction(3, null, null, theFunctions, theBounds, 774 null); 775 776 if (radial) { 777 if (theCoords.size() == 6) { 778 myShad = makeShading(res, 3, getDocument().getPDFColorSpace(), 779 null, null, 780 false, theCoords, null, myfunky, 781 null); 782 } else { List newCoords = new java.util.ArrayList (); 786 newCoords.add(theCoords.get(0)); 787 newCoords.add(theCoords.get(1)); 788 newCoords.add(theCoords.get(2)); 789 newCoords.add(theCoords.get(0)); 790 newCoords.add(theCoords.get(1)); 791 newCoords.add(new Double (0.0)); 792 793 myShad = makeShading(res, 3, getDocument().getPDFColorSpace(), 794 null, null, 795 false, newCoords, null, myfunky, 796 null); 797 798 } 799 } else { 800 myShad = makeShading(res, 2, getDocument().getPDFColorSpace(), 801 null, null, 802 false, theCoords, null, myfunky, 803 null); 804 805 } 806 807 myPattern = makePattern(res, 2, myShad, null, null, theMatrix); 808 809 return (myPattern); 810 } 811 812 813 814 822 public PDFLink makeLink(Rectangle2D rect, String page, String dest) { 823 PDFLink link = new PDFLink(rect); 824 getDocument().registerObject(link); 825 826 PDFGoTo gt = new PDFGoTo(page); 827 gt.setDestination(dest); 828 getDocument().addTrailerObject(gt); 829 PDFInternalLink internalLink = new PDFInternalLink(gt.referencePDF()); 830 link.setAction(internalLink); 831 832 return link; 833 } 834 835 844 public PDFLink makeLink(Rectangle2D rect, String destination, 845 int linkType, float yoffset) { 846 847 int index; 849 850 PDFLink link = new PDFLink(rect); 851 852 if (linkType == PDFLink.EXTERNAL) { 853 if (destination.startsWith("http://")) { 855 PDFUri uri = new PDFUri(destination); 856 link.setAction(uri); 857 } else if (destination.endsWith(".pdf")) { PDFGoToRemote remote = getGoToPDFAction(destination, null, -1); 859 link.setAction(remote); 860 } else if ((index = destination.indexOf(".pdf#page=")) > 0) { 861 int page = Integer.parseInt(destination.substring(index + 10)); 863 PDFGoToRemote remote = getGoToPDFAction(destination, null, page); 864 link.setAction(remote); 865 } else if ((index = destination.indexOf(".pdf#dest=")) > 0) { 866 String dest = destination.substring(index + 10); 868 PDFGoToRemote remote = getGoToPDFAction(destination, dest, -1); 869 link.setAction(remote); 870 } else { PDFUri uri = new PDFUri(destination); 872 link.setAction(uri); 873 } 874 } else { 875 String goToReference = getGoToReference(destination, yoffset); 877 PDFInternalLink internalLink = new PDFInternalLink(goToReference); 878 link.setAction(internalLink); 879 } 880 881 PDFLink oldlink = getDocument().findLink(link); 882 if (oldlink == null) { 883 getDocument().registerObject(link); 884 } else { 885 link = oldlink; 886 } 887 888 return link; 889 } 890 891 private String getGoToReference(String destination, float yoffset) { 892 getDocument().getProfile().verifyActionAllowed(); 893 String goToReference = null; 894 PDFGoTo gt = new PDFGoTo(destination); 895 gt.setYPosition(yoffset); 896 PDFGoTo oldgt = getDocument().findGoTo(gt); 897 if (oldgt == null) { 898 getDocument().assignObjectNumber(gt); 899 getDocument().addTrailerObject(gt); 900 } else { 901 gt = oldgt; 902 } 903 904 goToReference = gt.referencePDF(); 905 return goToReference; 906 } 907 908 919 private PDFGoToRemote getGoToPDFAction(String file, String dest, int page) { 920 getDocument().getProfile().verifyActionAllowed(); 921 PDFFileSpec fileSpec = new PDFFileSpec(file); 922 PDFFileSpec oldspec = getDocument().findFileSpec(fileSpec); 923 if (oldspec == null) { 924 getDocument().registerObject(fileSpec); 925 } else { 926 fileSpec = oldspec; 927 } 928 PDFGoToRemote remote; 929 930 if (dest == null && page == -1) { 931 remote = new PDFGoToRemote(fileSpec); 932 } else if (dest != null) { 933 remote = new PDFGoToRemote(fileSpec, dest); 934 } else { 935 remote = new PDFGoToRemote(fileSpec, page); 936 } 937 PDFGoToRemote oldremote = getDocument().findGoToRemote(remote); 938 if (oldremote == null) { 939 getDocument().registerObject(remote); 940 } else { 941 remote = oldremote; 942 } 943 return remote; 944 } 945 946 956 public PDFOutline makeOutline(PDFOutline parent, String label, 957 String destination, float yoffset, 958 boolean showSubItems) { 959 960 String goToRef = getGoToReference(destination, yoffset); 961 PDFOutline obj = new PDFOutline(label, goToRef, showSubItems); 962 963 if (parent != null) { 964 parent.addOutline(obj); 965 } 966 getDocument().registerObject(obj); 967 return obj; 968 } 969 970 971 972 973 974 980 public PDFEncoding makeEncoding(String encodingName) { 981 PDFEncoding encoding = new PDFEncoding(encodingName); 982 983 getDocument().registerObject(encoding); 984 return encoding; 985 } 986 987 997 public PDFFont makeFont(String fontname, String basefont, 998 String encoding, FontMetrics metrics, 999 FontDescriptor descriptor) { 1000 PDFFont preRegisteredfont = getDocument().findFont(fontname); 1001 if (preRegisteredfont != null) { 1002 return preRegisteredfont; 1003 } 1004 1005 if (descriptor == null) { 1006 PDFFont font = new PDFFont(fontname, FontType.TYPE1, basefont, encoding); 1007 getDocument().registerObject(font); 1008 return font; 1009 } else { 1010 FontType fonttype = metrics.getFontType(); 1011 1012 PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor); 1013 1014 PDFFontNonBase14 font = null; 1015 if (fonttype == FontType.TYPE0) { 1016 1027 font = 1028 (PDFFontNonBase14)PDFFont.createFont(fontname, fonttype, 1029 basefont, 1030 "Identity-H"); 1031 } else { 1032 1033 font = 1034 (PDFFontNonBase14)PDFFont.createFont(fontname, fonttype, 1035 basefont, encoding); 1036 } 1037 getDocument().registerObject(font); 1038 1039 font.setDescriptor(pdfdesc); 1040 1041 if (fonttype == FontType.TYPE0) { 1042 CIDFont cidMetrics; 1043 if (metrics instanceof LazyFont) { 1044 cidMetrics = (CIDFont)((LazyFont) metrics).getRealFont(); 1045 } else { 1046 cidMetrics = (CIDFont)metrics; 1047 } 1048 PDFCIDSystemInfo sysInfo = 1049 new PDFCIDSystemInfo(cidMetrics.getRegistry(), 1050 cidMetrics.getOrdering(), 1051 cidMetrics.getSupplement()); 1052 PDFCIDFont cidFont = 1053 new PDFCIDFont(basefont, 1054 cidMetrics.getCIDType(), 1055 cidMetrics.getDefaultWidth(), 1056 getSubsetWidths(cidMetrics), sysInfo, 1057 (PDFCIDFontDescriptor)pdfdesc); 1058 getDocument().registerObject(cidFont); 1059 1060 PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics, "fop-ucs-H", 1061 new PDFCIDSystemInfo("Adobe", 1062 "Identity", 1063 0)); 1064 getDocument().registerObject(cmap); 1065 ((PDFFontType0)font).setCMAP(cmap); 1066 ((PDFFontType0)font).setDescendantFonts(cidFont); 1067 } else { 1068 int firstChar = 0; 1069 int lastChar = 255; 1070 if (metrics instanceof CustomFont) { 1071 CustomFont cf = (CustomFont)metrics; 1072 firstChar = cf.getFirstChar(); 1073 lastChar = cf.getLastChar(); 1074 } 1075 font.setWidthMetrics(firstChar, 1076 lastChar, 1077 makeArray(metrics.getWidths())); 1078 } 1079 1080 return font; 1081 } 1082 } 1083 1084 public PDFWArray getSubsetWidths(CIDFont cidFont) { 1085 PDFWArray warray = new PDFWArray(); 1087 int[] tmpWidth = new int[cidFont.usedGlyphsCount]; 1088 1089 for (int i = 0; i < cidFont.usedGlyphsCount; i++) { 1090 Integer nw = (Integer )cidFont.usedGlyphsIndex.get(new Integer (i)); 1091 int nwx = (nw == null) ? 0 : nw.intValue(); 1092 tmpWidth[i] = cidFont.width[nwx]; 1093 } 1094 warray.addEntry(0, tmpWidth); 1095 return warray; 1096 } 1097 1098 1104 public PDFFontDescriptor makeFontDescriptor(FontDescriptor desc) { 1105 PDFFontDescriptor descriptor = null; 1106 1107 if (desc.getFontType() == FontType.TYPE0) { 1108 descriptor = new PDFCIDFontDescriptor(desc.getFontName(), 1110 desc.getFontBBox(), 1111 desc.getCapHeight(), 1112 desc.getFlags(), 1113 desc.getItalicAngle(), 1114 desc.getStemV(), null); 1115 } else { 1116 descriptor = new PDFFontDescriptor(desc.getFontName(), 1118 desc.getAscender(), 1119 desc.getDescender(), 1120 desc.getCapHeight(), 1121 desc.getFlags(), 1122 new PDFRectangle(desc.getFontBBox()), 1123 desc.getItalicAngle(), 1124 desc.getStemV()); 1125 } 1126 getDocument().registerObject(descriptor); 1127 1128 if (desc.isEmbeddable()) { 1130 AbstractPDFStream stream = makeFontFile(desc); 1131 if (stream != null) { 1132 descriptor.setFontFile(desc.getFontType(), stream); 1133 getDocument().registerObject(stream); 1134 } 1135 CustomFont font = getCustomFont(desc); 1136 if (font instanceof CIDFont) { 1137 CIDFont cidFont = (CIDFont)font; 1138 buildCIDSet(descriptor, cidFont); 1139 } 1140 } 1141 return descriptor; 1142 } 1143 1144 private void buildCIDSet(PDFFontDescriptor descriptor, CIDFont cidFont) { 1145 BitSet cidSubset = new BitSet (); 1146 Iterator iter = cidFont.usedGlyphs.keySet().iterator(); 1147 while (iter.hasNext()) { 1148 Integer cid = (Integer )iter.next(); 1149 cidSubset.set(cid.intValue()); 1150 } 1151 PDFStream cidSet = makeStream(null, true); 1152 ByteArrayOutputStream baout = new ByteArrayOutputStream(cidSubset.length() / 8 + 1); 1153 int value = 0; 1154 for (int i = 0, c = cidSubset.length(); i < c; i++) { 1155 int shift = i % 8; 1156 boolean b = cidSubset.get(i); 1157 if (b) { 1158 value |= 1 << 7 - shift; 1159 } 1160 if (shift == 7) { 1161 baout.write(value); 1162 value = 0; 1163 } 1164 } 1165 baout.write(value); 1166 try { 1167 cidSet.setData(baout.toByteArray()); 1168 descriptor.setCIDSet(cidSet); 1169 } catch (IOException ioe) { 1170 log.error( 1171 "Failed to write CIDSet [" + cidFont + "] " 1172 + cidFont.getFontName(), ioe); 1173 } 1174 } 1175 1176 1181 public AbstractPDFStream makeFontFile(FontDescriptor desc) { 1182 if (desc.getFontType() == FontType.OTHER) { 1183 throw new IllegalArgumentException ("Trying to embed unsupported font type: " 1184 + desc.getFontType()); 1185 } 1186 1187 CustomFont font = getCustomFont(desc); 1188 1189 InputStream in = null; 1190 try { 1191 Source source = font.getEmbedFileSource(); 1192 if (source == null && font.getEmbedResourceName() != null) { 1193 source = new StreamSource (this.getClass() 1194 .getResourceAsStream(font.getEmbedResourceName())); 1195 } 1196 if (source == null) { 1197 return null; 1198 } 1199 if (source instanceof StreamSource ) { 1200 in = ((StreamSource ) source).getInputStream(); 1201 } 1202 if (in == null && source.getSystemId() != null) { 1203 try { 1204 in = new java.net.URL (source.getSystemId()).openStream(); 1205 } catch (MalformedURLException e) { 1206 new FileNotFoundException ( 1207 "File not found. URL could not be resolved: " 1208 + e.getMessage()); 1209 } 1210 } 1211 if (in == null) { 1212 return null; 1213 } 1214 if (!(in instanceof java.io.BufferedInputStream )) { 1216 in = new java.io.BufferedInputStream (in); 1217 } 1218 if (in == null) { 1219 return null; 1220 } else { 1221 try { 1222 AbstractPDFStream embeddedFont; 1223 if (desc.getFontType() == FontType.TYPE0) { 1224 MultiByteFont mbfont = (MultiByteFont)font; 1225 FontFileReader reader = new FontFileReader(in); 1226 1227 TTFSubSetFile subset = new TTFSubSetFile(); 1228 byte[] subsetFont = subset.readFont(reader, 1229 mbfont.getTTCName(), mbfont.getUsedGlyphs()); 1230 1232 embeddedFont = new PDFTTFStream(subsetFont.length); 1233 ((PDFTTFStream)embeddedFont).setData(subsetFont, subsetFont.length); 1234 } else if (desc.getFontType() == FontType.TYPE1) { 1235 PFBParser parser = new PFBParser(); 1236 PFBData pfb = parser.parsePFB(in); 1237 embeddedFont = new PDFT1Stream(); 1238 ((PDFT1Stream)embeddedFont).setData(pfb); 1239 } else { 1240 byte[] file = IOUtils.toByteArray(in); 1241 embeddedFont = new PDFTTFStream(file.length); 1242 ((PDFTTFStream)embeddedFont).setData(file, file.length); 1243 } 1244 1245 1252 1253 return embeddedFont; 1254 } finally { 1255 in.close(); 1256 } 1257 } 1258 } catch (IOException ioe) { 1259 log.error( 1260 "Failed to embed font [" + desc + "] " 1261 + desc.getFontName(), ioe); 1262 return (PDFStream) null; 1263 } 1264 } 1265 1266 private CustomFont getCustomFont(FontDescriptor desc) { 1267 Typeface tempFont; 1268 if (desc instanceof LazyFont) { 1269 tempFont = ((LazyFont)desc).getRealFont(); 1270 } else { 1271 tempFont = (Typeface)desc; 1272 } 1273 if (!(tempFont instanceof CustomFont)) { 1274 throw new IllegalArgumentException ( 1275 "FontDescriptor must be instance of CustomFont, but is a " 1276 + desc.getClass().getName()); 1277 } 1278 return (CustomFont)tempFont; 1279 } 1280 1281 1282 1283 1284 1291 public PDFStream makeStream(String type, boolean add) { 1292 1293 PDFStream obj = new PDFStream(); 1296 obj.setDocument(getDocument()); 1297 obj.getFilterList().addDefaultFilters( 1298 getDocument().getFilterMap(), 1299 type); 1300 1301 if (add) { 1302 getDocument().registerObject(obj); 1303 } 1304 return obj; 1306 } 1307 1308 1315 public PDFICCStream makePDFICCStream() { 1316 PDFICCStream iccStream = new PDFICCStream(); 1317 iccStream.getFilterList().addDefaultFilters( 1318 getDocument().getFilterMap(), 1319 PDFFilterList.CONTENT_FILTER); 1320 1321 getDocument().registerObject(iccStream); 1322 return iccStream; 1324 } 1325 1326 1327 1328 1335 public PDFICCBasedColorSpace makeICCBasedColorSpace(PDFResourceContext res, 1336 String explicitName, PDFICCStream iccStream) { 1337 PDFICCBasedColorSpace cs = new PDFICCBasedColorSpace(explicitName, iccStream); 1338 1339 getDocument().registerObject(cs); 1340 1341 if (res != null) { 1342 res.getPDFResources().addColorSpace(cs); 1343 } else { 1344 getDocument().getResources().addColorSpace(cs); 1345 } 1346 1347 return cs; 1348 } 1349 1350 1356 public PDFArray makeArray(int[] values) { 1357 PDFArray array = new PDFArray(values); 1358 1359 getDocument().registerObject(array); 1360 return array; 1361 } 1362 1363 1373 public PDFGState makeGState(Map settings, PDFGState current) { 1374 1375 1379 PDFGState wanted = new PDFGState(); 1380 wanted.addValues(PDFGState.DEFAULT); 1381 wanted.addValues(settings); 1382 1383 1384 PDFGState existing = getDocument().findGState(wanted, current); 1385 if (existing != null) { 1386 return existing; 1387 } 1388 1389 PDFGState gstate = new PDFGState(); 1390 gstate.addValues(settings); 1391 getDocument().registerObject(gstate); 1392 return gstate; 1393 } 1394 1395 1400 public PDFAnnotList makeAnnotList() { 1401 PDFAnnotList obj = new PDFAnnotList(); 1402 getDocument().assignObjectNumber(obj); 1403 return obj; 1404 } 1405 1406} 1407 | Popular Tags |