| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.afp; |
| |
| import java.awt.geom.Rectangle2D; |
| |
| import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; |
| import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; |
| |
| import org.apache.fop.afp.ioca.IDEStructureParameter; |
| import org.apache.fop.afp.ioca.ImageContent; |
| import org.apache.fop.afp.modca.AbstractDataObject; |
| import org.apache.fop.afp.modca.AbstractNamedAFPObject; |
| import org.apache.fop.afp.modca.Document; |
| import org.apache.fop.afp.modca.GraphicsObject; |
| import org.apache.fop.afp.modca.ImageObject; |
| import org.apache.fop.afp.modca.IncludeObject; |
| import org.apache.fop.afp.modca.ObjectContainer; |
| import org.apache.fop.afp.modca.Overlay; |
| import org.apache.fop.afp.modca.PageSegment; |
| import org.apache.fop.afp.modca.Registry; |
| import org.apache.fop.afp.modca.ResourceObject; |
| import org.apache.fop.afp.modca.triplets.MappingOptionTriplet; |
| import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet; |
| |
| /** |
| * Factory for high level data objects (Image/Graphics etc) |
| */ |
| public class AFPDataObjectFactory { |
| |
| private final Factory factory; |
| |
| /** |
| * Main constructor |
| * |
| * @param factory an object factory |
| */ |
| public AFPDataObjectFactory(Factory factory) { |
| this.factory = factory; |
| } |
| |
| /** |
| * Creates and configures an ObjectContainer. |
| * |
| * @param dataObjectInfo the object container info |
| * @return a newly created Object Container |
| */ |
| public ObjectContainer createObjectContainer(AFPDataObjectInfo dataObjectInfo) { |
| ObjectContainer objectContainer = factory.createObjectContainer(); |
| |
| // set data object viewport (i.e. position, rotation, dimension, resolution) |
| objectContainer.setViewport(dataObjectInfo); |
| |
| // set object classification |
| Registry.ObjectType objectType = dataObjectInfo.getObjectType(); |
| AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); |
| AFPResourceLevel resourceLevel = resourceInfo.getLevel(); |
| final boolean dataInContainer = true; |
| final boolean containerHasOEG = resourceLevel.isInline(); |
| final boolean dataInOCD = true; |
| objectContainer.setObjectClassification( |
| ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, |
| objectType, dataInContainer, containerHasOEG, dataInOCD); |
| |
| objectContainer.setData(dataObjectInfo.getData()); |
| return objectContainer; |
| } |
| |
| /** |
| * Creates and configures an IOCA Image Object. |
| * |
| * @param imageObjectInfo the image object info |
| * @return a newly created IOCA Image Object |
| */ |
| public ImageObject createImage(AFPImageObjectInfo imageObjectInfo) { |
| // IOCA bitmap image |
| ImageObject imageObj = factory.createImageObject(); |
| |
| // set data object viewport (i.e. position, rotation, dimension, resolution) |
| imageObj.setViewport(imageObjectInfo); |
| |
| if (imageObjectInfo.hasCompression()) { |
| int compression = imageObjectInfo.getCompression(); |
| switch (compression) { |
| case TIFFImage.COMP_FAX_G3_1D: |
| imageObj.setEncoding(ImageContent.COMPID_G3_MH); |
| break; |
| case TIFFImage.COMP_FAX_G3_2D: |
| imageObj.setEncoding(ImageContent.COMPID_G3_MR); |
| break; |
| case TIFFImage.COMP_FAX_G4_2D: |
| imageObj.setEncoding(ImageContent.COMPID_G3_MMR); |
| break; |
| case ImageContent.COMPID_JPEG: |
| imageObj.setEncoding((byte)compression); |
| break; |
| default: |
| throw new IllegalStateException( |
| "Invalid compression scheme: " + compression); |
| } |
| } |
| |
| ImageContent content = imageObj.getImageSegment().getImageContent(); |
| int bitsPerPixel = imageObjectInfo.getBitsPerPixel(); |
| imageObj.setIDESize((byte) bitsPerPixel); |
| IDEStructureParameter ideStruct; |
| switch (bitsPerPixel) { |
| case 1: |
| //Skip IDE Structure Parameter |
| break; |
| case 4: |
| case 8: |
| //A grayscale image |
| ideStruct = content.needIDEStructureParameter(); |
| ideStruct.setBitsPerComponent(new int[] {bitsPerPixel}); |
| ideStruct.setColorModel(IDEStructureParameter.COLOR_MODEL_YCBCR); |
| break; |
| case 24: |
| ideStruct = content.needIDEStructureParameter(); |
| ideStruct.setDefaultRGBColorModel(); |
| break; |
| case 32: |
| ideStruct = content.needIDEStructureParameter(); |
| ideStruct.setDefaultCMYKColorModel(); |
| break; |
| default: |
| throw new IllegalArgumentException("Unsupported number of bits per pixel: " |
| + bitsPerPixel); |
| } |
| if (bitsPerPixel > 1 && imageObjectInfo.isSubtractive()) { |
| ideStruct = content.needIDEStructureParameter(); |
| ideStruct.setSubtractive(imageObjectInfo.isSubtractive()); |
| } |
| |
| imageObj.setData(imageObjectInfo.getData()); |
| imageObj.setTransparencyMask(imageObjectInfo.getTransparencyMask()); |
| |
| return imageObj; |
| } |
| |
| /** |
| * Creates and returns a new graphics object. |
| * |
| * @param graphicsObjectInfo the graphics object info |
| * @return a new graphics object |
| */ |
| public GraphicsObject createGraphic(AFPGraphicsObjectInfo graphicsObjectInfo) { |
| // set newly created graphics object in g2d |
| GraphicsObject graphicsObj = factory.createGraphicsObject(); |
| |
| // set data object viewport (i.e. position, rotation, dimension, resolution) |
| graphicsObj.setViewport(graphicsObjectInfo); |
| |
| AFPGraphics2D g2d = graphicsObjectInfo.getGraphics2D(); |
| g2d.setGraphicsObject(graphicsObj); |
| |
| //set color converter (i.e. an rgb to grayscale converter) |
| graphicsObj.setColorConverter(g2d.getPaintingState().getColorConverter()); |
| |
| // paint to graphics object |
| Graphics2DImagePainter painter = graphicsObjectInfo.getPainter(); |
| Rectangle2D area = graphicsObjectInfo.getArea(); |
| g2d.scale(1, -1); |
| g2d.translate(0, -area.getHeight()); |
| |
| painter.paint(g2d, area); |
| |
| graphicsObj.setComplete(true); |
| |
| // return painted graphics object |
| return graphicsObj; |
| } |
| |
| /** |
| * Creates and returns a new include object. |
| * |
| * @param includeName the include name |
| * @param dataObjectInfo a data object info |
| * |
| * @return a new include object |
| */ |
| public IncludeObject createInclude(String includeName, AFPDataObjectInfo dataObjectInfo) { |
| IncludeObject includeObj = factory.createInclude(includeName); |
| |
| if (dataObjectInfo instanceof AFPImageObjectInfo) { |
| // IOCA image object |
| includeObj.setObjectType(IncludeObject.TYPE_IMAGE); |
| } else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) { |
| // graphics object |
| includeObj.setObjectType(IncludeObject.TYPE_GRAPHIC); |
| } else { |
| // object container |
| includeObj.setObjectType(IncludeObject.TYPE_OTHER); |
| |
| // set mandatory object classification (type other) |
| Registry.ObjectType objectType = dataObjectInfo.getObjectType(); |
| if (objectType != null) { |
| // set object classification |
| final boolean dataInContainer = true; |
| final boolean containerHasOEG = false; // environment parameters set in include |
| final boolean dataInOCD = true; |
| includeObj.setObjectClassification( |
| // object scope not defined |
| ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT, |
| objectType, dataInContainer, containerHasOEG, dataInOCD); |
| } else { |
| throw new IllegalStateException( |
| "Failed to set Object Classification Triplet on Object Container."); |
| } |
| } |
| |
| AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); |
| |
| int xOffset = objectAreaInfo.getX(); |
| int yOffset = objectAreaInfo.getY(); |
| includeObj.setObjectAreaOffset(xOffset, yOffset); |
| |
| int width = objectAreaInfo.getWidth(); |
| int height = objectAreaInfo.getHeight(); |
| includeObj.setObjectAreaSize(width, height); |
| |
| int rotation = objectAreaInfo.getRotation(); |
| includeObj.setObjectAreaOrientation(rotation); |
| |
| int widthRes = objectAreaInfo.getWidthRes(); |
| int heightRes = objectAreaInfo.getHeightRes(); |
| includeObj.setMeasurementUnits(widthRes, heightRes); |
| |
| includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT); |
| |
| return includeObj; |
| } |
| |
| /** |
| * Creates a resource object wrapper for named includable data objects |
| * |
| * @param namedObj an named object |
| * @param resourceInfo resource information |
| * @param objectType the object type |
| * @return a new resource object wrapper |
| */ |
| public ResourceObject createResource(AbstractNamedAFPObject namedObj, |
| AFPResourceInfo resourceInfo, Registry.ObjectType objectType) { |
| ResourceObject resourceObj = null; |
| String resourceName = resourceInfo.getName(); |
| if (resourceName != null) { |
| resourceObj = factory.createResource(resourceName); |
| } else { |
| resourceObj = factory.createResource(); |
| } |
| |
| if (namedObj instanceof Document) { |
| resourceObj.setType(ResourceObject.TYPE_DOCUMENT); |
| } else if (namedObj instanceof PageSegment) { |
| resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT); |
| } else if (namedObj instanceof Overlay) { |
| resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT); |
| } else if (namedObj instanceof AbstractDataObject) { |
| AbstractDataObject dataObj = (AbstractDataObject)namedObj; |
| if (namedObj instanceof ObjectContainer) { |
| resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER); |
| |
| // set object classification |
| final boolean dataInContainer = true; |
| final boolean containerHasOEG = false; // must be included |
| final boolean dataInOCD = true; |
| // mandatory triplet for object container |
| resourceObj.setObjectClassification( |
| ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, |
| objectType, dataInContainer, containerHasOEG, dataInOCD); |
| } else if (namedObj instanceof ImageObject) { |
| // ioca image type |
| resourceObj.setType(ResourceObject.TYPE_IMAGE); |
| } else if (namedObj instanceof GraphicsObject) { |
| resourceObj.setType(ResourceObject.TYPE_GRAPHIC); |
| } else { |
| throw new UnsupportedOperationException( |
| "Unsupported resource object for data object type " + dataObj); |
| } |
| } else { |
| throw new UnsupportedOperationException( |
| "Unsupported resource object type " + namedObj); |
| } |
| |
| // set the resource information/classification on the data object |
| resourceObj.setDataObject(namedObj); |
| return resourceObj; |
| } |
| |
| } |