package com.tom_roush.pdfbox.pdmodel.graphics.state;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import com.tom_roush.pdfbox.pdmodel.common.PDRectangle;
import com.tom_roush.pdfbox.pdmodel.graphics.PDLineDashPattern;
import com.tom_roush.pdfbox.pdmodel.graphics.blend.BlendMode;
import com.tom_roush.pdfbox.pdmodel.graphics.color.PDColor;
import com.tom_roush.pdfbox.pdmodel.graphics.color.PDColorSpace;
import com.tom_roush.pdfbox.pdmodel.graphics.color.PDDeviceGray;
import com.tom_roush.pdfbox.util.Matrix;
/**
* The current state of the graphics parameters when executing a content stream.
*
* @author Ben Litchfield
*/
public class PDGraphicsState implements Cloneable
{
private boolean isClippingPathDirty;
private Region clippingPath;
private Matrix currentTransformationMatrix = new Matrix();
private PDColor strokingColor = PDDeviceGray.INSTANCE.getInitialColor();
private PDColor nonStrokingColor = PDDeviceGray.INSTANCE.getInitialColor();
private PDColorSpace strokingColorSpace = PDDeviceGray.INSTANCE;
private PDColorSpace nonStrokingColorSpace = PDDeviceGray.INSTANCE;
private PDTextState textState = new PDTextState();
private float lineWidth = 1;
private Paint.Cap lineCap = Paint.Cap.BUTT;
private Paint.Join lineJoin = Paint.Join.MITER;
private float miterLimit = 10;
private PDLineDashPattern lineDashPattern = new PDLineDashPattern();
private RenderingIntent renderingIntent;
private boolean strokeAdjustment = false;
private BlendMode blendMode = BlendMode.COMPATIBLE;
private PDSoftMask softMask;
private double alphaConstant = 1.0;
private double nonStrokingAlphaConstant = 1.0;
private boolean alphaSource = false;
// DEVICE-DEPENDENT parameters
private boolean overprint = false;
private double overprintMode = 0;
//black generation
//undercolor removal
//transfer
//halftone
private double flatness = 1.0;
private double smoothness = 0;
/**
* Constructor with a given page size to initialize the clipping path.
* @param page the size of the page
*/
public PDGraphicsState(PDRectangle page)
{
// clippingPath = new Area(new GeneralPath(page.toGeneralPath()));TODO: PdfBox-Android
RectF bounds = new RectF();
page.toGeneralPath().computeBounds(bounds, true);
clippingPath = new Region();
Rect boundsRounded = new Rect();
bounds.round(boundsRounded);
clippingPath.setPath(page.toGeneralPath(), new Region(boundsRounded));
}
/**
* Get the value of the CTM.
*
* @return The current transformation matrix.
*/
public Matrix getCurrentTransformationMatrix()
{
return currentTransformationMatrix;
}
/**
* Set the value of the CTM.
*
* @param value The current transformation matrix.
*/
public void setCurrentTransformationMatrix(Matrix value)
{
currentTransformationMatrix = value;
}
/**
* Get the value of the line width.
*
* @return The current line width.
*/
public float getLineWidth()
{
return lineWidth;
}
/**
* set the value of the line width.
*
* @param value The current line width.
*/
public void setLineWidth(float value)
{
lineWidth = value;
}
/**
* Get the value of the line cap.
*
* @return The current line cap.
*/
public Paint.Cap getLineCap()
{
return lineCap;
}
/**
* set the value of the line cap.
*
* @param value The current line cap.
*/
public void setLineCap(Paint.Cap value)
{
lineCap = value;
}
/**
* Get the value of the line join.
*
* @return The current line join value.
*/
public Paint.Join getLineJoin()
{
return lineJoin;
}
/**
* Get the value of the line join.
*
* @param value The current line join
*/
public void setLineJoin(Paint.Join value)
{
lineJoin = value;
}
/**
* Get the value of the miter limit.
*
* @return The current miter limit.
*/
public float getMiterLimit()
{
return miterLimit;
}
/**
* set the value of the miter limit.
*
* @param value The current miter limit.
*/
public void setMiterLimit(float value)
{
miterLimit = value;
}
/**
* Get the value of the stroke adjustment parameter.
*
* @return The current stroke adjustment.
*/
public boolean isStrokeAdjustment()
{
return strokeAdjustment;
}
/**
* set the value of the stroke adjustment.
*
* @param value The value of the stroke adjustment parameter.
*/
public void setStrokeAdjustment(boolean value)
{
strokeAdjustment = value;
}
/**
* Get the value of the stroke alpha constants property.
*
* @return The value of the stroke alpha constants parameter.
*/
public double getAlphaConstant()
{
return alphaConstant;
}
/**
* set the value of the stroke alpha constants property.
*
* @param value The value of the stroke alpha constants parameter.
*/
public void setAlphaConstant(double value)
{
alphaConstant = value;
}
/**
* Get the value of the non-stroke alpha constants property.
*
* @return The value of the non-stroke alpha constants parameter.
*/
public double getNonStrokeAlphaConstant()
{
return nonStrokingAlphaConstant;
}
/**
* set the value of the non-stroke alpha constants property.
*
* @param value The value of the non-stroke alpha constants parameter.
*/
public void setNonStrokeAlphaConstant(double value)
{
nonStrokingAlphaConstant = value;
}
/**
* get the value of the stroke alpha source property.
*
* @return The value of the stroke alpha source parameter.
*/
public boolean isAlphaSource()
{
return alphaSource;
}
/**
* set the value of the alpha source property.
*
* @param value The value of the alpha source parameter.
*/
public void setAlphaSource(boolean value)
{
alphaSource = value;
}
/**
* returns the current softmask
*
* @return softMask
*/
public PDSoftMask getSoftMask()
{
return softMask;
}
/**
* Sets the current soft mask
*
* @param softMask
*/
public void setSoftMask(PDSoftMask softMask)
{
this.softMask = softMask;
}
/**
* Returns the current blend mode
*
* @return the current blend mode
*/
public BlendMode getBlendMode()
{
return blendMode;
}
/**
* Sets the blend mode in the current graphics state
*
* @param blendMode
*/
public void setBlendMode(BlendMode blendMode)
{
this.blendMode = blendMode;
}
/**
/**
* get the value of the overprint property.
*
* @return The value of the overprint parameter.
*/
public boolean isOverprint()
{
return overprint;
}
/**
* set the value of the overprint property.
*
* @param value The value of the overprint parameter.
*/
public void setOverprint(boolean value)
{
overprint = value;
}
/**
* get the value of the overprint mode property.
*
* @return The value of the overprint mode parameter.
*/
public double getOverprintMode()
{
return overprintMode;
}
/**
* set the value of the overprint mode property.
*
* @param value The value of the overprint mode parameter.
*/
public void setOverprintMode(double value)
{
overprintMode = value;
}
/**
* get the value of the flatness property.
*
* @return The value of the flatness parameter.
*/
public double getFlatness()
{
return flatness;
}
/**
* set the value of the flatness property.
*
* @param value The value of the flatness parameter.
*/
public void setFlatness(double value)
{
flatness = value;
}
/**
* get the value of the smoothness property.
*
* @return The value of the smoothness parameter.
*/
public double getSmoothness()
{
return smoothness;
}
/**
* set the value of the smoothness property.
*
* @param value The value of the smoothness parameter.
*/
public void setSmoothness(double value)
{
smoothness = value;
}
/**
* This will get the graphics text state.
*
* @return The graphics text state.
*/
public PDTextState getTextState()
{
return textState;
}
/**
* This will set the graphics text state.
*
* @param value The graphics text state.
*/
public void setTextState(PDTextState value)
{
textState = value;
}
/**
* This will get the current line dash pattern.
*
* @return The line dash pattern.
*/
public PDLineDashPattern getLineDashPattern()
{
return lineDashPattern;
}
/**
* This will set the current line dash pattern.
*
* @param value The new line dash pattern.
*/
public void setLineDashPattern(PDLineDashPattern value)
{
lineDashPattern = value;
}
/**
* This will get the rendering intent.
*
* @see com.tom_roush.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState
*
* @return The rendering intent
*/
public RenderingIntent getRenderingIntent()
{
return renderingIntent;
}
/**
* This will set the rendering intent.
*
* @param value The new rendering intent.
*/
public void setRenderingIntent(RenderingIntent value)
{
renderingIntent = value;
}
@Override
public PDGraphicsState clone()
{
try
{
PDGraphicsState clone = (PDGraphicsState)super.clone();
clone.textState = textState.clone();
clone.currentTransformationMatrix = currentTransformationMatrix.clone();
clone.strokingColor = strokingColor; // immutable
clone.nonStrokingColor = nonStrokingColor; // immutable
clone.lineDashPattern = lineDashPattern; // immutable
clone.clippingPath = clippingPath; // not cloned, see intersectClippingPath
clone.isClippingPathDirty = false;
return clone;
}
catch (CloneNotSupportedException e)
{
// should not happen
throw new RuntimeException(e);
}
}
/**
* Returns the stroking color.
*
* @return stroking color
*/
public PDColor getStrokingColor()
{
return strokingColor;
}
/**
* Sets the stroking color.
*
* @param color The new stroking color
*/
public void setStrokingColor(PDColor color)
{
strokingColor = color;
}
/**
* Returns the non-stroking color.
*
* @return The non-stroking color
*/
public PDColor getNonStrokingColor()
{
return nonStrokingColor;
}
/**
* Sets the non-stroking color.
*
* @param color The new non-stroking color
*/
public void setNonStrokingColor(PDColor color)
{
nonStrokingColor = color;
}
/**
* Returns the stroking color space.
*
* @return The stroking color space.
*/
public PDColorSpace getStrokingColorSpace()
{
return strokingColorSpace;
}
/**
* Sets the the stroking color space.
*
* @param colorSpace The new stroking color space.
*/
public void setStrokingColorSpace(PDColorSpace colorSpace)
{
strokingColorSpace = colorSpace;
}
/**
* Returns the non-stroking color space.
*
* @return The non-stroking color space.
*/
public PDColorSpace getNonStrokingColorSpace()
{
return nonStrokingColorSpace;
}
/**
* Sets the the non-stroking color space.
*
* @param colorSpace The new non-stroking color space.
*/
public void setNonStrokingColorSpace(PDColorSpace colorSpace)
{
nonStrokingColorSpace = colorSpace;
}
/**
* Modify the current clipping path by intersecting it with the given path.
* @param path path to intersect with the clipping path
*/
public void intersectClippingPath(Path path)
{
RectF bounds = new RectF();
path.computeBounds(bounds, true);
Region r = new Region();
Rect boundsRounded = new Rect();
bounds.round(boundsRounded);
r.setPath(path, new Region(boundsRounded));
intersectClippingPath(r);
}
/**
* Modify the current clipping path by intersecting it with the given path.
* @param area area to intersect with the clipping path
*/
public void intersectClippingPath(Region area)
{
// lazy cloning of clipping path for performance
if (!isClippingPathDirty)
{
// deep copy (can't use clone() as it performs only a shallow copy)
Region cloned = new Region(area);
// cloned.add(clippingPath);
clippingPath = cloned;
isClippingPathDirty = true;
}
// intersection as usual
clippingPath.op(area, Region.Op.INTERSECT);
}
/**
* This will get the current clipping path. Do not modify this Area object!
*
* @return The current clipping path.
*/
public Region getCurrentClippingPath()
{
return clippingPath;
}
// public Composite getStrokingJavaComposite()
// {
// return BlendComposite.getInstance(blendMode, (float) alphaConstants);
// }TODO: PdfBox-Android
// public Composite getNonStrokingJavaComposite()
// {
// return BlendComposite.getInstance(blendMode, (float) nonStrokingAlphaConstants);
// }TODO: PdfBox-Android
}