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.

AFPDataObjectFactory.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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.afp;
  19. import java.awt.geom.Rectangle2D;
  20. import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
  21. import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
  22. import org.apache.fop.afp.ioca.IDEStructureParameter;
  23. import org.apache.fop.afp.ioca.ImageContent;
  24. import org.apache.fop.afp.modca.AbstractDataObject;
  25. import org.apache.fop.afp.modca.AbstractNamedAFPObject;
  26. import org.apache.fop.afp.modca.Document;
  27. import org.apache.fop.afp.modca.GraphicsObject;
  28. import org.apache.fop.afp.modca.ImageObject;
  29. import org.apache.fop.afp.modca.IncludeObject;
  30. import org.apache.fop.afp.modca.ObjectContainer;
  31. import org.apache.fop.afp.modca.Overlay;
  32. import org.apache.fop.afp.modca.PageSegment;
  33. import org.apache.fop.afp.modca.Registry;
  34. import org.apache.fop.afp.modca.ResourceObject;
  35. import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
  36. import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
  37. /**
  38. * Factory for high level data objects (Image/Graphics etc)
  39. */
  40. public class AFPDataObjectFactory {
  41. private final Factory factory;
  42. /**
  43. * Main constructor
  44. *
  45. * @param factory an object factory
  46. */
  47. public AFPDataObjectFactory(Factory factory) {
  48. this.factory = factory;
  49. }
  50. /**
  51. * Creates and configures an ObjectContainer.
  52. *
  53. * @param dataObjectInfo the object container info
  54. * @return a newly created Object Container
  55. */
  56. public ObjectContainer createObjectContainer(AFPDataObjectInfo dataObjectInfo) {
  57. ObjectContainer objectContainer = factory.createObjectContainer();
  58. // set data object viewport (i.e. position, rotation, dimension, resolution)
  59. objectContainer.setViewport(dataObjectInfo);
  60. // set object classification
  61. Registry.ObjectType objectType = dataObjectInfo.getObjectType();
  62. AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
  63. AFPResourceLevel resourceLevel = resourceInfo.getLevel();
  64. final boolean dataInContainer = true;
  65. final boolean containerHasOEG = resourceLevel.isInline();
  66. final boolean dataInOCD = true;
  67. objectContainer.setObjectClassification(
  68. ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
  69. objectType, dataInContainer, containerHasOEG, dataInOCD);
  70. objectContainer.setData(dataObjectInfo.getData());
  71. return objectContainer;
  72. }
  73. /**
  74. * Creates and configures an IOCA Image Object.
  75. *
  76. * @param imageObjectInfo the image object info
  77. * @return a newly created IOCA Image Object
  78. */
  79. public ImageObject createImage(AFPImageObjectInfo imageObjectInfo) {
  80. // IOCA bitmap image
  81. ImageObject imageObj = factory.createImageObject();
  82. // set data object viewport (i.e. position, rotation, dimension, resolution)
  83. imageObj.setViewport(imageObjectInfo);
  84. if (imageObjectInfo.hasCompression()) {
  85. int compression = imageObjectInfo.getCompression();
  86. switch (compression) {
  87. case TIFFImage.COMP_FAX_G3_1D:
  88. imageObj.setEncoding(ImageContent.COMPID_G3_MH);
  89. break;
  90. case TIFFImage.COMP_FAX_G3_2D:
  91. imageObj.setEncoding(ImageContent.COMPID_G3_MR);
  92. break;
  93. case TIFFImage.COMP_FAX_G4_2D:
  94. imageObj.setEncoding(ImageContent.COMPID_G3_MMR);
  95. break;
  96. case ImageContent.COMPID_JPEG:
  97. imageObj.setEncoding((byte)compression);
  98. break;
  99. default:
  100. throw new IllegalStateException(
  101. "Invalid compression scheme: " + compression);
  102. }
  103. }
  104. ImageContent content = imageObj.getImageSegment().getImageContent();
  105. int bitsPerPixel = imageObjectInfo.getBitsPerPixel();
  106. imageObj.setIDESize((byte) bitsPerPixel);
  107. IDEStructureParameter ideStruct;
  108. switch (bitsPerPixel) {
  109. case 1:
  110. //Skip IDE Structure Parameter
  111. break;
  112. case 4:
  113. case 8:
  114. //A grayscale image
  115. ideStruct = content.needIDEStructureParameter();
  116. ideStruct.setBitsPerComponent(new int[] {bitsPerPixel});
  117. ideStruct.setColorModel(IDEStructureParameter.COLOR_MODEL_YCBCR);
  118. break;
  119. case 24:
  120. ideStruct = content.needIDEStructureParameter();
  121. ideStruct.setDefaultRGBColorModel();
  122. break;
  123. case 32:
  124. ideStruct = content.needIDEStructureParameter();
  125. ideStruct.setDefaultCMYKColorModel();
  126. break;
  127. default:
  128. throw new IllegalArgumentException("Unsupported number of bits per pixel: "
  129. + bitsPerPixel);
  130. }
  131. if (bitsPerPixel > 1 && imageObjectInfo.isSubtractive()) {
  132. ideStruct = content.needIDEStructureParameter();
  133. ideStruct.setSubtractive(imageObjectInfo.isSubtractive());
  134. }
  135. imageObj.setData(imageObjectInfo.getData());
  136. return imageObj;
  137. }
  138. /**
  139. * Creates and returns a new graphics object.
  140. *
  141. * @param graphicsObjectInfo the graphics object info
  142. * @return a new graphics object
  143. */
  144. public GraphicsObject createGraphic(AFPGraphicsObjectInfo graphicsObjectInfo) {
  145. // set newly created graphics object in g2d
  146. GraphicsObject graphicsObj = factory.createGraphicsObject();
  147. // set data object viewport (i.e. position, rotation, dimension, resolution)
  148. graphicsObj.setViewport(graphicsObjectInfo);
  149. AFPGraphics2D g2d = graphicsObjectInfo.getGraphics2D();
  150. g2d.setGraphicsObject(graphicsObj);
  151. //set color converter (i.e. an rgb to grayscale converter)
  152. graphicsObj.setColorConverter(g2d.getPaintingState().getColorConverter());
  153. // paint to graphics object
  154. Graphics2DImagePainter painter = graphicsObjectInfo.getPainter();
  155. Rectangle2D area = graphicsObjectInfo.getArea();
  156. g2d.scale(1, -1);
  157. g2d.translate(0, -area.getHeight());
  158. painter.paint(g2d, area);
  159. graphicsObj.setComplete(true);
  160. // return painted graphics object
  161. return graphicsObj;
  162. }
  163. /**
  164. * Creates and returns a new include object.
  165. *
  166. * @param includeName the include name
  167. * @param dataObjectInfo a data object info
  168. *
  169. * @return a new include object
  170. */
  171. public IncludeObject createInclude(String includeName, AFPDataObjectInfo dataObjectInfo) {
  172. IncludeObject includeObj = factory.createInclude(includeName);
  173. if (dataObjectInfo instanceof AFPImageObjectInfo) {
  174. // IOCA image object
  175. includeObj.setObjectType(IncludeObject.TYPE_IMAGE);
  176. } else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) {
  177. // graphics object
  178. includeObj.setObjectType(IncludeObject.TYPE_GRAPHIC);
  179. } else {
  180. // object container
  181. includeObj.setObjectType(IncludeObject.TYPE_OTHER);
  182. // set mandatory object classification (type other)
  183. Registry.ObjectType objectType = dataObjectInfo.getObjectType();
  184. if (objectType != null) {
  185. // set object classification
  186. final boolean dataInContainer = true;
  187. final boolean containerHasOEG = false; // environment parameters set in include
  188. final boolean dataInOCD = true;
  189. includeObj.setObjectClassification(
  190. // object scope not defined
  191. ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT,
  192. objectType, dataInContainer, containerHasOEG, dataInOCD);
  193. } else {
  194. throw new IllegalStateException(
  195. "Failed to set Object Classification Triplet on Object Container.");
  196. }
  197. }
  198. AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
  199. int xOffset = objectAreaInfo.getX();
  200. int yOffset = objectAreaInfo.getY();
  201. includeObj.setObjectAreaOffset(xOffset, yOffset);
  202. int width = objectAreaInfo.getWidth();
  203. int height = objectAreaInfo.getHeight();
  204. includeObj.setObjectAreaSize(width, height);
  205. int rotation = objectAreaInfo.getRotation();
  206. includeObj.setObjectAreaOrientation(rotation);
  207. int widthRes = objectAreaInfo.getWidthRes();
  208. int heightRes = objectAreaInfo.getHeightRes();
  209. includeObj.setMeasurementUnits(widthRes, heightRes);
  210. includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT);
  211. return includeObj;
  212. }
  213. /**
  214. * Creates a resource object wrapper for named includable data objects
  215. *
  216. * @param namedObj an named object
  217. * @param resourceInfo resource information
  218. * @param objectType the object type
  219. * @return a new resource object wrapper
  220. */
  221. public ResourceObject createResource(AbstractNamedAFPObject namedObj,
  222. AFPResourceInfo resourceInfo, Registry.ObjectType objectType) {
  223. ResourceObject resourceObj = null;
  224. String resourceName = resourceInfo.getName();
  225. if (resourceName != null) {
  226. resourceObj = factory.createResource(resourceName);
  227. } else {
  228. resourceObj = factory.createResource();
  229. }
  230. if (namedObj instanceof Document) {
  231. resourceObj.setType(ResourceObject.TYPE_DOCUMENT);
  232. } else if (namedObj instanceof PageSegment) {
  233. resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT);
  234. } else if (namedObj instanceof Overlay) {
  235. resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT);
  236. } else if (namedObj instanceof AbstractDataObject) {
  237. AbstractDataObject dataObj = (AbstractDataObject)namedObj;
  238. if (namedObj instanceof ObjectContainer) {
  239. resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER);
  240. // set object classification
  241. final boolean dataInContainer = true;
  242. final boolean containerHasOEG = false; // must be included
  243. final boolean dataInOCD = true;
  244. // mandatory triplet for object container
  245. resourceObj.setObjectClassification(
  246. ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
  247. objectType, dataInContainer, containerHasOEG, dataInOCD);
  248. } else if (namedObj instanceof ImageObject) {
  249. // ioca image type
  250. resourceObj.setType(ResourceObject.TYPE_IMAGE);
  251. } else if (namedObj instanceof GraphicsObject) {
  252. resourceObj.setType(ResourceObject.TYPE_GRAPHIC);
  253. } else {
  254. throw new UnsupportedOperationException(
  255. "Unsupported resource object for data object type " + dataObj);
  256. }
  257. } else {
  258. throw new UnsupportedOperationException(
  259. "Unsupported resource object type " + namedObj);
  260. }
  261. // set the resource information/classification on the data object
  262. resourceObj.setDataObject(namedObj);
  263. return resourceObj;
  264. }
  265. }