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;
public class AFPDataObjectFactory {
private final Factory factory;
public AFPDataObjectFactory(Factory factory) {
this.factory = factory;
}
public ObjectContainer createObjectContainer(AFPDataObjectInfo dataObjectInfo) {
ObjectContainer objectContainer = factory.createObjectContainer();
objectContainer.setViewport(dataObjectInfo);
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;
}
public ImageObject createImage(AFPImageObjectInfo imageObjectInfo) {
ImageObject imageObj = factory.createImageObject();
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:
break;
case 4:
case 8:
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());
return imageObj;
}
public GraphicsObject createGraphic(AFPGraphicsObjectInfo graphicsObjectInfo) {
GraphicsObject graphicsObj = factory.createGraphicsObject();
graphicsObj.setViewport(graphicsObjectInfo);
AFPGraphics2D g2d = graphicsObjectInfo.getGraphics2D();
g2d.setGraphicsObject(graphicsObj);
graphicsObj.setColorConverter(g2d.getPaintingState().getColorConverter());
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 graphicsObj;
}
public IncludeObject createInclude(String includeName, AFPDataObjectInfo dataObjectInfo) {
IncludeObject includeObj = factory.createInclude(includeName);
if (dataObjectInfo instanceof AFPImageObjectInfo) {
includeObj.setObjectType(IncludeObject.TYPE_IMAGE);
} else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) {
includeObj.setObjectType(IncludeObject.TYPE_GRAPHIC);
} else {
includeObj.setObjectType(IncludeObject.TYPE_OTHER);
Registry.ObjectType objectType = dataObjectInfo.getObjectType();
if (objectType != null) {
final boolean dataInContainer = true;
final boolean containerHasOEG = false;
final boolean dataInOCD = true;
includeObj.setObjectClassification(
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;
}
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);
final boolean dataInContainer = true;
final boolean containerHasOEG = false;
final boolean dataInOCD = true;
resourceObj.setObjectClassification(
ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
objectType, dataInContainer, containerHasOEG, dataInOCD);
} else if (namedObj instanceof ImageObject) {
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);
}
resourceObj.setDataObject(namedObj);
return resourceObj;
}
}