Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

PDFEncoding.java 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.pdf;
  19. // Java
  20. import java.util.Collections;
  21. import java.util.Set;
  22. import org.apache.fop.fonts.CodePointMapping;
  23. import org.apache.fop.fonts.SingleByteEncoding;
  24. /**
  25. * Class representing an /Encoding object.
  26. *
  27. * A small object expressing the base encoding name and
  28. * the differences from the base encoding.
  29. *
  30. * The three base encodings are given by their name.
  31. *
  32. * Encodings are specified in section 5.5.5 of the PDF 1.4 spec.
  33. */
  34. public class PDFEncoding extends PDFDictionary {
  35. /** the name for the standard encoding scheme */
  36. public static final String STANDARD_ENCODING = "StandardEncoding";
  37. /** the name for the Mac Roman encoding scheme */
  38. public static final String MAC_ROMAN_ENCODING = "MacRomanEncoding";
  39. /** the name for the Mac Export encoding scheme */
  40. public static final String MAC_EXPERT_ENCODING = "MacExpertEncoding";
  41. /** the name for the WinAnsi encoding scheme */
  42. public static final String WIN_ANSI_ENCODING = "WinAnsiEncoding";
  43. /** the name for the PDF document encoding scheme */
  44. public static final String PDF_DOC_ENCODING = "PDFDocEncoding";
  45. /** the set of predefined encodings that can be assumed present in a PDF viewer */
  46. private static final Set PREDEFINED_ENCODINGS;
  47. static {
  48. Set encodings = new java.util.HashSet();
  49. encodings.add(STANDARD_ENCODING);
  50. encodings.add(MAC_ROMAN_ENCODING);
  51. encodings.add(MAC_EXPERT_ENCODING);
  52. encodings.add(WIN_ANSI_ENCODING);
  53. encodings.add(PDF_DOC_ENCODING);
  54. PREDEFINED_ENCODINGS = Collections.unmodifiableSet(encodings);
  55. }
  56. /**
  57. * Create a new /Encoding object.
  58. *
  59. * @param basename the name of the character encoding schema
  60. */
  61. public PDFEncoding(String basename) {
  62. super();
  63. put("Type", new PDFName("Encoding"));
  64. if (basename != null) {
  65. put("BaseEncoding", new PDFName(basename));
  66. }
  67. }
  68. /**
  69. * Creates a PDFEncoding instance from a CodePointMapping instance.
  70. * @param encoding the code point mapping (encoding)
  71. * @param fontName ...
  72. * @return the PDF Encoding dictionary (or a String with the predefined encoding)
  73. */
  74. static Object createPDFEncoding(SingleByteEncoding encoding, String fontName) {
  75. //If encoding type is null, return null which causes /Encoding to be omitted.
  76. if (encoding == null) {
  77. return null;
  78. }
  79. String encodingName = null;
  80. SingleByteEncoding baseEncoding;
  81. if (fontName.indexOf("Symbol") >= 0) {
  82. baseEncoding = CodePointMapping.getMapping(CodePointMapping.SYMBOL_ENCODING);
  83. encodingName = baseEncoding.getName();
  84. } else {
  85. baseEncoding = CodePointMapping.getMapping(CodePointMapping.STANDARD_ENCODING);
  86. }
  87. PDFEncoding pdfEncoding = new PDFEncoding(encodingName);
  88. PDFEncoding.DifferencesBuilder builder = pdfEncoding.createDifferencesBuilder();
  89. PDFArray differences = builder.buildDifferencesArray(baseEncoding, encoding);
  90. // TODO This method should not be returning an Object with two different outcomes
  91. // resulting in subsequent `if (X instanceof Y)` statements.
  92. if (differences.length() > 0) {
  93. pdfEncoding.setDifferences(differences);
  94. return pdfEncoding;
  95. } else {
  96. return encodingName;
  97. }
  98. }
  99. /**
  100. * Indicates whether a given encoding is one of the predefined encodings.
  101. * @param name the encoding name (ex. "StandardEncoding")
  102. * @return true if it is a predefined encoding
  103. */
  104. public static boolean isPredefinedEncoding(String name) {
  105. return PREDEFINED_ENCODINGS.contains(name);
  106. }
  107. /**
  108. * Indicates whether the given encoding type is that of standard encoding
  109. * @param name The encoding name
  110. * @return Returns true if it is of type standard encoding
  111. */
  112. static boolean hasStandardEncoding(String encodingName) {
  113. return encodingName.equals(STANDARD_ENCODING);
  114. }
  115. /**
  116. * Creates and returns a new DifferencesBuilder instance for constructing the Differences
  117. * array.
  118. * @return the DifferencesBuilder
  119. */
  120. public DifferencesBuilder createDifferencesBuilder() {
  121. return new DifferencesBuilder();
  122. }
  123. /**
  124. * Sets the Differences value.
  125. * @param differences the differences.
  126. */
  127. public void setDifferences(PDFArray differences) {
  128. put("Differences", differences);
  129. }
  130. /**
  131. * Builder class for constructing the Differences array.
  132. */
  133. public class DifferencesBuilder {
  134. private int currentCode = -1;
  135. /**
  136. * Creates an array containing the differences between two single-byte.
  137. * font encodings.
  138. * @param encodingA The first single-byte encoding
  139. * @param encodingB The second single-byte encoding
  140. * @return The PDFArray of differences between encodings
  141. */
  142. public PDFArray buildDifferencesArray(SingleByteEncoding encodingA,
  143. SingleByteEncoding encodingB) {
  144. PDFArray differences = new PDFArray();
  145. int start = -1;
  146. String[] baseNames = encodingA.getCharNameMap();
  147. String[] charNameMap = encodingB.getCharNameMap();
  148. for (int i = 0, ci = charNameMap.length; i < ci; i++) {
  149. String basec = baseNames[i];
  150. String c = charNameMap[i];
  151. if (!basec.equals(c)) {
  152. if (start != i) {
  153. addDifference(i, differences);
  154. start = i;
  155. }
  156. addName(c, differences);
  157. start++;
  158. }
  159. }
  160. return differences;
  161. }
  162. /**
  163. * Start a new difference.
  164. * @param code the starting code index inside the encoding
  165. * @return this builder instance
  166. */
  167. private void addDifference(int code, PDFArray differences) {
  168. this.currentCode = code;
  169. differences.add(Integer.valueOf(code));
  170. }
  171. /**
  172. * Adds a character name to the current difference.
  173. * @param name the character name
  174. * @return this builder instance
  175. */
  176. private void addName(String name, PDFArray differences) {
  177. if (this.currentCode < 0) {
  178. throw new IllegalStateException("addDifference(int) must be called first");
  179. }
  180. differences.add(new PDFName(name));
  181. }
  182. }
  183. /*
  184. * example (p. 214)
  185. * 25 0 obj
  186. * <<
  187. * /Type /Encoding
  188. * /Differences [39 /quotesingle 96 /grave 128
  189. * /Adieresis /Aring /Ccedilla /Eacute /Ntilde
  190. * /Odieresis /Udieresis /aacute /agrave]
  191. * >>
  192. * endobj
  193. */
  194. }