package com.revolsys.raster.io.format.pdf;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSNumber;
import org.apache.pdfbox.cos.COSObject;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.geometry.model.Point;
import com.revolsys.util.Property;
public class PdfUtil {
public static void addFloat(final COSArray array, final double number) {
try {
array.add(new COSFloat(String.valueOf(number)));
} catch (final IOException e) {
}
}
public static void addInt(final COSArray array, final long number) {
array.add(COSInteger.get(number));
}
public static COSArray findArray(final COSDictionary dictionary, final COSName key) {
final COSBase item = dictionary.getDictionaryObject(key);
if (item == null) {
return null;
} else if (item instanceof COSArray) {
return (COSArray)item;
} else {
throw new IllegalArgumentException("Expecting COSArray not " + item.getClass());
}
}
public static COSArray findArray(final COSDictionary dictionary, final String key) {
final COSBase item = dictionary.getDictionaryObject(key);
if (item == null) {
return null;
} else if (item instanceof COSArray) {
return (COSArray)item;
} else {
throw new IllegalArgumentException("Expecting COSArray not " + item.getClass());
}
}
public static Rectangle2D findRectangle(final COSDictionary dictionary, final COSName key) {
final COSArray bbox = PdfUtil.findArray(dictionary, key);
if (bbox == null) {
return null;
} else {
final float x1 = getFloat(bbox, 0);
final float y1 = getFloat(bbox, 1);
final float x2 = getFloat(bbox, 2);
final float y2 = getFloat(bbox, 3);
final float x = Math.min(x1, x2);
final float y = Math.min(y1, y2);
return new Rectangle2D.Float(x, y, Math.abs(x1 - x2), Math.abs(y1 - y2));
}
}
public static COSArray floatArray(final double... numbers) {
final COSArray array = new COSArray();
for (final double number : numbers) {
addFloat(array, number);
}
return array;
}
public static COSArray getArray(final COSDictionary dictionary, final String key) {
final COSBase item = dictionary.getDictionaryObject(key);
if (item == null) {
final COSArray array = new COSArray();
dictionary.setItem(key, array);
return array;
} else if (item instanceof COSArray) {
return (COSArray)item;
} else {
throw new IllegalArgumentException("Expecting COSArray not " + item.getClass());
}
}
public static COSDictionary getDictionary(final COSDictionary dictionary, final String key) {
final COSBase item = dictionary.getDictionaryObject(key);
if (item == null) {
final COSDictionary childDictionary = new COSDictionary();
dictionary.setItem(key, childDictionary);
return childDictionary;
} else if (item instanceof COSDictionary) {
return (COSDictionary)item;
} else {
throw new IllegalArgumentException("Expecting COSDictionary not " + item.getClass());
}
}
public static float getFloat(final COSArray array, final int index) {
final COSBase object = array.getObject(index);
if (object instanceof COSNumber) {
final COSNumber number = (COSNumber)object;
return number.floatValue();
} else {
return 0;
}
}
public static COSDictionary getPageViewport(final COSDictionary page) {
final COSArray viewports = PdfUtil.findArray(page, "VP");
if (viewports != null) {
for (COSBase item : viewports) {
if (item instanceof COSObject) {
final COSObject object = (COSObject)item;
item = object.getObject();
}
if (item instanceof COSDictionary) {
final COSDictionary viewport = (COSDictionary)item;
if (hasNameValue(viewport, "Type", "Viewport")) {
return viewport;
}
}
}
}
return null;
}
public static List<Point2D> getPoints(final COSDictionary dictionary, final String key) {
final COSArray array = PdfUtil.findArray(dictionary, key);
final List<Point2D> points = new ArrayList<>();
if (array != null) {
for (int i = 0; i < array.size(); i++) {
final float x = PdfUtil.getFloat(array, i++);
final float y = PdfUtil.getFloat(array, i);
final Point2D point = new Point2D.Double(x, y);
points.add(point);
}
}
return points;
}
public static BoundingBox getViewportBoundingBox(final COSDictionary viewport) {
if (hasNameValue(viewport, "Type", "Viewport")) {
final COSDictionary measure = PdfUtil.getDictionary(viewport, "Measure");
if (PdfUtil.hasNameValue(measure, "Type", "Measure")) {
if (PdfUtil.hasNameValue(measure, "Subtype", "GEO")) {
final COSDictionary gcs = PdfUtil.getDictionary(measure, "GCS");
if (gcs != null) {
GeometryFactory geometryFactory = GeometryFactory.DEFAULT_3D;
final int srid = gcs.getInt("EPSG");
if (srid == -1) {
final String wkt = gcs.getString("WKT");
if (Property.hasValue(wkt)) {
geometryFactory = GeometryFactory.getFactory(wkt);
}
} else {
geometryFactory = GeometryFactory.floating3(srid);
}
final GeometryFactory geoGeometryFactory = geometryFactory
.getGeographicGeometryFactory();
BoundingBox boundingBox = geometryFactory.newBoundingBoxEmpty();
final COSArray geoPoints = PdfUtil.findArray(measure, "GPTS");
for (int i = 0; i < geoPoints.size(); i++) {
final float lat = PdfUtil.getFloat(geoPoints, i++);
final float lon = PdfUtil.getFloat(geoPoints, i);
final Point geoPoint = geoGeometryFactory.point(lon, lat);
boundingBox = boundingBox.expandToInclude(geoPoint);
}
return boundingBox;
}
}
}
}
return BoundingBox.empty();
}
public static boolean hasNameValue(final COSDictionary dictionary, final String key,
final String value) {
final String name = dictionary.getNameAsString(key);
return value.equals(name);
}
public static COSArray intArray(final long... numbers) {
final COSArray array = new COSArray();
for (final long number : numbers) {
addInt(array, number);
}
return array;
}
}