📄 pdfcontentbyte.java
字号:
/*
* $Id: PdfContentByte.java,v 1.14 2001/12/10 13:53:21 blowagie Exp $
* $Name: $
*
* Copyright 1999, 2000, 2001 by Bruno Lowagie.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*
* You should have received a copy of the GNU Library General Public License along
* with this library; if not, write to the Free Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* http://www.lowagie.com/iText/
*
* ir-arch Bruno Lowagie,
* Adolf Baeyensstraat 121
* 9040 Sint-Amandsberg
* BELGIUM
* tel. +32 (0)9 228.10.97
* bruno@lowagie.com
*
*/
package com.lowagie.text.pdf;
import java.awt.Color;
import com.lowagie.text.Image;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import java.io.UnsupportedEncodingException;
import com.lowagie.text.Image;
import java.util.ArrayList;
/**
* <CODE>PdfContentByte</CODE> is an object containing the user positioned
* text and graphic contents of a page. It knows how to apply the proper
* font encoding.
*/
public class PdfContentByte {
/**
* This class keeps the graphic state of the current page
*/
class GraphicState {
/** This is the font in use */
FontDetails fontDetails;
/** This is the font size in use */
float size;
/** The x position of the text line matrix. */
protected float xTLM = 0;
/** The y position of the text line matrix. */
protected float yTLM = 0;
/** The current text leading. */
protected float leading = 0;
}
/** The alignement is center */
public static final int ALIGN_CENTER = 0;
/** The alignement is left */
public static final int ALIGN_LEFT = 1;
/** The alignement is right */
public static final int ALIGN_RIGHT = 2;
// membervariables
/** This is the actual content */
protected ByteBuffer content = new ByteBuffer();
/** This is the writer */
protected PdfWriter writer;
/** This is the PdfDocument */
protected PdfDocument pdf;
/** This is the GraphicState in use */
protected GraphicState state = new GraphicState();
/** The list were we save/restore the state */
protected ArrayList stateList = new ArrayList();
// constructors
/**
* Constructs a new <CODE>PdfContentByte</CODE>-object.
*
* @param wr the writer associated to this content
*/
public PdfContentByte(PdfWriter wr)
{
if (wr != null) {
writer = wr;
pdf = writer.getPdfDocument();
}
}
// methods to get the content of this object
/**
* Returns the <CODE>String</CODE> representation of this <CODE>PdfContentByte</CODE>-object.
*
* @return a <CODE>String</CODE>
*/
public String toString() {
return content.toString();
}
/**
* Gets the internal buffer.
* @return the internal buffer
*/
ByteBuffer getInternalBuffer() {
return content;
}
/**
* Returns the PDF representation of this <CODE>PdfContentByte</CODE>-object.
*
* @param crypto the encryption data
* @return a <CODE>String</CODE>
*/
public byte[] toPdf(PdfEncryption crypto) {
return content.toByteArray();
}
// methods to add graphical content
/**
* Adds the content of another <CODE>PdfContent</CODE>-object to this object.
*
* @param other another <CODE>PdfByteContent</CODE>-object
*/
public final void add(PdfContentByte other) {
content.append(other.content);
}
/**
* Gets the x position of the text line matrix.
*
* @return the x position of the text line matrix
*/
public float getXTLM()
{
return state.xTLM;
}
/**
* Gets the y position of the text line matrix.
*
* @return the y position of the text line matrix
*/
public float getYTLM()
{
return state.yTLM;
}
/**
* Gets the current text leading.
*
* @return the current text leading
*/
public float getLeading()
{
return state.leading;
}
/**
* Changes the <VAR>Flatness</VAR>.
* <P>
* <VAR>Flatness</VAR> sets the maximum permitted distance in device pixels between the
* mathematically correct path and an approximation constructed from straight line segments.<BR>
*
* @param flatness a value
*/
public final void setFlatness(float flatness) {
if (flatness >= 0 && flatness <= 100) {
content.append(flatness).append(" i\n");
}
}
/**
* Changes the <VAR>Line cap style</VAR>.
* <P>
* The <VAR>line cap style</VAR> specifies the shape to be used at the end of open subpaths
* when they are stroked.<BR>
* Allowed values are 0 (Butt end caps), 1 (Round end caps) and 2 (Projecting square end caps).<BR>
*
* @param style a value
*/
public final void setLineCap(int style) {
if (style >= 0 && style <= 2) {
content.append(style).append(" J\n");
}
}
/**
* Changes the value of the <VAR>line dash pattern</VAR>.
* <P>
* The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
* It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
* of the alternating dashes and gaps. The phase specifies the distance into the dash
* pattern to start the dash.<BR>
*
* @param phase the value of the phase
*/
public final void setLineDash(float phase) {
content.append("[] ").append(phase).append(" d\n");
}
/**
* Changes the value of the <VAR>line dash pattern</VAR>.
* <P>
* The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
* It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
* of the alternating dashes and gaps. The phase specifies the distance into the dash
* pattern to start the dash.<BR>
*
* @param phase the value of the phase
* @param unitsOn the number of units that must be 'on' (equals the number of units that must be 'off').
*/
public final void setLineDash(float unitsOn, float phase) {
content.append("[").append(unitsOn).append("] ").append(phase).append(" d\n");
}
/**
* Changes the value of the <VAR>line dash pattern</VAR>.
* <P>
* The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
* It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
* of the alternating dashes and gaps. The phase specifies the distance into the dash
* pattern to start the dash.<BR>
*
* @param phase the value of the phase
* @param unitsOn the number of units that must be 'on'
* @param unitsOff the number of units that must be 'off'
*/
public final void setLineDash(float unitsOn, float unitsOff, float phase) {
content.append("[").append(unitsOn).append(' ').append(unitsOff).append("] ").append(phase).append(" d\n");
}
/**
* Changes the <VAR>Line join style</VAR>.
* <P>
* The <VAR>line join style</VAR> specifies the shape to be used at the corners of paths
* that are stroked.<BR>
* Allowed values are 0 (Miter joins), 1 (Round joins) and 2 (Bevel joins).<BR>
*
* @param style a value
*/
public final void setLineJoin(int style) {
if (style >= 0 && style <= 2) {
content.append(style).append(" j\n");
}
}
/**
* Changes the <VAR>line width</VAR>.
* <P>
* The line width specifies the thickness of the line used to stroke a path and is measured
* in used space units.<BR>
*
* @param w a width
*/
public final void setLineWidth(float w) {
content.append(w).append(" w\n");
}
/**
* Changes the <VAR>Miter limit</VAR>.
* <P>
* When two line segments meet at a sharp angle and mitered joins have been specified as the
* line join style, it is possible for the miter to extend far beyond the thickness of the line
* stroking path. The miter limit imposes a maximum on the ratio of the miter length to the line
* witdh. When the limit is exceeded, the join is converted from a miter to a bevel.<BR>
*
* @param miterLimit a miter limit
*/
public final void setMiterLimit(float miterLimit) {
if (miterLimit > 1) {
content.append(miterLimit).append(" M\n");
}
}
/**
* Modify the current clipping path by intersecting it with the current path, using the
* nonzero winding number rule to determine which regions lie inside the clipping
* path.
*/
public final void clip() {
content.append("W\n");
}
/**
* Modify the current clipping path by intersecting it with the current path, using the
* even-odd rule to determine which regions lie inside the clipping path.
*/
public final void eoClip() {
content.append("W*\n");
}
/**
* Changes the currentgray tint for filling paths (device dependent colors!).
* <P>
* Sets the color space to <B>DeviceGray</B> (or the <B>DefaultGray</B> color space),
* and sets the gray tint to use for filling paths.</P>
*
* @param gray a value between 0 (black) and 1 (white)
*/
public final void setGrayFill(float gray) {
content.append(gray).append(" g\n");
}
/**
* Changes the current gray tint for filling paths to black.
*/
public final void resetGrayFill() {
content.append("0 g\n");
}
/**
* Changes the currentgray tint for stroking paths (device dependent colors!).
* <P>
* Sets the color space to <B>DeviceGray</B> (or the <B>DefaultGray</B> color space),
* and sets the gray tint to use for stroking paths.</P>
*
* @param gray a value between 0 (black) and 1 (white)
*/
public final void setGrayStroke(float gray) {
content.append(gray).append(" G\n");
}
/**
* Changes the current gray tint for stroking paths to black.
*/
public final void resetGrayStroke() {
content.append("0 G\n");
}
/**
* Helper to validate and write the RGB color components
* @param red the intensity of red. A value between 0 and 1
* @param green the intensity of green. A value between 0 and 1
* @param blue the intensity of blue. A value between 0 and 1
*/
private void HelperRGB(float red, float green, float blue) {
if (red < 0)
red = 0.0f;
else if (red > 1.0f)
red = 1.0f;
if (green < 0)
green = 0.0f;
else if (green > 1.0f)
green = 1.0f;
if (blue < 0)
blue = 0.0f;
else if (blue > 1.0f)
blue = 1.0f;
content.append(red).append(' ').append(green).append(' ').append(blue);
}
/**
* Changes the current color for filling paths (device dependent colors!).
* <P>
* Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
* and sets the color to use for filling paths.</P>
* <P>
* Following the PDF manual, each operand must be a number between 0 (minimum intensity) and
* 1 (maximum intensity).</P>
*
* @param red the intensity of red. A value between 0 and 1
* @param green the intensity of green. A value between 0 and 1
* @param blue the intensity of blue. A value between 0 and 1
*/
public final void setRGBColorFillF(float red, float green, float blue) {
HelperRGB(red, green, blue);
content.append(" rg\n");
}
/**
* Changes the current color for filling paths to black.
*/
public final void resetRGBColorFill() {
content.append("0 0 0 rg\n");
}
/**
* Changes the current color for stroking paths (device dependent colors!).
* <P>
* Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
* and sets the color to use for stroking paths.</P>
* <P>
* Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and
* 1 (maximum intensity).
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -