Browse Source

REPORT-23453 html切割时,丢失<br> 标签

bugfix/10.0
Hugh.C 5 years ago
parent
commit
de740d5754
  1. 157
      fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java
  2. 14
      fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfLine.java

157
fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java

@ -88,6 +88,12 @@ public class PdfChunk {
private static final float FONT_SCALE = 100f; private static final float FONT_SCALE = 100f;
private static final String BREAK = "\n";
private static final String BREAK_TAG = "<br>";
private boolean breakTag = false;
public float getHeight() { public float getHeight() {
return height; return height;
} }
@ -135,16 +141,16 @@ public class PdfChunk {
keysNoStroke.put(Chunk.TEXTRENDERMODE, null); keysNoStroke.put(Chunk.TEXTRENDERMODE, null);
} }
// membervariables // membervariables
/** The value of this object. */ /** The value of this object. */
protected String value = PdfObject.NOTHING; protected String value = PdfObject.NOTHING;
/** The encoding. */ /** The encoding. */
protected String encoding = BaseFont.WINANSI; protected String encoding = BaseFont.WINANSI;
/** The font for this <CODE>PdfChunk</CODE>. */ /** The font for this <CODE>PdfChunk</CODE>. */
protected PdfFont font; protected PdfFont font;
@ -164,7 +170,7 @@ public class PdfChunk {
* such as underline. * such as underline.
*/ */
protected HashMap attributes = new HashMap(); protected HashMap attributes = new HashMap();
/** /**
* Non metric attributes. * Non metric attributes.
* <P> * <P>
@ -172,16 +178,16 @@ public class PdfChunk {
* such as Color. * such as Color.
*/ */
protected HashMap noStroke = new HashMap(); protected HashMap noStroke = new HashMap();
/** <CODE>true</CODE> if the chunk split was cause by a newline. */ /** <CODE>true</CODE> if the chunk split was cause by a newline. */
protected boolean newlineSplit; protected boolean newlineSplit;
/** The image in this <CODE>PdfChunk</CODE>, if it has one */ /** The image in this <CODE>PdfChunk</CODE>, if it has one */
protected Image image; protected Image image;
/** The offset in the x direction for the image */ /** The offset in the x direction for the image */
protected float offsetX; protected float offsetX;
/** The offset in the y direction for the image */ /** The offset in the y direction for the image */
protected float offsetY; protected float offsetY;
@ -189,17 +195,18 @@ public class PdfChunk {
protected boolean changeLeading = false; protected boolean changeLeading = false;
// constructors // constructors
/** /**
* Constructs a <CODE>PdfChunk</CODE>-object. * Constructs a <CODE>PdfChunk</CODE>-object.
* *
* @param string the content of the <CODE>PdfChunk</CODE>-object * @param string the content of the <CODE>PdfChunk</CODE>-object
* @param other Chunk with the same style you want for the new Chunk * @param other Chunk with the same style you want for the new Chunk
*/ */
PdfChunk(String string, PdfChunk other) { PdfChunk(String string, PdfChunk other) {
thisChunk[0] = this; thisChunk[0] = this;
value = string; value = string;
updateBreakTag();
this.font = other.font; this.font = other.font;
this.attributes = other.attributes; this.attributes = other.attributes;
this.noStroke = other.noStroke; this.noStroke = other.noStroke;
@ -217,18 +224,18 @@ public class PdfChunk {
splitCharacter = DefaultSplitCharacter.DEFAULT; splitCharacter = DefaultSplitCharacter.DEFAULT;
this.height = other.getHeight(); this.height = other.getHeight();
} }
/** /**
* Constructs a <CODE>PdfChunk</CODE>-object. * Constructs a <CODE>PdfChunk</CODE>-object.
* *
* @param chunk the original <CODE>Chunk</CODE>-object * @param chunk the original <CODE>Chunk</CODE>-object
* @param action the <CODE>PdfAction</CODE> if the <CODE>Chunk</CODE> comes from an <CODE>Anchor</CODE> * @param action the <CODE>PdfAction</CODE> if the <CODE>Chunk</CODE> comes from an <CODE>Anchor</CODE>
*/ */
public PdfChunk(Chunk chunk, PdfAction action) { public PdfChunk(Chunk chunk, PdfAction action) {
thisChunk[0] = this; thisChunk[0] = this;
value = chunk.getContent(); value = chunk.getContent();
updateBreakTag();
Font f = chunk.getFont(); Font f = chunk.getFont();
float size = f.getSize(); float size = f.getSize();
if (size == Font.UNDEFINED) if (size == Font.UNDEFINED)
@ -302,15 +309,15 @@ public class PdfChunk {
if (splitCharacter == null) if (splitCharacter == null)
splitCharacter = DefaultSplitCharacter.DEFAULT; splitCharacter = DefaultSplitCharacter.DEFAULT;
} }
// methods // methods
/** Gets the Unicode equivalent to a CID. /** Gets the Unicode equivalent to a CID.
* The (inexistent) CID <FF00> is translated as '\n'. * The (inexistent) CID <FF00> is translated as '\n'.
* It has only meaning with CJK fonts with Identity encoding. * It has only meaning with CJK fonts with Identity encoding.
* @param c the CID code * @param c the CID code
* @return the Unicode equivalent * @return the Unicode equivalent
*/ */
public int getUnicodeEquivalent(int c) { public int getUnicodeEquivalent(int c) {
return c; return c;
} }
@ -407,7 +414,7 @@ public class PdfChunk {
* @param width a given width * @param width a given width
* @return the <CODE>PdfChunk</CODE> that doesn't fit into the width. * @return the <CODE>PdfChunk</CODE> that doesn't fit into the width.
*/ */
PdfChunk truncate(float width) { PdfChunk truncate(float width) {
if (image != null) { if (image != null) {
if (image.getScaledWidth() + indent.getLeft() + indent.getRight() > width) { if (image.getScaledWidth() + indent.getLeft() + indent.getRight() > width) {
@ -421,10 +428,10 @@ public class PdfChunk {
else else
return null; return null;
} }
int currentPosition = 0; int currentPosition = 0;
float currentWidth = indent.getLeft(); float currentWidth = indent.getLeft();
// it's no use trying to split if there isn't even enough place for a space // it's no use trying to split if there isn't even enough place for a space
if (width < font.width() + indent.getLeft() + indent.getRight()) { if (width < font.width() + indent.getLeft() + indent.getRight()) {
String returnValue = value.substring(1); String returnValue = value.substring(1);
@ -432,7 +439,7 @@ public class PdfChunk {
PdfChunk pc = new PdfChunk(returnValue, this); PdfChunk pc = new PdfChunk(returnValue, this);
return pc; return pc;
} }
// loop over all the characters of a string // loop over all the characters of a string
// or until the totalWidth is reached // or until the totalWidth is reached
int length = value.length(); int length = value.length();
@ -451,12 +458,12 @@ public class PdfChunk {
currentPosition++; currentPosition++;
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) {
return null; return null;
} }
// otherwise, the string has to be truncated // otherwise, the string has to be truncated
//currentPosition -= 2; //currentPosition -= 2;
// we have to chop off minimum 1 character from the chunk // we have to chop off minimum 1 character from the chunk
@ -470,49 +477,49 @@ public class PdfChunk {
PdfChunk pc = new PdfChunk(returnValue, this); PdfChunk pc = new PdfChunk(returnValue, this);
return pc; return pc;
} }
// methods to retrieve the membervariables // methods to retrieve the membervariables
/** /**
* Returns the font of this <CODE>Chunk</CODE>. * Returns the font of this <CODE>Chunk</CODE>.
* *
* @return a <CODE>PdfFont</CODE> * @return a <CODE>PdfFont</CODE>
*/ */
PdfFont font() { PdfFont font() {
return font; return font;
} }
/** /**
* Returns the color of this <CODE>Chunk</CODE>. * Returns the color of this <CODE>Chunk</CODE>.
* *
* @return a <CODE>Color</CODE> * @return a <CODE>Color</CODE>
*/ */
Color color() { Color color() {
return (Color)noStroke.get(Chunk.COLOR); return (Color)noStroke.get(Chunk.COLOR);
} }
/** /**
* Returns the width of this <CODE>PdfChunk</CODE>. * Returns the width of this <CODE>PdfChunk</CODE>.
* *
* @return a width * @return a width
*/ */
public float width() { public float width() {
return font.width(value) + indent.getLeft() + indent.getRight(); return font.width(value) + indent.getLeft() + indent.getRight();
} }
/** /**
* Checks if the <CODE>PdfChunk</CODE> split was caused by a newline. * Checks if the <CODE>PdfChunk</CODE> split was caused by a newline.
* @return <CODE>true</CODE> if the <CODE>PdfChunk</CODE> split was caused by a newline. * @return <CODE>true</CODE> if the <CODE>PdfChunk</CODE> split was caused by a newline.
*/ */
public boolean isNewlineSplit() public boolean isNewlineSplit()
{ {
return newlineSplit; return newlineSplit;
} }
/** /**
* Gets the width of the <CODE>PdfChunk</CODE> taking into account the * Gets the width of the <CODE>PdfChunk</CODE> taking into account the
* extra character and word spacing. * extra character and word spacing.
@ -520,7 +527,7 @@ public class PdfChunk {
* @param wordSpacing the extra word spacing * @param wordSpacing the extra word spacing
* @return the calculated width * @return the calculated width
*/ */
public float getWidthCorrected(float charSpacing, float wordSpacing) public float getWidthCorrected(float charSpacing, float wordSpacing)
{ {
if (image != null) { if (image != null) {
@ -532,7 +539,7 @@ public class PdfChunk {
++numberOfSpaces; ++numberOfSpaces;
return width() + (value.length() * charSpacing + numberOfSpaces * wordSpacing); return width() + (value.length() * charSpacing + numberOfSpaces * wordSpacing);
} }
/** /**
* Gets the text displacement relative to the baseline. * Gets the text displacement relative to the baseline.
* @return a displacement in points * @return a displacement in points
@ -544,7 +551,7 @@ public class PdfChunk {
} }
return 0.0f; return 0.0f;
} }
/** /**
* Trims the last space. * Trims the last space.
* @return the width of the space trimmed, otherwise 0 * @return the width of the space trimmed, otherwise 0
@ -565,44 +572,44 @@ public class PdfChunk {
} }
return 0; return 0;
} }
/** /**
* Gets an attribute. The search is made in <CODE>attributes</CODE> * Gets an attribute. The search is made in <CODE>attributes</CODE>
* and <CODE>noStroke</CODE>. * and <CODE>noStroke</CODE>.
* @param name the attribute key * @param name the attribute key
* @return the attribute value or null if not found * @return the attribute value or null if not found
*/ */
public Object getAttribute(String name) public Object getAttribute(String name)
{ {
if (attributes.containsKey(name)) if (attributes.containsKey(name))
return attributes.get(name); return attributes.get(name);
return noStroke.get(name); return noStroke.get(name);
} }
/** /**
*Checks if the attribute exists. *Checks if the attribute exists.
* @param name the attribute key * @param name the attribute key
* @return <CODE>true</CODE> if the attribute exists * @return <CODE>true</CODE> if the attribute exists
*/ */
boolean isAttribute(String name) boolean isAttribute(String name)
{ {
if (attributes.containsKey(name)) if (attributes.containsKey(name))
return true; return true;
return noStroke.containsKey(name); return noStroke.containsKey(name);
} }
/** /**
* Checks if this <CODE>PdfChunk</CODE> needs some special metrics handling. * Checks if this <CODE>PdfChunk</CODE> needs some special metrics handling.
* @return <CODE>true</CODE> if this <CODE>PdfChunk</CODE> needs some special metrics handling. * @return <CODE>true</CODE> if this <CODE>PdfChunk</CODE> needs some special metrics handling.
*/ */
boolean isStroked() boolean isStroked()
{ {
return (!attributes.isEmpty()); return (!attributes.isEmpty());
} }
/** /**
* Checks if this <CODE>PdfChunk</CODE> is a Separator Chunk. * Checks if this <CODE>PdfChunk</CODE> is a Separator Chunk.
* @return true if this chunk is a separator. * @return true if this chunk is a separator.
@ -611,7 +618,7 @@ public class PdfChunk {
boolean isSeparator() { boolean isSeparator() {
return isAttribute(Chunk.SEPARATOR); return isAttribute(Chunk.SEPARATOR);
} }
/** /**
* Checks if this <CODE>PdfChunk</CODE> is a horizontal Separator Chunk. * Checks if this <CODE>PdfChunk</CODE> is a horizontal Separator Chunk.
* @return true if this chunk is a horizontal separator. * @return true if this chunk is a horizontal separator.
@ -624,7 +631,7 @@ public class PdfChunk {
} }
return false; return false;
} }
/** /**
* Checks if this <CODE>PdfChunk</CODE> is a tab Chunk. * Checks if this <CODE>PdfChunk</CODE> is a tab Chunk.
* @return true if this chunk is a separator. * @return true if this chunk is a separator.
@ -633,7 +640,7 @@ public class PdfChunk {
boolean isTab() { boolean isTab() {
return isAttribute(Chunk.TAB); return isAttribute(Chunk.TAB);
} }
/** /**
* Correction for the tab position based on the left starting position. * Correction for the tab position based on the left starting position.
* @param newValue the new value for the left X. * @param newValue the new value for the left X.
@ -645,72 +652,72 @@ public class PdfChunk {
attributes.put(Chunk.TAB, new Object[]{o[0], o[1], o[2], new Float(newValue)}); attributes.put(Chunk.TAB, new Object[]{o[0], o[1], o[2], new Float(newValue)});
} }
} }
/** /**
* Checks if there is an image in the <CODE>PdfChunk</CODE>. * Checks if there is an image in the <CODE>PdfChunk</CODE>.
* @return <CODE>true</CODE> if an image is present * @return <CODE>true</CODE> if an image is present
*/ */
public boolean isImage() public boolean isImage()
{ {
return image != null; return image != null;
} }
/** /**
* Gets the image in the <CODE>PdfChunk</CODE>. * Gets the image in the <CODE>PdfChunk</CODE>.
* @return the image or <CODE>null</CODE> * @return the image or <CODE>null</CODE>
*/ */
public Image getImage() public Image getImage()
{ {
return image; return image;
} }
/** /**
* Sets the image offset in the x direction * Sets the image offset in the x direction
* @param offsetX the image offset in the x direction * @param offsetX the image offset in the x direction
*/ */
void setImageOffsetX(float offsetX) void setImageOffsetX(float offsetX)
{ {
this.offsetX = offsetX; this.offsetX = offsetX;
} }
/** /**
* Gets the image offset in the x direction * Gets the image offset in the x direction
* @return the image offset in the x direction * @return the image offset in the x direction
*/ */
float getImageOffsetX() float getImageOffsetX()
{ {
return offsetX; return offsetX;
} }
/** /**
* Sets the image offset in the y direction * Sets the image offset in the y direction
* @param offsetY the image offset in the y direction * @param offsetY the image offset in the y direction
*/ */
void setImageOffsetY(float offsetY) void setImageOffsetY(float offsetY)
{ {
this.offsetY = offsetY; this.offsetY = offsetY;
} }
/** /**
* Gets the image offset in the y direction * Gets the image offset in the y direction
* @return Gets the image offset in the y direction * @return Gets the image offset in the y direction
*/ */
float getImageOffsetY() float getImageOffsetY()
{ {
return offsetY; return offsetY;
} }
/** /**
* sets the value. * sets the value.
* @param value content of the Chunk * @param value content of the Chunk
*/ */
void setValue(String value) void setValue(String value)
{ {
this.value = value; this.value = value;
@ -727,17 +734,17 @@ public class PdfChunk {
* Tells you if this string is in Chinese, Japanese, Korean or Identity-H. * Tells you if this string is in Chinese, Japanese, Korean or Identity-H.
* @return true if the Chunk has a special encoding * @return true if the Chunk has a special encoding
*/ */
boolean isSpecialEncoding() { boolean isSpecialEncoding() {
return encoding.equals(CJKFont.CJK_ENCODING) || encoding.equals(BaseFont.IDENTITY_H); return encoding.equals(CJKFont.CJK_ENCODING) || encoding.equals(BaseFont.IDENTITY_H);
} }
/** /**
* Gets the encoding of this string. * Gets the encoding of this string.
* *
* @return a <CODE>String</CODE> * @return a <CODE>String</CODE>
*/ */
String getEncoding() { String getEncoding() {
return encoding; return encoding;
} }
@ -745,7 +752,7 @@ public class PdfChunk {
int length() { int length() {
return value.length(); return value.length();
} }
int lengthUtf32() { int lengthUtf32() {
if (!BaseFont.IDENTITY_H.equals(encoding)) if (!BaseFont.IDENTITY_H.equals(encoding))
return value.length(); return value.length();
@ -758,17 +765,17 @@ public class PdfChunk {
} }
return total; return total;
} }
boolean isExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { boolean isExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
return splitCharacter.isSplitCharacter(start, current, end, cc, ck); return splitCharacter.isSplitCharacter(start, current, end, cc, ck);
} }
/** /**
* Removes all the <VAR>' '</VAR> and <VAR>'-'</VAR>-characters on the right of a <CODE>String</CODE>. * Removes all the <VAR>' '</VAR> and <VAR>'-'</VAR>-characters on the right of a <CODE>String</CODE>.
* <P> * <P>
* @param string the <CODE>String<CODE> that has to be trimmed. * @param string the <CODE>String<CODE> that has to be trimmed.
* @return the trimmed <CODE>String</CODE> * @return the trimmed <CODE>String</CODE>
*/ */
String trim(String string) { String trim(String string) {
while (string.endsWith(" ") || string.endsWith("\t")) { while (string.endsWith(" ") || string.endsWith("\t")) {
string = string.substring(0, string.length() - 1); string = string.substring(0, string.length() - 1);
@ -779,7 +786,7 @@ public class PdfChunk {
public boolean changeLeading() { public boolean changeLeading() {
return changeLeading; return changeLeading;
} }
float getCharWidth(int c) { float getCharWidth(int c) {
if (noPrint(c)) if (noPrint(c))
return 0; return 0;
@ -798,7 +805,7 @@ public class PdfChunk {
htmlString.append("<span style='"); htmlString.append("<span style='");
htmlString.append(getStyleAttributes()).append("'"); htmlString.append(getStyleAttributes()).append("'");
htmlString.append(">"); htmlString.append(">");
htmlString.append(value); htmlString.append(breakTag ? BREAK_TAG : value);
htmlString.append("</span>"); htmlString.append("</span>");
return htmlString.toString(); return htmlString.toString();
} }
@ -856,4 +863,12 @@ public class PdfChunk {
return indent.getLeft(); return indent.getLeft();
} }
private void updateBreakTag() {
breakTag = BREAK.equals(value);
}
public boolean isBreakTag() {
return breakTag;
}
} }

14
fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfLine.java

@ -91,9 +91,11 @@ public class PdfLine {
/** The original width. */ /** The original width. */
protected float originalWidth; protected float originalWidth;
protected boolean isRTL = false; protected boolean isRTL = false;
public float getHeight() { public float getHeight() {
return height; return height;
} }
@ -155,9 +157,15 @@ public class PdfLine {
public PdfChunk add(PdfChunk chunk) { public PdfChunk add(PdfChunk chunk) {
// nothing happens if the chunk is null. // nothing happens if the chunk is null.
if (chunk == null || chunk.toString().equals("")) { if (chunk == null || chunk.toString().equals("")) {
return null; return null;
} }
// add to line if the chunk is break tag ("\n")
if (chunk.isBreakTag()) {
addToLine(chunk);
width = 0;
return null;
}
// we split the chunk to be added // we split the chunk to be added
PdfChunk overflow = chunk.split(width); PdfChunk overflow = chunk.split(width);
newlineSplit = (chunk.isNewlineSplit() || overflow == null); newlineSplit = (chunk.isNewlineSplit() || overflow == null);

Loading…
Cancel
Save