|
|
@ -50,6 +50,7 @@ |
|
|
|
package com.fr.third.v2.lowagie.text.pdf; |
|
|
|
package com.fr.third.v2.lowagie.text.pdf; |
|
|
|
|
|
|
|
|
|
|
|
import java.awt.Color; |
|
|
|
import java.awt.Color; |
|
|
|
|
|
|
|
import java.awt.FontMetrics; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Iterator; |
|
|
|
import java.util.Iterator; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
@ -59,6 +60,7 @@ import com.fr.third.v2.lowagie.text.Utilities; |
|
|
|
import com.fr.third.v2.lowagie.text.Chunk; |
|
|
|
import com.fr.third.v2.lowagie.text.Chunk; |
|
|
|
import com.fr.third.v2.lowagie.text.Font; |
|
|
|
import com.fr.third.v2.lowagie.text.Font; |
|
|
|
import com.fr.third.v2.lowagie.text.Image; |
|
|
|
import com.fr.third.v2.lowagie.text.Image; |
|
|
|
|
|
|
|
import sun.font.FontDesignMetrics; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A <CODE>PdfChunk</CODE> is the PDF translation of a <CODE>Chunk</CODE>. |
|
|
|
* A <CODE>PdfChunk</CODE> is the PDF translation of a <CODE>Chunk</CODE>. |
|
|
@ -125,7 +127,13 @@ public class PdfChunk { |
|
|
|
/** The font for this <CODE>PdfChunk</CODE>. */ |
|
|
|
/** The font for this <CODE>PdfChunk</CODE>. */ |
|
|
|
protected PdfFont font; |
|
|
|
protected PdfFont font; |
|
|
|
|
|
|
|
|
|
|
|
protected BaseFont baseFont; |
|
|
|
public PdfFont getFont() { |
|
|
|
|
|
|
|
return font; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setFont(PdfFont font) { |
|
|
|
|
|
|
|
this.font = font; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected SplitCharacter splitCharacter; |
|
|
|
protected SplitCharacter splitCharacter; |
|
|
|
/** |
|
|
|
/** |
|
|
@ -174,7 +182,6 @@ public class PdfChunk { |
|
|
|
this.font = other.font; |
|
|
|
this.font = other.font; |
|
|
|
this.attributes = other.attributes; |
|
|
|
this.attributes = other.attributes; |
|
|
|
this.noStroke = other.noStroke; |
|
|
|
this.noStroke = other.noStroke; |
|
|
|
this.baseFont = other.baseFont; |
|
|
|
|
|
|
|
Object obj[] = (Object[])attributes.get(Chunk.IMAGE); |
|
|
|
Object obj[] = (Object[])attributes.get(Chunk.IMAGE); |
|
|
|
if (obj == null) |
|
|
|
if (obj == null) |
|
|
|
image = null; |
|
|
|
image = null; |
|
|
@ -184,7 +191,6 @@ public class PdfChunk { |
|
|
|
offsetY = ((Float)obj[2]).floatValue(); |
|
|
|
offsetY = ((Float)obj[2]).floatValue(); |
|
|
|
changeLeading = ((Boolean)obj[3]).booleanValue(); |
|
|
|
changeLeading = ((Boolean)obj[3]).booleanValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
encoding = font.getFont().getEncoding(); |
|
|
|
|
|
|
|
splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); |
|
|
|
splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); |
|
|
|
if (splitCharacter == null) |
|
|
|
if (splitCharacter == null) |
|
|
|
splitCharacter = DefaultSplitCharacter.DEFAULT; |
|
|
|
splitCharacter = DefaultSplitCharacter.DEFAULT; |
|
|
@ -206,28 +212,20 @@ public class PdfChunk { |
|
|
|
float size = f.getSize(); |
|
|
|
float size = f.getSize(); |
|
|
|
if (size == Font.UNDEFINED) |
|
|
|
if (size == Font.UNDEFINED) |
|
|
|
size = 12; |
|
|
|
size = 12; |
|
|
|
baseFont = f.getBaseFont(); |
|
|
|
|
|
|
|
int style = f.getStyle(); |
|
|
|
int style = f.getStyle(); |
|
|
|
if (style == Font.UNDEFINED) { |
|
|
|
if (style == Font.UNDEFINED) { |
|
|
|
style = Font.NORMAL; |
|
|
|
style = Font.NORMAL; |
|
|
|
} |
|
|
|
} |
|
|
|
if (baseFont == null) { |
|
|
|
|
|
|
|
// translation of the font-family to a PDF font-family
|
|
|
|
|
|
|
|
baseFont = f.getCalculatedBaseFont(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// bold simulation
|
|
|
|
// bold simulation
|
|
|
|
if ((style & Font.BOLD) != 0) |
|
|
|
if ((style & Font.BOLD) != 0) |
|
|
|
attributes.put(Chunk.TEXTRENDERMODE, new Object[]{new Integer(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), new Float(size / 30f), null}); |
|
|
|
attributes.put(Chunk.TEXTRENDERMODE, new Object[]{new Integer(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), new Float(size / 30f), null}); |
|
|
|
// italic simulation
|
|
|
|
// italic simulation
|
|
|
|
if ((style & Font.ITALIC) != 0) |
|
|
|
if ((style & Font.ITALIC) != 0) |
|
|
|
attributes.put(Chunk.SKEW, new float[]{0, ITALIC_ANGLE}); |
|
|
|
attributes.put(Chunk.SKEW, new float[]{0, ITALIC_ANGLE}); |
|
|
|
} |
|
|
|
FontMetrics metrics = FontDesignMetrics.getMetrics(new java.awt.Font(f.getFontName(), f.getStyle(), (int)f.getSize())); |
|
|
|
font = new PdfFont(baseFont, size); |
|
|
|
font = new PdfFont(f, f.getSize()); |
|
|
|
float fontSize = font.size(); |
|
|
|
height = metrics.getHeight(); |
|
|
|
float ascender = font.getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); |
|
|
|
|
|
|
|
float descender = font.getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); |
|
|
|
|
|
|
|
height = ascender - descender; |
|
|
|
|
|
|
|
// other style possibilities
|
|
|
|
// other style possibilities
|
|
|
|
HashMap attr = chunk.getAttributes(); |
|
|
|
HashMap attr = chunk.getAttributes(); |
|
|
|
if (attr != null) { |
|
|
|
if (attr != null) { |
|
|
@ -259,7 +257,7 @@ public class PdfChunk { |
|
|
|
attributes.put(Chunk.ACTION, action); |
|
|
|
attributes.put(Chunk.ACTION, action); |
|
|
|
// the color can't be stored in a PdfFont
|
|
|
|
// the color can't be stored in a PdfFont
|
|
|
|
noStroke.put(Chunk.COLOR, f.getColor()); |
|
|
|
noStroke.put(Chunk.COLOR, f.getColor()); |
|
|
|
noStroke.put(Chunk.ENCODING, font.getFont().getEncoding()); |
|
|
|
// noStroke.put(Chunk.ENCODING, font.getFont().getEncoding());
|
|
|
|
Object obj[] = (Object[])attributes.get(Chunk.IMAGE); |
|
|
|
Object obj[] = (Object[])attributes.get(Chunk.IMAGE); |
|
|
|
if (obj == null) { |
|
|
|
if (obj == null) { |
|
|
|
image = null; |
|
|
|
image = null; |
|
|
@ -267,6 +265,7 @@ public class PdfChunk { |
|
|
|
else { |
|
|
|
else { |
|
|
|
attributes.remove(Chunk.HSCALE); // images are scaled in other ways
|
|
|
|
attributes.remove(Chunk.HSCALE); // images are scaled in other ways
|
|
|
|
image = (Image)obj[0]; |
|
|
|
image = (Image)obj[0]; |
|
|
|
|
|
|
|
this.height = image.getHeight(); |
|
|
|
offsetX = ((Float)obj[1]).floatValue(); |
|
|
|
offsetX = ((Float)obj[1]).floatValue(); |
|
|
|
offsetY = ((Float)obj[2]).floatValue(); |
|
|
|
offsetY = ((Float)obj[2]).floatValue(); |
|
|
|
changeLeading = ((Boolean)obj[3]).booleanValue(); |
|
|
|
changeLeading = ((Boolean)obj[3]).booleanValue(); |
|
|
@ -275,7 +274,6 @@ public class PdfChunk { |
|
|
|
Float hs = (Float)attributes.get(Chunk.HSCALE); |
|
|
|
Float hs = (Float)attributes.get(Chunk.HSCALE); |
|
|
|
if (hs != null) |
|
|
|
if (hs != null) |
|
|
|
font.setHorizontalScaling(hs.floatValue()); |
|
|
|
font.setHorizontalScaling(hs.floatValue()); |
|
|
|
encoding = font.getFont().getEncoding(); |
|
|
|
|
|
|
|
splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); |
|
|
|
splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); |
|
|
|
if (splitCharacter == null) |
|
|
|
if (splitCharacter == null) |
|
|
|
splitCharacter = DefaultSplitCharacter.DEFAULT; |
|
|
|
splitCharacter = DefaultSplitCharacter.DEFAULT; |
|
|
@ -290,7 +288,7 @@ public class PdfChunk { |
|
|
|
* @return the Unicode equivalent |
|
|
|
* @return the Unicode equivalent |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public int getUnicodeEquivalent(int c) { |
|
|
|
public int getUnicodeEquivalent(int c) { |
|
|
|
return baseFont.getUnicodeEquivalent(c); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected int getWord(String text, int start) { |
|
|
|
protected int getWord(String text, int start) { |
|
|
@ -338,38 +336,7 @@ public class PdfChunk { |
|
|
|
int length = value.length(); |
|
|
|
int length = value.length(); |
|
|
|
char valueArray[] = value.toCharArray(); |
|
|
|
char valueArray[] = value.toCharArray(); |
|
|
|
char character = 0; |
|
|
|
char character = 0; |
|
|
|
BaseFont ft = font.getFont(); |
|
|
|
|
|
|
|
boolean surrogate = false; |
|
|
|
boolean surrogate = false; |
|
|
|
if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { |
|
|
|
|
|
|
|
while (currentPosition < length) { |
|
|
|
|
|
|
|
// the width of every character is added to the currentWidth
|
|
|
|
|
|
|
|
char cidChar = valueArray[currentPosition]; |
|
|
|
|
|
|
|
character = (char)ft.getUnicodeEquivalent(cidChar); |
|
|
|
|
|
|
|
// if a newLine or carriageReturn is encountered
|
|
|
|
|
|
|
|
if (character == '\n') { |
|
|
|
|
|
|
|
newlineSplit = true; |
|
|
|
|
|
|
|
String returnValue = value.substring(currentPosition + 1); |
|
|
|
|
|
|
|
value = value.substring(0, currentPosition); |
|
|
|
|
|
|
|
if (value.length() < 1) { |
|
|
|
|
|
|
|
value = "\u0001"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PdfChunk pc = new PdfChunk(returnValue, this); |
|
|
|
|
|
|
|
return pc; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
currentWidth += font.width(cidChar); |
|
|
|
|
|
|
|
if (character == ' ') { |
|
|
|
|
|
|
|
lastSpace = currentPosition + 1; |
|
|
|
|
|
|
|
lastSpaceWidth = currentWidth; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (currentWidth > width) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
// if a split-character is encountered, the splitPosition is altered
|
|
|
|
|
|
|
|
if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, thisChunk)) |
|
|
|
|
|
|
|
splitPosition = currentPosition + 1; |
|
|
|
|
|
|
|
currentPosition++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
while (currentPosition < length) { |
|
|
|
while (currentPosition < length) { |
|
|
|
// the width of every character is added to the currentWidth
|
|
|
|
// the width of every character is added to the currentWidth
|
|
|
|
character = valueArray[currentPosition]; |
|
|
|
character = valueArray[currentPosition]; |
|
|
@ -381,9 +348,6 @@ public class PdfChunk { |
|
|
|
inc = 2; |
|
|
|
inc = 2; |
|
|
|
String returnValue = value.substring(currentPosition + inc); |
|
|
|
String returnValue = value.substring(currentPosition + inc); |
|
|
|
value = value.substring(0, currentPosition); |
|
|
|
value = value.substring(0, currentPosition); |
|
|
|
if (value.length() < 1) { |
|
|
|
|
|
|
|
value = " "; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PdfChunk pc = new PdfChunk(returnValue, this); |
|
|
|
PdfChunk pc = new PdfChunk(returnValue, this); |
|
|
|
return pc; |
|
|
|
return pc; |
|
|
|
} |
|
|
|
} |
|
|
@ -405,7 +369,6 @@ public class PdfChunk { |
|
|
|
splitPosition = currentPosition + 1; |
|
|
|
splitPosition = currentPosition + 1; |
|
|
|
currentPosition++; |
|
|
|
currentPosition++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if all the characters fit in the total width, null is returned (there is no overflow)
|
|
|
|
// if all the characters fit in the total width, null is returned (there is no overflow)
|
|
|
|
if (currentPosition == length) { |
|
|
|
if (currentPosition == length) { |
|
|
@ -710,7 +673,7 @@ public class PdfChunk { |
|
|
|
* @return <CODE>true</CODE> if an image is present |
|
|
|
* @return <CODE>true</CODE> if an image is present |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
boolean isImage() |
|
|
|
public boolean isImage() |
|
|
|
{ |
|
|
|
{ |
|
|
|
return image != null; |
|
|
|
return image != null; |
|
|
|
} |
|
|
|
} |
|
|
@ -720,7 +683,7 @@ public class PdfChunk { |
|
|
|
* @return the image or <CODE>null</CODE> |
|
|
|
* @return the image or <CODE>null</CODE> |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
Image getImage() |
|
|
|
public Image getImage() |
|
|
|
{ |
|
|
|
{ |
|
|
|
return image; |
|
|
|
return image; |
|
|
|
} |
|
|
|
} |
|
|
|