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.

PageBoundariesAttributes.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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.render.extensions.prepress;
  19. import java.awt.Rectangle;
  20. import java.text.MessageFormat;
  21. import java.util.regex.Matcher;
  22. import java.util.regex.Pattern;
  23. import org.apache.xmlgraphics.util.QName;
  24. import org.apache.fop.fo.extensions.ExtensionElementMapping;
  25. import org.apache.fop.fo.properties.FixedLength;
  26. /**
  27. * This class contains definition of page boundaries FOF's extension attributes for XSL-FO.
  28. * That is: bleedBox, trimBox and cropBox.
  29. * Also this class provides method to parse the possible values of these attributes
  30. * and to generate original size of bounded area.
  31. */
  32. public final class PageBoundariesAttributes {
  33. /**
  34. * The extension attribute for calculating the PDF BleedBox area - specifies the bleed width
  35. */
  36. public static final QName EXT_BLEED
  37. = new QName(ExtensionElementMapping.URI, null, "bleed");
  38. /**
  39. * The extension attribute for the PDF CropBox area
  40. */
  41. public static final QName EXT_CROP_OFFSET
  42. = new QName(ExtensionElementMapping.URI, null, "crop-offset");
  43. /**
  44. * The extension attribute for the PDF CropBox area
  45. */
  46. public static final QName EXT_CROP_BOX
  47. = new QName(ExtensionElementMapping.URI, null, "crop-box");
  48. private static final Pattern SIZE_UNIT_PATTERN
  49. = Pattern.compile("^(-?\\d*\\.?\\d*)(px|in|cm|mm|pt|pc|mpt)$");
  50. /**
  51. * Utility classes should not have a public or default constructor.
  52. */
  53. private PageBoundariesAttributes() {
  54. }
  55. /**
  56. * The BleedBox is calculated by expanding the TrimBox by the bleed widths.
  57. *
  58. * @param trimBox the TrimBox rectangle
  59. * @param bleed the given bleed widths
  60. * @return the calculated BleedBox rectangle
  61. */
  62. public static Rectangle getBleedBoxRectangle(Rectangle trimBox, String bleed) {
  63. return getRectagleUsingOffset(trimBox, bleed);
  64. }
  65. /**
  66. * The MediaBox is calculated by expanding the TrimBox by the crop offsets.
  67. *
  68. * @param trimBox the TrimBox rectangle
  69. * @param cropOffsets the given crop offsets
  70. * @return the calculated MediaBox rectangle
  71. */
  72. public static Rectangle getMediaBoxRectangle(Rectangle trimBox, String cropOffsets) {
  73. return getRectagleUsingOffset(trimBox, cropOffsets);
  74. }
  75. /**
  76. * The crop box controls how Acrobat display the page or how the Java2DRenderer
  77. * sizes the output media. The PDF spec defines that the CropBox defaults to the MediaBox.
  78. * <p/>
  79. * The possible values of crop-box: (trim-box|bleed-box|media-box)
  80. * Default value: media-box
  81. *
  82. * @param trimBox the TrimBox rectangle
  83. * @param bleedBox the BleedBox rectangle
  84. * @param mediaBox the MediaBox rectangle
  85. * @param value the crop-box value
  86. * @return the calculated CropBox rectangle
  87. */
  88. public static Rectangle getCropBoxRectangle(final Rectangle trimBox, final Rectangle bleedBox,
  89. final Rectangle mediaBox, final String value) {
  90. final String err = "The crop-box has invalid value: {0}, "
  91. + "possible values of crop-box: (trim-box|bleed-box|media-box)";
  92. if ("trim-box".equals(value)) {
  93. return trimBox;
  94. } else if ("bleed-box".equals(value)) {
  95. return bleedBox;
  96. } else if ("media-box".equals(value) || value == null || "".equals(value)) {
  97. return mediaBox;
  98. } else {
  99. throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{value}));
  100. }
  101. }
  102. /**
  103. * The crop box controls how Acrobat display the page or how the Java2DRenderer
  104. * sizes the output media. The PDF spec defines that the CropBox defaults to the MediaBox
  105. * <p/>
  106. * The possible values of crop-box: (trim-box|bleed-box|media-box)
  107. * Default value: media-box
  108. *
  109. * @param trimBox the TrimBox rectangle
  110. * @param bleed the given bleed widths
  111. * @param cropOffset the given crop offsets
  112. * @param value the crop-box value
  113. * @return the calculated CropBox rectangle
  114. */
  115. public static Rectangle getCropBoxRectangle(final Rectangle trimBox, final String bleed,
  116. final String cropOffset, final String value) {
  117. Rectangle bleedBox = getBleedBoxRectangle(trimBox, bleed);
  118. Rectangle mediaBox = getMediaBoxRectangle(trimBox, cropOffset);
  119. return getCropBoxRectangle(trimBox, bleedBox, mediaBox, value);
  120. }
  121. private static Rectangle getRectagleUsingOffset(Rectangle originalRect, String offset) {
  122. if (offset == null || "".equals(offset) || originalRect == null) {
  123. return originalRect;
  124. }
  125. String[] bleeds = offset.split(" ");
  126. int[] coords = new int[4]; // top, rigth, bottom, left
  127. if (bleeds.length == 1) {
  128. coords[0] = getLengthIntValue(bleeds[0]);
  129. coords[1] = coords[0];
  130. coords[2] = coords[0];
  131. coords[3] = coords[0];
  132. } else if (bleeds.length == 2) {
  133. coords[0] = getLengthIntValue(bleeds[0]);
  134. coords[2] = coords[0];
  135. coords[1] = getLengthIntValue(bleeds[1]);
  136. coords[3] = coords[1];
  137. } else if (bleeds.length == 3) {
  138. coords[0] = getLengthIntValue(bleeds[0]);
  139. coords[1] = getLengthIntValue(bleeds[1]);
  140. coords[3] = coords[1];
  141. coords[2] = getLengthIntValue(bleeds[2]);
  142. } else if (bleeds.length == 4) {
  143. coords[0] = getLengthIntValue(bleeds[0]);
  144. coords[1] = getLengthIntValue(bleeds[1]);
  145. coords[2] = getLengthIntValue(bleeds[2]);
  146. coords[3] = getLengthIntValue(bleeds[3]);
  147. }
  148. return new Rectangle((int) (originalRect.getX() - coords[3]),
  149. (int) (originalRect.getY() - coords[0]),
  150. (int) (originalRect.getWidth() + coords[3] + coords[1]),
  151. (int) (originalRect.getHeight() + coords[0] + coords[2]));
  152. }
  153. private static int getLengthIntValue(final String length) {
  154. final String err = "Incorrect length value: {0}";
  155. Matcher m = SIZE_UNIT_PATTERN.matcher(length);
  156. if (m.find()) {
  157. return FixedLength.getInstance(Double.parseDouble(m.group(1)),
  158. m.group(2)).getLength().getValue();
  159. } else {
  160. throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{length}));
  161. }
  162. }
  163. }