You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PDFName.java 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. import java.io.IOException;
  20. import java.io.OutputStream;
  21. import org.apache.commons.io.output.CountingOutputStream;
  22. /**
  23. * Class representing a PDF name object.
  24. */
  25. public class PDFName extends PDFObject {
  26. private String name;
  27. /**
  28. * Creates a new PDF name object.
  29. * @param name the name value
  30. */
  31. public PDFName(String name) {
  32. super();
  33. this.name = escapeName(name);
  34. }
  35. private static final String ESCAPED_NAME_CHARS = "/()<>[]%#";
  36. /**
  37. * Escapes a PDF name. It adds the leading slash and escapes characters as necessary.
  38. * @param name the name
  39. * @return the escaped name
  40. */
  41. static String escapeName(String name) {
  42. StringBuilder sb = new StringBuilder(Math.min(16, name.length() + 4));
  43. boolean skipFirst = false;
  44. sb.append('/');
  45. if (name.startsWith("/")) {
  46. skipFirst = true;
  47. }
  48. for (int i = (skipFirst ? 1 : 0), c = name.length(); i < c; i++) {
  49. char ch = name.charAt(i);
  50. if (ch < 33 || ch > 126 || ESCAPED_NAME_CHARS.indexOf(ch) >= 0) {
  51. sb.append('#');
  52. toHex(ch, sb);
  53. } else {
  54. sb.append(ch);
  55. }
  56. }
  57. return sb.toString();
  58. }
  59. private static final char[] DIGITS
  60. = {'0', '1', '2', '3', '4', '5', '6', '7',
  61. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  62. private static void toHex(char ch, StringBuilder sb) {
  63. if (ch >= 256) {
  64. throw new IllegalArgumentException(
  65. "Only 8-bit characters allowed by this implementation");
  66. }
  67. sb.append(DIGITS[ch >>> 4 & 0x0F]);
  68. sb.append(DIGITS[ch & 0x0F]);
  69. }
  70. /** {@inheritDoc} */
  71. @Override
  72. public String toString() {
  73. return this.name;
  74. }
  75. /**
  76. * Returns the name without the leading slash.
  77. * @return the name without the leading slash
  78. */
  79. public String getName() {
  80. return this.name.substring(1);
  81. }
  82. /** {@inheritDoc} */
  83. public boolean equals(Object obj) {
  84. if (!(obj instanceof PDFName)) {
  85. return false;
  86. }
  87. PDFName other = (PDFName)obj;
  88. return this.name.equals(other.name);
  89. }
  90. /** {@inheritDoc} */
  91. public int hashCode() {
  92. return name.hashCode();
  93. }
  94. @Override
  95. public int output(OutputStream stream) throws IOException {
  96. CountingOutputStream cout = new CountingOutputStream(stream);
  97. StringBuilder textBuffer = new StringBuilder(64);
  98. textBuffer.append(toString());
  99. PDFDocument.flushTextBuffer(textBuffer, cout);
  100. return cout.getCount();
  101. }
  102. @Override
  103. public void outputInline(OutputStream out, StringBuilder textBuffer) throws IOException {
  104. if (hasObjectNumber()) {
  105. textBuffer.append(referencePDF());
  106. } else {
  107. textBuffer.append(toString());
  108. }
  109. }
  110. }