Browse Source

提交demo代码

10.0
LAPTOP-SB56SG4Q\86185 4 years ago
parent
commit
112acddb00
  1. 5
      README.md
  2. 124
      build.gradle
  3. 13
      encrypt.xml
  4. 29
      plugin.xml
  5. 20
      src/main/java/com/fr/plugin/html/locale/LocaleFinder.java
  6. 37
      src/main/java/com/fr/plugin/html/parse/AbstractHtmlBlock.java
  7. 50
      src/main/java/com/fr/plugin/html/parse/HtmlBlock.java
  8. 252
      src/main/java/com/fr/plugin/html/parse/HtmlContainer.java
  9. 78
      src/main/java/com/fr/plugin/html/parse/HtmlParserImpl.java
  10. 676
      src/main/java/com/fr/plugin/html/parse/block/HtmlParagraph.java
  11. 213
      src/main/java/com/fr/plugin/html/parse/block/HtmlTable.java
  12. 44
      src/main/java/com/fr/plugin/html/parse/config/ParseCheckConfig.java
  13. 279
      src/main/java/com/fr/plugin/html/parse/utils/Html2ChunkUtils.java
  14. 129
      src/main/java/com/fr/plugin/html/parse/utils/Html2RichTextUtils.java
  15. 127
      src/main/java/com/fr/plugin/html/parse/utils/HtmlBackgroundUtils.java
  16. 128
      src/main/java/com/fr/plugin/html/parse/utils/HtmlBorderUtils.java
  17. 328
      src/main/java/com/fr/plugin/html/parse/utils/HtmlUtils.java
  18. 17
      src/main/java/com/fr/third/lowagie/Container.java
  19. 306
      src/main/java/com/fr/third/lowagie/text/Anchor.java
  20. 601
      src/main/java/com/fr/third/lowagie/text/Annotation.java
  21. 87
      src/main/java/com/fr/third/lowagie/text/BadElementException.java
  22. 852
      src/main/java/com/fr/third/lowagie/text/Cell.java
  23. 136
      src/main/java/com/fr/third/lowagie/text/Chapter.java
  24. 124
      src/main/java/com/fr/third/lowagie/text/ChapterAutoNumber.java
  25. 893
      src/main/java/com/fr/third/lowagie/text/Chunk.java
  26. 167
      src/main/java/com/fr/third/lowagie/text/DocListener.java
  27. 488
      src/main/java/com/fr/third/lowagie/text/DocWriter.java
  28. 919
      src/main/java/com/fr/third/lowagie/text/Document.java
  29. 92
      src/main/java/com/fr/third/lowagie/text/DocumentException.java
  30. 354
      src/main/java/com/fr/third/lowagie/text/Element.java
  31. 74
      src/main/java/com/fr/third/lowagie/text/ElementListener.java
  32. 522
      src/main/java/com/fr/third/lowagie/text/ElementTags.java
  33. 160
      src/main/java/com/fr/third/lowagie/text/ExceptionConverter.java
  34. 778
      src/main/java/com/fr/third/lowagie/text/Font.java
  35. 446
      src/main/java/com/fr/third/lowagie/text/FontFactory.java
  36. 701
      src/main/java/com/fr/third/lowagie/text/FontFactoryImp.java
  37. 129
      src/main/java/com/fr/third/lowagie/text/GreekList.java
  38. 97
      src/main/java/com/fr/third/lowagie/text/Header.java
  39. 203
      src/main/java/com/fr/third/lowagie/text/HeaderFooter.java
  40. 2056
      src/main/java/com/fr/third/lowagie/text/Image.java
  41. 102
      src/main/java/com/fr/third/lowagie/text/ImgCCITT.java
  42. 131
      src/main/java/com/fr/third/lowagie/text/ImgJBIG2.java
  43. 96
      src/main/java/com/fr/third/lowagie/text/ImgRaw.java
  44. 92
      src/main/java/com/fr/third/lowagie/text/ImgTemplate.java
  45. 190
      src/main/java/com/fr/third/lowagie/text/ImgWMF.java
  46. 345
      src/main/java/com/fr/third/lowagie/text/Jpeg.java
  47. 238
      src/main/java/com/fr/third/lowagie/text/Jpeg2000.java
  48. 85
      src/main/java/com/fr/third/lowagie/text/LargeElement.java
  49. 597
      src/main/java/com/fr/third/lowagie/text/List.java
  50. 251
      src/main/java/com/fr/third/lowagie/text/ListItem.java
  51. 470
      src/main/java/com/fr/third/lowagie/text/MPL-1.1.txt
  52. 150
      src/main/java/com/fr/third/lowagie/text/MarkedObject.java
  53. 281
      src/main/java/com/fr/third/lowagie/text/MarkedSection.java
  54. 229
      src/main/java/com/fr/third/lowagie/text/Meta.java
  55. 246
      src/main/java/com/fr/third/lowagie/text/PageSize.java
  56. 541
      src/main/java/com/fr/third/lowagie/text/Paragraph.java
  57. 589
      src/main/java/com/fr/third/lowagie/text/Phrase.java
  58. 876
      src/main/java/com/fr/third/lowagie/text/Rectangle.java
  59. 357
      src/main/java/com/fr/third/lowagie/text/RectangleReadOnly.java
  60. 118
      src/main/java/com/fr/third/lowagie/text/RomanList.java
  61. 381
      src/main/java/com/fr/third/lowagie/text/Row.java
  62. 60
      src/main/java/com/fr/third/lowagie/text/RtfElementInterface.java
  63. 18
      src/main/java/com/fr/third/lowagie/text/SafeEmptyEntityResolver.java
  64. 756
      src/main/java/com/fr/third/lowagie/text/Section.java
  65. 533
      src/main/java/com/fr/third/lowagie/text/SimpleCell.java
  66. 354
      src/main/java/com/fr/third/lowagie/text/SimpleTable.java
  67. 210
      src/main/java/com/fr/third/lowagie/text/SpecialSymbol.java
  68. 96
      src/main/java/com/fr/third/lowagie/text/SplitCharacter.java
  69. 1494
      src/main/java/com/fr/third/lowagie/text/Table.java
  70. 73
      src/main/java/com/fr/third/lowagie/text/TextElementArray.java
  71. 342
      src/main/java/com/fr/third/lowagie/text/Utilities.java
  72. 134
      src/main/java/com/fr/third/lowagie/text/ZapfDingbatsList.java
  73. 145
      src/main/java/com/fr/third/lowagie/text/ZapfDingbatsNumberList.java
  74. 219
      src/main/java/com/fr/third/lowagie/text/apache_license.txt
  75. 70
      src/main/java/com/fr/third/lowagie/text/exceptions/BadPasswordException.java
  76. 68
      src/main/java/com/fr/third/lowagie/text/exceptions/IllegalPdfSyntaxException.java
  77. 71
      src/main/java/com/fr/third/lowagie/text/exceptions/InvalidPdfException.java
  78. 72
      src/main/java/com/fr/third/lowagie/text/exceptions/UnsupportedPdfException.java
  79. 627
      src/main/java/com/fr/third/lowagie/text/factories/ElementFactory.java
  80. 131
      src/main/java/com/fr/third/lowagie/text/factories/GreekAlphabetFactory.java
  81. 129
      src/main/java/com/fr/third/lowagie/text/factories/RomanAlphabetFactory.java
  82. 185
      src/main/java/com/fr/third/lowagie/text/factories/RomanNumberFactory.java
  83. 40
      src/main/java/com/fr/third/lowagie/text/html/Border.java
  84. 107
      src/main/java/com/fr/third/lowagie/text/html/BorderAttribute.java
  85. 79
      src/main/java/com/fr/third/lowagie/text/html/BorderEnum.java
  86. 200
      src/main/java/com/fr/third/lowagie/text/html/CSS.java
  87. 110
      src/main/java/com/fr/third/lowagie/text/html/CSSUtils.java
  88. 210
      src/main/java/com/fr/third/lowagie/text/html/HtmlEncoder.java
  89. 192
      src/main/java/com/fr/third/lowagie/text/html/HtmlParser.java
  90. 111
      src/main/java/com/fr/third/lowagie/text/html/HtmlPeer.java
  91. 302
      src/main/java/com/fr/third/lowagie/text/html/HtmlTagMap.java
  92. 342
      src/main/java/com/fr/third/lowagie/text/html/HtmlTags.java
  93. 1130
      src/main/java/com/fr/third/lowagie/text/html/HtmlWriter.java
  94. 55
      src/main/java/com/fr/third/lowagie/text/html/IndentAttribute.java
  95. 641
      src/main/java/com/fr/third/lowagie/text/html/Markup.java
  96. 96
      src/main/java/com/fr/third/lowagie/text/html/ParseIndentAttrUtils.java
  97. 276
      src/main/java/com/fr/third/lowagie/text/html/SAXmyHtmlHandler.java
  98. 108
      src/main/java/com/fr/third/lowagie/text/html/SpaceWithPunctuationBreakIterator.java
  99. 319
      src/main/java/com/fr/third/lowagie/text/html/WebColors.java
  100. 57
      src/main/java/com/fr/third/lowagie/text/html/simpleparser/ALink.java
  101. Some files were not shown because too many files have changed in this diff Show More

5
README.md

@ -1,4 +1,5 @@
# shop-report-html-parse # shop-report-html-parse
html解析 插件源码 html解析 商城免费插件源码\
https://market.fanruan.com/plugin/d7d05eb3-e57c-4fd5-897d-a0795a8fcf84 https://market.fanruan.com/plugin/d7d05eb3-e57c-4fd5-897d-a0795a8fcf84\
该接口开发细节很多,建议开发者不要独立开发新的插件,基于商城插件去做自身业务需要的调整即可

124
build.gradle

@ -0,0 +1,124 @@
apply plugin: 'java'
[compileJava,compileTestJava]*.options*.encoding = 'UTF-8'
ext {
/**
* jar的路径
* 1.jar需要打包到zip中,lib根目录下
* 2.jar仅仅是编译时需要lib下子目录下即可
*/
libPath = "$projectDir/../../webroot/WEB-INF/lib"
/**
* class进行加密保护
*/
guard = false
def pluginInfo = getPluginInfo()
pluginPre = "fine-plugin"
pluginName = pluginInfo.id
pluginVersion = pluginInfo.version
outputPath = "$projectDir/../../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes"
}
group = 'com.fr.plugin'
version = '10.0'
sourceCompatibility = '8'
sourceSets {
main {
java.outputDir = file(outputPath)
output.resourcesDir = file(outputPath)
}
}
ant.importBuild("encrypt.xml")
//ant变量
ant.projectDir = projectDir
ant.references["compile.classpath"] = ant.path {
fileset(dir: libPath, includes: '**/*.jar')
fileset(dir: ".",includes:"**/*.jar" )
}
classes.dependsOn('clean')
task copyFiles(type: Copy,dependsOn: 'classes'){
from outputPath
into "$projectDir/classes"
}
task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){
from "$projectDir/classes"
into "$projectDir/transform-classes"
include "**/*.*"
}
jar.dependsOn("preJar")
task makeJar(type: Jar,dependsOn: preJar){
from fileTree(dir: "$projectDir/transform-classes")
baseName pluginPre
appendix pluginName
version pluginVersion
destinationDir = file("$buildDir/libs")
doLast(){
delete file("$projectDir/classes")
delete file("$projectDir/transform-classes")
}
}
task copyFile(type: Copy,dependsOn: ["makeJar"]){
from "$buildDir/libs"
from("$projectDir/lib") {
include "*.jar"
}
from "$projectDir/plugin.xml"
into file("$buildDir/temp/plugin")
}
task zip(type:Zip,dependsOn:["copyFile"]){
from "$buildDir/temp/plugin"
destinationDir file("$buildDir/install")
baseName pluginPre
appendix pluginName
version pluginVersion
}
//build时包含哪些文件,
processResources {
// exclude everything
// *.css没效果
// exclude '**/*.css'
// except this file
// include 'xx.xml'
}
/*读取plugin.xml中的version*/
def getPluginInfo(){
def xmlFile = file("plugin.xml")
if (!xmlFile.exists()) {
return ["id":"none", "version":"1.0.0"]
}
def plugin = new XmlParser().parse(xmlFile)
def version = plugin.version[0].text()
def id = plugin.id[0].text()
return ["id":id,"version":version]
}
repositories {
mavenLocal()
maven {
url = uri('http://mvn.finedevelop.com/repository/maven-public/')
}
}
dependencies {
//使jar
implementation fileTree(dir: 'lib', include: ['**/*.jar'])
implementation fileTree(dir: libPath, include: ['**/*.jar'])
}

13
encrypt.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<target name="compile_encrypt_javas" depends="copyFiles">
<echo message="加密文件"/>
<echo message="${projectDir}"/>
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask">
<classpath refid="compile.classpath"/>
</taskdef>
<pretreatment baseDir="${projectDir}"/>
</target>
<target name="compile_plain_javas" depends="copyFiles">
</target>
</project>

29
plugin.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<main-package>com.fr.plugin.html</main-package>
<id>com.fr.plugin.html.parse</id>
<name><![CDATA[Html解析]]></name>
<active>yes</active>
<version>1.0.6</version>
<env-version>10.0</env-version>
<jartime>2020-10-20</jartime>
<vendor>finereport</vendor>
<description>
<![CDATA[用于处理模版中html相关的导出预览逻辑,确保html的显示和导出效果,安装后将优先使用插件中的逻辑来展示及导出html.]]></description>
<change-notes><![CDATA[
<p>[2021-04-26]修复 itext XXE安全漏洞问题</p>
<p>[2021-04-25]修复li标签写不全时导出excel内容空白的的问题</p>
<p>[2021-03-09]修复html显示的图片加百分比的宽高属性值导致导出后的图片变得很小的问题</p>
<p>[2021-01-05]修复块标签含margin属性和width属性时文字换行异常和文字距离顶部边框距离不对的问题</p>
<p>[2020-10-27]修复border相关属性只指定style值时边框不生效的问题</p>
<p>[2020-10-22]修复img标签没有定义宽高属性导致word导出时图片过大的问题</p>
<p>[2020-09-29]解决插件初始化遇到的一系列问题</p>
]]></change-notes>
<function-recorder class="com.fr.plugin.html.parse.HtmlParserImpl"/>
<extra-report>
<HtmlParser class="com.fr.plugin.html.parse.HtmlParserImpl"/>
</extra-report>
<extra-core>
<LocaleFinder class="com.fr.plugin.html.locale.LocaleFinder"/>
</extra-core>
</plugin>

20
src/main/java/com/fr/plugin/html/locale/LocaleFinder.java

@ -0,0 +1,20 @@
package com.fr.plugin.html.locale;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/18
*/
public class LocaleFinder extends AbstractLocaleFinder {
/**
* 国际化文件路径
*
* @return 路径
*/
public String find() {
return "com/fr/plugin/html/parse/locale";
}
}

37
src/main/java/com/fr/plugin/html/parse/AbstractHtmlBlock.java

@ -0,0 +1,37 @@
package com.fr.plugin.html.parse;
import com.fr.third.lowagie.text.html.IndentAttribute;
public abstract class AbstractHtmlBlock implements HtmlBlock {
protected IndentAttribute padding = new IndentAttribute();
protected IndentAttribute margin = new IndentAttribute();
protected IndentAttribute border = new IndentAttribute();
public IndentAttribute getPadding() {
return padding;
}
public void setPadding(IndentAttribute padding) {
this.padding = padding;
}
public IndentAttribute getMargin() {
return margin;
}
public void setMargin(IndentAttribute margin) {
this.margin = margin;
}
public IndentAttribute getBorder() {
return border;
}
public void setBorder(IndentAttribute border) {
this.border = border;
}
}

50
src/main/java/com/fr/plugin/html/parse/HtmlBlock.java

@ -0,0 +1,50 @@
package com.fr.plugin.html.parse;
import com.fr.base.Style;
import com.fr.third.lowagie.text.html.IndentAttribute;
import java.awt.Graphics2D;
/**
* @author kerry
* @date 2018/8/10
*/
public interface HtmlBlock {
/**
* 获取block元素高度
*
* @return float 返回高度
*/
float getHeight();
/**
* 计算block元素内部高度
*/
void calculateHeight();
/**
* 获取margin
*
* @return IndentAttribute
*/
IndentAttribute getMargin();
/**
* 切割html元素
*
* @param startY 切割起始位置
* @param endY 切割结束位置
* @return html字符串
*/
String toHtml(double startY, double endY);
/**
* 绘制元素
*
* @param g2d 绘制对象
* @param style 绘制样式
* @throws Exception
*/
void paint(Graphics2D g2d, Style style) throws Exception;
}

252
src/main/java/com/fr/plugin/html/parse/HtmlContainer.java

@ -0,0 +1,252 @@
package com.fr.plugin.html.parse;
import com.fr.base.Style;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.block.HtmlParagraph;
import com.fr.plugin.html.parse.block.HtmlTable;
import com.fr.plugin.html.parse.utils.HtmlUtils;
import com.fr.stable.Constants;
import com.fr.stable.unit.PT;
import com.fr.third.lowagie.Container;
import com.fr.third.lowagie.text.html.IndentAttribute;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.List;
import com.fr.third.lowagie.text.Paragraph;
import com.fr.third.lowagie.text.pdf.PdfLine;
import com.fr.third.lowagie.text.pdf.PdfPTable;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author kerry
* @date 2018/4/4
*/
public class HtmlContainer implements Container {
protected java.util.List<HtmlBlock> blocks = new ArrayList<HtmlBlock>();
private float x = 0.0f;
private float y = 0.0f;
protected float width;
protected float height;
private Style style;
private int resolution;
public HtmlContainer(float width, float height, Style style, int resolution) {
this.width = width;
this.height = height;
this.style = style;
this.resolution = resolution;
}
public void setHeight(float height) {
this.height = height;
}
public java.util.List<HtmlBlock> getHtmlBlocks() {
return blocks;
}
/**
* 向container中添加PdfElement
*
* @param element
*/
public boolean add(Element element) {
if (style == null) {
style = Style.getInstance();
}
try {
switch (element.type()) {
case Element.PARAGRAPH: {
HtmlParagraph HtmlParagraph = new HtmlParagraph(width, 0, style, resolution);
Paragraph paragraph = (Paragraph) element;
HtmlParagraph.getOtherAttribute(paragraph);
Iterator a = paragraph.iterator();
while (a.hasNext()) {
HtmlParagraph.add((Element) a.next(), style);
}
blocks.add(HtmlParagraph);
break;
}
case Element.LIST: {
List list = (List) element;
if (list.isAlignindent()) {
list.normalizeIndentation();
}
for (Iterator i = list.getList().iterator(); i.hasNext(); ) {
add((Element) i.next());
}
break;
}
case Element.LISTITEM: {
HtmlParagraph HtmlParagraph = new HtmlParagraph(width, 0, style, resolution);
HtmlParagraph.add(element, style);
blocks.add(HtmlParagraph);
break;
}
case Element.PTABLE: {
HtmlTable HtmlTable = new HtmlTable(width, style, resolution);
HtmlTable.addPdfPTable((PdfPTable) element);
blocks.add(HtmlTable);
break;
}
default:
return false;
}
return true;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
}
/**
* 添加元素之后进行内部高度计算
*/
public void calculateHeight() {
HtmlBlock l;
for (Iterator i = blocks.iterator(); i.hasNext(); ) {
l = (HtmlBlock) i.next();
l.calculateHeight();
}
}
/**
* 进行绘制
*
* @param g2d pdf图形对象
*/
public void paint(Graphics2D g2d) throws Exception {
if (blocks == null) {
return;
}
if (blocks.isEmpty()) {
return;
}
float innerHeight = getHeight();
applyVerticalAlignment(innerHeight, style);
y += HtmlUtils.frPadding2px(style.getSpacingBefore(), resolution);
HtmlBlock l;
float lastMarginBottom = 0.0f;
for (Iterator i = blocks.iterator(); i.hasNext(); ) {
l = (HtmlBlock) i.next();
IndentAttribute marginAttribute = l.getMargin();
float marginTop = marginAttribute.getTop();
float marginBottom = marginAttribute.getBottom();
x = HtmlUtils.frPadding2px(style.getPaddingLeft(), resolution);
y += lastMarginBottom > marginTop ? 0.0f : marginTop - lastMarginBottom;
lastMarginBottom = marginBottom;
g2d.translate(x, y);
l.paint(g2d, style);
g2d.translate(-x, -y);
y += l.getHeight() + marginBottom;
}
blocks = new ArrayList();
}
/**
* HtmlParagraph进行垂直居中处理
*
* @param innerHeight 渲染的content高度
* @param style 单元格样式
*/
private void applyVerticalAlignment(float innerHeight, Style style) {
switch (style.getVerticalAlignment()) {
case Constants.BOTTOM: {
float blockHeight = height;
float deltaY = blockHeight;
deltaY -= innerHeight;
if (deltaY > 0) {
y += deltaY;
}
break;
}
case Constants.CENTER: {
float blockHeight = height;
float deltaY = blockHeight;
deltaY -= innerHeight;
if (deltaY > 0) {
y += deltaY / 2;
}
break;
}
}
}
/**
* 计算并获取整体高度
*
* @return 高度
*/
@Override
public float getHeight() {
double spacingBefore = PT.pt2pix(style.getSpacingBefore(), resolution);
double spacingAfter = PT.pt2pix(style.getSpacingAfter(), resolution);
float totalHeight = 0.0f;
totalHeight += spacingBefore;
HtmlBlock l;
float lastMarginBottom = 0.0f;
for (Iterator i = blocks.iterator(); i.hasNext(); ) {
l = (HtmlBlock) i.next();
IndentAttribute marginAttribute = l.getMargin();
float marginTop = marginAttribute.getTop();
float marginBottom = marginAttribute.getBottom();
totalHeight += lastMarginBottom > marginTop ? 0.0f : marginTop - lastMarginBottom;
totalHeight += marginBottom;
lastMarginBottom = marginBottom;
totalHeight += l.getHeight();
}
totalHeight += spacingAfter;
return totalHeight;
}
/**
* 获取内部所有的渲染行对象
*
* @return 渲染行list
*/
public java.util.List getLines() {
java.util.List<PdfLine> lines = new ArrayList<PdfLine>();
HtmlParagraph l;
for (Iterator i = blocks.iterator(); i.hasNext(); ) {
l = (HtmlParagraph) i.next();
lines.addAll(l.getLines());
}
return lines;
}
/**
* 获取从起始行到结束行生成的html字符串
*
* @param lineStartY 起始行
* @param lineEndY 结束行
* @return html字符串
*/
public String getHtml(double lineStartY, double lineEndY) {
float totalHeight = 0.0f;
HtmlBlock l;
StringBuffer sb = new StringBuffer();
double lastMarginBottom = 0.0f;
for (int i = 0; i < blocks.size(); i++) {
l = blocks.get(i);
IndentAttribute marginAttribute = l.getMargin();
double marginTop = marginAttribute.getTop();
double marginBottom = marginAttribute.getBottom();
totalHeight += lastMarginBottom > marginTop ? 0.0f : marginTop - lastMarginBottom;
totalHeight += marginBottom;
sb.append(l.toHtml(lineStartY - totalHeight, lineEndY - totalHeight));
lastMarginBottom = marginBottom;
totalHeight += l.getHeight();
}
return sb.toString();
}
}

78
src/main/java/com/fr/plugin/html/parse/HtmlParserImpl.java

@ -0,0 +1,78 @@
package com.fr.plugin.html.parse;
import com.fr.base.Style;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.utils.Html2ChunkUtils;
import com.fr.plugin.html.parse.utils.Html2RichTextUtils;
import com.fr.plugin.html.parse.utils.HtmlUtils;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.report.cell.cellattr.core.RichText;
import com.fr.stable.HtmlCheckParamWraper;
import com.fr.stable.fun.impl.AbstractHtmlParser;
import com.fr.stable.unit.UNIT;
import com.fr.third.com.lowagie.text.Chunk;
import com.fr.third.lowagie.text.html.simpleparser.HTMLWorker;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.List;
import org.jetbrains.annotations.NotNull;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/18
*/
@EnableMetrics
public class HtmlParserImpl extends AbstractHtmlParser {
public HtmlParserImpl() {
init();
}
@Focus(id = "com.fr.plugin.html.parse", text = "FR-Plugin_html_parse", source = Original.PLUGIN)
protected void init() {
}
@Override
public @NotNull UNIT getHtmlHeight(String html, UNIT width, Style style, int resolution) {
return HtmlUtils.getHtmlHeight(html, width, style, resolution);
}
@Override
public @NotNull String clipHtml(String html, Rectangle rec, int startY, int endY, Style style, int resolution) {
return HtmlUtils.clipHtml(html, style, rec, startY, endY, resolution);
}
@Override
public void paintHtml(@NotNull Graphics2D g2d, String html, @NotNull Rectangle rec, Style style, int resolution) {
try {
HtmlUtils.html2HtmlContainer(html, rec.width, rec.height, style, resolution).paint(g2d);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
g2d.dispose();
}
@Override
public @NotNull RichText htmlToRichText(String html, Style style, int resolution, HtmlCheckParamWraper wraper) {
try {
HTMLWorker.allowInlineElementInheritBlockElementBackground();
return Html2RichTextUtils.html2RichText(html, style, wraper);
} finally {
HTMLWorker.resetInlineElementInheritBlockElementBackground();
}
}
@Override
public @NotNull List<Chunk> htmlToChunkList(String html, Style style, int resolution, HtmlCheckParamWraper wraper) {
try {
HTMLWorker.allowInlineElementInheritBlockElementBackground();
return Html2ChunkUtils.html2OtherChunkList(html, style, wraper);
} finally {
HTMLWorker.resetInlineElementInheritBlockElementBackground();
}
}
}

676
src/main/java/com/fr/plugin/html/parse/block/HtmlParagraph.java

@ -0,0 +1,676 @@
package com.fr.plugin.html.parse.block;
import com.fr.base.Base64;
import com.fr.base.BaseUtils;
import com.fr.base.Style;
import com.fr.base.background.ColorBackground;
import com.fr.base.background.ImageBackground;
import com.fr.general.Background;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.AbstractHtmlBlock;
import com.fr.plugin.html.parse.utils.HtmlBackgroundUtils;
import com.fr.plugin.html.parse.utils.HtmlBorderUtils;
import com.fr.plugin.html.parse.utils.HtmlUtils;
import com.fr.report.core.utils.WebUnit;
import com.fr.stable.AssistUtils;
import com.fr.stable.Constants;
import com.fr.stable.FontMeasureAction;
import com.fr.stable.GraphDrawHelper;
import com.fr.stable.StringUtils;
import com.fr.third.com.lowagie.text.pdf.PdfGraphics2D;
import com.fr.third.lowagie.text.Chunk;
import com.fr.third.lowagie.text.DocumentException;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.Image;
import com.fr.third.lowagie.text.List;
import com.fr.third.lowagie.text.ListItem;
import com.fr.third.lowagie.text.Paragraph;
import com.fr.third.lowagie.text.html.BorderAttribute;
import com.fr.third.lowagie.text.html.CSS;
import com.fr.third.lowagie.text.html.CSSUtils;
import com.fr.third.lowagie.text.html.HtmlTags;
import com.fr.third.lowagie.text.html.Markup;
import com.fr.third.lowagie.text.html.ParseIndentAttrUtils;
import com.fr.third.lowagie.text.html.simpleparser.ChainedProperties;
import com.fr.third.lowagie.text.html.utils.BackgroundUtil;
import com.fr.third.lowagie.text.pdf.PdfChunk;
import com.fr.third.lowagie.text.pdf.PdfFont;
import com.fr.third.lowagie.text.pdf.PdfLine;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author kerry
* @date 2018/5/2
*/
public class HtmlParagraph extends AbstractHtmlBlock {
private static final HashMap otherAttributes = new HashMap();
static {
otherAttributes.put(CSS.Property.WIDTH, null);
otherAttributes.put(CSS.Property.HEIGHT, null);
otherAttributes.put("noexist-attrid", null);
otherAttributes.put("background-size", null);
otherAttributes.put("background-color", null);
otherAttributes.put("background-image", null);
otherAttributes.put("background", null);
}
private static final int SCALE = 100;
protected PdfLine line = null;
protected java.util.List<PdfLine> lines = new ArrayList<PdfLine>();
public String getBackground() {
return background;
}
public void setBackground(String background) {
this.background = background;
}
private String background;
private BorderAttribute borderAttr;
private float x = 0.0f;
private float y = 0.0f;
private static final float DEFAULT_LINE_HEIGHT = 0.0f;
//当前高度
protected float currentHeight = 0.0f;
protected int alignment = Element.ALIGN_UNDEFINED;
protected float width;
protected float height;
private Style style = Style.getInstance();
private int resolution = Constants.FR_PAINT_RESOLUTION;
//首行缩进
protected float text_indent;
private float lineHeight;
private HashMap attributes = new HashMap();
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public PdfLine getLine() {
return line;
}
public void setLine(PdfLine line) {
this.line = line;
}
public java.util.List<PdfLine> getLines() {
return lines;
}
public void setLines(ArrayList lines) {
this.lines = lines;
}
public HtmlParagraph() {
}
public HtmlParagraph(float width, float height) {
this.width = width;
this.height = height;
}
public HtmlParagraph(float width, float height, Style style, int resolution) {
this.width = width;
this.height = height;
this.style = null == style ? Style.getInstance() : style;
this.resolution = resolution;
}
/**
* 从paragraph对象中获取其他属性
*
* @param paragraph paragraph对象
* @return PdfParagraph对象
*/
public HtmlParagraph getOtherAttribute(Paragraph paragraph) {
HashMap attr = paragraph.getAttributes();
this.borderAttr = paragraph.getBorderAttr();
this.padding = ParseIndentAttrUtils.parsePaddingAttribute(attr);
this.margin = ParseIndentAttrUtils.parseMarginAttribute(attr);
this.border = ParseIndentAttrUtils.parseBorderAttribute(this.borderAttr);
this.text_indent = paragraph.getFirstLineIndent();
this.alignment = HtmlUtils.htmlAlign2FrAlign(paragraph.getAlignment(), style);
if (attr.containsKey("line-height")) {
this.lineHeight = WebUnit.parse((String) attr.get("line-height")).toFloatValue(0, 12, 96, 0);
}
if (attr != null) {
for (Iterator i = attr.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry) i.next();
Object name = entry.getKey();
if (otherAttributes.containsKey(name)) {
attributes.put(name, entry.getValue());
}
}
}
if (attr.get(CSS.Property.WIDTH) != null ) {
String w = (String) attr.get(CSS.Property.WIDTH);
float length = Markup.parseLength(w);
float paddingLength = attr.containsKey("CellWidth") ? 0 : padding.getLeft() + padding.getRight() + margin.getLeft() + margin.getRight();
width = w.endsWith("%") ? width * length / 100f + paddingLength : length + paddingLength;
}
//这里没用到,高度都是后面计算出来的,attr中没包含 height,浏览器中指定高度也没啥用,会根据内容撑开
if (attr.get(CSS.Property.HEIGHT) != null) {
String h = (String) attr.get(CSS.Property.HEIGHT);
height = Markup.parseLength(h) + padding.getTop() + padding.getBottom();
}
return this;
}
/**
* 向container中添加PdfElement
*
* @param element
* @param style 单元格的样式(用来和html解析出来的样式统一)
*/
public boolean add(Element element, Style style) throws DocumentException {
try {
switch (element.type()) {
case Element.CHUNK: {
if (line == null) {
//首行需要添加缩进
line = new PdfLine(margin.getLeft() + padding.getLeft() + border.getLeft() + text_indent,
width - margin.getRight() - padding.getRight() - border.getRight(), alignment, DEFAULT_LINE_HEIGHT);
}
Chunk ck = (Chunk) element;
PdfChunk chunk = new PdfChunk(ck, null);
{
PdfChunk overflow;
while ((overflow = line.add(chunk)) != null) {
carriageReturn();
chunk = overflow;
chunk.trimFirstSpace();
}
}
break;
}
case Element.PARAGRAPH: {
//todo paragraph应该有单独的背景属性,对生成后的lines都添加background
Paragraph paragraph = (Paragraph) element;
carriageReturn();
Iterator a = paragraph.iterator();
while (a.hasNext()) {
this.add((Element) a.next(), style);
}
carriageReturn();
break;
}
case Element.LIST: {
List list = (List) element;
if (list.isAlignindent()) {
list.normalizeIndentation();
}
for (Iterator i = list.getList().iterator(); i.hasNext(); ) {
add((Element) i.next(), style);
}
carriageReturn();
break;
}
case Element.LISTITEM: {
ListItem listItem = (ListItem) element;
alignment = listItem.getAlignment();
carriageReturn();
line.setListItem(listItem);
add(listItem.getListSymbol(), style);
for (Iterator i = listItem.iterator(); i.hasNext(); ) {
add((Element) i.next(), style);
}
if (line.hasToBeJustified()) {
line.resetAlignment();
}
carriageReturn();
break;
}
default:
return false;
}
return true;
} catch (Exception e) {
throw new DocumentException(e);
}
}
/**
* 将pdfLine对象添加到lines中并生产新的pdfLine
*/
protected void carriageReturn() {
if (lines == null) {
lines = new ArrayList();
}
if (line != null) {
if (line.size() > 0) {
currentHeight += line.height();
lines.add(line);
}
}
line = new PdfLine(margin.getLeft() + padding.getLeft() + border.getLeft(),
width - margin.getRight() - padding.getRight() - border.getRight(), alignment, DEFAULT_LINE_HEIGHT);
}
/**
* 将line对象绘制到pdf上
*
* @param line 渲染行对象
* @param graphics pdf图形对象
* @param style 单元格样式
*/
void writeLineToContent(PdfLine line, Graphics2D graphics, Style style) throws DocumentException {
PdfChunk chunk;
float lineY = getLineY(line, graphics, style);
for (Iterator j = line.iterator(); j.hasNext(); ) {
chunk = (PdfChunk) j.next();
String url = chunk.getHyperlink();
if (chunk.isImage()) {
drawChunkBackground(graphics, chunk, x, y, 1);
Image image = chunk.getImage();
String src = image.getSrcString();
java.awt.Image awtImg = null;
try {
//处理base64编码图片
if (src.startsWith("data")) {
String[] srcArray = src.split(",");
String base64string = srcArray[srcArray.length - 1];
awtImg = Base64.base64Decoder(base64string);
} else {
awtImg = BaseUtils.readImage(src);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
HtmlUtils.setHyperlink(graphics, url);
graphics.drawImage(awtImg, (int) (x + chunk.getLeftIndent()), (int) (lineY - image.getScaledHeight()), (int) image.getScaledWidth(), (int) image.getScaledHeight(), null);
HtmlUtils.undoHyperlink(graphics, url);
x += image.getScaledWidth();
continue;
}
//将解析出来的font转换成FRfont
String value = chunk.toString();
int scale = 1;
if (needZoom(graphics, chunk.getFont().getAwtFont(), url)) {
scale = SCALE;
}
FRFont font = parseFRFont(chunk, style, scale);
graphics.setColor(font.getForeground());
Font oldFont = graphics.getFont();
graphics.setFont(font);
//TextRise : 上下标Y轴偏差
float scaleX = (x + chunk.getLeftIndent()) * scale;
float scaleY = (lineY - (line.neddRiseOrDrop() ? chunk.getTextRise() : 0)) * scale;
drawChunkBackground(graphics, chunk, scaleX, scaleY, scale);
graphics.scale(1f / scale, 1f / scale);
HtmlUtils.setHyperlink(graphics, url);
GraphDrawHelper.drawString(graphics, value, scaleX, scaleY, new PdfFontMeasureAction(chunk.getFont(), scale), scale);
HtmlUtils.undoHyperlink(graphics, url);
graphics.setFont(oldFont);
graphics.scale(scale, scale);
x += chunk.width();
}
}
/**
* 绘制chunk背景
*
* @param g2d
* @param chunk
*/
private void drawChunkBackground(Graphics2D g2d, PdfChunk chunk, float x, float y, int scale) {
Object attr = chunk.getAttribute(Chunk.BACKGROUND);
if (null == attr) {
return;
}
parseAndDrawBackground(g2d, calcuChunkBackgroundRectangle(g2d, chunk, x, y, scale), (String) ((Object[]) attr)[0]);
}
/**
* 计算chunk 背景Rectangle
*
* @param g2d
* @param chunk
* @param x
* @param y
* @param scale
* @return
*/
private Rectangle2D calcuChunkBackgroundRectangle(Graphics2D g2d, PdfChunk chunk, float x, float y, int scale) {
Rectangle2D r2d = null;
if (chunk.isImage()) {
r2d = new Rectangle2D.Float(x, y, chunk.width(), chunk.getHeight());
} else {
FontMetrics fontMetrics = g2d.getFontMetrics();
r2d = new Rectangle2D.Float(x / scale, (y - fontMetrics.getAscent()) / scale,
chunk.width(), (fontMetrics.getDescent() + fontMetrics.getAscent()) / scale);
}
return r2d;
}
/**
* ture: 可以进行放大绘制 PSpdf 中的粗体和斜体不能进行放大绘制
*
* @param g2d
* @param font
* @return
*/
private boolean needZoom(Graphics2D g2d, Font font, String url) {
return !(g2d instanceof PdfGraphics2D && (font.isBold() || font.isItalic() || StringUtils.isNotEmpty(url)));
}
/**
* 获取行的Y坐标 ps需要在同一水平线上画
*
* @param line
* @param graphics
* @param style
* @return
*/
private float getLineY(PdfLine line, Graphics2D graphics, Style style) {
float maxLinespacing = 0;
float maxAscen = 0;
float maxHeight = 0;
float offsetY = 0;
for (Iterator j = line.iterator(); j.hasNext(); ) {
PdfChunk chunk = (PdfChunk) j.next();
if (chunk.isImage()) {
Image image = chunk.getImage();
offsetY = Math.max(offsetY, image.getScaledHeight());
continue;
}
//将解析出来的font转换成FRfont
FRFont font = parseFRFont(chunk, style);
Font oldFont = graphics.getFont();
graphics.setFont(font);
FontMetrics fontMetrics = graphics.getFontMetrics();
maxLinespacing = Math.max(maxLinespacing, lineHeight > 0 ? (lineHeight - (float) fontMetrics.getHeight()) / 2 : 0);
maxAscen = Math.max(maxAscen, fontMetrics.getAscent());
maxHeight = Math.max(maxHeight, chunk.getHeight());
graphics.setFont(oldFont);
}
offsetY = offsetY != 0 ? offsetY - maxHeight : offsetY;
return y + maxLinespacing + (offsetY != 0 ? maxHeight : maxAscen) + (line.neddRiseOrDrop() && !line.imgBigThanText() ? line.getMaxTextRise() : 0) + offsetY;
}
class PdfFontMeasureAction implements FontMeasureAction {
private PdfFont pdfFont;
private int scale = 1;
public PdfFontMeasureAction(PdfFont font, int scale) {
this.pdfFont = font;
this.scale = scale;
}
@Override
public float charWidth(Font font, char c) {
return pdfFont.width(c) * scale;
}
@Override
public float stringWidth(Font font, String str) {
return pdfFont.width(str) * scale;
}
}
private FRFont parseFRFont(PdfChunk chunk, Style style) {
return parseFRFont(chunk, style, 1);
}
private FRFont parseFRFont(PdfChunk chunk, Style style, int scale) {
com.fr.third.lowagie.text.Font pdfFont = chunk.getFont().getOriFont();
float fontSize = pdfFont.getSize() * (chunk.getTextRise() != 0 ? PdfChunk.SUB_PERCENT : 1) * scale;
int underLine = pdfFont.isUnderlined() ? Constants.LINE_THIN : style.getFRFont().getUnderline();
FRFont font = style.getFRFont();
font = font.applyUnderline(underLine).applyStrikethrough(pdfFont.isStrikethru()).applyName(pdfFont.getFontName()).
applyStyle(pdfFont.getStyle()).applySize(fontSize).applyForeground(pdfFont.getColor());
return font;
}
/**
* 解析并绘制背景
*
* @param graphics pdf图形对象
* @param rectangle 绘制区域
* @param backgroundString background 字符串
*/
private void parseAndDrawBackground(Graphics2D graphics, Rectangle2D rectangle, String backgroundString) {
Background back = null;
//todo 解析background属性(先简单解析下img和color,可能还要解析repeat、fixed、position等属性)
Map<String, String> backgroundStyles = CSSUtils.processBackground(backgroundString);
for (String backgroundKey : backgroundStyles.keySet()) {
if (backgroundKey.equals("background-color")) {
back = ColorBackground.getInstance(Markup.decodeColor(backgroundStyles.get(backgroundKey)));
} else if (backgroundKey.equals("background-image")) {
try {
String value = backgroundStyles.get(backgroundKey);
String url = CSSUtils.extractUrl(value);
BufferedImage image = IOUtils.readImage(url);
back = new ImageBackground(image);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
if (back != null) {
back.paint(graphics, rectangle);
}
}
/**
* 进行绘制
*
* @param g2d pdf图形对象
* @param style 单元格样式
*/
public void paint(Graphics2D g2d, Style style) throws Exception {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
if (lines == null) {
return;
}
if (line != null && line.size() > 0) {
lines.add(line);
line = new PdfLine(margin.getLeft() + padding.getLeft() + border.getLeft(),
width - margin.getRight() - padding.getRight() - border.getRight(), alignment, DEFAULT_LINE_HEIGHT);
}
if (lines.isEmpty()) {
return;
}
PdfLine l;
Rectangle2D.Float r2d = calBorderRectangle();
paintBackground(g2d, r2d);
//确定起始位置
y += this.padding.getTop() + this.border.getTop();
x = text_indent + this.border.getLeft();
for (int i = 0; i < lines.size(); i++) {
l = lines.get(i);
x += this.padding.getLeft() + this.getMargin().getLeft() + this.border.getLeft();
applyTextAlignment(i == 0 ? width - text_indent : width, style, l);
writeLineToContent(l, g2d, style);
y += lineHeight > 0 ? lineHeight : l.getHeight();
x = 0;
}
HtmlBorderUtils.drawBlockBorder(g2d, r2d, borderAttr);
lines = new ArrayList();
}
/**
* 绘制背景
*
* @param g2d pdf图形对象
*/
private void paintBackground(Graphics2D g2d, Rectangle2D.Float r2d) {
ChainedProperties props = new ChainedProperties();
props.addToChain(HtmlTags.DIV, attributes);
Map<String, String> map = BackgroundUtil.parse2RulesMap(props);
if (null != map) {
HtmlBackgroundUtils.parseAndDrawBackground(g2d, r2d,
map, style.getFRFont().getSize(), resolution);
}
}
/**
* 计算边框矩形
*
* @return
*/
private Rectangle.Float calBorderRectangle() {
return new Rectangle2D.Float(x + margin.getLeft() + border.getLeft() / 2, y + border.getTop() / 2,
width - margin.getLeft() - margin.getRight() - (border.getLeft() + border.getRight()) / 2,
height - (border.getTop() + border.getBottom()) / 2);
}
/**
* pdfLine进行水平居中处理
*
* @param width 宽度
* @param style 单元格样式
* @param line 渲染行
*/
private void applyTextAlignment(float width, Style style, PdfLine line) {
if (alignment != Element.ALIGN_UNDEFINED) {
style = style.deriveHorizontalAlignment(alignment);
}
int textAlignment = BaseUtils.getAlignment4Horizontal(style, StringUtils.EMPTY);
float totalWidth = 0;
for (Iterator j = line.iterator(); j.hasNext(); ) {
totalWidth += ((PdfChunk) j.next()).width();
}
width -= (margin.getLeft() + margin.getRight() + padding.getLeft() + padding.getRight() + border.getLeft() + border.getRight());
switch (textAlignment) {
case Constants.CENTER: {
float deltaX = width - totalWidth;
x += deltaX / 2;
break;
}
case Constants.RIGHT: {
float deltaX = width - totalWidth;
x += deltaX;
break;
}
}
}
/**
* 计算渲染行高度
*/
public void calculateHeight() {
carriageReturn();
if (!AssistUtils.equals(height, 0.0F)) {
return;
}
PdfLine l;
float innerHeight = padding.getTop() + border.getTop();
for (int i = 0; i < lines.size(); i++) {
l = lines.get(i);
innerHeight += lineHeight > 0 ? lineHeight : l.getHeight();
}
innerHeight += padding.getBottom() + border.getBottom();
setHeight(innerHeight);
}
/**
* 将渲染行转换成对应的html字符串
*
* @param lineStartY 起始行
* @param lineEndY 结束行
* @return html字符串
*/
@Override
public String toHtml(double lineStartY, double lineEndY) {
boolean hasElement = false;
StringBuffer sb = new StringBuffer();
float currentHeight = 0.0f;
sb.append("<div style='");
if (attrFromOriginalHtml("line-height") && lineHeight > 0) {
sb.append("line-height:" + lineHeight + "px;");
}
if (HtmlUtils.inClipArea(currentHeight, currentHeight + lines.get(0).getHeight(), lineStartY, lineEndY)) {
sb.append("text-indent:").append(this.text_indent).append("px;");
ParseIndentAttrUtils.createIndent(sb, CSS.Property.PADDING, padding);
ParseIndentAttrUtils.createIndent(sb, CSS.Property.MARGIN, margin);
if (null != borderAttr) {
sb.append(borderAttr.toStyleAttr());
}
}
sb.append(getStyleAttributes()).append("'>");
for (PdfLine l : lines) {
if (HtmlUtils.inClipArea(currentHeight, currentHeight + l.getHeight(), lineStartY, lineEndY)) {
hasElement = true;
for (int i = 0; i < l.size(); i++) {
sb.append(l.getChunk(i).toHtmlString());
}
}
currentHeight += lineHeight > 0 ? lineHeight : l.getHeight();
}
sb.append("</div>");
return hasElement ? sb.toString() : StringUtils.EMPTY;
}
/**
* 判断属性是否来自原始HTML
*
* @param attr 属性
* @return true 存在于原始HTML
*/
private boolean attrFromOriginalHtml(String attr) {
Object value = attributes.get("noexist-attrid");
if (null == value || !(value instanceof String)) {
return true;
}
return !((String) value).contains(attr);
}
/**
* 拼接style样式字符串
*
* @return style样式字符串
*/
private String getStyleAttributes() {
StringBuffer stringBuffer = new StringBuffer();
Iterator iter = attributes.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
String val = (String) entry.getValue();
stringBuffer.append(key).append(":").append(val).append(";");
}
return stringBuffer.toString();
}
}

213
src/main/java/com/fr/plugin/html/parse/block/HtmlTable.java

@ -0,0 +1,213 @@
package com.fr.plugin.html.parse.block;
import com.fr.base.Style;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.AbstractHtmlBlock;
import com.fr.plugin.html.parse.HtmlContainer;
import com.fr.plugin.html.parse.utils.HtmlBackgroundUtils;
import com.fr.plugin.html.parse.utils.HtmlBorderUtils;
import com.fr.plugin.html.parse.utils.HtmlUtils;
import com.fr.stable.CommonUtils;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.pdf.BorderStyle;
import com.fr.third.lowagie.text.pdf.ColumnText;
import com.fr.third.lowagie.text.pdf.PdfPCell;
import com.fr.third.lowagie.text.pdf.PdfPRow;
import com.fr.third.lowagie.text.pdf.PdfPTable;
import com.fr.third.lowagie.text.pdf.TableProperties;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.Map;
public class HtmlTable extends AbstractHtmlBlock {
private float width;
private Style style;
private int resolution;
public PdfPTable getPdfPTable() {
return pdfPTable;
}
private PdfPTable pdfPTable;
public HtmlTable(float width, Style style, int resolution) {
this.width = width;
this.style = style;
this.resolution = resolution;
}
@SuppressWarnings("squid:S2164")
public void addPdfPTable(PdfPTable ptable) {
pdfPTable = ptable;
TableProperties tableProperties = pdfPTable.getTableProperties();
BorderStyle borderStyle = tableProperties.getBorderStyle();
float borderWidth = borderStyle.getBorderWidth();
if (CommonUtils.equals(ptable.getTotalWidth(), 0.0f)) {
ptable.setTotalWidth(width * ptable.getWidthPercentage() / 100 - borderWidth * 2);
}
java.util.List<PdfPRow> rows = ptable.getRows();
for (PdfPRow row : rows) {
PdfPCell[] cells = row.getCells();
for (PdfPCell cell : cells) {
if (cell == null) {
continue;
}
cell.addContent(createHtmlContainerFromColumText(cell.getWidth(), cell.getColumn()));
}
}
this.pdfPTable.calculateHeights(true);
}
private HtmlContainer createHtmlContainerFromColumText(float tableWidth, ColumnText columnText) {
Style cellStyle;
switch (columnText.getAlignment()) {
case 0:
cellStyle = style.deriveHorizontalAlignment(Constants.LEFT);
break;
case 1:
cellStyle = style.deriveHorizontalAlignment(Constants.CENTER);
break;
case 2:
cellStyle = style.deriveHorizontalAlignment(Constants.RIGHT);
break;
default:
cellStyle = style;
}
//由cellPadding 决定cell 的padiing 值,这边是多余的,给置为0
cellStyle = cellStyle.derivePadding(0, 0);
HtmlContainer container = new HtmlContainer(tableWidth, 0, cellStyle, resolution);
if (columnText.getCompositeElements() != null) {
try {
for (Object element : (columnText.getCompositeElements())) {
Element e = (Element) element;
container.add(e);
}
container.calculateHeight();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return container;
}
@Override
@SuppressWarnings("squid:S2164")
public void paint(Graphics2D g2d, Style style) throws Exception {
java.util.List<PdfPRow> rows = pdfPTable.getRows();
TableProperties tableProperties = pdfPTable.getTableProperties();
if (tableProperties.getBackground() != null) {
HtmlBackgroundUtils.parseAndDrawBackground(g2d, new Rectangle2D.Float(0, 0, pdfPTable.getTotalWidth(), pdfPTable.getTotalHeight()), tableProperties.getBackground(), style.getFRFont().getSize(), resolution);
}
BorderStyle borderStyle = tableProperties.getBorderStyle();
float borderWidth = borderStyle.getBorderWidth();
float halfBorderWidth = borderWidth / 2;
float cellspacing = tableProperties.getCellspacing();
float cellpadding = tableProperties.getCellpadding();
float middleBorderWidth = 0 == cellspacing ? borderWidth : borderWidth * 2;
float tableY = middleBorderWidth + cellspacing - halfBorderWidth;
float outsideWidthOfContent = halfBorderWidth + cellpadding;
for (PdfPRow row : rows) {
float tableX = middleBorderWidth + cellspacing - halfBorderWidth;
float rowHeight = row.getMaxHeights();
PdfPCell[] cells = row.getCells();
for (PdfPCell cell : cells) {
if (cell == null) {
continue;
}
((HtmlContainer) cell.getContainer()).setHeight(rowHeight);
if (!cell.isInvalid()) {
g2d.translate(tableX, tableY);
if (cell.getBackground() != null) {
HtmlBackgroundUtils.parseAndDrawBackground(g2d, new Rectangle2D.Float(0, 0, cell.getWidth() + cellpadding * 2, rowHeight + cellpadding * 2), cell.getBackground(), style.getFRFont().getSize(), resolution);
}
HtmlBorderUtils.drawBlockBorder(g2d, 0, 0, (int) (cell.getWidth() + borderWidth + cellpadding * 2), (int) (rowHeight + borderWidth + cellpadding * 2), borderStyle);
g2d.translate(-tableX, -tableY);
}
g2d.translate(tableX + outsideWidthOfContent, tableY + outsideWidthOfContent);
cell.getContainer().paint(g2d);
g2d.translate(-tableX - outsideWidthOfContent, -tableY - outsideWidthOfContent);
tableX += cell.getWidth() + middleBorderWidth + cellpadding * 2 + cellspacing;
}
tableY += rowHeight + middleBorderWidth + cellpadding * 2 + cellspacing;
}
HtmlBorderUtils.drawBlockBorder(g2d, 0, 0, (int) (pdfPTable.getTotalWidth()), (int) (pdfPTable.getTotalHeight()), borderStyle);
}
@Override
public float getHeight() {
return pdfPTable.getTotalHeight();
}
@Override
public void calculateHeight() {
}
@Override
public String toHtml(double startY, double endY) {
boolean hasElement = false;
StringBuffer sb = new StringBuffer();
float currentHeight = 0.0f;
TableProperties properties = pdfPTable.getTableProperties();
sb.append("<table ").append(properties.toHtmlString());
sb.append("style='").append(background2StyleAttr(properties.getBackground()))
.append(StringUtils.isEmpty(properties.getLayout()) ? StringUtils.EMPTY : "table-layout:" + properties.getLayout() + ";")
.append("border-collapse:").append(properties.isCollapse() ? "collapse" : "separate")
.append(";").append("width:").append(this.pdfPTable.getTotalWidth()).append("px;'>");
for (Object r : pdfPTable.getRows()) {
PdfPRow row = (PdfPRow) r;
float rowHeight = row.getMaxHeights();
if (HtmlUtils.inClipArea(currentHeight, currentHeight + rowHeight, startY, endY)) {
hasElement = true;
if (row.getStyleHeight() != 0) {
sb.append("<tr style='height:").append(row.getStyleHeight()).append("px;'>");
} else {
sb.append("<tr>");
}
for (PdfPCell cell : row.getCells()) {
if (cell == null) {
continue;
}
if (cell.getStyleWidth() == 0) {
sb.append("<td");
if (null != cell.getBackground() && cell.getBackground().size() > 0) {
sb.append(" style='").append(background2StyleAttr(cell.getBackground())).append("'");
}
sb.append(" colspan='").append(cell.getColspan()).append("'>").append(cell.getContainer().getHtml(0, rowHeight)).append("</td>");
} else {
sb.append("<td style='width:").append(cell.getStyleWidth()).append("px;").append(background2StyleAttr(cell.getBackground())).append("' colspan='")
.append(cell.getColspan()).append("'>").append(cell.getContainer().getHtml(0, rowHeight)).append("</td>");
}
}
sb.append("</tr>");
}
currentHeight += row.getMaxHeights();
}
sb.append("</table>");
return hasElement ? sb.toString() : StringUtils.EMPTY;
}
/**
* 背景属性转换成 html中的style
*
* @return
*/
private String background2StyleAttr(Map<String, String> background) {
if (null == background) {
return StringUtils.EMPTY;
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : background.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
sb.append(entry.getKey()).append(":").append(entry.getValue()).append(";");
}
return sb.toString();
}
}

44
src/main/java/com/fr/plugin/html/parse/config/ParseCheckConfig.java

@ -0,0 +1,44 @@
package com.fr.plugin.html.parse.config;
import com.fr.config.ConfigContext;
import com.fr.config.DefaultConfiguration;
import com.fr.config.Identifier;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/19
*/
public class ParseCheckConfig extends DefaultConfiguration {
private static volatile ParseCheckConfig instance = null;
@Identifier("allowDrawing")
private Conf<Boolean> allowDrawing = Holders.simple(true);
private ParseCheckConfig() {
}
public static ParseCheckConfig getInstance() {
if (instance == null) {
synchronized (ParseCheckConfig.class) {
if (instance == null) {
instance = ConfigContext.getConfigInstance(ParseCheckConfig.class);
}
}
}
return instance;
}
public boolean allowDrawing() {
return allowDrawing.get();
}
public Object clone() throws CloneNotSupportedException {
ParseCheckConfig clone = (ParseCheckConfig) super.clone();
clone.allowDrawing = (Conf) this.allowDrawing.clone();
return clone;
}
}

279
src/main/java/com/fr/plugin/html/parse/utils/Html2ChunkUtils.java

@ -0,0 +1,279 @@
package com.fr.plugin.html.parse.utils;
import com.fr.base.Style;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.config.ParseCheckConfig;
import com.fr.report.core.Html2ImageUtils;
import com.fr.stable.HtmlCheckParamWraper;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.lowagie.text.Chunk;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.Font;
import com.fr.third.lowagie.text.ListItem;
import com.fr.third.lowagie.text.Paragraph;
import com.fr.third.lowagie.text.html.Markup;
import com.fr.third.lowagie.text.html.simpleparser.HTMLWorker;
import com.fr.third.lowagie.text.html.simpleparser.StyleSheet;
import com.fr.third.lowagie.text.pdf.PdfPCell;
import com.fr.third.lowagie.text.pdf.PdfPRow;
import com.fr.third.lowagie.text.pdf.PdfPTable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.jetbrains.annotations.NotNull;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/19
*/
public class Html2ChunkUtils {
private static Chunk BREAK_LINE = new Chunk("\n", new Font(StringUtils.EMPTY, Font.UNDEFINED, Font.UNDEFINED, null));
public static @NotNull List<Chunk> html2ChunkList(String html, Style style, HtmlCheckParamWraper wraper) {
if (StringUtils.isEmpty(html)) {
return new ArrayList<>();
}
html = HtmlUtils.wrapperSpan(html, style);
html = Html2ImageUtils.convertPx2Pt(html);
ArrayList<Chunk> chunkList = new ArrayList<>();
List<Element> elementList;
//段落列表
try {
// 这边不用使用itext的Font对象,直接用解析出来的字体属性构建FRFont,否则第一次加载itext提供的字体的时间较长
elementList = HTMLWorker.parseToList(new StringReader(html), new StyleSheet());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
//不返回空白内容,替换掉html中标签, 返回纯文本
String content = HtmlUtils.splitAndFilterString(html);
chunkList.add(new Chunk(content));
return chunkList;
}
TagAttrCheck check = null == wraper ? new TagAttrCheck() :
new TagAttrCheck(wraper.getNotSupportTag(), wraper.getNotSupportAttr(), wraper.getIgnoreTag());
for (int i = 0; i < elementList.size(); i++) {
Element element = elementList.get(i);
boolean needBreakLine = i != (elementList.size() - 1);
checkAndAddChunk(element, chunkList, needBreakLine, check);
}
return chunkList;
}
public static List<com.fr.third.com.lowagie.text.Chunk> html2OtherChunkList(String html, Style style, HtmlCheckParamWraper wraper) {
return toOtherChunkList(html2ChunkList(html, style, wraper), style);
}
private static void checkAndAddChunk(Element element, List<Chunk> chunkList, boolean needBreakLine, TagAttrCheck check) {
check.check(element);
switch (element.type()) {
case Element.PARAGRAPH:
Paragraph paragraph = (Paragraph) element;
//为了兼容,只检查是否含需要忽略的标签
TagAttrCheck chunkCheck = new TagAttrCheck(null, null, check.getIgnoreTag());
for (Iterator i = paragraph.getChunks().iterator(); i.hasNext(); ) {
Element e = (Element) i.next();
checkAndAddChunk(e, chunkList, false, chunkCheck);
}
appendBreakLine(needBreakLine, chunkList);
break;
case Element.CHUNK:
Chunk chunk = (Chunk) element;
if (null != chunk.getImage() && check.ignoreTagContent("img", true)) {
break;
}
chunkList.add(chunk);
appendBreakLine(needBreakLine, chunkList);
break;
case Element.LIST:
//<ul><ol>标签
com.fr.third.lowagie.text.List list = (com.fr.third.lowagie.text.List) element;
for (Iterator i = list.getItems().iterator(); i.hasNext(); ) {
Element e = (Element) i.next();
checkAndAddChunk(e, chunkList, needBreakLine, check);
}
break;
case Element.LISTITEM:
//li标签解析出来自带换行
ListItem listItem = (ListItem) element;
if (null != listItem.getListSymbol()) {
chunkList.add(listItem.getListSymbol());
}
chunkList.addAll(listItem.getChunks());
break;
case Element.PTABLE:
if (check.ignoreTagContent("table", true)) {
break;
}
PdfPTable table = (PdfPTable) element;
java.util.List<PdfPRow> rows = table.getRows();
for (int i = 0; i < rows.size(); i++) {
PdfPCell[] cells = rows.get(i).getCells();
for (PdfPCell cell : cells) {
if (null == cell || null == cell.getColumn() || null == cell.getColumn().getCompositeElements()) {
continue;
}
for (Object obj : cell.getColumn().getCompositeElements()) {
checkAndAddChunk((Element) obj, chunkList, false, check);
}
}
if (i != rows.size() - 1) {
appendBreakLine(true, chunkList);
}
}
appendBreakLine(needBreakLine, chunkList);
default:
return;
}
}
//段落里解析出来的Chunk, 相互之间要加上换行, 例如<div><p>等等
private static void appendBreakLine(boolean needBreakLine, List<Chunk> chunkList) {
if (needBreakLine) {
chunkList.add(BREAK_LINE);
}
}
private static List<com.fr.third.com.lowagie.text.Chunk> toOtherChunkList(List<Chunk> chunkList, Style style) {
List<com.fr.third.com.lowagie.text.Chunk> oldChunkList = new ArrayList<>();
if (!CollectionUtils.isEmpty(chunkList)) {
chunkList.stream().forEach(item -> {
Font font = item.getFont();
HtmlUtils.dealWithUnderLine(style, font);
com.fr.third.com.lowagie.text.Chunk chunk = new com.fr.third.com.lowagie.text.Chunk(item.getContent(),
new com.fr.third.com.lowagie.text.Font(null == font.getFontName() ? StringUtils.EMPTY : font.getFontName(), font.getSize(), font.getStyle(), font.getColor()));
//防止npe
HashMap attrMap = null == item.getAttributes() ? new HashMap() : item.getAttributes();
attrMap.remove(Chunk.IMAGE);
if (item.getOldImage() != null) {
attrMap.put(Chunk.IMAGE, new Object[]{item.getOldImage(), new Float(0),
new Float(0), Boolean.FALSE});
attrMap.remove(Chunk.OLD_IMAGE);
}
chunk.setAttributes(attrMap);
oldChunkList.add(chunk);
});
}
return oldChunkList;
}
static class TagAttrCheck {
private List<String> notSupportTag;
private List<String> notSupportAttr;
private List<String> ignoreTag;
public TagAttrCheck() {
this.notSupportTag = new ArrayList<>();
this.notSupportAttr = new ArrayList<>();
this.ignoreTag = new ArrayList<>();
}
public TagAttrCheck(List<String> notSupportTag, List<String> notSupportAttr, List<String> ignoreTag) {
this.notSupportTag = null == notSupportTag ? new ArrayList<>() : notSupportTag;
this.notSupportAttr = null == notSupportAttr ? new ArrayList<>() : notSupportAttr;
this.ignoreTag = null == ignoreTag ? new ArrayList<>() : ignoreTag;
}
public List<String> getIgnoreTag() {
return ignoreTag;
}
/**
* 检测是否含有不支持的属性 or 标签
*
* @return boolean
*/
public void check(Element element) throws UnsupportedOperationException {
switch (element.type()) {
case Element.PARAGRAPH:
Paragraph paragraph = (Paragraph) element;
checkAttr(paragraph.getAttributes());
paragraph.getChunks().stream().forEach(item -> check((Element) item));
break;
case Element.CHUNK:
Chunk chunk = (Chunk) element;
if (null != chunk.getImage()) {
checkTag("img");
}
// Chunk 中背景颜色|图片 都叫 background ,特殊对待一下
HashMap chunkAttr = chunk.getAttributes();
if (chunkAttr.get(Chunk.BACKGROUND) != null) {
String background = (String) ((Object[]) chunkAttr.get(Chunk.BACKGROUND))[0];
if (null == Markup.decodeColor(background)) {
chunkAttr.put("background-image", background);
} else {
chunkAttr.put("background-color", background);
}
}
checkAttr(chunkAttr);
break;
case Element.LIST:
// 先不检测,保持和主代码一致
// checkTag("ol");
// checkTag("ul");
break;
case Element.LISTITEM:
// 先不检测,保持和主代码一致
// checkTag("li");
// ListItem listItem = (ListItem) element;
// check(listItem.getListSymbol());
// listItem.getChunks().stream().forEach(item -> check((Element) item));
break;
case Element.PTABLE:
checkTag("table");
break;
default:
return;
}
}
private void checkAttr(HashMap attrMap) {
if (null == attrMap || attrMap.isEmpty()) {
return;
}
for (String attr : notSupportAttr) {
attr = attr.toLowerCase();
if (attrMap.containsKey(attr.toLowerCase()) || attrMap.containsKey(attr.toUpperCase())) {
UnsupportedOperationException e = new UnsupportedOperationException("unSupport attr : " + attr);
if (ParseCheckConfig.getInstance().allowDrawing()) {
throw e;
} else {
//记一下日志,方便定位
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}
private void checkTag(String tag) {
if (ignoreTagContent(tag, false)) {
return;
}
if (notSupportTag.contains(tag) || notSupportTag.contains(tag.toUpperCase())) {
UnsupportedOperationException e = new UnsupportedOperationException("unSupport tag : " + tag);
if (ParseCheckConfig.getInstance().allowDrawing()) {
throw e;
} else {
//记一下日志,方便定位
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
public boolean ignoreTagContent(String tag, boolean recordLog) {
if (StringUtils.isEmpty(tag) ? false : (ignoreTag.contains(tag) || ignoreTag.contains(tag.toUpperCase()))) {
if (recordLog) {
UnsupportedOperationException e = new UnsupportedOperationException("unSupport tag : " + tag);
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return true;
}
return false;
}
}
}

129
src/main/java/com/fr/plugin/html/parse/utils/Html2RichTextUtils.java

@ -0,0 +1,129 @@
package com.fr.plugin.html.parse.utils;
import com.fr.base.Style;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.Inter;
import com.fr.report.cell.cellattr.core.RichChar;
import com.fr.report.cell.cellattr.core.RichText;
import com.fr.stable.Constants;
import com.fr.stable.HtmlCheckParamWraper;
import com.fr.third.lowagie.text.Chunk;
import com.fr.third.lowagie.text.Font;
import java.awt.Color;
import java.util.List;
import java.util.Map;
/**
* html 转富文本只给性能插件用代码性能插件 copy过来
*
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/20
*/
public class Html2RichTextUtils {
private static String DEF_FONTNAME = "unknown";
private static float DEF_FONTSIZE = -1f;
private static final String KAITI = "KaiTi";
private static final String ST_XINGKAI = "STXingkai";
private static final String ST_KAITI = "STKaiti";
private static final String FANGSONG = "FangSong";
public static RichText html2RichText(String html, Style style) {
return html2RichText(html, style,null);
}
/**
* 将html内容转为富文本
*
* @param html html内容
* @param style 样式
* @return 富文本对象
* @author neil
* @date 2014-12-8-下午4:06:35
*/
public static RichText html2RichText(String html, Style style, HtmlCheckParamWraper wraper) {
RichText richText = new RichText();
List<Chunk> chunkList = Html2ChunkUtils.html2ChunkList(html, style, wraper);
chunkList.stream().forEach(item -> {
if (validChar(item)) {
item.setFont(validChunkFont(item.getFont(), style));
}
HtmlUtils.dealWithUnderLine(style, item.getFont());
richText.addContent(new RichChar(item.getContent(), convertHtmlStyle(item, style)));
});
return richText;
}
/**
* 转换html样式
*
* @param chunk 一个段落
* @param cellStyle 当前单元格样式
* @return 样式
* @date 2014-12-8-下午4:08:00
*/
private static Style convertHtmlStyle(Chunk chunk, Style cellStyle) {
Style style = cellStyle;
Font htmlFont = chunk.getFont();
String fontName = htmlFont.getFontName();
float size = htmlFont.getSize();
int fontStyle = htmlFont.getStyle();
Color color = converHtmlColor(htmlFont.getColor());
int underLine = htmlFont.isUnderlined() ? Constants.LINE_THIN : Constants.LINE_NONE;
Map attributes = chunk.getAttributes();
boolean isSub = false;
boolean isSuper = false;
if (attributes != null && attributes.containsKey("SUBSUPSCRIPT")) {
float subsupscript = ((Number) attributes.get("SUBSUPSCRIPT")).floatValue();
isSuper = subsupscript > 0;
isSub = !isSuper;
}
FRFont font = FRFont.getInstance(fontName, fontStyle, size, color, underLine, htmlFont.isStrikethru(), false, isSuper, isSub);
font = font.applyName(font.getFontName());
return style.deriveFRFont(font);
}
private static boolean validChar(Chunk chunk) {
//78592 \n的字体变成了010101001000011的超长字符串,导致内存溢出
return !ComparatorUtils.equals(chunk.getContent(), "\n");
}
//默认Chunk是12pt字体, 不是12px, 这样会带来问题, 我们默认的是9pt
//如果格子里html没有设置字体样式, 就会被转成12pt, 即16px, 所以这边处理下.
private static Font validChunkFont(Font htmlFont, Style style) {
String fontName = htmlFont.getFontName();
float size = htmlFont.getSize();
if (size == DEF_FONTSIZE) {
size = style.getFRFont().getSize();
htmlFont.setSize(size);
}
if (!ComparatorUtils.equals(DEF_FONTNAME, fontName)) {
//要转成RTF的字体, 不然在word 2013以下的版本, 识别不出来.
return getLocaleRFTFont(fontName, htmlFont);
}
fontName = style.getFRFont().getFontName();
htmlFont.setFamily(fontName);
return getLocaleRFTFont(fontName, htmlFont);
}
//获取当前locale下的RTF字体, itext默认解析html后, 返回的亚洲字体是KaiTi, XingKai这种, 而宋体, 隶书这些则正常.
private static Font getLocaleRFTFont(String familyname, Font htmlFont) {
if (ComparatorUtils.equals(KAITI, familyname)) {
familyname = Inter.getLocText("FR-Engine_KaiTi");
} else if (ComparatorUtils.equals(ST_KAITI, familyname)) {
familyname = Inter.getLocText("FR-Engine_STKaiTi");
} else if (ComparatorUtils.equals(ST_XINGKAI, familyname)) {
familyname = Inter.getLocText("FR-Engine_STXingKai");
} else if (ComparatorUtils.equals(FANGSONG, familyname)) {
familyname = Inter.getLocText("FR-Engine_FangSong");
}
return new Font(familyname, htmlFont.getSize(), htmlFont.getStyle(), htmlFont.getColor());// 0.65f
}
private static Color converHtmlColor(Color color) {
return color == null ? Color.BLACK : new Color(color.getRed(), color.getGreen(), color.getBlue());
}
}

127
src/main/java/com/fr/plugin/html/parse/utils/HtmlBackgroundUtils.java

@ -0,0 +1,127 @@
package com.fr.plugin.html.parse.utils;
import com.fr.base.background.ColorBackground;
import com.fr.base.background.ImageBackground;
import com.fr.general.Background;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.report.core.utils.WebUnit;
import com.fr.stable.StringUtils;
import com.fr.third.lowagie.text.html.CSS;
import com.fr.third.lowagie.text.html.CSSUtils;
import com.fr.third.lowagie.text.html.Markup;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
import java.util.Map;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/8/19
*/
public class HtmlBackgroundUtils {
private static final String BACKGROUND_COVER = "cover";
private static final String BACKGROUND_CONTAIN = "contain";
/**
* 解析并绘制背景
*
* @param graphics 绘图对象
* @param rectangle 绘制区域
* @param rules 背景属性规则
*/
public static void parseAndDrawBackground(Graphics2D graphics, Rectangle2D.Float rectangle, Map<String, String> rules, int fontsize, int resolution) {
Background back = null;
//颜色和图片共存时,图片优先
if (rules.keySet().contains(CSS.Property.BACKGROUND_IMAGE)) {
Image image;
try {
String url = CSSUtils.extractUrl(rules.get(CSS.Property.BACKGROUND_IMAGE));
image = IOUtils.readImage(url);
if (rules.keySet().contains(CSS.Property.BACKGROUND_SIZE)) {
BackgroundSize backgroundSize = parseBackgroundSize(rules.get(CSS.Property.BACKGROUND_SIZE), rectangle,
image.getWidth(null), image.getHeight(null), fontsize, resolution);
image = image.getScaledInstance(backgroundSize.getWidth(),
backgroundSize.getHeight(), Image.SCALE_SMOOTH);
}
back = new ImageBackground(image);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
} else if (rules.keySet().contains(CSS.Property.BACKGROUND_COLOR)) {
back = ColorBackground.getInstance(Markup.decodeColor(rules.get(CSS.Property.BACKGROUND_COLOR)));
}
if (back != null) {
back.paint(graphics, rectangle);
}
}
/**
* 解析背景图大小
*
* @param value
* @param rectangle
* @param imgWidth
* @param imgHeight
* @param fontsize
* @param resolution
* @return
*/
@SuppressWarnings("squid:S2164")
public static BackgroundSize parseBackgroundSize(String value, Rectangle2D.Float rectangle, int imgWidth, int imgHeight, int fontsize, int resolution) {
int drawWidth = 0;
int drawHeight = 0;
BackgroundSize backgroundSize = new BackgroundSize();
//cover和contain都是等比例缩放,contain是按照宽高和容器宽高比例较大的缩放,cover相反
float widthScale = rectangle.width / imgWidth;
float heightScale = rectangle.height / imgHeight;
if (ComparatorUtils.equals(BACKGROUND_COVER, value)) {
double scale = Math.max(widthScale, heightScale);
drawWidth = (int) (imgWidth * scale);
drawHeight = (int) (imgHeight * scale);
} else if (ComparatorUtils.equals(BACKGROUND_CONTAIN, value)) {
double scale = Math.min(widthScale, heightScale);
drawWidth = (int) (imgWidth * scale);
drawHeight = (int) (imgHeight * scale);
} else {
String[] bgSize = value.split(StringUtils.BLANK);
if (bgSize.length > 0) {
drawWidth = (int) WebUnit.parse(bgSize[0]).toFloatValue(rectangle.width, fontsize, resolution, imgWidth);
}
drawHeight = bgSize.length > 1 ? (int) WebUnit.parse(bgSize[1]).toFloatValue(rectangle.height, fontsize, resolution, imgHeight) :
(int) WebUnit.parse(bgSize[0]).toFloatValue(rectangle.height, fontsize, resolution, imgHeight);
}
backgroundSize.setWidth(drawWidth);
backgroundSize.setHeight(drawHeight);
return backgroundSize;
}
public static class BackgroundSize {
private int width;
private int height;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public BackgroundSize() {
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
}

128
src/main/java/com/fr/plugin/html/parse/utils/HtmlBorderUtils.java

@ -0,0 +1,128 @@
package com.fr.plugin.html.parse.utils;
import com.fr.stable.CommonUtils;
import com.fr.stable.Constants;
import com.fr.stable.GraphDrawHelper;
import com.fr.stable.StringUtils;
import com.fr.third.lowagie.text.html.Border;
import com.fr.third.lowagie.text.html.BorderAttribute;
import com.fr.third.lowagie.text.pdf.BorderStyle;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/6/3
*/
public class HtmlBorderUtils {
public static void drawBlockBorder(Graphics2D g2d, Rectangle2D.Float rectang2D, BorderAttribute borderAttr) {
if (null == g2d || null == rectang2D || null == borderAttr) {
return;
}
//用于计算边框线相交处的误差
float topWidth = verify(borderAttr.getTop()) ? borderAttr.getTop().getWidth() : 0;
float rightWidth = verify(borderAttr.getRight()) ? borderAttr.getRight().getWidth() : 0;
float bottomWidth = verify(borderAttr.getBottom()) ? borderAttr.getBottom().getWidth() : 0;
float leftWidth = verify(borderAttr.getLeft()) ? borderAttr.getLeft().getWidth() : 0;
//top
drawBorderLine(g2d, borderAttr.getTop(),
rectang2D.x - leftWidth / 2, rectang2D.y, rectang2D.x + rectang2D.width + rightWidth / 2, rectang2D.y);
//right
drawBorderLine(g2d, borderAttr.getRight(),
rectang2D.x + rectang2D.width, rectang2D.y - topWidth / 2,
rectang2D.x + rectang2D.width, rectang2D.y + rectang2D.height + bottomWidth / 2);
//bottom
drawBorderLine(g2d, borderAttr.getBottom(),
rectang2D.x - leftWidth / 2, rectang2D.y + rectang2D.height,
rectang2D.x + rectang2D.width + rightWidth / 2, rectang2D.y + rectang2D.height);
//left
drawBorderLine(g2d, borderAttr.getLeft(),
rectang2D.x, rectang2D.y - topWidth / 2, rectang2D.x, rectang2D.y + rectang2D.height + bottomWidth / 2);
}
/**
* 绘制block元素border
*
* @param g 绘图对象
* @param x 横坐标
* @param y 纵坐标
* @param width 绘制区域宽度
* @param height 绘制区域高度
* @param borderStyle border属性
*/
@SuppressWarnings("unchecked")
public static void drawBlockBorder(Graphics2D g, int x, int y, int width, int height, BorderStyle borderStyle) {
if (CommonUtils.equals(borderStyle.getBorderWidth(), 0.0f)) {
return;
}
Color oldColor = g.getColor();
g.setColor(borderStyle.getBorderColor());
g.setStroke(new BasicStroke(borderStyle.getBorderWidth()));
g.drawRect(x, y, width, height);
g.setColor(oldColor);
}
/**
* 绘制边框线 x1,y1 x2,y2
*
* @param g2d
* @param border
* @param x1
* @param y1
* @param x2
* @param y2
*/
public static void drawBorderLine(Graphics2D g2d, Border border, float x1, float y1, float x2, float y2) {
if (!verify(border)) {
return;
}
int lineStyle = convertHtmlBorderStyle(border.getStyle());
Color c = null == border.getColor() ? Color.BLACK : border.getColor();
Paint oldPaint = g2d.getPaint();
g2d.setPaint(c);
GraphDrawHelper.drawLine(g2d, x1, y1, x2, y2, lineStyle, border.getWidth());
g2d.setPaint(oldPaint);
}
/**
* 验证下 border 是否有绘制的必要
*
* @param border
* @return
*/
public static boolean verify(Border border) {
return null != border && 0 < border.getWidth() && StringUtils.isNotEmpty(border.getStyle());
}
/**
* 将HTML中的边框样式转换成fr中使用的样式(全部为 1px的样式)
*
* @param style
* @return
*/
public static int convertHtmlBorderStyle(String style) {
if (StringUtils.isEmpty(style)) {
return Constants.LINE_NONE;
}
switch (style) {
case "solid":
return Constants.LINE_THIN;
case "dashed":
return Constants.LINE_DASH;
case "dotted":
return Constants.LINE_DOT;
case "double":
return Constants.LINE_DOUBLE;
default:
return Constants.LINE_NONE;
}
}
}

328
src/main/java/com/fr/plugin/html/parse/utils/HtmlUtils.java

@ -0,0 +1,328 @@
package com.fr.plugin.html.parse.utils;
import com.fr.base.GraphHelper;
import com.fr.base.Style;
import com.fr.general.FRFont;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.html.parse.HtmlContainer;
import com.fr.report.core.Html2ImageUtils;
import com.fr.stable.AssistUtils;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import com.fr.stable.unit.FU;
import com.fr.stable.unit.PT;
import com.fr.stable.unit.UNIT;
import com.fr.third.com.lowagie.text.pdf.PdfGraphics2D;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.Font;
import com.fr.third.lowagie.text.html.simpleparser.HTMLWorker;
import com.fr.third.lowagie.text.html.simpleparser.StyleSheet;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.jetbrains.annotations.NotNull;
public class HtmlUtils {
private static final int FUZZY_BOUNDARY = 2;
/**
* 获取限定宽度下html内容的高度
*
* @param content 指定的html内容
* @param paintWidth 限定的宽度
*/
public static UNIT getHtmlHeight(String content, @NotNull UNIT paintWidth, Style style, int resolution) {
if (style == null) {
style = Style.getInstance();
}
double limitWidth = paintWidth.toPixD(resolution);
HtmlContainer HtmlContainer = html2HtmlContainer(content, (int) limitWidth, 0, style, resolution);
return FU.valueOfPix(Math.round(HtmlContainer.getHeight()), resolution);
}
/**
* 切割HtmlContainer获取切割后的pdfLines并转换成原始html
*
* @param html 原始html值
* @param style 单元格样式
* @param primitiveArea 单元格尺寸
* @param resolution 分辨率
* @param startY 起始Y坐标
* @param endY 终止Y坐标
* @return 切割后的字符串
*/
public static String clipHtml(String html, Style style, @NotNull Rectangle primitiveArea, int startY, int endY, int resolution) {
if (StringUtils.isEmpty(html)) {
return StringUtils.EMPTY;
}
if (null == style) {
style = Style.getInstance();
}
//这边需要添加一个2px的模糊边界,防止后台文本宽度计算和浏览器文本宽度的计算的误差过大
HtmlContainer container = html2HtmlContainer(html, primitiveArea.width - FUZZY_BOUNDARY, primitiveArea.height, style, resolution);
//第一行距区域顶部高度
double areaStartY = 0.0d;
double totalHeight = container.getHeight();
if (style.getVerticalAlignment() == Constants.BOTTOM) {
areaStartY += (primitiveArea.height - totalHeight);
}
if (endY <= areaStartY || startY >= areaStartY + totalHeight) {
return StringUtils.EMPTY;
}
return container.getHtml(startY - areaStartY, endY - areaStartY);
}
/**
* 将html转换成pdf对象用于计算和绘制
*
* @param html 待转换的html
* @param width 绘制宽度
* @param height 绘制高度
* @param style 单元格样式
* @param resolution 分辨率
* @return container对象.
*/
public static HtmlContainer html2HtmlContainer(String html, int width, int height, Style style, int resolution) {
if (null == style) {
style = Style.getInstance();
}
html = wrapperSpan(html, style);
html = Html2ImageUtils.convertPt2Px(html);
float containerWidth = getContainerWidth(width, style, resolution);
HtmlContainer container = new HtmlContainer(containerWidth, height, style, resolution);
if (StringUtils.isEmpty(html)) {
return container;
}
try {
HTMLWorker.initDefaultFont(InterProviderFactory.getProvider().getLocText("Fine-Core_Base_Song_TypeFace"));
List<Element> elementList = HTMLWorker.parseToList(new StringReader(html), new StyleSheet());
for (Element element : elementList) {
container.add(element);
}
container.calculateHeight();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return html2HtmlContainer(splitAndFilterString(html), width, height, style, resolution);
}
return container;
}
/**
* 给html包裹一层span解决样式问题 但word导出不要设置行高
*
* @param html
* @param style
* @return
*/
public static String wrapperSpan(String html, Style style) {
if (style == null) {
return html;
}
FRFont font = style.getFRFont();
String fontName = font.getFontName();
float fontSize = font.getSize2D();
StringBuilder sb = new StringBuilder();
sb.append("<span");
// 这个属性在拼接HTML内容时使用,标记原始HTML不存在的属性
if (!(StringUtils.isNotEmpty(html) && html.toLowerCase().contains("line-height"))) {
sb.append(" noexist-attrid='line-height'");
}
sb.append(" style='font-size:");
sb.append(fontSize).append("pt;font-family:").append(fontName);
if (font.isBold()) {
sb.append(";font-weight:bold");
}
if (font.isItalic()) {
sb.append(";font-style: italic");
}
if (font.isStrikethrough()) {
sb.append(";text-decoration: line-through;");
}
float lineSpacing = style.getLineSpacing();
if (!AssistUtils.equals(lineSpacing, 0.0F)) {
FontMetrics fontMetrics = GraphHelper.getFontMetrics(FRFont.getInstance(font).applyResolutionNP(Constants.FR_PAINT_RESOLUTION));
int lineHeight = (int) (fontMetrics.getHeight() + PT.pt2pix(lineSpacing, Constants.FR_PAINT_RESOLUTION));
sb.append(";line-height:").append(lineHeight).append("px");
}
sb.append(";color:rgb(").append(font.getForeground().getRed()).append(",").append(font.getForeground().getGreen()).append(",").append(font.getForeground().getBlue()).append(")'>");
sb.append(html);
sb.append("</span>");
return sb.toString();
}
/**
* 根据设置的样式获取container的宽度
*
* @param width 绘制宽度
* @param style 单元格样式
* @param resolution 分辨率
* @return 返回宽度
*/
public static float getContainerWidth(int width, Style style, int resolution) {
if (null == style) {
style = Style.getInstance();
}
//暂时先和Style里面设置padding的逻辑保持一致
int paddingLeft = style.getPaddingLeft();
int paddingRight = style.getPaddingRight();
double left = paddingLeft > Style.DEFAULT_PADDING ? (float) PT.pt2pix(paddingLeft, resolution) : paddingLeft;
double right = 0.0f;
if (paddingRight > Style.DEFAULT_PADDING) {
right = (float) PT.pt2pix(paddingRight, resolution);
} else if (paddingRight < Style.DEFAULT_PADDING) {
right = paddingRight;
}
int sum = style.getBorderLeft() + style.getBorderRight();
double average = (double) sum / 2;
double borderWidth = Math.round(average);
return (float) (width - left - right - borderWidth);
}
/**
* 替换掉html中标签, 返回纯文本
*
* @param html html字符串
* @return 纯文本
* @date 2014-12-8-下午4:07:18
*/
public static String splitAndFilterString(String html) {
if (StringUtils.isEmpty(html)) {
return "";
}
// 去掉所有html元素
String str = html.replaceAll("<[a-zA-Z]+[1-9]?[^><]*>", "")
.replaceAll("</[a-zA-Z]+[1-9]?>", "");
str = str.replaceAll("[(/>)<]", "").replaceAll("&nbsp;", " ");
return str;
}
/**
* 确认行是否在切割区域内
*
* @param rowStartY row起始位置
* @param rowEndY row结束位置
* @param startY 切割起始位置
* @param endY 切割结束位置
* @return boolean 是否在切割区域内
*/
public static boolean inClipArea(float rowStartY, float rowEndY, double startY, double endY) {
if (rowEndY <= endY) {
if (rowStartY >= startY || rowEndY - startY >= ((double) rowEndY - (double) rowStartY) / 2) {
return true;
}
return false;
} else {
if (rowStartY > endY || endY - rowStartY < ((double) rowEndY - (double) rowStartY) / 2) {
return false;
}
return true;
}
}
/**
* 处理pdf超链接
*
* @param g2d
* @param url
*/
public static void setHyperlink(Graphics2D g2d, String url) {
if (!needDealWithHyperlink(g2d, url)) {
return;
}
try {
g2d.setRenderingHint(PdfGraphics2D.HyperLinkKey.KEY_INSTANCE, new URL(url));
} catch (MalformedURLException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 撤销pdf超链接设置
*
* @param g2d
* @param url
*/
public static void undoHyperlink(Graphics2D g2d, String url) {
if (!needDealWithHyperlink(g2d, url)) {
return;
}
g2d.setRenderingHint(PdfGraphics2D.HyperLinkKey.KEY_INSTANCE, null);
}
/**
* 是否需要处理超链接
*
* @param g2d
* @param url
* @return
*/
private static boolean needDealWithHyperlink(Graphics2D g2d, String url) {
return StringUtils.isNotEmpty(url) && isPDFExport(g2d);
}
/**
* 判断是否为 Pdf导出 | 打印
*
* @param g2d
* @return
*/
public static boolean isPDFExport(Graphics2D g2d) {
return null != g2d && g2d instanceof PdfGraphics2D;
}
/**
* 将HTML中使用的对齐属性 转换成style中的水平对齐属性
*
* @param align
*/
public static int htmlAlign2FrAlign(int align, Style style) {
if (null == style) {
style = Style.getInstance();
}
if (align == Element.ALIGN_UNDEFINED) {
return style.getHorizontalAlignment();
}
switch (align) {
case Element.ALIGN_CENTER:
return Constants.CENTER;
case Element.ALIGN_RIGHT:
return Constants.RIGHT;
case Element.ALIGN_LEFT:
return Constants.LEFT;
default:
return Constants.NULL;
}
}
/**
* 将报表中的 padding 单位转 px
*
* @param padding
* @param resolution dpi
* @return
*/
public static float frPadding2px(float padding, int resolution) {
if (padding <= Style.DEFAULT_PADDING) {
return padding;
}
return (float) PT.pt2pix(padding, resolution);
}
public static void dealWithUnderLine(Style style, @NotNull Font font) {
if (null == style || font.isUnderlined()) {
return;
}
if (Constants.LINE_NONE != style.getFRFont().getUnderline()) {
font.setStyle(font.getStyle() | Font.UNDERLINE);
}
}
}

17
src/main/java/com/fr/third/lowagie/Container.java

@ -0,0 +1,17 @@
package com.fr.third.lowagie;
import java.awt.Graphics2D;
/**
* @author kerry
* @date 2018/8/20
*/
public interface Container {
float getHeight();
String getHtml(double lineStartY, double lineEndY);
void paint(Graphics2D g2d) throws Exception;
}

306
src/main/java/com/fr/third/lowagie/text/Anchor.java

@ -0,0 +1,306 @@
/*
* $Id: Anchor.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
/**
* An <CODE>Anchor</CODE> can be a reference or a destination of a reference.
* <P>
* An <CODE>Anchor</CODE> is a special kind of <CODE>Phrase</CODE>.
* It is constructed in the same way.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* <STRONG>Anchor anchor = new Anchor("this is a link");</STRONG>
* <STRONG>anchor.setName("LINK");</STRONG>
* <STRONG>anchor.setReference("http://www.lowagie.com");</STRONG>
* </PRE></BLOCKQUOTE>
*
* @see Element
* @see Phrase
*/
public class Anchor extends Phrase {
// constant
private static final long serialVersionUID = -852278536049236911L;
// membervariables
/** This is the name of the <CODE>Anchor</CODE>. */
protected String name = null;
/** This is the reference of the <CODE>Anchor</CODE>. */
protected String reference = null;
// constructors
/**
* Constructs an <CODE>Anchor</CODE> without specifying a leading.
*/
public Anchor() {
super(16);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain leading.
*
* @param leading the leading
*/
public Anchor(float leading) {
super(leading);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain <CODE>Chunk</CODE>.
*
* @param chunk a <CODE>Chunk</CODE>
*/
public Anchor(Chunk chunk) {
super(chunk);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain <CODE>String</CODE>.
*
* @param string a <CODE>String</CODE>
*/
public Anchor(String string) {
super(string);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain <CODE>String</CODE>
* and a certain <CODE>Font</CODE>.
*
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Anchor(String string, Font font) {
super(string, font);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain <CODE>Chunk</CODE>
* and a certain leading.
*
* @param leading the leading
* @param chunk a <CODE>Chunk</CODE>
*/
public Anchor(float leading, Chunk chunk) {
super(leading, chunk);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain leading
* and a certain <CODE>String</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
*/
public Anchor(float leading, String string) {
super(leading, string);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain leading,
* a certain <CODE>String</CODE> and a certain <CODE>Font</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Anchor(float leading, String string, Font font) {
super(leading, string, font);
}
/**
* Constructs an <CODE>Anchor</CODE> with a certain <CODE>Phrase</CODE>.
*
* @param phrase a <CODE>Phrase</CODE>
*/
public Anchor(Phrase phrase) {
super(phrase);
if (phrase instanceof Anchor) {
Anchor a = (Anchor) phrase;
setName(a.name);
setReference(a.reference);
}
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
Chunk chunk;
Iterator i = getChunks().iterator();
boolean localDestination = (reference != null && reference.startsWith("#"));
boolean notGotoOK = true;
while (i.hasNext()) {
chunk = (Chunk) i.next();
if (name != null && notGotoOK && !chunk.isEmpty()) {
chunk.setLocalDestination(name);
notGotoOK = false;
}
if (localDestination) {
chunk.setLocalGoto(reference.substring(1));
}
listener.add(chunk);
}
return true;
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
Chunk chunk;
Iterator i = iterator();
boolean localDestination = (reference != null && reference.startsWith("#"));
boolean notGotoOK = true;
while (i.hasNext()) {
chunk = (Chunk) i.next();
if (name != null && notGotoOK && !chunk.isEmpty()) {
chunk.setLocalDestination(name);
notGotoOK = false;
}
if (localDestination) {
chunk.setLocalGoto(reference.substring(1));
}
else if (reference != null)
chunk.setAnchor(reference);
tmp.add(chunk);
}
return tmp;
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return ANCHOR;
}
// methods
/**
* Sets the name of this <CODE>Anchor</CODE>.
*
* @param name a new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the reference of this <CODE>Anchor</CODE>.
*
* @param reference a new reference
*/
public void setReference(String reference) {
this.reference = reference;
}
// methods to retrieve information
/**
* Returns the name of this <CODE>Anchor</CODE>.
*
* @return a name
*/
public String getName() {
return name;
}
/**
* Gets the reference of this <CODE>Anchor</CODE>.
*
* @return a reference
*/
public String getReference() {
return reference;
}
/**
* Gets the reference of this <CODE>Anchor</CODE>.
*
* @return an <CODE>URL</CODE>
*/
public URL getUrl() {
try {
return new URL(reference);
}
catch(MalformedURLException mue) {
return null;
}
}
}

601
src/main/java/com/fr/third/lowagie/text/Annotation.java

@ -0,0 +1,601 @@
/*
* $Id: Annotation.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
/**
* An <CODE>Annotation</CODE> is a little note that can be added to a page on
* a document.
*
* @see Element
* @see Anchor
*/
public class Annotation implements Element {
// membervariables
/** This is a possible annotation type. */
public static final int TEXT = 0;
/** This is a possible annotation type. */
public static final int URL_NET = 1;
/** This is a possible annotation type. */
public static final int URL_AS_STRING = 2;
/** This is a possible annotation type. */
public static final int FILE_DEST = 3;
/** This is a possible annotation type. */
public static final int FILE_PAGE = 4;
/** This is a possible annotation type. */
public static final int NAMED_DEST = 5;
/** This is a possible annotation type. */
public static final int LAUNCH = 6;
/** This is a possible annotation type. */
public static final int SCREEN = 7;
/** This is a possible attribute. */
public static final String TITLE = "title";
/** This is a possible attribute. */
public static final String CONTENT = "content";
/** This is a possible attribute. */
public static final String URL = "url";
/** This is a possible attribute. */
public static final String FILE = "file";
/** This is a possible attribute. */
public static final String DESTINATION = "destination";
/** This is a possible attribute. */
public static final String PAGE = "page";
/** This is a possible attribute. */
public static final String NAMED = "named";
/** This is a possible attribute. */
public static final String APPLICATION = "application";
/** This is a possible attribute. */
public static final String PARAMETERS = "parameters";
/** This is a possible attribute. */
public static final String OPERATION = "operation";
/** This is a possible attribute. */
public static final String DEFAULTDIR = "defaultdir";
/** This is a possible attribute. */
public static final String LLX = "llx";
/** This is a possible attribute. */
public static final String LLY = "lly";
/** This is a possible attribute. */
public static final String URX = "urx";
/** This is a possible attribute. */
public static final String URY = "ury";
/** This is a possible attribute. */
public static final String MIMETYPE = "mime";
/** This is the type of annotation. */
protected int annotationtype;
/** This is the title of the <CODE>Annotation</CODE>. */
protected HashMap annotationAttributes = new HashMap();
/** This is the lower left x-value */
protected float llx = Float.NaN;
/** This is the lower left y-value */
protected float lly = Float.NaN;
/** This is the upper right x-value */
protected float urx = Float.NaN;
/** This is the upper right y-value */
protected float ury = Float.NaN;
// constructors
/**
* Constructs an <CODE>Annotation</CODE> with a certain title and some
* text.
*
* @param llx
* lower left x coordinate
* @param lly
* lower left y coordinate
* @param urx
* upper right x coordinate
* @param ury
* upper right y coordinate
*/
private Annotation(float llx, float lly, float urx, float ury) {
this.llx = llx;
this.lly = lly;
this.urx = urx;
this.ury = ury;
}
/**
* Copy constructor.
*/
public Annotation(Annotation an) {
annotationtype = an.annotationtype;
annotationAttributes = an.annotationAttributes;
llx = an.llx;
lly = an.lly;
urx = an.urx;
ury = an.ury;
}
/**
* Constructs an <CODE>Annotation</CODE> with a certain title and some
* text.
*
* @param title
* the title of the annotation
* @param text
* the content of the annotation
*/
public Annotation(String title, String text) {
annotationtype = TEXT;
annotationAttributes.put(TITLE, title);
annotationAttributes.put(CONTENT, text);
}
/**
* Constructs an <CODE>Annotation</CODE> with a certain title and some
* text.
*
* @param title
* the title of the annotation
* @param text
* the content of the annotation
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
*/
public Annotation(String title, String text, float llx, float lly,
float urx, float ury) {
this(llx, lly, urx, ury);
annotationtype = TEXT;
annotationAttributes.put(TITLE, title);
annotationAttributes.put(CONTENT, text);
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param url
* the external reference
*/
public Annotation(float llx, float lly, float urx, float ury, URL url) {
this(llx, lly, urx, ury);
annotationtype = URL_NET;
annotationAttributes.put(URL, url);
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param url
* the external reference
*/
public Annotation(float llx, float lly, float urx, float ury, String url) {
this(llx, lly, urx, ury);
annotationtype = URL_AS_STRING;
annotationAttributes.put(FILE, url);
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param file
* an external PDF file
* @param dest
* the destination in this file
*/
public Annotation(float llx, float lly, float urx, float ury, String file,
String dest) {
this(llx, lly, urx, ury);
annotationtype = FILE_DEST;
annotationAttributes.put(FILE, file);
annotationAttributes.put(DESTINATION, dest);
}
/**
* Creates a Screen annotation to embed media clips
*
* @param llx
* @param lly
* @param urx
* @param ury
* @param moviePath
* path to the media clip file
* @param mimeType
* mime type of the media
* @param showOnDisplay
* if true play on display of the page
*/
public Annotation(float llx, float lly, float urx, float ury,
String moviePath, String mimeType, boolean showOnDisplay) {
this(llx, lly, urx, ury);
annotationtype = SCREEN;
annotationAttributes.put(FILE, moviePath);
annotationAttributes.put(MIMETYPE, mimeType);
annotationAttributes.put(PARAMETERS, new boolean[] {
false /* embedded */, showOnDisplay });
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param file
* an external PDF file
* @param page
* a page number in this file
*/
public Annotation(float llx, float lly, float urx, float ury, String file,
int page) {
this(llx, lly, urx, ury);
annotationtype = FILE_PAGE;
annotationAttributes.put(FILE, file);
annotationAttributes.put(PAGE, new Integer(page));
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param named
* a named destination in this file
*/
public Annotation(float llx, float lly, float urx, float ury, int named) {
this(llx, lly, urx, ury);
annotationtype = NAMED_DEST;
annotationAttributes.put(NAMED, new Integer(named));
}
/**
* Constructs an <CODE>Annotation</CODE>.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
* @param application
* an external application
* @param parameters
* parameters to pass to this application
* @param operation
* the operation to pass to this application
* @param defaultdir
* the default directory to run this application in
*/
public Annotation(float llx, float lly, float urx, float ury,
String application, String parameters, String operation,
String defaultdir) {
this(llx, lly, urx, ury);
annotationtype = LAUNCH;
annotationAttributes.put(APPLICATION, application);
annotationAttributes.put(PARAMETERS, parameters);
annotationAttributes.put(OPERATION, operation);
annotationAttributes.put(DEFAULTDIR, defaultdir);
}
// implementation of the Element-methods
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return ANNOTATION;
}
/**
* Processes the element by adding it (or the different parts) to an <CODE>
* ElementListener</CODE>.
*
* @param listener
* an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
} catch (DocumentException de) {
return false;
}
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
return new ArrayList();
}
// methods
/**
* Sets the dimensions of this annotation.
*
* @param llx
* the lower left x-value
* @param lly
* the lower left y-value
* @param urx
* the upper right x-value
* @param ury
* the upper right y-value
*/
public void setDimensions(float llx, float lly, float urx, float ury) {
this.llx = llx;
this.lly = lly;
this.urx = urx;
this.ury = ury;
}
// methods to retrieve information
/**
* Returns the lower left x-value.
*
* @return a value
*/
public float llx() {
return llx;
}
/**
* Returns the lower left y-value.
*
* @return a value
*/
public float lly() {
return lly;
}
/**
* Returns the upper right x-value.
*
* @return a value
*/
public float urx() {
return urx;
}
/**
* Returns the upper right y-value.
*
* @return a value
*/
public float ury() {
return ury;
}
/**
* Returns the lower left x-value.
*
* @param def
* the default value
* @return a value
*/
public float llx(float def) {
if (Float.isNaN(llx))
return def;
return llx;
}
/**
* Returns the lower left y-value.
*
* @param def
* the default value
* @return a value
*/
public float lly(float def) {
if (Float.isNaN(lly))
return def;
return lly;
}
/**
* Returns the upper right x-value.
*
* @param def
* the default value
* @return a value
*/
public float urx(float def) {
if (Float.isNaN(urx))
return def;
return urx;
}
/**
* Returns the upper right y-value.
*
* @param def
* the default value
* @return a value
*/
public float ury(float def) {
if (Float.isNaN(ury))
return def;
return ury;
}
/**
* Returns the type of this <CODE>Annotation</CODE>.
*
* @return a type
*/
public int annotationType() {
return annotationtype;
}
/**
* Returns the title of this <CODE>Annotation</CODE>.
*
* @return a name
*/
public String title() {
String s = (String) annotationAttributes.get(TITLE);
if (s == null)
s = "";
return s;
}
/**
* Gets the content of this <CODE>Annotation</CODE>.
*
* @return a reference
*/
public String content() {
String s = (String) annotationAttributes.get(CONTENT);
if (s == null)
s = "";
return s;
}
/**
* Gets the content of this <CODE>Annotation</CODE>.
*
* @return a reference
*/
public HashMap attributes() {
return annotationAttributes;
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
}

87
src/main/java/com/fr/third/lowagie/text/BadElementException.java

@ -0,0 +1,87 @@
/*
* $Id: BadElementException.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* Signals an attempt to create an <CODE>Element</CODE> that hasn't got the right form.
*
* @see DocumentException
* @see Cell
* @see Table
*/
public class BadElementException extends DocumentException {
private static final long serialVersionUID = -799006030723822254L;
// constructors
/**
* Constructs a BadElementException
* @param ex an Exception object that has to be turned into a BadElementException
*/
public BadElementException(Exception ex) {
super(ex);
}
/**
* Constructs a <CODE>BadElementException</CODE> without a message.
*/
BadElementException() {
super();
}
/**
* Constructs a <code>BadElementException</code> with a message.
* @param message a message describing the exception
*/
public BadElementException(String message) {
super(message);
}
}

852
src/main/java/com/fr/third/lowagie/text/Cell.java

@ -0,0 +1,852 @@
/*
* $Id: Cell.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Iterator;
import com.fr.third.lowagie.text.pdf.PdfPCell;
/**
* A <CODE>Cell</CODE> is a <CODE>Rectangle</CODE> containing other
* <CODE>Element</CODE>s.
* <P>
* A <CODE>Cell</CODE> must be added to a <CODE>Table</CODE>.
* The <CODE>Table</CODE> will place the <CODE>Cell</CODE> in
* a <CODE>Row</CODE>.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* Table table = new Table(3);
* table.setBorderWidth(1);
* table.setBorderColor(new Color(0, 0, 255));
* table.setCellpadding(5);
* table.setCellspacing(5);
* <STRONG>Cell cell = new Cell("header");</STRONG>
* <STRONG>cell.setHeader(true);</STRONG>
* <STRONG>cell.setColspan(3);</STRONG>
* table.addCell(cell);
* <STRONG>cell = new Cell("example cell with colspan 1 and rowspan 2");</STRONG>
* <STRONG>cell.setRowspan(2);</STRONG>
* <STRONG>cell.setBorderColor(new Color(255, 0, 0));</STRONG>
* table.addCell(cell);
* table.addCell("1.1");
* table.addCell("2.1");
* table.addCell("1.2");
* table.addCell("2.2");
* </PRE></BLOCKQUOTE>
*
* @see Rectangle
* @see Element
* @see Table
* @see Row
*/
public class Cell extends Rectangle implements TextElementArray {
// membervariables
/**
* The <CODE>ArrayList</CODE> of <CODE>Element</CODE>s
* that are part of the content of the Cell.
*/
protected ArrayList arrayList = null;
/** The horizontal alignment of the cell content. */
protected int horizontalAlignment = ALIGN_UNDEFINED;
/** The vertical alignment of the cell content. */
protected int verticalAlignment = ALIGN_UNDEFINED;
/**
* The width of the cell as a String.
* It can be an absolute value "100" or a percentage "20%".
*/
protected float width;
protected boolean percentage = false;
/** The colspan of the cell. */
protected int colspan = 1;
/** The rowspan of the cell. */
protected int rowspan = 1;
/** The leading of the content inside the cell. */
float leading = Float.NaN;
/** Is this <CODE>Cell</CODE> a header? */
protected boolean header;
/**
* Maximum number of lines allowed in the cell.
* The default value of this property is not to limit the maximum number of lines
* (contributed by dperezcar@fcc.es)
*/
protected int maxLines = Integer.MAX_VALUE;
/**
* If a truncation happens due to the maxLines property, then this text will
* be added to indicate a truncation has happened.
* Default value is null, and means avoiding marking the truncation.
* A useful value of this property could be e.g. "..."
* (contributed by dperezcar@fcc.es)
*/
String showTruncation;
/**
* Indicates that the largest ascender height should be used to determine the
* height of the first line. Note that this only has an effect when rendered
* to PDF. Setting this to true can help with vertical alignment problems.
*/
protected boolean useAscender = false;
/**
* Indicates that the largest descender height should be added to the height of
* the last line (so characters like y don't dip into the border). Note that
* this only has an effect when rendered to PDF.
*/
protected boolean useDescender = false;
/**
* Adjusts the cell contents to compensate for border widths. Note that
* this only has an effect when rendered to PDF.
*/
protected boolean useBorderPadding;
/** Does this <CODE>Cell</CODE> force a group change? */
protected boolean groupChange = true;
// constructors
/** Constructs an empty <CODE>Cell</CODE>. */
public Cell() {
// creates a Rectangle with BY DEFAULT a border of 0.5
super(0, 0, 0, 0);
setBorder(UNDEFINED);
setBorderWidth(0.5f);
// initializes the arraylist
arrayList = new ArrayList();
}
/**
* Constructs an empty <CODE>Cell</CODE> (for internal use only).
*
* @param dummy a dummy value
*/
public Cell(boolean dummy) {
this();
arrayList.add(new Paragraph(0));
}
/**
* Constructs a <CODE>Cell</CODE> with a certain content.<p>
* The <CODE>String</CODE> will be converted into a <CODE>Paragraph</CODE>.
* @param content a <CODE>String</CODE>
*/
public Cell(String content) {
this();
try {
addElement(new Paragraph(content));
}
catch(BadElementException bee) {
}
}
/**
* Constructs a <CODE>Cell</CODE> with a certain <CODE>Element</CODE>.<p>
* if the element is a <CODE>ListItem</CODE>, <CODE>Row</CODE> or
* <CODE>Cell</CODE>, an exception will be thrown.
*
* @param element the element
* @throws BadElementException when the creator was called with a <CODE>ListItem</CODE>, <CODE>Row</CODE> or <CODE>Cell</CODE>
*/
public Cell(Element element) throws BadElementException {
this();
if(element instanceof Phrase) {
setLeading(((Phrase)element).getLeading());
}
addElement(element);
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return CELL;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
for (Iterator i = arrayList.iterator(); i.hasNext(); ) {
tmp.addAll(((Element) i.next()).getChunks());
}
return tmp;
}
// Getters and setters
/**
* Gets the horizontal alignment.
*
* @return a value
*/
public int getHorizontalAlignment() {
return horizontalAlignment;
}
/**
* Sets the horizontal alignment.
* @param value the new value
*/
public void setHorizontalAlignment(int value) {
horizontalAlignment = value;
}
/**
* Sets the alignment of this cell.
* This methods allows you to set the alignment as a String.
* @param alignment the new alignment as a <CODE>String</CODE>
*/
public void setHorizontalAlignment(String alignment) {
setHorizontalAlignment(ElementTags.alignmentValue(alignment));
}
/**
* Gets the vertical alignment.
* @return a value
*/
public int getVerticalAlignment() {
return verticalAlignment;
}
/**
* Sets the vertical alignment.
* @param value the new value
*/
public void setVerticalAlignment(int value) {
verticalAlignment = value;
}
/**
* Sets the alignment of this paragraph.
*
* @param alignment the new alignment as a <CODE>String</CODE>
*/
public void setVerticalAlignment(String alignment) {
setVerticalAlignment(ElementTags.alignmentValue(alignment));
}
/**
* Sets the width.
*
* @param value the new value
*/
public void setWidth(float value) {
this.width = value;
}
/**
* Sets the width.
* It can be an absolute value "100" or a percentage "20%"
*
* @param value the new value
*/
public void setWidth(String value) {
if (value.endsWith("%")) {
value = value.substring(0, value.length() - 1);
percentage = true;
}
width = Integer.parseInt(value);
}
/**
* Gets the width.
*/
public float getWidth() {
return width;
}
/**
* Gets the width as a String.
*
* @return a value
*/
public String getWidthAsString() {
String w = String.valueOf(width);
if (w.endsWith(".0")) w = w.substring(0, w.length() - 2);
if (percentage) w += "%";
return w;
}
/**
* Sets the colspan.
*
* @param value the new value
*/
public void setColspan(int value) {
colspan = value;
}
/**
* Gets the colspan.
* @return a value
*/
public int getColspan() {
return colspan;
}
/**
* Sets the rowspan.
*
* @param value the new value
*/
public void setRowspan(int value) {
rowspan = value;
}
/**
* Gets the rowspan.
* @return a value
*/
public int getRowspan() {
return rowspan;
}
/**
* Sets the leading.
*
* @param value the new value
*/
public void setLeading(float value) {
leading = value;
}
/**
* Gets the leading.
*
* @return a value
*/
public float getLeading() {
if (Float.isNaN(leading)) {
return 16;
}
return leading;
}
/**
* Sets header.
*
* @param value the new value
*/
public void setHeader(boolean value) {
header = value;
}
/**
* Is this <CODE>Cell</CODE> a header?
*
* @return a value
*/
public boolean isHeader() {
return header;
}
/**
* Setter for maxLines
* @param value the maximum number of lines
*/
public void setMaxLines(int value) {
maxLines = value;
}
/**
* Getter for maxLines
* @return the maxLines value
*/
public int getMaxLines() {
return maxLines;
}
/**
* Setter for showTruncation
* @param value Can be null for avoiding marking the truncation.
*/
public void setShowTruncation(String value) {
showTruncation = value;
}
/**
* Getter for showTruncation
* @return the showTruncation value
*/
public String getShowTruncation() {
return showTruncation;
}
/**
* Sets the value of useAscender.
* @param use use ascender height if true
*/
public void setUseAscender(boolean use) {
useAscender = use;
}
/**
* Gets the value of useAscender
* @return useAscender
*/
public boolean isUseAscender() {
return useAscender;
}
/**
* Sets the value of useDescender.
* @param use use descender height if true
*/
public void setUseDescender(boolean use) {
useDescender = use;
}
/**
* gets the value of useDescender
* @return useDescender
*/
public boolean isUseDescender() {
return useDescender;
}
/**
* Sets the value of useBorderPadding.
* @param use adjust layout for borders if true
*/
public void setUseBorderPadding(boolean use) {
useBorderPadding = use;
}
/**
* Gets the value of useBorderPadding.
* @return useBorderPadding
*/
public boolean isUseBorderPadding() {
return useBorderPadding;
}
/**
* Does this <CODE>Cell</CODE> force a group change?
*
* @return a value
*/
public boolean getGroupChange() {
return groupChange;
}
/**
* Sets group change.
*
* @param value the new value
*/
public void setGroupChange(boolean value) {
groupChange = value;
}
// arraylist stuff
/**
* Gets the number of <CODE>Element</CODE>s in the Cell.
*
* @return a <CODE>size</CODE>.
*/
public int size() {
return arrayList.size();
}
/**
* Gets an iterator of <CODE>Element</CODE>s.
*
* @return an <CODE>Iterator</CODE>.
*/
public Iterator getElements() {
return arrayList.iterator();
}
/**
* Clears all the <CODE>Element</CODE>s of this <CODE>Cell</CODE>.
*/
public void clear() {
arrayList.clear();
}
/**
* Checks if the <CODE>Cell</CODE> is empty.
*
* @return <CODE>false</CODE> if there are non-empty <CODE>Element</CODE>s in the <CODE>Cell</CODE>.
*/
public boolean isEmpty() {
switch(size()) {
case 0:
return true;
case 1:
Element element = (Element) arrayList.get(0);
switch (element.type()) {
case CHUNK:
return ((Chunk) element).isEmpty();
case ANCHOR:
case PHRASE:
case PARAGRAPH:
return ((Phrase) element).isEmpty();
case LIST:
return ((List) element).isEmpty();
}
return false;
default:
return false;
}
}
/**
* Makes sure there is at least 1 object in the Cell.
*
* Otherwise it might not be shown in the table.
*/
void fill() {
if (size() == 0) arrayList.add(new Paragraph(0));
}
/**
* Checks if this <CODE>Cell</CODE> is a placeholder for a (nested) table.
*
* @return true if the only element in this cell is a table
*/
public boolean isTable() {
return (size() == 1)
&& (((Element)arrayList.get(0)).type() == TABLE);
}
/**
* Adds an element to this <CODE>Cell</CODE>.
* <P>
* Remark: you can't add <CODE>ListItem</CODE>s, <CODE>Row</CODE>s, <CODE>Cell</CODE>s,
* <CODE>JPEG</CODE>s, <CODE>GIF</CODE>s or <CODE>PNG</CODE>s to a <CODE>Cell</CODE>.
*
* @param element The <CODE>Element</CODE> to add
* @throws BadElementException if the method was called with a <CODE>ListItem</CODE>, <CODE>Row</CODE> or <CODE>Cell</CODE>
*/
public void addElement(Element element) throws BadElementException {
if (isTable()) {
Table table = (Table) arrayList.get(0);
Cell tmp = new Cell(element);
tmp.setBorder(NO_BORDER);
tmp.setColspan(table.getColumns());
table.addCell(tmp);
return;
}
switch(element.type()) {
case LISTITEM:
case ROW:
case CELL:
throw new BadElementException("You can't add listitems, rows or cells to a cell.");
case LIST:
List list = (List)element;
if (Float.isNaN(leading)) {
setLeading(list.getTotalLeading());
}
if (list.isEmpty()) return;
arrayList.add(element);
return;
case ANCHOR:
case PARAGRAPH:
case PHRASE:
Phrase p = (Phrase)element;
if (Float.isNaN(leading)) {
setLeading(p.getLeading());
}
if (p.isEmpty()) return;
arrayList.add(element);
return;
case CHUNK:
if (((Chunk) element).isEmpty()) return;
arrayList.add(element);
return;
case TABLE:
Table table = new Table(3);
float[] widths = new float[3];
widths[1] = ((Table)element).getWidth();
switch(((Table)element).getAlignment()) {
case ALIGN_LEFT:
widths[0] = 0f;
widths[2] = 100f - widths[1];
break;
case ALIGN_CENTER:
widths[0] = (100f - widths[1]) / 2f;
widths[2] = widths[0];
break;
case ALIGN_RIGHT:
widths[0] = 100f - widths[1];
widths[2] = 0f;
}
table.setWidths(widths);
Cell tmp;
if (arrayList.isEmpty()) {
table.addCell(getDummyCell());
}
else {
tmp = new Cell();
tmp.setBorder(NO_BORDER);
tmp.setColspan(3);
for (Iterator i = arrayList.iterator(); i.hasNext(); ) {
tmp.add(i.next());
}
table.addCell(tmp);
}
tmp = new Cell();
tmp.setBorder(NO_BORDER);
table.addCell(tmp);
table.insertTable((Table)element);
tmp = new Cell();
tmp.setBorder(NO_BORDER);
table.addCell(tmp);
table.addCell(getDummyCell());
clear();
arrayList.add(table);
return;
default:
arrayList.add(element);
}
}
/**
* Add an <CODE>Object</CODE> to this cell.
*
* @param o the object to add
* @return always <CODE>true</CODE>
*/
public boolean add(Object o) {
try {
this.addElement((Element) o);
return true;
}
catch(ClassCastException cce) {
throw new ClassCastException("You can only add objects that implement the Element interface.");
}
catch(BadElementException bee) {
throw new ClassCastException(bee.getMessage());
}
}
// helper methods
/**
* Get dummy cell used when merging inner tables.
* @return a cell with colspan 3 and no border
*/
private static Cell getDummyCell() {
Cell cell = new Cell(true);
cell.setColspan(3);
cell.setBorder(NO_BORDER);
return cell;
}
/**
* Creates a PdfPCell based on this Cell object.
* @return a PdfPCell
* @throws BadElementException
*/
public PdfPCell createPdfPCell() throws BadElementException {
if (rowspan > 1) throw new BadElementException("PdfPCells can't have a rowspan > 1");
if (isTable()) return new PdfPCell(((Table)arrayList.get(0)).createPdfPTable());
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(verticalAlignment);
cell.setHorizontalAlignment(horizontalAlignment);
cell.setColspan(colspan);
cell.setUseBorderPadding(useBorderPadding);
cell.setUseDescender(useDescender);
cell.setLeading(getLeading(), 0);
cell.cloneNonPositionParameters(this);
cell.setNoWrap(getMaxLines() == 1);
for (Iterator i = getElements(); i.hasNext(); ) {
Element e = (Element)i.next();
if (e.type() == PHRASE || e.type() == PARAGRAPH) {
Paragraph p = new Paragraph((Phrase)e);
p.setAlignment(horizontalAlignment);
e = p;
}
cell.addElement(e);
}
return cell;
}
// unsupported Rectangle methods
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @return NA
*/
public float getTop() {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @return NA
*/
public float getBottom() {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @return NA
*/
public float getLeft() {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @return NA
*/
public float getRight() {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param margin
* @return NA
*/
public float top(int margin) {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param margin
* @return NA
*/
public float bottom(int margin) {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param margin
* @return NA
*/
public float left(int margin) {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param margin NA
* @return NA
*/
public float right(int margin) {
throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param value NA
*/
public void setTop(int value) {
throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param value NA
*/
public void setBottom(int value) {
throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param value NA
*/
public void setLeft(int value) {
throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ.");
}
/**
* This method throws an <CODE>UnsupportedOperationException</CODE>.
* @param value NA
*/
public void setRight(int value) {
throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ.");
}
}

136
src/main/java/com/fr/third/lowagie/text/Chapter.java

@ -0,0 +1,136 @@
/*
* $Id: Chapter.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
/**
* A <CODE>Chapter</CODE> is a special <CODE>Section</CODE>.
* <P>
* A chapter number has to be created using a <CODE>Paragraph</CODE> as title
* and an <CODE>int</CODE> as chapter number. The chapter number is shown be
* default. If you don't want to see the chapter number, you have to set the
* numberdepth to <VAR>0</VAR>.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
* <STRONG>Chapter chapter2 = new Chapter(title2, 2);</STRONG>
* <STRONG>chapter2.setNumberDepth(0);</STRONG>
* Paragraph someText = new Paragraph("This is some text");
* <STRONG>chapter2.add(someText);</STRONG>
* Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
* Section section1 = <STRONG>chapter2.addSection(title21);</STRONG>
* Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
* section1.add(someSectionText);
* </PRE></BLOCKQUOTE>
*/
public class Chapter extends Section {
// constant
private static final long serialVersionUID = 1791000695779357361L;
/**
* Constructs a new <CODE>Chapter</CODE>.
* @param number the Chapter number
*/
public Chapter(int number) {
super(null, 1);
numbers = new ArrayList();
numbers.add(new Integer(number));
triggerNewPage = true;
}
/**
* Constructs a new <CODE>Chapter</CODE>.
*
* @param title the Chapter title (as a <CODE>Paragraph</CODE>)
* @param number the Chapter number
*/
public Chapter(Paragraph title, int number) {
super(title, 1);
numbers = new ArrayList();
numbers.add(new Integer(number));
triggerNewPage = true;
}
/**
* Constructs a new <CODE>Chapter</CODE>.
*
* @param title the Chapter title (as a <CODE>String</CODE>)
* @param number the Chapter number
*/
public Chapter(String title, int number) {
this(new Paragraph(title), number);
}
// implementation of the Element-methods
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return CHAPTER;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return false;
}
}

124
src/main/java/com/fr/third/lowagie/text/ChapterAutoNumber.java

@ -0,0 +1,124 @@
/*
* Copyright 2005 by Michael Niedermair.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* Chapter with auto numbering.
*
* @author Michael Niedermair
*/
public class ChapterAutoNumber extends Chapter {
// constant
private static final long serialVersionUID = -9217457637987854167L;
/**
* Is the chapter number already set?
* @since 2.1.4
*/
protected boolean numberSet = false;
/**
* Create a new object.
*
* @param para the Chapter title (as a <CODE>Paragraph</CODE>)
*/
public ChapterAutoNumber(final Paragraph para) {
super(para, 0);
}
/**
* Create a new object.
*
* @param title the Chapter title (as a <CODE>String</CODE>)
*/
public ChapterAutoNumber(final String title) {
super(title, 0);
}
/**
* Create a new section for this chapter and ad it.
*
* @param title the Section title (as a <CODE>String</CODE>)
* @return Returns the new section.
*/
public Section addSection(final String title) {
if (isAddedCompletely()) {
throw new IllegalStateException("This LargeElement has already been added to the Document.");
}
return addSection(title, 2);
}
/**
* Create a new section for this chapter and add it.
*
* @param title the Section title (as a <CODE>Paragraph</CODE>)
* @return Returns the new section.
*/
public Section addSection(final Paragraph title) {
if (isAddedCompletely()) {
throw new IllegalStateException("This LargeElement has already been added to the Document.");
}
return addSection(title, 2);
}
/**
* Changes the Chapter number.
* @param number the new chapter number
* @since 2.1.4
*/
public int setAutomaticNumber(int number) {
if (!numberSet) {
number++;
super.setChapterNumber(number);
numberSet = true;
}
return number;
}
}

893
src/main/java/com/fr/third/lowagie/text/Chunk.java

@ -0,0 +1,893 @@
/*
* $Id: Chunk.java 3427 2008-05-24 18:32:31Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
import java.awt.FontMetrics;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import com.fr.third.lowagie.text.pdf.HyphenationEvent;
import com.fr.third.lowagie.text.pdf.PdfAction;
import com.fr.third.lowagie.text.pdf.PdfAnnotation;
import com.fr.third.lowagie.text.pdf.PdfContentByte;
import com.fr.third.lowagie.text.pdf.draw.DrawInterface;
import sun.font.FontDesignMetrics;
/**
* This is the smallest significant part of text that can be added to a
* document.
* <P>
* Most elements can be divided in one or more <CODE>Chunk</CODE>s. A chunk
* is a <CODE>String</CODE> with a certain <CODE>Font</CODE>. All other
* layout parameters should be defined in the object to which this chunk of text
* is added.
* <P>
* Example: <BLOCKQUOTE>
*
* <PRE>
*
* <STRONG>Chunk chunk = new Chunk("Hello world",
* FontFactory.getFont(FontFactory.COURIER, 20, Font.ITALIC, new Color(255, 0,
* 0))); </STRONG> document.add(chunk);
*
* </PRE>
*
* </BLOCKQUOTE>
*/
public class Chunk implements Element {
// public static membervariables
/** The character stand in for an image or a separator. */
public static final String OBJECT_REPLACEMENT_CHARACTER = "\ufffc";
/** This is a Chunk containing a newline. */
public static final Chunk NEWLINE = new Chunk("\n");
/** This is a Chunk containing a newpage. */
public static final Chunk NEXTPAGE = new Chunk("");
static {
NEXTPAGE.setNewPage();
}
// member variables
/** This is the content of this chunk of text. */
protected StringBuffer content = null;
/** This is the <CODE>Font</CODE> of this chunk of text. */
protected Font font = null;
/** Contains some of the attributes for this Chunk. */
protected HashMap attributes = null;
// constructors
/**
* Empty constructor.
*/
public Chunk() {
this.content = new StringBuffer();
this.font = new Font();
}
/**
* A <CODE>Chunk</CODE> copy constructor.
* @param ck the <CODE>Chunk</CODE> to be copied
*/
public Chunk(Chunk ck) {
if (ck.content != null) {
content = new StringBuffer(ck.content.toString());
}
if (ck.font != null) {
font = new Font(ck.font);
}
if (ck.attributes != null) {
attributes = new HashMap(ck.attributes);
}
}
/**
* Constructs a chunk of text with a certain content and a certain <CODE>
* Font</CODE>.
*
* @param content
* the content
* @param font
* the font
*/
public Chunk(String content, Font font) {
this.content = new StringBuffer(content);
this.font = font;
}
/**
* Constructs a chunk of text with a certain content, without specifying a
* <CODE>Font</CODE>.
*
* @param content
* the content
*/
public Chunk(String content) {
this(content, new Font());
}
/**
* Constructs a chunk of text with a char and a certain <CODE>Font</CODE>.
*
* @param c
* the content
* @param font
* the font
*/
public Chunk(char c, Font font) {
this.content = new StringBuffer();
this.content.append(c);
this.font = font;
}
/**
* Constructs a chunk of text with a char, without specifying a <CODE>Font
* </CODE>.
*
* @param c
* the content
*/
public Chunk(char c) {
this(c, new Font());
}
/**
* Constructs a chunk containing an <CODE>Image</CODE>.
*
* @param image
* the image
* @param offsetX
* the image offset in the x direction
* @param offsetY
* the image offset in the y direction
*/
public Chunk(Image image, float offsetX, float offsetY) {
this(OBJECT_REPLACEMENT_CHARACTER, new Font());
Image copyImage = Image.getInstance(image);
copyImage.setAbsolutePosition(Float.NaN, Float.NaN);
setAttribute(IMAGE, new Object[] { copyImage, new Float(offsetX),
new Float(offsetY), Boolean.FALSE });
}
/**
* Key for drawInterface of the Separator.
* @since 2.1.2
*/
public static final String SEPARATOR = "SEPARATOR";
/**
* Creates a separator Chunk.
* Note that separator chunks can't be used in combination with tab chunks!
* @param separator the drawInterface to use to draw the separator.
* @since 2.1.2
*/
public Chunk(DrawInterface separator) {
this(separator, false);
}
/**
* Creates a separator Chunk.
* Note that separator chunks can't be used in combination with tab chunks!
* @param separator the drawInterface to use to draw the separator.
* @param vertical true if this is a vertical separator
* @since 2.1.2
*/
public Chunk(DrawInterface separator, boolean vertical) {
this(OBJECT_REPLACEMENT_CHARACTER, new Font());
setAttribute(SEPARATOR, new Object[] {separator, Boolean.valueOf(vertical)});
}
/**
* Key for drawInterface of the tab.
* @since 2.1.2
*/
public static final String TAB = "TAB";
/**
* Creates a tab Chunk.
* Note that separator chunks can't be used in combination with tab chunks!
* @param separator the drawInterface to use to draw the tab.
* @param tabPosition an X coordinate that will be used as start position for the next Chunk.
* @since 2.1.2
*/
public Chunk(DrawInterface separator, float tabPosition) {
this(separator, tabPosition, false);
}
/**
* Creates a tab Chunk.
* Note that separator chunks can't be used in combination with tab chunks!
* @param separator the drawInterface to use to draw the tab.
* @param tabPosition an X coordinate that will be used as start position for the next Chunk.
* @param newline if true, a newline will be added if the tabPosition has already been reached.
* @since 2.1.2
*/
public Chunk(DrawInterface separator, float tabPosition, boolean newline) {
this(OBJECT_REPLACEMENT_CHARACTER, new Font());
if (tabPosition < 0) {
throw new IllegalArgumentException("A tab position may not be lower than 0; yours is " + tabPosition);
}
setAttribute(TAB, new Object[] {separator, new Float(tabPosition), Boolean.valueOf(newline), new Float(0)});
}
/**
* Constructs a chunk containing an <CODE>Image</CODE>.
*
* @param image
* the image
* @param offsetX
* the image offset in the x direction
* @param offsetY
* the image offset in the y direction
* @param changeLeading
* true if the leading has to be adapted to the image
*/
public Chunk(Image image, float offsetX, float offsetY,
boolean changeLeading) {
this(OBJECT_REPLACEMENT_CHARACTER, new Font());
setAttribute(IMAGE, new Object[] { image, new Float(offsetX),
new Float(offsetY), Boolean.valueOf(changeLeading) });
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an <CODE>
* ElementListener</CODE>.
*
* @param listener
* an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
} catch (DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return Element.CHUNK;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
tmp.add(this);
return tmp;
}
// methods that change the member variables
/**
* appends some text to this <CODE>Chunk</CODE>.
*
* @param string
* <CODE>String</CODE>
* @return a <CODE>StringBuffer</CODE>
*/
public StringBuffer append(String string) {
return content.append(string);
}
/**
* Sets the font of this <CODE>Chunk</CODE>.
*
* @param font
* a <CODE>Font</CODE>
*/
public void setFont(Font font) {
this.font = font;
}
// methods to retrieve information
/**
* Gets the font of this <CODE>Chunk</CODE>.
*
* @return a <CODE>Font</CODE>
*/
public Font getFont() {
return font;
}
/**
* Returns the content of this <CODE>Chunk</CODE>.
*
* @return a <CODE>String</CODE>
*/
public String getContent() {
return content.toString();
}
/**
* Returns the content of this <CODE>Chunk</CODE>.
*
* @return a <CODE>String</CODE>
*/
public String toString() {
return getContent();
}
/**
* Checks is this <CODE>Chunk</CODE> is empty.
*
* @return <CODE>false</CODE> if the Chunk contains other characters than
* space.
*/
public boolean isEmpty() {
return (content.toString().trim().length() == 0)
&& (content.toString().indexOf("\n") == -1)
&& (attributes == null);
}
/**
* Gets the width of the Chunk in points.
*
* @return a width in points
*/
public float getWidthPoint() {
if (getImage() != null) {
return getImage().getScaledWidth();
}
java.awt.Font awtFont = new java.awt.Font(font.getFontName(), font.getStyle(), (int)font.getSize());
FontMetrics metrics = FontDesignMetrics.getMetrics(awtFont);
return metrics.stringWidth(getContent())* getHorizontalScaling();
}
// attributes
/**
* Checks the attributes of this <CODE>Chunk</CODE>.
*
* @return false if there aren't any.
*/
public boolean hasAttributes() {
return attributes != null;
}
/**
* Gets the attributes for this <CODE>Chunk</CODE>.
* <P>
* It may be null.
*
* @return the attributes for this <CODE>Chunk</CODE>
*/
public HashMap getAttributes() {
return attributes;
}
/**
* Sets the attributes all at once.
* @param attributes the attributes of a Chunk
*/
public void setAttributes(HashMap attributes) {
this.attributes = attributes;
}
/**
* Sets an arbitrary attribute.
*
* @param name
* the key for the attribute
* @param obj
* the value of the attribute
* @return this <CODE>Chunk</CODE>
*/
public Chunk setAttribute(String name, Object obj) {
if (attributes == null)
attributes = new HashMap();
attributes.put(name, obj);
return this;
}
// the attributes are ordered as they appear in the book 'iText in Action'
/** Key for text horizontal scaling. */
public static final String HSCALE = "HSCALE";
/**
* Sets the text horizontal scaling. A value of 1 is normal and a value of
* 0.5f shrinks the text to half it's width.
*
* @param scale
* the horizontal scaling factor
* @return this <CODE>Chunk</CODE>
*/
public Chunk setHorizontalScaling(float scale) {
return setAttribute(HSCALE, new Float(scale));
}
/**
* Gets the horizontal scaling.
*
* @return a percentage in float
*/
public float getHorizontalScaling() {
if (attributes == null)
return 1f;
Float f = (Float) attributes.get(HSCALE);
if (f == null)
return 1f;
return f.floatValue();
}
/** Key for underline. */
public static final String UNDERLINE = "UNDERLINE";
/**
* Sets an horizontal line that can be an underline or a strikethrough.
* Actually, the line can be anywhere vertically and has always the <CODE>
* Chunk</CODE> width. Multiple call to this method will produce multiple
* lines.
*
* @param thickness
* the absolute thickness of the line
* @param yPosition
* the absolute y position relative to the baseline
* @return this <CODE>Chunk</CODE>
*/
public Chunk setUnderline(float thickness, float yPosition) {
return setUnderline(null, thickness, 0f, yPosition, 0f,
PdfContentByte.LINE_CAP_BUTT);
}
/**
* Sets an horizontal line that can be an underline or a strikethrough.
* Actually, the line can be anywhere vertically and has always the <CODE>
* Chunk</CODE> width. Multiple call to this method will produce multiple
* lines.
*
* @param color
* the color of the line or <CODE>null</CODE> to follow the
* text color
* @param thickness
* the absolute thickness of the line
* @param thicknessMul
* the thickness multiplication factor with the font size
* @param yPosition
* the absolute y position relative to the baseline
* @param yPositionMul
* the position multiplication factor with the font size
* @param cap
* the end line cap. Allowed values are
* PdfContentByte.LINE_CAP_BUTT, PdfContentByte.LINE_CAP_ROUND
* and PdfContentByte.LINE_CAP_PROJECTING_SQUARE
* @return this <CODE>Chunk</CODE>
*/
public Chunk setUnderline(Color color, float thickness, float thicknessMul,
float yPosition, float yPositionMul, int cap) {
if (attributes == null)
attributes = new HashMap();
Object obj[] = {
color,
new float[] { thickness, thicknessMul, yPosition, yPositionMul, cap } };
Object unders[][] = Utilities.addToArray((Object[][]) attributes.get(UNDERLINE),
obj);
return setAttribute(UNDERLINE, unders);
}
/** Key for sub/superscript. */
public static final String SUBSUPSCRIPT = "SUBSUPSCRIPT";
/**
* Sets the text displacement relative to the baseline. Positive values rise
* the text, negative values lower the text.
* <P>
* It can be used to implement sub/superscript.
*
* @param rise
* the displacement in points
* @return this <CODE>Chunk</CODE>
*/
public Chunk setTextRise(float rise) {
return setAttribute(SUBSUPSCRIPT, new Float(rise));
}
/**
* Gets the text displacement relative to the baseline.
*
* @return a displacement in points
*/
public float getTextRise() {
if (attributes != null && attributes.containsKey(SUBSUPSCRIPT)) {
Float f = (Float) attributes.get(SUBSUPSCRIPT);
return f.floatValue();
}
return 0.0f;
}
/** Key for text skewing. */
public static final String SKEW = "SKEW";
/**
* Skews the text to simulate italic and other effects. Try <CODE>alpha=0
* </CODE> and <CODE>beta=12</CODE>.
*
* @param alpha
* the first angle in degrees
* @param beta
* the second angle in degrees
* @return this <CODE>Chunk</CODE>
*/
public Chunk setSkew(float alpha, float beta) {
alpha = (float) Math.tan(alpha * Math.PI / 180);
beta = (float) Math.tan(beta * Math.PI / 180);
return setAttribute(SKEW, new float[] { alpha, beta });
}
/** Key for background. */
public static final String BACKGROUND = "BACKGROUND";
/**
* Sets the color of the background <CODE>Chunk</CODE>.
*
* @param background
* the color of the background
* @return this <CODE>Chunk</CODE>
*/
public Chunk setBackground(String background) {
return setBackground(background, 0, 0, 0, 0);
}
/**
* Sets the color and the size of the background <CODE>Chunk</CODE>.
*
* @param background
* the color of the background
* @param extraLeft
* increase the size of the rectangle in the left
* @param extraBottom
* increase the size of the rectangle in the bottom
* @param extraRight
* increase the size of the rectangle in the right
* @param extraTop
* increase the size of the rectangle in the top
* @return this <CODE>Chunk</CODE>
*/
public Chunk setBackground(String background, float extraLeft, float extraBottom,
float extraRight, float extraTop) {
return setAttribute(BACKGROUND, new Object[] { background,
new float[] { extraLeft, extraBottom, extraRight, extraTop } });
}
/** Key for text rendering mode. */
public static final String TEXTRENDERMODE = "TEXTRENDERMODE";
/**
* Sets the text rendering mode. It can outline text, simulate bold and make
* text invisible.
*
* @param mode
* the text rendering mode. It can be <CODE>
* PdfContentByte.TEXT_RENDER_MODE_FILL</CODE>,<CODE>
* PdfContentByte.TEXT_RENDER_MODE_STROKE</CODE>,<CODE>
* PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE</CODE> and <CODE>
* PdfContentByte.TEXT_RENDER_MODE_INVISIBLE</CODE>.
* @param strokeWidth
* the stroke line width for the modes <CODE>
* PdfContentByte.TEXT_RENDER_MODE_STROKE</CODE> and <CODE>
* PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE</CODE>.
* @param strokeColor
* the stroke color or <CODE>null</CODE> to follow the text
* color
* @return this <CODE>Chunk</CODE>
*/
public Chunk setTextRenderMode(int mode, float strokeWidth,
Color strokeColor) {
return setAttribute(TEXTRENDERMODE, new Object[] { new Integer(mode),
new Float(strokeWidth), strokeColor });
}
/** Key for split character. */
public static final String SPLITCHARACTER = "SPLITCHARACTER";
/**
* Sets the split characters.
*
* @param splitCharacter
* the <CODE>SplitCharacter</CODE> interface
* @return this <CODE>Chunk</CODE>
*/
public Chunk setSplitCharacter(SplitCharacter splitCharacter) {
return setAttribute(SPLITCHARACTER, splitCharacter);
}
/** Key for hyphenation. */
public static final String HYPHENATION = "HYPHENATION";
/**
* sets the hyphenation engine to this <CODE>Chunk</CODE>.
*
* @param hyphenation
* the hyphenation engine
* @return this <CODE>Chunk</CODE>
*/
public Chunk setHyphenation(HyphenationEvent hyphenation) {
return setAttribute(HYPHENATION, hyphenation);
}
/** Key for remote goto. */
public static final String REMOTEGOTO = "REMOTEGOTO";
/**
* Sets a goto for a remote destination for this <CODE>Chunk</CODE>.
*
* @param filename
* the file name of the destination document
* @param name
* the name of the destination to go to
* @return this <CODE>Chunk</CODE>
*/
public Chunk setRemoteGoto(String filename, String name) {
return setAttribute(REMOTEGOTO, new Object[] { filename, name });
}
/**
* Sets a goto for a remote destination for this <CODE>Chunk</CODE>.
*
* @param filename
* the file name of the destination document
* @param page
* the page of the destination to go to. First page is 1
* @return this <CODE>Chunk</CODE>
*/
public Chunk setRemoteGoto(String filename, int page) {
return setAttribute(REMOTEGOTO, new Object[] { filename,
new Integer(page) });
}
/** Key for local goto. */
public static final String LOCALGOTO = "LOCALGOTO";
/**
* Sets a local goto for this <CODE>Chunk</CODE>.
* <P>
* There must be a local destination matching the name.
*
* @param name
* the name of the destination to go to
* @return this <CODE>Chunk</CODE>
*/
public Chunk setLocalGoto(String name) {
return setAttribute(LOCALGOTO, name);
}
/** Key for local destination. */
public static final String LOCALDESTINATION = "LOCALDESTINATION";
/**
* Sets a local destination for this <CODE>Chunk</CODE>.
*
* @param name
* the name for this destination
* @return this <CODE>Chunk</CODE>
*/
public Chunk setLocalDestination(String name) {
return setAttribute(LOCALDESTINATION, name);
}
/** Key for generic tag. */
public static final String GENERICTAG = "GENERICTAG";
/**
* Sets the generic tag <CODE>Chunk</CODE>.
* <P>
* The text for this tag can be retrieved with <CODE>PdfPageEvent</CODE>.
*
* @param text
* the text for the tag
* @return this <CODE>Chunk</CODE>
*/
public Chunk setGenericTag(String text) {
return setAttribute(GENERICTAG, text);
}
/** Key for image. */
public static final String IMAGE = "IMAGE";
public static final String OLD_IMAGE = "OLD_IMAGE";
/**
* Returns the image.
*
* @return the image
*/
public Image getImage() {
if (attributes == null)
return null;
Object obj[] = (Object[]) attributes.get(Chunk.IMAGE);
if (obj == null)
return null;
else {
return (Image) obj[0];
}
}
public com.fr.third.com.lowagie.text.Image getOldImage() {
if (attributes == null)
return null;
Object obj[] = (Object[]) attributes.get(Chunk.OLD_IMAGE);
if (obj == null || obj.length == 0)
return null;
else {
return (com.fr.third.com.lowagie.text.Image) obj[0];
}
}
/** Key for Action. */
public static final String ACTION = "ACTION";
/**
* Sets an action for this <CODE>Chunk</CODE>.
*
* @param action
* the action
* @return this <CODE>Chunk</CODE>
*/
public Chunk setAction(PdfAction action) {
return setAttribute(ACTION, action);
}
/**
* Sets an anchor for this <CODE>Chunk</CODE>.
*
* @param url
* the <CODE>URL</CODE> to link to
* @return this <CODE>Chunk</CODE>
*/
public Chunk setAnchor(URL url) {
return setAttribute(ACTION, new PdfAction(url.toExternalForm()));
}
/**
* Sets an anchor for this <CODE>Chunk</CODE>.
*
* @param url
* the url to link to
* @return this <CODE>Chunk</CODE>
*/
public Chunk setAnchor(String url) {
return setAttribute(ACTION, new PdfAction(url));
}
/** Key for newpage. */
public static final String NEWPAGE = "NEWPAGE";
/**
* Sets a new page tag..
*
* @return this <CODE>Chunk</CODE>
*/
public Chunk setNewPage() {
return setAttribute(NEWPAGE, null);
}
/** Key for annotation. */
public static final String PDFANNOTATION = "PDFANNOTATION";
/**
* Sets a generic annotation to this <CODE>Chunk</CODE>.
*
* @param annotation
* the annotation
* @return this <CODE>Chunk</CODE>
*/
public Chunk setAnnotation(PdfAnnotation annotation) {
return setAttribute(PDFANNOTATION, annotation);
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
/**
* Returns the hyphenation (if present).
* @since 2.1.2
*/
public HyphenationEvent getHyphenation() {
if (attributes == null) return null;
return (HyphenationEvent) attributes.get(Chunk.HYPHENATION);
}
// keys used in PdfChunk
/** Key for color. */
public static final String COLOR = "COLOR";
/** Key for encoding. */
public static final String ENCODING = "ENCODING";
}

167
src/main/java/com/fr/third/lowagie/text/DocListener.java

@ -0,0 +1,167 @@
/*
* $Id: DocListener.java 3939 2009-05-27 13:09:45Z blowagie $
*
* Copyright (c) 1999, 2000, 2001, 2002 Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* A class that implements <CODE>DocListener</CODE> will perform some
* actions when some actions are performed on a <CODE>Document</CODE>.
*
* @see ElementListener
* @see Document
* @see DocWriter
*/
public interface DocListener extends ElementListener {
// methods
/**
* Signals that the <CODE>Document</CODE> has been opened and that
* <CODE>Elements</CODE> can be added.
*/
public void open(); // [L1]
/**
* Signals that the <CODE>Document</CODE> was closed and that no other
* <CODE>Elements</CODE> will be added.
* <P>
* The outputstream of every writer implementing <CODE>DocListener</CODE> will be closed.
*/
public void close(); // [L2]
/**
* Signals that an new page has to be started.
*
* @return <CODE>true</CODE> if the page was added, <CODE>false</CODE> if not.
*/
public boolean newPage(); // [L3]
/**
* Sets the pagesize.
*
* @param pageSize the new pagesize
* @return a <CODE>boolean</CODE>
*/
public boolean setPageSize(Rectangle pageSize); // [L4]
/**
* Sets the margins.
*
* @param marginLeft the margin on the left
* @param marginRight the margin on the right
* @param marginTop the margin on the top
* @param marginBottom the margin on the bottom
* @return a <CODE>boolean</CODE>
*/
public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom); // [L5]
/**
* Parameter that allows you to do left/right margin mirroring (odd/even pages)
* @param marginMirroring
* @return true if successful
*/
public boolean setMarginMirroring(boolean marginMirroring); // [L6]
/**
* Parameter that allows you to do top/bottom margin mirroring (odd/even pages)
* @param marginMirroringTopBottom
* @return true if successful
* @since 2.1.6
*/
public boolean setMarginMirroringTopBottom(boolean marginMirroringTopBottom); // [L6]
/**
* Sets the page number.
*
* @param pageN the new page number
*/
public void setPageCount(int pageN); // [L7]
/**
* Sets the page number to 0.
*/
public void resetPageCount(); // [L8]
/**
* Changes the header of this document.
*
* @param header the new header
*/
public void setHeader(HeaderFooter header); // [L9]
/**
* Resets the header of this document.
*/
public void resetHeader(); // [L10]
/**
* Changes the footer of this document.
*
* @param footer the new footer
*/
public void setFooter(HeaderFooter footer); // [L11]
/**
* Resets the footer of this document.
*/
public void resetFooter(); // [L12]
}

488
src/main/java/com/fr/third/lowagie/text/DocWriter.java

@ -0,0 +1,488 @@
/*
* $Id: DocWriter.java 3937 2009-05-27 12:56:48Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Properties;
import com.fr.third.lowagie.text.pdf.OutputStreamCounter;
/**
* An abstract <CODE>Writer</CODE> class for documents.
* <P>
* <CODE>DocWriter</CODE> is the abstract class of several writers such
* as <CODE>PdfWriter</CODE> and <CODE>HtmlWriter</CODE>.
* A <CODE>DocWriter</CODE> can be added as a <CODE>DocListener</CODE>
* to a certain <CODE>Document</CODE> by getting an instance (see method
* <CODE>getInstance()</CODE> in the specific writer-classes).
* Every <CODE>Element</CODE> added to the original <CODE>Document</CODE>
* will be written to the <CODE>OutputStream</CODE> of the listening
* <CODE>DocWriter</CODE>.
*
* @see Document
* @see DocListener
*/
public abstract class DocWriter implements DocListener {
/** This is some byte that is often used. */
public static final byte NEWLINE = (byte)'\n';
/** This is some byte that is often used. */
public static final byte TAB = (byte)'\t';
/** This is some byte that is often used. */
public static final byte LT = (byte)'<';
/** This is some byte that is often used. */
public static final byte SPACE = (byte)' ';
/** This is some byte that is often used. */
public static final byte EQUALS = (byte)'=';
/** This is some byte that is often used. */
public static final byte QUOTE = (byte)'\"';
/** This is some byte that is often used. */
public static final byte GT = (byte)'>';
/** This is some byte that is often used. */
public static final byte FORWARD = (byte)'/';
// membervariables
/** The pageSize. */
protected Rectangle pageSize;
/** This is the document that has to be written. */
protected Document document;
/** The outputstream of this writer. */
protected OutputStreamCounter os;
/** Is the writer open for writing? */
protected boolean open = false;
/** Do we have to pause all writing actions? */
protected boolean pause = false;
/** Closes the stream on document close */
protected boolean closeStream = true;
// constructor
protected DocWriter() {
}
/**
* Constructs a <CODE>DocWriter</CODE>.
*
* @param document The <CODE>Document</CODE> that has to be written
* @param os The <CODE>OutputStream</CODE> the writer has to write to.
*/
protected DocWriter(Document document, OutputStream os) {
this.document = document;
this.os = new OutputStreamCounter(new BufferedOutputStream(os));
}
// implementation of the DocListener methods
/**
* Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class.
*
* @param element A high level object to add
* @return <CODE>false</CODE>
* @throws DocumentException when a document isn't open yet, or has been closed
*/
public boolean add(Element element) throws DocumentException {
return false;
}
/**
* Signals that the <CODE>Document</CODE> was opened.
*/
public void open() {
open = true;
}
/**
* Sets the pagesize.
*
* @param pageSize the new pagesize
* @return a <CODE>boolean</CODE>
*/
public boolean setPageSize(Rectangle pageSize) {
this.pageSize = pageSize;
return true;
}
/**
* Sets the margins.
* <P>
* This does nothing. Has to be overridden if needed.
*
* @param marginLeft the margin on the left
* @param marginRight the margin on the right
* @param marginTop the margin on the top
* @param marginBottom the margin on the bottom
* @return <CODE>false</CODE>
*/
public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
return false;
}
/**
* Signals that an new page has to be started.
* <P>
* This does nothing. Has to be overridden if needed.
*
* @return <CODE>true</CODE> if the page was added, <CODE>false</CODE> if not.
*/
public boolean newPage() {
if (!open) {
return false;
}
return true;
}
/**
* Changes the header of this document.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* headers.
*
* @param header the new header
*/
public void setHeader(HeaderFooter header) {
}
/**
* Resets the header of this document.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* headers.
*/
public void resetHeader() {
}
/**
* Changes the footer of this document.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* footers.
*
* @param footer the new footer
*/
public void setFooter(HeaderFooter footer) {
}
/**
* Resets the footer of this document.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* footers.
*/
public void resetFooter() {
}
/**
* Sets the page number to 0.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* pagenumbers.
*/
public void resetPageCount() {
}
/**
* Sets the page number.
* <P>
* This method should be overridden in the specific <CODE>DocWriter<CODE> classes
* derived from this abstract class if they actually support the use of
* pagenumbers.
*
* @param pageN the new page number
*/
public void setPageCount(int pageN) {
}
/**
* Signals that the <CODE>Document</CODE> was closed and that no other
* <CODE>Elements</CODE> will be added.
*/
public void close() {
open = false;
try {
os.flush();
if (closeStream)
os.close();
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
// methods
/** Converts a <CODE>String</CODE> into a <CODE>Byte</CODE> array
* according to the ISO-8859-1 codepage.
* @param text the text to be converted
* @return the conversion result
*/
public static final byte[] getISOBytes(String text)
{
if (text == null)
return null;
int len = text.length();
byte b[] = new byte[len];
for (int k = 0; k < len; ++k)
b[k] = (byte)text.charAt(k);
return b;
}
/**
* Let the writer know that all writing has to be paused.
*/
public void pause() {
pause = true;
}
/**
* Checks if writing is paused.
*
* @return <CODE>true</CODE> if writing temporarily has to be paused, <CODE>false</CODE> otherwise.
*/
public boolean isPaused() {
return pause;
}
/**
* Let the writer know that writing may be resumed.
*/
public void resume() {
pause = false;
}
/**
* Flushes the <CODE>BufferedOutputStream</CODE>.
*/
public void flush() {
try {
os.flush();
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/**
* Writes a <CODE>String</CODE> to the <CODE>OutputStream</CODE>.
*
* @param string the <CODE>String</CODE> to write
* @throws IOException
*/
protected void write(String string) throws IOException {
os.write(getISOBytes(string));
}
/**
* Writes a number of tabs.
*
* @param indent the number of tabs to add
* @throws IOException
*/
protected void addTabs(int indent) throws IOException {
os.write(NEWLINE);
for (int i = 0; i < indent; i++) {
os.write(TAB);
}
}
/**
* Writes a key-value pair to the outputstream.
*
* @param key the name of an attribute
* @param value the value of an attribute
* @throws IOException
*/
protected void write(String key, String value)
throws IOException {
os.write(SPACE);
write(key);
os.write(EQUALS);
os.write(QUOTE);
write(value);
os.write(QUOTE);
}
/**
* Writes a starttag to the outputstream.
*
* @param tag the name of the tag
* @throws IOException
*/
protected void writeStart(String tag)
throws IOException {
os.write(LT);
write(tag);
}
/**
* Writes an endtag to the outputstream.
*
* @param tag the name of the tag
* @throws IOException
*/
protected void writeEnd(String tag)
throws IOException {
os.write(LT);
os.write(FORWARD);
write(tag);
os.write(GT);
}
/**
* Writes an endtag to the outputstream.
* @throws IOException
*/
protected void writeEnd()
throws IOException {
os.write(SPACE);
os.write(FORWARD);
os.write(GT);
}
/**
* Writes the markup attributes of the specified <CODE>MarkupAttributes</CODE>
* object to the <CODE>OutputStream</CODE>.
* @param markup a <CODE>Properties</CODE> collection to write.
* @return true, if writing the markup attributes succeeded
* @throws IOException
*/
protected boolean writeMarkupAttributes(Properties markup)
throws IOException {
if (markup == null) return false;
Iterator attributeIterator = markup.keySet().iterator();
String name;
while (attributeIterator.hasNext()) {
name = String.valueOf(attributeIterator.next());
write(name, markup.getProperty(name));
}
markup.clear();
return true;
}
/** Checks if the stream is to be closed on document close
* @return true if the stream is closed on document close
*
*/
public boolean isCloseStream() {
return closeStream;
}
/** Sets the close state of the stream after document close
* @param closeStream true if the stream is closed on document close
*
*/
public void setCloseStream(boolean closeStream) {
this.closeStream = closeStream;
}
/**
* @see DocListener#setMarginMirroring(boolean)
*/
public boolean setMarginMirroring(boolean MarginMirroring) {
return false;
}
/**
* @see DocListener#setMarginMirroring(boolean)
* @since 2.1.6
*/
public boolean setMarginMirroringTopBottom(boolean MarginMirroring) {
return false;
}
}

919
src/main/java/com/fr/third/lowagie/text/Document.java

@ -0,0 +1,919 @@
/*
* $Id: Document.java 4007 2009-07-07 09:43:40Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
* A generic Document class.
* <P>
* All kinds of Text-elements can be added to a <CODE>HTMLDocument</CODE>.
* The <CODE>Document</CODE> signals all the listeners when an element has
* been added.
* <P>
* Remark:
* <OL>
* <LI>Once a document is created you can add some meta information.
* <LI>You can also set the headers/footers.
* <LI>You have to open the document before you can write content.
* <LI>You can only write content (no more meta-formation!) once a document is
* opened.
* <LI>When you change the header/footer on a certain page, this will be
* effective starting on the next page.
* <LI>After closing the document, every listener (as well as its <CODE>
* OutputStream</CODE>) is closed too.
* </OL>
* Example: <BLOCKQUOTE>
*
* <PRE>// creation of the document with a certain size and certain margins
* <STRONG>Document document = new Document(PageSize.A4, 50, 50, 50, 50);
* </STRONG> try {
* // creation of the different writers
* HtmlWriter.getInstance(<STRONG>document </STRONG>, System.out);
* PdfWriter.getInstance(<STRONG>document </STRONG>, new FileOutputStream("text.pdf"));
* // we add some meta information to the document
* <STRONG>document.addAuthor("Bruno Lowagie"); </STRONG>
* <STRONG>document.addSubject("This is the result of a Test."); </STRONG>
* // we open the document for writing
* <STRONG>document.open(); </STRONG>
* <STRONG>document.add(new Paragraph("Hello world"));</STRONG>
* } catch(DocumentException de) {
* System.err.println(de.getMessage());
* }
* <STRONG>document.close();</STRONG>
* </PRE>
*
* </BLOCKQUOTE>
*/
public class Document implements DocListener {
// membervariables
/**
* This constant may only be changed by Paulo Soares and/or Bruno Lowagie.
* @since 2.1.6
*/
private static final String ITEXT = "iText";
/**
* This constant may only be changed by Paulo Soares and/or Bruno Lowagie.
* @since 2.1.6
*/
private static final String RELEASE = "2.1.7";
/** This constant may only be changed by Paulo Soares and/or Bruno Lowagie. */
private static final String ITEXT_VERSION = ITEXT + " " + RELEASE + " by 1T3XT";
/**
* Allows the pdf documents to be produced without compression for debugging
* purposes.
*/
public static boolean compress = true;
/**
* When true the file access is not done through a memory mapped file. Use it if the file
* is too big to be mapped in your address space.
*/
public static boolean plainRandomAccess = false;
/** Scales the WMF font size. The default value is 0.86. */
public static float wmfFontCorrection = 0.86f;
/** The DocListener. */
private ArrayList listeners = new ArrayList();
/** Is the document open or not? */
protected boolean open;
/** Has the document already been closed? */
protected boolean close;
// membervariables concerning the layout
/** The size of the page. */
protected Rectangle pageSize;
/** margin in x direction starting from the left */
protected float marginLeft = 0;
/** margin in x direction starting from the right */
protected float marginRight = 0;
/** margin in y direction starting from the top */
protected float marginTop = 0;
/** margin in y direction starting from the bottom */
protected float marginBottom = 0;
/** mirroring of the left/right margins */
protected boolean marginMirroring = false;
/**
* mirroring of the top/bottom margins
* @since 2.1.6
*/
protected boolean marginMirroringTopBottom = false;
/** Content of JavaScript onLoad function */
protected String javaScript_onLoad = null;
/** Content of JavaScript onUnLoad function */
protected String javaScript_onUnLoad = null;
/** Style class in HTML body tag */
protected String htmlStyleClass = null;
// headers, footers
/** Current pagenumber */
protected int pageN = 0;
/** This is the textual part of a Page; it can contain a header */
protected HeaderFooter header = null;
/** This is the textual part of the footer */
protected HeaderFooter footer = null;
/** This is a chapter number in case ChapterAutoNumber is used. */
protected int chapternumber = 0;
// constructor
/**
* Constructs a new <CODE>Document</CODE> -object.
*/
public Document() {
this(PageSize.A4);
}
/**
* Constructs a new <CODE>Document</CODE> -object.
*
* @param pageSize
* the pageSize
*/
public Document(Rectangle pageSize) {
this(pageSize, 36, 36, 36, 36);
}
/**
* Constructs a new <CODE>Document</CODE> -object.
*
* @param pageSize
* the pageSize
* @param marginLeft
* the margin on the left
* @param marginRight
* the margin on the right
* @param marginTop
* the margin on the top
* @param marginBottom
* the margin on the bottom
*/
public Document(Rectangle pageSize, float marginLeft, float marginRight,
float marginTop, float marginBottom) {
this.pageSize = pageSize;
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.marginTop = marginTop;
this.marginBottom = marginBottom;
}
// listener methods
/**
* Adds a <CODE>DocListener</CODE> to the <CODE>Document</CODE>.
*
* @param listener
* the new DocListener.
*/
public void addDocListener(DocListener listener) {
listeners.add(listener);
}
/**
* Removes a <CODE>DocListener</CODE> from the <CODE>Document</CODE>.
*
* @param listener
* the DocListener that has to be removed.
*/
public void removeDocListener(DocListener listener) {
listeners.remove(listener);
}
// methods implementing the DocListener interface
/**
* Adds an <CODE>Element</CODE> to the <CODE>Document</CODE>.
*
* @param element
* the <CODE>Element</CODE> to add
* @return <CODE>true</CODE> if the element was added, <CODE>false
* </CODE> if not
* @throws DocumentException
* when a document isn't open yet, or has been closed
*/
public boolean add(Element element) throws DocumentException {
if (close) {
throw new DocumentException(
"The document has been closed. You can't add any Elements.");
}
if (!open && element.isContent()) {
throw new DocumentException(
"The document is not open yet; you can only add Meta information.");
}
boolean success = false;
DocListener listener;
if (element instanceof ChapterAutoNumber) {
chapternumber = ((ChapterAutoNumber)element).setAutomaticNumber(chapternumber);
}
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
success |= listener.add(element);
}
if (element instanceof LargeElement) {
LargeElement e = (LargeElement)element;
if (!e.isComplete())
e.flushContent();
}
return success;
}
/**
* Opens the document.
* <P>
* Once the document is opened, you can't write any Header- or
* Meta-information anymore. You have to open the document before you can
* begin to add content to the body of the document.
*/
public void open() {
if (!close) {
open = true;
}
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setPageSize(pageSize);
listener.setMargins(marginLeft, marginRight, marginTop,
marginBottom);
listener.open();
}
}
/**
* Sets the pagesize.
*
* @param pageSize
* the new pagesize
* @return a <CODE>boolean</CODE>
*/
public boolean setPageSize(Rectangle pageSize) {
this.pageSize = pageSize;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setPageSize(pageSize);
}
return true;
}
/**
* Sets the margins.
*
* @param marginLeft
* the margin on the left
* @param marginRight
* the margin on the right
* @param marginTop
* the margin on the top
* @param marginBottom
* the margin on the bottom
* @return a <CODE>boolean</CODE>
*/
public boolean setMargins(float marginLeft, float marginRight,
float marginTop, float marginBottom) {
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.marginTop = marginTop;
this.marginBottom = marginBottom;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setMargins(marginLeft, marginRight, marginTop,
marginBottom);
}
return true;
}
/**
* Signals that an new page has to be started.
*
* @return <CODE>true</CODE> if the page was added, <CODE>false</CODE>
* if not.
*/
public boolean newPage() {
if (!open || close) {
return false;
}
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.newPage();
}
return true;
}
/**
* Changes the header of this document.
*
* @param header
* the new header
*/
public void setHeader(HeaderFooter header) {
this.header = header;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setHeader(header);
}
}
/**
* Resets the header of this document.
*/
public void resetHeader() {
this.header = null;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.resetHeader();
}
}
/**
* Changes the footer of this document.
*
* @param footer
* the new footer
*/
public void setFooter(HeaderFooter footer) {
this.footer = footer;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setFooter(footer);
}
}
/**
* Resets the footer of this document.
*/
public void resetFooter() {
this.footer = null;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.resetFooter();
}
}
/**
* Sets the page number to 0.
*/
public void resetPageCount() {
pageN = 0;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.resetPageCount();
}
}
/**
* Sets the page number.
*
* @param pageN
* the new page number
*/
public void setPageCount(int pageN) {
this.pageN = pageN;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setPageCount(pageN);
}
}
/**
* Returns the current page number.
*
* @return the current page number
*/
public int getPageNumber() {
return this.pageN;
}
/**
* Closes the document.
* <P>
* Once all the content has been written in the body, you have to close the
* body. After that nothing can be written to the body anymore.
*/
public void close() {
if (!close) {
open = false;
close = true;
}
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.close();
}
}
// methods concerning the header or some meta information
/**
* Adds a user defined header to the document.
*
* @param name
* the name of the header
* @param content
* the content of the header
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addHeader(String name, String content) {
try {
return add(new Header(name, content));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the title to a Document.
*
* @param title
* the title
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addTitle(String title) {
try {
return add(new Meta(Element.TITLE, title));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the subject to a Document.
*
* @param subject
* the subject
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addSubject(String subject) {
try {
return add(new Meta(Element.SUBJECT, subject));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the keywords to a Document.
*
* @param keywords
* adds the keywords to the document
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addKeywords(String keywords) {
try {
return add(new Meta(Element.KEYWORDS, keywords));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the author to a Document.
*
* @param author
* the name of the author
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addAuthor(String author) {
try {
return add(new Meta(Element.AUTHOR, author));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the creator to a Document.
*
* @param creator
* the name of the creator
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addCreator(String creator) {
try {
return add(new Meta(Element.CREATOR, creator));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the producer to a Document.
*
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addProducer() {
try {
return add(new Meta(Element.PRODUCER, getVersion()));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Adds the current date and time to a Document.
*
* @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
*/
public boolean addCreationDate() {
try {
/* bugfix by 'taqua' (Thomas) */
final SimpleDateFormat sdf = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss zzz yyyy");
return add(new Meta(Element.CREATIONDATE, sdf.format(new Date())));
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
// methods to get the layout of the document.
/**
* Returns the left margin.
*
* @return the left margin
*/
public float leftMargin() {
return marginLeft;
}
/**
* Return the right margin.
*
* @return the right margin
*/
public float rightMargin() {
return marginRight;
}
/**
* Returns the top margin.
*
* @return the top margin
*/
public float topMargin() {
return marginTop;
}
/**
* Returns the bottom margin.
*
* @return the bottom margin
*/
public float bottomMargin() {
return marginBottom;
}
/**
* Returns the lower left x-coordinate.
*
* @return the lower left x-coordinate
*/
public float left() {
return pageSize.getLeft(marginLeft);
}
/**
* Returns the upper right x-coordinate.
*
* @return the upper right x-coordinate
*/
public float right() {
return pageSize.getRight(marginRight);
}
/**
* Returns the upper right y-coordinate.
*
* @return the upper right y-coordinate
*/
public float top() {
return pageSize.getTop(marginTop);
}
/**
* Returns the lower left y-coordinate.
*
* @return the lower left y-coordinate
*/
public float bottom() {
return pageSize.getBottom(marginBottom);
}
/**
* Returns the lower left x-coordinate considering a given margin.
*
* @param margin
* a margin
* @return the lower left x-coordinate
*/
public float left(float margin) {
return pageSize.getLeft(marginLeft + margin);
}
/**
* Returns the upper right x-coordinate, considering a given margin.
*
* @param margin
* a margin
* @return the upper right x-coordinate
*/
public float right(float margin) {
return pageSize.getRight(marginRight + margin);
}
/**
* Returns the upper right y-coordinate, considering a given margin.
*
* @param margin
* a margin
* @return the upper right y-coordinate
*/
public float top(float margin) {
return pageSize.getTop(marginTop + margin);
}
/**
* Returns the lower left y-coordinate, considering a given margin.
*
* @param margin
* a margin
* @return the lower left y-coordinate
*/
public float bottom(float margin) {
return pageSize.getBottom(marginBottom + margin);
}
/**
* Gets the pagesize.
*
* @return the page size
*/
public Rectangle getPageSize() {
return this.pageSize;
}
/**
* Checks if the document is open.
*
* @return <CODE>true</CODE> if the document is open
*/
public boolean isOpen() {
return open;
}
/**
* Gets the product name.
* This method may only be changed by Paulo Soares and/or Bruno Lowagie.
* @return the product name
* @since 2.1.6
*/
public static final String getProduct() {
return ITEXT;
}
/**
* Gets the release number.
* This method may only be changed by Paulo Soares and/or Bruno Lowagie.
* @return the product name
* @since 2.1.6
*/
public static final String getRelease() {
return RELEASE;
}
/**
* Gets the iText version.
* This method may only be changed by Paulo Soares and/or Bruno Lowagie.
* @return iText version
*/
public static final String getVersion() {
return ITEXT_VERSION;
}
/**
* Adds a JavaScript onLoad function to the HTML body tag
*
* @param code
* the JavaScript code to be executed on load of the HTML page
*/
public void setJavaScript_onLoad(String code) {
this.javaScript_onLoad = code;
}
/**
* Gets the JavaScript onLoad command.
*
* @return the JavaScript onLoad command
*/
public String getJavaScript_onLoad() {
return this.javaScript_onLoad;
}
/**
* Adds a JavaScript onUnLoad function to the HTML body tag
*
* @param code
* the JavaScript code to be executed on unload of the HTML page
*/
public void setJavaScript_onUnLoad(String code) {
this.javaScript_onUnLoad = code;
}
/**
* Gets the JavaScript onUnLoad command.
*
* @return the JavaScript onUnLoad command
*/
public String getJavaScript_onUnLoad() {
return this.javaScript_onUnLoad;
}
/**
* Adds a style class to the HTML body tag
*
* @param htmlStyleClass
* the style class for the HTML body tag
*/
public void setHtmlStyleClass(String htmlStyleClass) {
this.htmlStyleClass = htmlStyleClass;
}
/**
* Gets the style class of the HTML body tag
*
* @return the style class of the HTML body tag
*/
public String getHtmlStyleClass() {
return this.htmlStyleClass;
}
/**
* Set the margin mirroring. It will mirror right/left margins for odd/even pages.
* <p>
* Note: it will not work with {@link Table}.
*
* @param marginMirroring
* <CODE>true</CODE> to mirror the margins
* @return always <CODE>true</CODE>
*/
public boolean setMarginMirroring(boolean marginMirroring) {
this.marginMirroring = marginMirroring;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setMarginMirroring(marginMirroring);
}
return true;
}
/**
* Set the margin mirroring. It will mirror top/bottom margins for odd/even pages.
* <p>
* Note: it will not work with {@link Table}.
*
* @param marginMirroringTopBottom
* <CODE>true</CODE> to mirror the margins
* @return always <CODE>true</CODE>
* @since 2.1.6
*/
public boolean setMarginMirroringTopBottom(boolean marginMirroringTopBottom) {
this.marginMirroringTopBottom = marginMirroringTopBottom;
DocListener listener;
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
listener = (DocListener) iterator.next();
listener.setMarginMirroringTopBottom(marginMirroringTopBottom);
}
return true;
}
/**
* Gets the margin mirroring flag.
*
* @return the margin mirroring flag
*/
public boolean isMarginMirroring() {
return marginMirroring;
}
}

92
src/main/java/com/fr/third/lowagie/text/DocumentException.java

@ -0,0 +1,92 @@
/*
* $Id: DocumentException.java 3831 2009-04-01 16:31:17Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*
*/
package com.fr.third.lowagie.text;
/**
* Signals that an error has occurred in a <CODE>Document</CODE>.
*
* @see BadElementException
* @see Document
* @see DocWriter
* @see DocListener
*/
public class DocumentException extends Exception {
/** A serial version UID */
private static final long serialVersionUID = -2191131489390840739L;
/**
* Creates a Document exception.
* @param ex an exception that has to be turned into a DocumentException
*/
public DocumentException(Exception ex) {
super(ex);
}
// constructors
/**
* Constructs a <CODE>DocumentException</CODE> without a message.
*/
public DocumentException() {
super();
}
/**
* Constructs a <code>DocumentException</code> with a message.
*
* @param message a message describing the exception
*/
public DocumentException(String message) {
super(message);
}
}

354
src/main/java/com/fr/third/lowagie/text/Element.java

@ -0,0 +1,354 @@
/*
* $Id: Element.java 3672 2009-02-01 15:32:09Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
/**
* Interface for a text element.
* <P>
* Remark: I looked at the interface javax.swing.text.Element, but I decided to
* write my own text-classes for two reasons:
* <OL>
* <LI>The javax.swing.text-classes may be very generic, I think they are
* overkill: they are to heavy for what they have to do.
* <LI>A lot of people using iText (formerly known as rugPdf), still use
* JDK1.1.x. I try to keep the Java2 requirements limited to the Collection
* classes (I think they're really great). However, if I use the
* javax.swing.text classes, it will become very difficult to downgrade rugPdf.
* </OL>
*
* @see Anchor
* @see Cell
* @see Chapter
* @see Chunk
* @see Header
* @see Image
* @see Jpeg
* @see List
* @see ListItem
* @see Meta
* @see Paragraph
* @see Phrase
* @see Rectangle
* @see Row
* @see Section
* @see Table
*/
public interface Element {
// static membervariables (meta information)
/** This is a possible type of <CODE>Element</CODE>. */
public static final int HEADER = 0;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int TITLE = 1;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int SUBJECT = 2;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int KEYWORDS = 3;
/** This is a possible type of <CODE>Element </CIDE>. */
public static final int AUTHOR = 4;
/** This is a possible type of <CODE>Element </CIDE>. */
public static final int PRODUCER = 5;
/** This is a possible type of <CODE>Element </CIDE>. */
public static final int CREATIONDATE = 6;
/** This is a possible type of <CODE>Element </CIDE>. */
public static final int CREATOR = 7;
// static membervariables (content)
/** This is a possible type of <CODE>Element</CODE>. */
public static final int CHUNK = 10;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int PHRASE = 11;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int PARAGRAPH = 12;
/** This is a possible type of <CODE>Element</CODE> */
public static final int SECTION = 13;
/** This is a possible type of <CODE>Element</CODE> */
public static final int LIST = 14;
/** This is a possible type of <CODE>Element</CODE> */
public static final int LISTITEM = 15;
/** This is a possible type of <CODE>Element</CODE> */
public static final int CHAPTER = 16;
/** This is a possible type of <CODE>Element</CODE> */
public static final int ANCHOR = 17;
// static membervariables (tables)
/** This is a possible type of <CODE>Element</CODE>. */
public static final int CELL = 20;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int ROW = 21;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int TABLE = 22;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int PTABLE = 23;
// static membervariables (annotations)
/** This is a possible type of <CODE>Element</CODE>. */
public static final int ANNOTATION = 29;
// static membervariables (geometric figures)
/** This is a possible type of <CODE>Element</CODE>. */
public static final int RECTANGLE = 30;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int JPEG = 32;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int JPEG2000 = 33;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int IMGRAW = 34;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int IMGTEMPLATE = 35;
/**
* This is a possible type of <CODE>Element</CODE>.
* @since 2.1.5
*/
public static final int JBIG2 = 36;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int MULTI_COLUMN_TEXT = 40;
/** This is a possible type of <CODE>Element</CODE>. */
public static final int MARKED = 50;
/** This is a possible type of <CODE>Element</CODE>.
* @since 2.1.2
*/
public static final int YMARK = 55;
// static membervariables (alignment)
/**
* A possible value for paragraph alignment. This specifies that the text is
* aligned to the left indent and extra whitespace should be placed on the
* right.
*/
public static final int ALIGN_UNDEFINED = -1;
/**
* A possible value for paragraph alignment. This specifies that the text is
* aligned to the left indent and extra whitespace should be placed on the
* right.
*/
public static final int ALIGN_LEFT = 0;
/**
* A possible value for paragraph alignment. This specifies that the text is
* aligned to the center and extra whitespace should be placed equally on
* the left and right.
*/
public static final int ALIGN_CENTER = 1;
/**
* A possible value for paragraph alignment. This specifies that the text is
* aligned to the right indent and extra whitespace should be placed on the
* left.
*/
public static final int ALIGN_RIGHT = 2;
/**
* A possible value for paragraph alignment. This specifies that extra
* whitespace should be spread out through the rows of the paragraph with
* the text lined up with the left and right indent except on the last line
* which should be aligned to the left.
*/
public static final int ALIGN_JUSTIFIED = 3;
/**
* A possible value for vertical alignment.
*/
public static final int ALIGN_TOP = 4;
/**
* A possible value for vertical alignment.
*/
public static final int ALIGN_MIDDLE = 5;
/**
* A possible value for vertical alignment.
*/
public static final int ALIGN_BOTTOM = 6;
/**
* A possible value for vertical alignment.
*/
public static final int ALIGN_BASELINE = 7;
/**
* Does the same as ALIGN_JUSTIFIED but the last line is also spread out.
*/
public static final int ALIGN_JUSTIFIED_ALL = 8;
// static member variables for CCITT compression
/**
* Pure two-dimensional encoding (Group 4)
*/
public static final int CCITTG4 = 0x100;
/**
* Pure one-dimensional encoding (Group 3, 1-D)
*/
public static final int CCITTG3_1D = 0x101;
/**
* Mixed one- and two-dimensional encoding (Group 3, 2-D)
*/
public static final int CCITTG3_2D = 0x102;
/**
* A flag indicating whether 1-bits are to be interpreted as black pixels
* and 0-bits as white pixels,
*/
public static final int CCITT_BLACKIS1 = 1;
/**
* A flag indicating whether the filter expects extra 0-bits before each
* encoded line so that the line begins on a byte boundary.
*/
public static final int CCITT_ENCODEDBYTEALIGN = 2;
/**
* A flag indicating whether end-of-line bit patterns are required to be
* present in the encoding.
*/
public static final int CCITT_ENDOFLINE = 4;
/**
* A flag indicating whether the filter expects the encoded data to be
* terminated by an end-of-block pattern, overriding the Rows parameter. The
* use of this flag will set the key /EndOfBlock to false.
*/
public static final int CCITT_ENDOFBLOCK = 8;
// methods
/**
* Processes the element by adding it (or the different parts) to an <CODE>
* ElementListener</CODE>.
*
* @param listener
* an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener);
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type();
/**
* Checks if this element is a content object.
* If not, it's a metadata object.
* @since iText 2.0.8
* @return true if this is a 'content' element; false if this is a 'metadata' element
*/
public boolean isContent();
/**
* Checks if this element is nestable.
* @since iText 2.0.8
* @return true if this element can be nested inside other elements.
*/
public boolean isNestable();
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks();
/**
* Gets the content of the text element.
*
* @return a type
*/
public String toString();
}

74
src/main/java/com/fr/third/lowagie/text/ElementListener.java

@ -0,0 +1,74 @@
/*
* $Id: ElementListener.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.EventListener;
/**
* A class that implements <CODE>ElementListener</CODE> will perform some
* actions when an <CODE>Element</CODE> is added.
*
* @see DocListener
*/
public interface ElementListener extends EventListener {
// methods
/**
* Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
*
* @param element a high level object
* @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
* @throws DocumentException when a document isn't open yet, or has been closed
*/
public boolean add(Element element) throws DocumentException; // [L0]
}

522
src/main/java/com/fr/third/lowagie/text/ElementTags.java

@ -0,0 +1,522 @@
/*
* $Id: ElementTags.java 3533 2008-07-07 21:27:13Z Howard_s $
*
* Copyright (c) 2001, 2002 Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* Contributions by:
* Lubos Strapko
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* A class that contains all the possible tagnames and their attributes.
*/
public class ElementTags {
/** the root tag. */
public static final String ITEXT = "itext";
/** attribute of the root and annotation tag (also a special tag within a chapter or section) */
public static final String TITLE = "title";
/** attribute of the root tag */
public static final String SUBJECT = "subject";
/** attribute of the root tag */
public static final String KEYWORDS = "keywords";
/** attribute of the root tag */
public static final String AUTHOR = "author";
/** attribute of the root tag */
public static final String CREATIONDATE = "creationdate";
/** attribute of the root tag */
public static final String PRODUCER = "producer";
// Chapters and Sections
/** the chapter tag */
public static final String CHAPTER = "chapter";
/** the section tag */
public static final String SECTION = "section";
/** attribute of section/chapter tag */
public static final String NUMBERDEPTH = "numberdepth";
/** attribute of section/chapter tag */
public static final String DEPTH = "depth";
/** attribute of section/chapter tag */
public static final String NUMBER = "number";
/** attribute of section/chapter tag */
public static final String INDENT = "indent";
/** attribute of chapter/section/paragraph/table/cell tag */
public static final String LEFT = "left";
/** attribute of chapter/section/paragraph/table/cell tag */
public static final String RIGHT = "right";
// Phrases, Anchors, Lists and Paragraphs
/** the phrase tag */
public static final String PHRASE = "phrase";
/** the anchor tag */
public static final String ANCHOR = "anchor";
/** the list tag */
public static final String LIST = "list";
/** the listitem tag */
public static final String LISTITEM = "listitem";
/** the paragraph tag */
public static final String PARAGRAPH = "paragraph";
/** attribute of phrase/paragraph/cell tag */
public static final String LEADING = "leading";
/** attribute of paragraph/image/table tag */
public static final String ALIGN = "align";
/** attribute of paragraph */
public static final String KEEPTOGETHER = "keeptogether";
/** attribute of anchor tag */
public static final String NAME = "name";
/** attribute of anchor tag */
public static final String REFERENCE = "reference";
/** attribute of list tag */
public static final String LISTSYMBOL = "listsymbol";
/** attribute of list tag */
public static final String NUMBERED = "numbered";
/** attribute of the list tag */
public static final String LETTERED = "lettered";
/** attribute of list tag */
public static final String FIRST = "first";
/** attribute of list tag */
public static final String SYMBOLINDENT = "symbolindent";
/** attribute of list tag */
public static final String INDENTATIONLEFT = "indentationleft";
/** attribute of list tag */
public static final String INDENTATIONRIGHT = "indentationright";
// Chunks
/** the chunk tag */
public static final String IGNORE = "ignore";
/** the chunk tag */
public static final String ENTITY = "entity";
/** the chunk tag */
public static final String ID = "id";
/** the chunk tag */
public static final String CHUNK = "chunk";
/** attribute of the chunk tag */
public static final String ENCODING = "encoding";
/** attribute of the chunk tag */
public static final String EMBEDDED = "embedded";
/** attribute of the chunk/table/cell tag */
public static final String COLOR = "color";
/** attribute of the chunk/table/cell tag */
public static final String RED = "red";
/** attribute of the chunk/table/cell tag */
public static final String GREEN = "green";
/** attribute of the chunk/table/cell tag */
public static final String BLUE = "blue";
/** attribute of the chunk tag */
public static final String SUBSUPSCRIPT = Chunk.SUBSUPSCRIPT.toLowerCase();
/** attribute of the chunk tag */
public static final String LOCALGOTO = Chunk.LOCALGOTO.toLowerCase();
/** attribute of the chunk tag */
public static final String REMOTEGOTO = Chunk.REMOTEGOTO.toLowerCase();
/** attribute of the chunk tag */
public static final String LOCALDESTINATION = Chunk.LOCALDESTINATION.toLowerCase();
/** attribute of the chunk tag */
public static final String GENERICTAG = Chunk.GENERICTAG.toLowerCase();
// tables/cells
/** the table tag */
public static final String TABLE = "table";
/** the cell tag */
public static final String ROW = "row";
/** the cell tag */
public static final String CELL = "cell";
/** attribute of the table tag */
public static final String COLUMNS = "columns";
/** attribute of the table tag */
public static final String LASTHEADERROW = "lastHeaderRow";
/** attribute of the table tag */
public static final String CELLPADDING = "cellpadding";
/** attribute of the table tag */
public static final String CELLSPACING = "cellspacing";
/** attribute of the table tag */
public static final String OFFSET = "offset";
/** attribute of the table tag */
public static final String WIDTHS = "widths";
/** attribute of the table tag */
public static final String TABLEFITSPAGE = "tablefitspage";
/** attribute of the table tag */
public static final String CELLSFITPAGE = "cellsfitpage";
/** attribute of the table tag */
public static final String CONVERT2PDFP = "convert2pdfp";
/** attribute of the cell tag */
public static final String HORIZONTALALIGN = "horizontalalign";
/** attribute of the cell tag */
public static final String VERTICALALIGN = "verticalalign";
/** attribute of the cell tag */
public static final String COLSPAN = "colspan";
/** attribute of the cell tag */
public static final String ROWSPAN = "rowspan";
/** attribute of the cell tag */
public static final String HEADER = "header";
/** attribute of the cell tag */
public static final String NOWRAP = "nowrap";
/** attribute of the table/cell tag */
public static final String BORDERWIDTH = "borderwidth";
/** attribute of the table/cell tag */
public static final String TOP = "top";
/** attribute of the table/cell tag */
public static final String BOTTOM = "bottom";
/** attribute of the table/cell tag */
public static final String WIDTH = "width";
/** attribute of the table/cell tag */
public static final String BORDERCOLOR = "bordercolor";
/** attribute of the table/cell tag */
public static final String BACKGROUNDCOLOR = "backgroundcolor";
/** attribute of the table/cell tag */
public static final String BGRED = "bgred";
/** attribute of the table/cell tag */
public static final String BGGREEN = "bggreen";
/** attribute of the table/cell tag */
public static final String BGBLUE = "bgblue";
/** attribute of the table/cell tag */
public static final String GRAYFILL = "grayfill";
// Misc
/** the image tag */
public static final String IMAGE = "image";
/** attribute of the image and annotation tag */
public static final String URL = "url";
/** attribute of the image tag */
public static final String UNDERLYING = "underlying";
/** attribute of the image tag */
public static final String TEXTWRAP = "textwrap";
/** attribute of the image tag */
public static final String ALT = "alt";
/** attribute of the image tag */
public static final String ABSOLUTEX = "absolutex";
/** attribute of the image tag */
public static final String ABSOLUTEY = "absolutey";
/** attribute of the image tag */
public static final String PLAINWIDTH = "plainwidth";
/** attribute of the image tag */
public static final String PLAINHEIGHT = "plainheight";
/** attribute of the image tag */
public static final String SCALEDWIDTH = "scaledwidth";
/** attribute of the image tag */
public static final String SCALEDHEIGHT = "scaledheight";
/** attribute of the image tag */
public static final String ROTATION = "rotation";
/** the newpage tag */
public static final String NEWPAGE = "newpage";
/** the newpage tag */
public static final String NEWLINE = "newline";
/** the annotation tag */
public static final String ANNOTATION = "annotation";
/** attribute of the annotation tag */
public static final String FILE = "file";
/** attribute of the annotation tag */
public static final String DESTINATION = "destination";
/** attribute of the annotation tag */
public static final String PAGE = "page";
/** attribute of the annotation tag */
public static final String NAMED = "named";
/** attribute of the annotation tag */
public static final String APPLICATION = "application";
/** attribute of the annotation tag */
public static final String PARAMETERS = "parameters";
/** attribute of the annotation tag */
public static final String OPERATION = "operation";
/** attribute of the annotation tag */
public static final String DEFAULTDIR = "defaultdir";
/** attribute of the annotation tag */
public static final String LLX = "llx";
/** attribute of the annotation tag */
public static final String LLY = "lly";
/** attribute of the annotation tag */
public static final String URX = "urx";
/** attribute of the annotation tag */
public static final String URY = "ury";
/** attribute of the annotation tag */
public static final String CONTENT = "content";
// alignment attribute values
/** the possible value of an alignment attribute */
public static final String ALIGN_LEFT = "Left";
/** the possible value of an alignment attribute */
public static final String ALIGN_CENTER = "Center";
/** the possible value of an alignment attribute */
public static final String ALIGN_RIGHT = "Right";
/** the possible value of an alignment attribute */
public static final String ALIGN_JUSTIFIED = "Justify";
/** the possible value of an alignment attribute */
public static final String ALIGN_JUSTIFIED_ALL = "JustifyAll";
/** the possible value of an alignment attribute */
public static final String ALIGN_TOP = "Top";
/** the possible value of an alignment attribute */
public static final String ALIGN_MIDDLE = "Middle";
/** the possible value of an alignment attribute */
public static final String ALIGN_BOTTOM = "Bottom";
/** the possible value of an alignment attribute */
public static final String ALIGN_BASELINE = "Baseline";
/** the possible value of an alignment attribute */
public static final String DEFAULT = "Default";
/** the possible value of an alignment attribute */
public static final String UNKNOWN = "unknown";
/** the possible value of an alignment attribute */
public static final String FONT = "font";
/** the possible value of an alignment attribute */
public static final String SIZE = "size";
/** the possible value of an alignment attribute */
public static final String STYLE = "fontstyle";
/** the possible value of a tag */
public static final String HORIZONTALRULE = "horizontalrule";
/** the possible value of a tag */
public static final String PAGE_SIZE = "pagesize";
/** the possible value of a tag */
public static final String ORIENTATION = "orientation";
/** a possible list attribute */
public static final String ALIGN_INDENTATION_ITEMS = "alignindent";
/** a possible list attribute */
public static final String AUTO_INDENT_ITEMS = "autoindent";
/** a possible list attribute */
public static final String LOWERCASE = "lowercase";
/**
* a possible list attribute
* @since 2.1.3
*/
public static final String FACE = "face";
/** attribute of the image or iframe tag
* @since 2.1.3
*/
public static final String SRC = "src";
// methods
/**
* Translates the alignment value to a String value.
*
* @param alignment the alignment value
* @return the translated value
*/
public static String getAlignment(int alignment) {
switch(alignment) {
case Element.ALIGN_LEFT:
return ALIGN_LEFT;
case Element.ALIGN_CENTER:
return ALIGN_CENTER;
case Element.ALIGN_RIGHT:
return ALIGN_RIGHT;
case Element.ALIGN_JUSTIFIED:
case Element.ALIGN_JUSTIFIED_ALL:
return ALIGN_JUSTIFIED;
case Element.ALIGN_TOP:
return ALIGN_TOP;
case Element.ALIGN_MIDDLE:
return ALIGN_MIDDLE;
case Element.ALIGN_BOTTOM:
return ALIGN_BOTTOM;
case Element.ALIGN_BASELINE:
return ALIGN_BASELINE;
default:
return DEFAULT;
}
}
/**
* Translates a String value to an alignment value.
* (written by Norman Richards, integrated into iText by Bruno)
* @param alignment a String (one of the ALIGN_ constants of this class)
* @return an alignment value (one of the ALIGN_ constants of the Element interface)
*/
public static int alignmentValue(String alignment) {
if (alignment == null) return Element.ALIGN_UNDEFINED;
if (ALIGN_CENTER.equalsIgnoreCase(alignment)) {
return Element.ALIGN_CENTER;
}
if (ALIGN_LEFT.equalsIgnoreCase(alignment)) {
return Element.ALIGN_LEFT;
}
if (ALIGN_RIGHT.equalsIgnoreCase(alignment)) {
return Element.ALIGN_RIGHT;
}
if (ALIGN_JUSTIFIED.equalsIgnoreCase(alignment)) {
return Element.ALIGN_JUSTIFIED;
}
if (ALIGN_JUSTIFIED_ALL.equalsIgnoreCase(alignment)) {
return Element.ALIGN_JUSTIFIED_ALL;
}
if (ALIGN_TOP.equalsIgnoreCase(alignment)) {
return Element.ALIGN_TOP;
}
if (ALIGN_MIDDLE.equalsIgnoreCase(alignment)) {
return Element.ALIGN_MIDDLE;
}
if (ALIGN_BOTTOM.equalsIgnoreCase(alignment)) {
return Element.ALIGN_BOTTOM;
}
if (ALIGN_BASELINE.equalsIgnoreCase(alignment)) {
return Element.ALIGN_BASELINE;
}
return Element.ALIGN_UNDEFINED;
}
}

160
src/main/java/com/fr/third/lowagie/text/ExceptionConverter.java

@ -0,0 +1,160 @@
/*
* The original version of this class was published in an article by professor Heinz Kabutz.
* Read http://www.javaspecialists.co.za/archive/newsletter.do?issue=033&print=yes&locale=en_US
* "This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa).
* Please contact Maximum Solutions for more information."
*
* Copyright (C) 2001 Dr. Heinz M. Kabutz
*/
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* The ExceptionConverter changes a checked exception into an
* unchecked exception.
*/
public class ExceptionConverter extends RuntimeException {
private static final long serialVersionUID = 8657630363395849399L;
/** we keep a handle to the wrapped exception */
private Exception ex;
/** prefix for the exception */
private String prefix;
/**
* Construct a RuntimeException based on another Exception
* @param ex the exception that has to be turned into a RuntimeException
*/
public ExceptionConverter(Exception ex) {
this.ex = ex;
prefix = (ex instanceof RuntimeException) ? "" : "ExceptionConverter: ";
}
/**
* Convert an Exception into an unchecked exception. Return the exception if it is
* already an unchecked exception or return an ExceptionConverter wrapper otherwise
*
* @param ex the exception to convert
* @return an unchecked exception
* @since 2.1.6
*/
public static final RuntimeException convertException(Exception ex) {
if (ex instanceof RuntimeException) {
return (RuntimeException) ex;
}
return new ExceptionConverter(ex);
}
/**
* and allow the user of ExceptionConverter to get a handle to it.
* @return the original exception
*/
public Exception getException() {
return ex;
}
/**
* We print the message of the checked exception
* @return message of the original exception
*/
public String getMessage() {
return ex.getMessage();
}
/**
* and make sure we also produce a localized version
* @return localized version of the message
*/
public String getLocalizedMessage() {
return ex.getLocalizedMessage();
}
/**
* The toString() is changed to be prefixed with ExceptionConverter
* @return String version of the exception
*/
public String toString() {
return prefix + ex;
}
/** we have to override this as well */
public void printStackTrace() {
printStackTrace(System.err);
}
/**
* here we prefix, with s.print(), not s.println(), the stack
* trace with "ExceptionConverter:"
* @param s
*/
public void printStackTrace(java.io.PrintStream s) {
synchronized (s) {
s.print(prefix);
ex.printStackTrace(s);
}
}
/**
* Again, we prefix the stack trace with "ExceptionConverter:"
* @param s
*/
public void printStackTrace(java.io.PrintWriter s) {
synchronized (s) {
s.print(prefix);
ex.printStackTrace(s);
}
}
/**
* requests to fill in the stack trace we will have to ignore.
* We can't throw an exception here, because this method
* is called by the constructor of Throwable
* @return a Throwable
*/
public Throwable fillInStackTrace() {
return this;
}
}

778
src/main/java/com/fr/third/lowagie/text/Font.java

@ -0,0 +1,778 @@
/*
* $Id: Font.java 3678 2009-02-07 14:46:01Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
import com.fr.third.lowagie.text.html.Markup;
import com.fr.third.lowagie.text.pdf.BaseFont;
/**
* Contains all the specifications of a font: fontfamily, size, style and color.
* <P>
* Example: <BLOCKQUOTE>
*
* <PRE>
*
* Paragraph p = new Paragraph("This is a paragraph", <STRONG>new
* Font(Font.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)) </STRONG>);
*
* </PRE>
*
* </BLOCKQUOTE>
*/
public class Font implements Comparable {
// static membervariables for the different families
/** a possible value of a font family. */
public static final int COURIER = 0;
/** a possible value of a font family. */
public static final int HELVETICA = 1;
/** a possible value of a font family. */
public static final int TIMES_ROMAN = 2;
/** a possible value of a font family. */
public static final int SYMBOL = 3;
/** a possible value of a font family. */
public static final int ZAPFDINGBATS = 4;
// static membervariables for the different styles
/** this is a possible style. */
public static final int NORMAL = 0;
/** this is a possible style. */
public static final int BOLD = 1;
/** this is a possible style. */
public static final int ITALIC = 2;
/** this is a possible style. */
public static final int UNDERLINE = 4;
/** this is a possible style. */
public static final int STRIKETHRU = 8;
/** this is a possible style. */
public static final int BOLDITALIC = BOLD | ITALIC;
// static membervariables
/** the value of an undefined attribute. */
public static final int UNDEFINED = -1;
/** the value of the default size. */
public static final int DEFAULTSIZE = 12;
// membervariables
/** the value of the fontfamily. */
private int family = UNDEFINED;
/** the value of the fontsize. */
private float size = UNDEFINED;
/** the value of the style. */
private int style = UNDEFINED;
/** the value of the color. */
private Color color = null;
/** the external font */
private BaseFont baseFont = null;
private String fontName;
public String getFontName(){
return fontName;
}
// constructors
/**
* Copy constructor of a Font
*
* @param other
* the font that has to be copied
*/
public Font(Font other) {
this.family = other.family;
this.size = other.size;
this.style = other.style;
this.color = other.color;
this.baseFont = other.baseFont;
}
/**
* Constructs a Font.
*
* @param family
* the family to which this font belongs
* @param size
* the size of this font
* @param style
* the style of this font
* @param color
* the <CODE>Color</CODE> of this font.
*/
public Font(int family, float size, int style, Color color) {
this.family = family;
this.size = size;
this.style = style;
this.color = color;
}
public Font(String face, float size, int style, Color color) {
this.fontName = face;
this.size =size;
this.style = style;
this.color = color;
}
/**
* Constructs a Font.
*
* @param bf
* the external font
* @param size
* the size of this font
* @param style
* the style of this font
* @param color
* the <CODE>Color</CODE> of this font.
*/
public Font(BaseFont bf, float size, int style, Color color) {
this.baseFont = bf;
this.size = size;
this.style = style;
this.color = color;
}
/**
* Constructs a Font.
*
* @param bf
* the external font
* @param size
* the size of this font
* @param style
* the style of this font
*/
public Font(BaseFont bf, float size, int style) {
this(bf, size, style, null);
}
/**
* Constructs a Font.
*
* @param bf
* the external font
* @param size
* the size of this font
*/
public Font(BaseFont bf, float size) {
this(bf, size, UNDEFINED, null);
}
/**
* Constructs a Font.
*
* @param bf
* the external font
*/
public Font(BaseFont bf) {
this(bf, UNDEFINED, UNDEFINED, null);
}
/**
* Constructs a Font.
*
* @param family
* the family to which this font belongs
* @param size
* the size of this font
* @param style
* the style of this font
*/
public Font(int family, float size, int style) {
this(family, size, style, null);
}
/**
* Constructs a Font.
*
* @param family
* the family to which this font belongs
* @param size
* the size of this font
*/
public Font(int family, float size) {
this(family, size, UNDEFINED, null);
}
/**
* Constructs a Font.
*
* @param family
* the family to which this font belongs
*/
public Font(int family) {
this(family, UNDEFINED, UNDEFINED, null);
}
/**
* Constructs a Font.
*/
public Font() {
this(UNDEFINED, UNDEFINED, UNDEFINED, null);
}
// implementation of the Comparable interface
/**
* Compares this <CODE>Font</CODE> with another
*
* @param object
* the other <CODE>Font</CODE>
* @return a value
*/
public int compareTo(Object object) {
if (object == null) {
return -1;
}
Font font;
try {
font = (Font) object;
if (baseFont != null && !baseFont.equals(font.getBaseFont())) {
return -2;
}
if (this.family != font.getFamily()) {
return 1;
}
if (this.size != font.getSize()) {
return 2;
}
if (this.style != font.getStyle()) {
return 3;
}
if (this.color == null) {
if (font.color == null) {
return 0;
}
return 4;
}
if (font.color == null) {
return 4;
}
if (this.color.equals(font.getColor())) {
return 0;
}
return 4;
} catch (ClassCastException cce) {
return -3;
}
}
// FAMILY
/**
* Gets the family of this font.
*
* @return the value of the family
*/
public int getFamily() {
return family;
}
/**
* Gets the familyname as a String.
*
* @return the familyname
*/
public String getFamilyname() {
return getFontName();
}
/**
* Sets the family using a <CODE>String</CODE> ("Courier", "Helvetica",
* "Times New Roman", "Symbol" or "ZapfDingbats").
*
* @param family
* A <CODE>String</CODE> representing a certain font-family.
*/
public void setFamily(String family) {
this.fontName = family;
}
/**
* Translates a <CODE>String</CODE> -value of a certain family into the
* index that is used for this family in this class.
*
* @param family
* A <CODE>String</CODE> representing a certain font-family
* @return the corresponding index
*/
public static int getFamilyIndex(String family) {
if (family.equalsIgnoreCase(FontFactory.COURIER)) {
return COURIER;
}
if (family.equalsIgnoreCase(FontFactory.HELVETICA)) {
return HELVETICA;
}
if (family.equalsIgnoreCase(FontFactory.TIMES_ROMAN)) {
return TIMES_ROMAN;
}
if (family.equalsIgnoreCase(FontFactory.SYMBOL)) {
return SYMBOL;
}
if (family.equalsIgnoreCase(FontFactory.ZAPFDINGBATS)) {
return ZAPFDINGBATS;
}
return UNDEFINED;
}
// SIZE
/**
* Gets the size of this font.
*
* @return a size
*/
public float getSize() {
return size;
}
/**
* Gets the size that can be used with the calculated <CODE>BaseFont
* </CODE>.
*
* @return the size that can be used with the calculated <CODE>BaseFont
* </CODE>
*/
public float getCalculatedSize() {
float s = this.size;
if (s == UNDEFINED) {
s = DEFAULTSIZE;
}
return s;
}
/**
* Gets the leading that can be used with this font.
*
* @param linespacing
* a certain linespacing
* @return the height of a line
*/
public float getCalculatedLeading(float linespacing) {
return linespacing * getCalculatedSize();
}
/**
* Sets the size.
*
* @param size
* The new size of the font.
*/
public void setSize(float size) {
this.size = size;
}
// STYLE
/**
* Gets the style of this font.
*
* @return a size
*/
public int getStyle() {
return style;
}
/**
* Gets the style that can be used with the calculated <CODE>BaseFont
* </CODE>.
*
* @return the style that can be used with the calculated <CODE>BaseFont
* </CODE>
*/
public int getCalculatedStyle() {
int style = this.style;
if (style == UNDEFINED) {
style = NORMAL;
}
if (baseFont != null)
return style;
if (family == SYMBOL || family == ZAPFDINGBATS)
return style;
else
return style & (~BOLDITALIC);
}
/**
* checks if this font is Bold.
*
* @return a <CODE>boolean</CODE>
*/
public boolean isBold() {
if (style == UNDEFINED) {
return false;
}
return (style & BOLD) == BOLD;
}
/**
* checks if this font is Bold.
*
* @return a <CODE>boolean</CODE>
*/
public boolean isItalic() {
if (style == UNDEFINED) {
return false;
}
return (style & ITALIC) == ITALIC;
}
/**
* checks if this font is underlined.
*
* @return a <CODE>boolean</CODE>
*/
public boolean isUnderlined() {
if (style == UNDEFINED) {
return false;
}
return (style & UNDERLINE) == UNDERLINE;
}
/**
* checks if the style of this font is STRIKETHRU.
*
* @return a <CODE>boolean</CODE>
*/
public boolean isStrikethru() {
if (style == UNDEFINED) {
return false;
}
return (style & STRIKETHRU) == STRIKETHRU;
}
/**
* Sets the style.
*
* @param style
* the style.
*/
public void setStyle(int style) {
this.style = style;
}
/**
* Sets the style using a <CODE>String</CODE> containing one of more of
* the following values: normal, bold, italic, underline, strike.
*
* @param style
* A <CODE>String</CODE> representing a certain style.
*/
public void setStyle(String style) {
if (this.style == UNDEFINED)
this.style = NORMAL;
this.style |= getStyleValue(style);
}
/**
* Translates a <CODE>String</CODE> -value of a certain style into the
* index value is used for this style in this class.
*
* @param style
* A <CODE>String</CODE>
* @return the corresponding value
*/
public static int getStyleValue(String style) {
int s = 0;
if (style.indexOf(Markup.CSS_VALUE_NORMAL) != -1) {
s |= NORMAL;
}
if (style.indexOf(Markup.CSS_VALUE_BOLD) != -1) {
s |= BOLD;
}
if (style.indexOf(Markup.CSS_VALUE_ITALIC) != -1) {
s |= ITALIC;
}
if (style.indexOf(Markup.CSS_VALUE_OBLIQUE) != -1) {
s |= ITALIC;
}
if (style.indexOf(Markup.CSS_VALUE_UNDERLINE) != -1) {
s |= UNDERLINE;
}
if (style.indexOf(Markup.CSS_VALUE_LINETHROUGH) != -1) {
s |= STRIKETHRU;
}
return s;
}
// COLOR
/**
* Gets the color of this font.
*
* @return a color
*/
public Color getColor() {
return color;
}
/**
* Sets the color.
*
* @param color
* the new color of the font
*/
public void setColor(Color color) {
this.color = color;
}
/**
* Sets the color.
*
* @param red
* the red-value of the new color
* @param green
* the green-value of the new color
* @param blue
* the blue-value of the new color
*/
public void setColor(int red, int green, int blue) {
this.color = new Color(red, green, blue);
}
// BASEFONT
/**
* Gets the <CODE>BaseFont</CODE> inside this object.
*
* @return the <CODE>BaseFont</CODE>
*/
public BaseFont getBaseFont() {
return baseFont;
}
/**
* Gets the <CODE>BaseFont</CODE> this class represents. For the built-in
* fonts a <CODE>BaseFont</CODE> is calculated.
*
* @param specialEncoding
* <CODE>true</CODE> to use the special encoding for Symbol and
* ZapfDingbats, <CODE>false</CODE> to always use <CODE>Cp1252
* </CODE>
* @return the <CODE>BaseFont</CODE> this class represents
*/
public BaseFont getCalculatedBaseFont(boolean specialEncoding) {
if (baseFont != null)
return baseFont;
int style = this.style;
if (style == UNDEFINED) {
style = NORMAL;
}
String fontName = BaseFont.HELVETICA;
String encoding = BaseFont.WINANSI;
BaseFont cfont = null;
switch (family) {
case COURIER:
switch (style & BOLDITALIC) {
case BOLD:
fontName = BaseFont.COURIER_BOLD;
break;
case ITALIC:
fontName = BaseFont.COURIER_OBLIQUE;
break;
case BOLDITALIC:
fontName = BaseFont.COURIER_BOLDOBLIQUE;
break;
default:
//case NORMAL:
fontName = BaseFont.COURIER;
break;
}
break;
case TIMES_ROMAN:
switch (style & BOLDITALIC) {
case BOLD:
fontName = BaseFont.TIMES_BOLD;
break;
case ITALIC:
fontName = BaseFont.TIMES_ITALIC;
break;
case BOLDITALIC:
fontName = BaseFont.TIMES_BOLDITALIC;
break;
default:
case NORMAL:
fontName = BaseFont.TIMES_ROMAN;
break;
}
break;
case SYMBOL:
fontName = BaseFont.SYMBOL;
if (specialEncoding)
encoding = BaseFont.SYMBOL;
break;
case ZAPFDINGBATS:
fontName = BaseFont.ZAPFDINGBATS;
if (specialEncoding)
encoding = BaseFont.ZAPFDINGBATS;
break;
default:
case Font.HELVETICA:
switch (style & BOLDITALIC) {
case BOLD:
fontName = BaseFont.HELVETICA_BOLD;
break;
case ITALIC:
fontName = BaseFont.HELVETICA_OBLIQUE;
break;
case BOLDITALIC:
fontName = BaseFont.HELVETICA_BOLDOBLIQUE;
break;
default:
case NORMAL:
fontName = BaseFont.HELVETICA;
break;
}
break;
}
try {
cfont = BaseFont.createFont(fontName, encoding, false);
} catch (Exception ee) {
throw new ExceptionConverter(ee);
}
return cfont;
}
// Helper methods
/**
* Checks if the properties of this font are undefined or null.
* <P>
* If so, the standard should be used.
*
* @return a <CODE>boolean</CODE>
*/
public boolean isStandardFont() {
return (family == UNDEFINED && size == UNDEFINED && style == UNDEFINED
&& color == null && baseFont == null);
}
/**
* Replaces the attributes that are equal to <VAR>null</VAR> with the
* attributes of a given font.
*
* @param font
* the font of a bigger element class
* @return a <CODE>Font</CODE>
*/
public Font difference(Font font) {
if (font == null) return this;
// size
float dSize = font.size;
if (dSize == UNDEFINED) {
dSize = this.size;
}
// style
int dStyle = UNDEFINED;
int style1 = this.style;
int style2 = font.getStyle();
if (style1 != UNDEFINED || style2 != UNDEFINED) {
if (style1 == UNDEFINED)
style1 = 0;
if (style2 == UNDEFINED)
style2 = 0;
dStyle = style1 | style2;
}
// color
Color dColor = font.color;
if (dColor == null) {
dColor = this.color;
}
// family
if (font.baseFont != null) {
return new Font(font.baseFont, dSize, dStyle, dColor);
}
if (font.getFamily() != UNDEFINED) {
return new Font(font.family, dSize, dStyle, dColor);
}
if (this.baseFont != null) {
if (dStyle == style1) {
return new Font(this.baseFont, dSize, dStyle, dColor);
} else {
return FontFactory.getFont(this.getFamilyname(), dSize, dStyle,
dColor);
}
}
return new Font(this.family, dSize, dStyle, dColor);
}
}

446
src/main/java/com/fr/third/lowagie/text/FontFactory.java

@ -0,0 +1,446 @@
/*
* $Id: FontFactory.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
import java.util.Properties;
import java.util.Set;
import com.fr.third.lowagie.text.pdf.BaseFont;
/**
* If you are using True Type fonts, you can declare the paths of the different ttf- and ttc-files
* to this static class first and then create fonts in your code using one of the static getFont-method
* without having to enter a path as parameter.
*
* @author Bruno Lowagie
*/
public final class FontFactory {
/** This is a possible value of a base 14 type 1 font */
public static final String COURIER = BaseFont.COURIER;
/** This is a possible value of a base 14 type 1 font */
public static final String COURIER_BOLD = BaseFont.COURIER_BOLD;
/** This is a possible value of a base 14 type 1 font */
public static final String COURIER_OBLIQUE = BaseFont.COURIER_OBLIQUE;
/** This is a possible value of a base 14 type 1 font */
public static final String COURIER_BOLDOBLIQUE = BaseFont.COURIER_BOLDOBLIQUE;
/** This is a possible value of a base 14 type 1 font */
public static final String HELVETICA = BaseFont.HELVETICA;
/** This is a possible value of a base 14 type 1 font */
public static final String HELVETICA_BOLD = BaseFont.HELVETICA_BOLD;
/** This is a possible value of a base 14 type 1 font */
public static final String HELVETICA_OBLIQUE = BaseFont.HELVETICA_OBLIQUE;
/** This is a possible value of a base 14 type 1 font */
public static final String HELVETICA_BOLDOBLIQUE = BaseFont.HELVETICA_BOLDOBLIQUE;
/** This is a possible value of a base 14 type 1 font */
public static final String SYMBOL = BaseFont.SYMBOL;
/** This is a possible value of a base 14 type 1 font */
public static final String TIMES = "Times";
/** This is a possible value of a base 14 type 1 font */
public static final String TIMES_ROMAN = BaseFont.TIMES_ROMAN;
/** This is a possible value of a base 14 type 1 font */
public static final String TIMES_BOLD = BaseFont.TIMES_BOLD;
/** This is a possible value of a base 14 type 1 font */
public static final String TIMES_ITALIC = BaseFont.TIMES_ITALIC;
/** This is a possible value of a base 14 type 1 font */
public static final String TIMES_BOLDITALIC = BaseFont.TIMES_BOLDITALIC;
/** This is a possible value of a base 14 type 1 font */
public static final String ZAPFDINGBATS = BaseFont.ZAPFDINGBATS;
private static FontFactoryImp fontImp = new FontFactoryImp();
/** This is the default encoding to use. */
public static String defaultEncoding = BaseFont.WINANSI;
/** This is the default value of the <VAR>embedded</VAR> variable. */
public static boolean defaultEmbedding = BaseFont.NOT_EMBEDDED;
/** Creates new FontFactory */
private FontFactory() {
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color) {
return fontImp.getFont(fontname, encoding, embedded, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @param cached true if the font comes from the cache or is added to
* the cache if new, false if the font is always created new
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color, boolean cached) {
return fontImp.getFont(fontname, encoding, embedded, size, style, color, cached);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param attributes the attributes of a <CODE>Font</CODE> object.
* @return the Font constructed based on the attributes
*/
public static Font getFont(Properties attributes) {
fontImp.defaultEmbedding = defaultEmbedding;
fontImp.defaultEncoding = defaultEncoding;
return fontImp.getFont(attributes);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style) {
return getFont(fontname, encoding, embedded, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, boolean embedded, float size) {
return getFont(fontname, encoding, embedded, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, boolean embedded) {
return getFont(fontname, encoding, embedded, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, float size, int style, Color color) {
return getFont(fontname, encoding, defaultEmbedding, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, float size, int style) {
return getFont(fontname, encoding, defaultEmbedding, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding, float size) {
return getFont(fontname, encoding, defaultEmbedding, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, String encoding) {
return getFont(fontname, encoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, float size, int style, Color color) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
* @since 2.1.0
*/
public static Font getFont(String fontname, float size, Color color) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, float size, int style) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname, float size) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @return the Font constructed based on the parameters
*/
public static Font getFont(String fontname) {
return getFont(fontname, defaultEncoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Register a font by giving explicitly the font family and name.
* @param familyName the font family
* @param fullName the font name
* @param path the font path
*/
public void registerFamily(String familyName, String fullName, String path) {
fontImp.registerFamily(familyName, fullName, path);
}
/**
* Register a ttf- or a ttc-file.
*
* @param path the path to a ttf- or ttc-file
*/
public static void register(String path) {
register(path, null);
}
/**
* Register a font file and use an alias for the font contained in it.
*
* @param path the path to a font file
* @param alias the alias you want to use for the font
*/
public static void register(String path, String alias) {
fontImp.register(path, alias);
}
/** Register all the fonts in a directory.
* @param dir the directory
* @return the number of fonts registered
*/
public static int registerDirectory(String dir) {
return fontImp.registerDirectory(dir);
}
/**
* Register all the fonts in a directory and possibly its subdirectories.
* @param dir the directory
* @param scanSubdirectories recursively scan subdirectories if <code>true</true>
* @return the number of fonts registered
* @since 2.1.2
*/
public static int registerDirectory(String dir, boolean scanSubdirectories) {
return fontImp.registerDirectory(dir, scanSubdirectories);
}
/** Register fonts in some probable directories. It usually works in Windows,
* Linux and Solaris.
* @return the number of fonts registered
*/
public static int registerDirectories() {
return fontImp.registerDirectories();
}
/**
* Gets a set of registered fontnames.
* @return a set of registered fonts
*/
public static Set getRegisteredFonts() {
return fontImp.getRegisteredFonts();
}
/**
* Gets a set of registered fontnames.
* @return a set of registered font families
*/
public static Set getRegisteredFamilies() {
return fontImp.getRegisteredFamilies();
}
/**
* Gets a set of registered fontnames.
* @param fontname of a font that may or may not be registered
* @return true if a given font is registered
*/
public static boolean contains(String fontname) {
return fontImp.isRegistered(fontname);
}
/**
* Checks if a certain font is registered.
*
* @param fontname the name of the font that has to be checked.
* @return true if the font is found
*/
public static boolean isRegistered(String fontname) {
return fontImp.isRegistered(fontname);
}
/**
* Gets the font factory implementation.
* @return the font factory implementation
*/
public static FontFactoryImp getFontImp() {
return fontImp;
}
/**
* Sets the font factory implementation.
* @param fontImp the font factory implementation
*/
public static void setFontImp(FontFactoryImp fontImp) {
if (fontImp == null)
throw new NullPointerException("FontFactoryImp cannot be null.");
FontFactory.fontImp = fontImp;
}
}

701
src/main/java/com/fr/third/lowagie/text/FontFactoryImp.java

@ -0,0 +1,701 @@
/*
* $Id: FontFactoryImp.java 3548 2008-07-12 11:15:35Z blowagie $
*
* Copyright 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import com.fr.third.lowagie.text.html.Markup;
import com.fr.third.lowagie.text.pdf.BaseFont;
/**
* If you are using True Type fonts, you can declare the paths of the different ttf- and ttc-files
* to this class first and then create fonts in your code using one of the getFont method
* without having to enter a path as parameter.
*
* @author Bruno Lowagie
*/
public class FontFactoryImp {
/** This is a map of postscriptfontnames of True Type fonts and the path of their ttf- or ttc-file. */
private Properties trueTypeFonts = new Properties();
private static String[] TTFamilyOrder = {
"3", "1", "1033",
"3", "0", "1033",
"1", "0", "0",
"0", "3", "0"
};
/** This is a map of fontfamilies. */
private Hashtable fontFamilies = new Hashtable();
/** This is the default encoding to use. */
public String defaultEncoding = BaseFont.WINANSI;
/** This is the default value of the <VAR>embedded</VAR> variable. */
public boolean defaultEmbedding = BaseFont.NOT_EMBEDDED;
/** Creates new FontFactory */
public FontFactoryImp() {
trueTypeFonts.setProperty(FontFactory.COURIER.toLowerCase(), FontFactory.COURIER);
trueTypeFonts.setProperty(FontFactory.COURIER_BOLD.toLowerCase(), FontFactory.COURIER_BOLD);
trueTypeFonts.setProperty(FontFactory.COURIER_OBLIQUE.toLowerCase(), FontFactory.COURIER_OBLIQUE);
trueTypeFonts.setProperty(FontFactory.COURIER_BOLDOBLIQUE.toLowerCase(), FontFactory.COURIER_BOLDOBLIQUE);
trueTypeFonts.setProperty(FontFactory.HELVETICA.toLowerCase(), FontFactory.HELVETICA);
trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLD.toLowerCase(), FontFactory.HELVETICA_BOLD);
trueTypeFonts.setProperty(FontFactory.HELVETICA_OBLIQUE.toLowerCase(), FontFactory.HELVETICA_OBLIQUE);
trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLDOBLIQUE.toLowerCase(), FontFactory.HELVETICA_BOLDOBLIQUE);
trueTypeFonts.setProperty(FontFactory.SYMBOL.toLowerCase(), FontFactory.SYMBOL);
trueTypeFonts.setProperty(FontFactory.TIMES_ROMAN.toLowerCase(), FontFactory.TIMES_ROMAN);
trueTypeFonts.setProperty(FontFactory.TIMES_BOLD.toLowerCase(), FontFactory.TIMES_BOLD);
trueTypeFonts.setProperty(FontFactory.TIMES_ITALIC.toLowerCase(), FontFactory.TIMES_ITALIC);
trueTypeFonts.setProperty(FontFactory.TIMES_BOLDITALIC.toLowerCase(), FontFactory.TIMES_BOLDITALIC);
trueTypeFonts.setProperty(FontFactory.ZAPFDINGBATS.toLowerCase(), FontFactory.ZAPFDINGBATS);
ArrayList tmp;
tmp = new ArrayList();
tmp.add(FontFactory.COURIER);
tmp.add(FontFactory.COURIER_BOLD);
tmp.add(FontFactory.COURIER_OBLIQUE);
tmp.add(FontFactory.COURIER_BOLDOBLIQUE);
fontFamilies.put(FontFactory.COURIER.toLowerCase(), tmp);
tmp = new ArrayList();
tmp.add(FontFactory.HELVETICA);
tmp.add(FontFactory.HELVETICA_BOLD);
tmp.add(FontFactory.HELVETICA_OBLIQUE);
tmp.add(FontFactory.HELVETICA_BOLDOBLIQUE);
fontFamilies.put(FontFactory.HELVETICA.toLowerCase(), tmp);
tmp = new ArrayList();
tmp.add(FontFactory.SYMBOL);
fontFamilies.put(FontFactory.SYMBOL.toLowerCase(), tmp);
tmp = new ArrayList();
tmp.add(FontFactory.TIMES_ROMAN);
tmp.add(FontFactory.TIMES_BOLD);
tmp.add(FontFactory.TIMES_ITALIC);
tmp.add(FontFactory.TIMES_BOLDITALIC);
fontFamilies.put(FontFactory.TIMES.toLowerCase(), tmp);
fontFamilies.put(FontFactory.TIMES_ROMAN.toLowerCase(), tmp);
tmp = new ArrayList();
tmp.add(FontFactory.ZAPFDINGBATS);
fontFamilies.put(FontFactory.ZAPFDINGBATS.toLowerCase(), tmp);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color) {
return getFont(fontname, encoding, embedded, size, style, color, true);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @param cached true if the font comes from the cache or is added to
* the cache if new, false if the font is always created new
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color, boolean cached) {
if (fontname == null) return new Font(Font.UNDEFINED, size, style, color);
String lowercasefontname = fontname.toLowerCase();
ArrayList tmp = (ArrayList) fontFamilies.get(lowercasefontname);
if (tmp != null) {
// some bugs were fixed here by Daniel Marczisovszky
int s = style == Font.UNDEFINED ? Font.NORMAL : style;
int fs = Font.NORMAL;
boolean found = false;
for (Iterator i = tmp.iterator(); i.hasNext(); ) {
String f = (String) i.next();
String lcf = f.toLowerCase();
fs = Font.NORMAL;
if (lcf.toLowerCase().indexOf("bold") != -1) fs |= Font.BOLD;
if (lcf.toLowerCase().indexOf("italic") != -1 || lcf.toLowerCase().indexOf("oblique") != -1) fs |= Font.ITALIC;
if ((s & Font.BOLDITALIC) == fs) {
fontname = f;
found = true;
break;
}
}
if (style != Font.UNDEFINED && found) {
style &= ~fs;
}
}
BaseFont basefont = null;
try {
try {
// the font is a type 1 font or CJK font
basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null, true);
}
catch(DocumentException de) {
}
if (basefont == null) {
// the font is a true type font or an unknown font
fontname = trueTypeFonts.getProperty(fontname.toLowerCase());
// the font is not registered as truetype font
if (fontname == null) return new Font(Font.UNDEFINED, size, style, color);
// the font is registered as truetype font
basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null);
}
}
catch(DocumentException de) {
// this shouldn't happen
throw new ExceptionConverter(de);
}
catch(IOException ioe) {
// the font is registered as a true type font, but the path was wrong
return new Font(Font.UNDEFINED, size, style, color);
}
catch(NullPointerException npe) {
// null was entered as fontname and/or encoding
return new Font(Font.UNDEFINED, size, style, color);
}
return new Font(basefont, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param attributes the attributes of a <CODE>Font</CODE> object.
* @return the Font constructed based on the attributes
*/
public Font getFont(Properties attributes) {
String fontname = null;
String encoding = defaultEncoding;
boolean embedded = defaultEmbedding;
float size = Font.UNDEFINED;
int style = Font.NORMAL;
Color color = null;
String value = attributes.getProperty(Markup.HTML_ATTR_STYLE);
if (value != null && value.length() > 0) {
Properties styleAttributes = Markup.parseAttributes(value);
if (styleAttributes.isEmpty()) {
attributes.put(Markup.HTML_ATTR_STYLE, value);
}
else {
fontname = styleAttributes.getProperty(Markup.CSS_KEY_FONTFAMILY);
if (fontname != null) {
String tmp;
while (fontname.indexOf(',') != -1) {
tmp = fontname.substring(0, fontname.indexOf(','));
if (isRegistered(tmp)) {
fontname = tmp;
}
else {
fontname = fontname.substring(fontname.indexOf(',') + 1);
}
}
}
if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSIZE)) != null) {
size = Markup.parseLength(value);
}
if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTWEIGHT)) != null) {
style |= Font.getStyleValue(value);
}
if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSTYLE)) != null) {
style |= Font.getStyleValue(value);
}
if ((value = styleAttributes.getProperty(Markup.CSS_KEY_COLOR)) != null) {
color = Markup.decodeColor(value);
}
attributes.putAll(styleAttributes);
for (Enumeration e = styleAttributes.keys(); e.hasMoreElements();) {
Object o = e.nextElement();
attributes.put(o, styleAttributes.get(o));
}
}
}
if ((value = attributes.getProperty(ElementTags.ENCODING)) != null) {
encoding = value;
}
if ("true".equals(attributes.getProperty(ElementTags.EMBEDDED))) {
embedded = true;
}
if ((value = attributes.getProperty(ElementTags.FONT)) != null) {
fontname = value;
}
if ((value = attributes.getProperty(ElementTags.SIZE)) != null) {
size = Markup.parseLength(value);
}
if ((value = attributes.getProperty(Markup.HTML_ATTR_STYLE)) != null) {
style |= Font.getStyleValue(value);
}
if ((value = attributes.getProperty(ElementTags.STYLE)) != null) {
style |= Font.getStyleValue(value);
}
String r = attributes.getProperty(ElementTags.RED);
String g = attributes.getProperty(ElementTags.GREEN);
String b = attributes.getProperty(ElementTags.BLUE);
if (r != null || g != null || b != null) {
int red = 0;
int green = 0;
int blue = 0;
if (r != null) red = Integer.parseInt(r);
if (g != null) green = Integer.parseInt(g);
if (b != null) blue = Integer.parseInt(b);
color = new Color(red, green, blue);
}
else if ((value = attributes.getProperty(ElementTags.COLOR)) != null) {
color = Markup.decodeColor(value);
}
if (fontname == null) {
return getFont(null, encoding, embedded, size, style, color);
}
return getFont(fontname, encoding, embedded, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style) {
return getFont(fontname, encoding, embedded, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, boolean embedded, float size) {
return getFont(fontname, encoding, embedded, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, boolean embedded) {
return getFont(fontname, encoding, embedded, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, float size, int style, Color color) {
return getFont(fontname, encoding, defaultEmbedding, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, float size, int style) {
return getFont(fontname, encoding, defaultEmbedding, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding, float size) {
return getFont(fontname, encoding, defaultEmbedding, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
* @since 2.1.0
*/
public Font getFont(String fontname, float size, Color color) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param encoding the encoding of the font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, String encoding) {
return getFont(fontname, encoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>Color</CODE> of this font.
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, float size, int style, Color color) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, color);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @param style the style of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, float size, int style) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @param size the size of this font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname, float size) {
return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, null);
}
/**
* Constructs a <CODE>Font</CODE>-object.
*
* @param fontname the name of the font
* @return the Font constructed based on the parameters
*/
public Font getFont(String fontname) {
return getFont(fontname, defaultEncoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null);
}
/**
* Register a font by giving explicitly the font family and name.
* @param familyName the font family
* @param fullName the font name
* @param path the font path
*/
public void registerFamily(String familyName, String fullName, String path) {
if (path != null)
trueTypeFonts.setProperty(fullName, path);
ArrayList tmp = (ArrayList) fontFamilies.get(familyName);
if (tmp == null) {
tmp = new ArrayList();
tmp.add(fullName);
fontFamilies.put(familyName, tmp);
}
else {
int fullNameLength = fullName.length();
boolean inserted = false;
for (int j = 0; j < tmp.size(); ++j) {
if (((String)tmp.get(j)).length() >= fullNameLength) {
tmp.add(j, fullName);
inserted = true;
break;
}
}
if (!inserted)
tmp.add(fullName);
}
}
/**
* Register a ttf- or a ttc-file.
*
* @param path the path to a ttf- or ttc-file
*/
public void register(String path) {
register(path, null);
}
/**
* Register a font file and use an alias for the font contained in it.
*
* @param path the path to a font file
* @param alias the alias you want to use for the font
*/
public void register(String path, String alias) {
try {
if (path.toLowerCase().endsWith(".ttf") || path.toLowerCase().endsWith(".otf") || path.toLowerCase().indexOf(".ttc,") > 0) {
Object allNames[] = BaseFont.getAllFontNames(path, BaseFont.WINANSI, null);
trueTypeFonts.setProperty(((String)allNames[0]).toLowerCase(), path);
if (alias != null) {
trueTypeFonts.setProperty(alias.toLowerCase(), path);
}
// register all the font names with all the locales
String[][] names = (String[][])allNames[2]; //full name
for (int i = 0; i < names.length; i++) {
trueTypeFonts.setProperty(names[i][3].toLowerCase(), path);
}
String fullName = null;
String familyName = null;
names = (String[][])allNames[1]; //family name
for (int k = 0; k < TTFamilyOrder.length; k += 3) {
for (int i = 0; i < names.length; i++) {
if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) {
familyName = names[i][3].toLowerCase();
k = TTFamilyOrder.length;
break;
}
}
}
if (familyName != null) {
String lastName = "";
names = (String[][])allNames[2]; //full name
for (int i = 0; i < names.length; i++) {
for (int k = 0; k < TTFamilyOrder.length; k += 3) {
if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) {
fullName = names[i][3];
if (fullName.equals(lastName))
continue;
lastName = fullName;
registerFamily(familyName, fullName, null);
break;
}
}
}
}
}
else if (path.toLowerCase().endsWith(".ttc")) {
if (alias != null)
System.err.println("class FontFactory: You can't define an alias for a true type collection.");
String[] names = BaseFont.enumerateTTCNames(path);
for (int i = 0; i < names.length; i++) {
register(path + "," + i);
}
}
else if (path.toLowerCase().endsWith(".afm") || path.toLowerCase().endsWith(".pfm")) {
BaseFont bf = BaseFont.createFont(path, BaseFont.CP1252, false);
String fullName = bf.getFullFontName()[0][3].toLowerCase();
String familyName = bf.getFamilyFontName()[0][3].toLowerCase();
String psName = bf.getPostscriptFontName().toLowerCase();
registerFamily(familyName, fullName, null);
trueTypeFonts.setProperty(psName, path);
trueTypeFonts.setProperty(fullName, path);
}
}
catch(DocumentException de) {
// this shouldn't happen
throw new ExceptionConverter(de);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/** Register all the fonts in a directory.
* @param dir the directory
* @return the number of fonts registered
*/
public int registerDirectory(String dir) {
return registerDirectory(dir, false);
}
/**
* Register all the fonts in a directory and possibly its subdirectories.
* @param dir the directory
* @param scanSubdirectories recursively scan subdirectories if <code>true</true>
* @return the number of fonts registered
* @since 2.1.2
*/
public int registerDirectory(String dir, boolean scanSubdirectories) {
int count = 0;
try {
File file = new File(dir);
if (!file.exists() || !file.isDirectory())
return 0;
String files[] = file.list();
if (files == null)
return 0;
for (int k = 0; k < files.length; ++k) {
try {
file = new File(dir, files[k]);
if (file.isDirectory()) {
if (scanSubdirectories) {
count += registerDirectory(file.getAbsolutePath(), true);
}
} else {
String name = file.getPath();
String suffix = name.length() < 4 ? null : name.substring(name.length() - 4).toLowerCase();
if (".afm".equals(suffix) || ".pfm".equals(suffix)) {
/* Only register Type 1 fonts with matching .pfb files */
File pfb = new File(name.substring(0, name.length() - 4) + ".pfb");
if (pfb.exists()) {
register(name, null);
++count;
}
} else if (".ttf".equals(suffix) || ".otf".equals(suffix) || ".ttc".equals(suffix)) {
register(name, null);
++count;
}
}
}
catch (Exception e) {
//empty on purpose
}
}
}
catch (Exception e) {
//empty on purpose
}
return count;
}
/** Register fonts in some probable directories. It usually works in Windows,
* Linux and Solaris.
* @return the number of fonts registered
*/
public int registerDirectories() {
int count = 0;
count += registerDirectory("c:/windows/fonts");
count += registerDirectory("c:/winnt/fonts");
count += registerDirectory("d:/windows/fonts");
count += registerDirectory("d:/winnt/fonts");
count += registerDirectory("/usr/share/X11/fonts", true);
count += registerDirectory("/usr/X/lib/X11/fonts", true);
count += registerDirectory("/usr/openwin/lib/X11/fonts", true);
count += registerDirectory("/usr/share/fonts", true);
count += registerDirectory("/usr/X11R6/lib/X11/fonts", true);
count += registerDirectory("/Library/Fonts");
count += registerDirectory("/System/Library/Fonts");
return count;
}
/**
* Gets a set of registered fontnames.
* @return a set of registered fonts
*/
public Set getRegisteredFonts() {
return Utilities.getKeySet(trueTypeFonts);
}
/**
* Gets a set of registered fontnames.
* @return a set of registered font families
*/
public Set getRegisteredFamilies() {
return Utilities.getKeySet(fontFamilies);
}
/**
* Checks if a certain font is registered.
*
* @param fontname the name of the font that has to be checked.
* @return true if the font is found
*/
public boolean isRegistered(String fontname) {
return trueTypeFonts.containsKey(fontname.toLowerCase());
}
}

129
src/main/java/com/fr/third/lowagie/text/GreekList.java

@ -0,0 +1,129 @@
/*
* Copyright 2003 by Michael Niedermair and 2007 Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import com.fr.third.lowagie.text.factories.GreekAlphabetFactory;
/**
*
* A special-version of <CODE>LIST</CODE> which use greek-letters.
*
* @see List
*/
public class GreekList extends List {
// constructors
/**
* Initialization
*/
public GreekList() {
super(true);
setGreekFont();
}
/**
* Initialization
*
* @param symbolIndent indent
*/
public GreekList(int symbolIndent) {
super(true, symbolIndent);
setGreekFont();
}
/**
* Initialization
* @param greeklower greek-char in lowercase
* @param symbolIndent indent
*/
public GreekList(boolean greeklower, int symbolIndent) {
super(true, symbolIndent);
lowercase = greeklower;
setGreekFont();
}
// helper method
/**
* change the font to SYMBOL
*/
protected void setGreekFont() {
float fontsize = symbol.getFont().getSize();
symbol.setFont(FontFactory.getFont(FontFactory.SYMBOL, fontsize, Font.NORMAL));
}
// overridden method
/**
* Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
*
* @param o the object to add.
* @return true if adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof ListItem) {
ListItem item = (ListItem) o;
Chunk chunk = new Chunk(preSymbol, symbol.getFont());
chunk.append(GreekAlphabetFactory.getString(first + list.size(), lowercase));
chunk.append(postSymbol);
item.setListSymbol(chunk);
item.setIndentationLeft(symbolIndent, autoindent);
item.setIndentationRight(0);
list.add(item);
} else if (o instanceof List) {
List nested = (List) o;
nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
first--;
return list.add(nested);
} else if (o instanceof String) {
return this.add(new ListItem((String) o));
}
return false;
}
}

97
src/main/java/com/fr/third/lowagie/text/Header.java

@ -0,0 +1,97 @@
/*
* $Id: Header.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* This is an <CODE>Element</CODE> that contains
* some user defined meta information about the document.
* <P>
* <B>Example:</B>
* <BLOCKQUOTE><PRE>
* <STRONG>Header header = new Header("inspired by", "William Shakespeare");</STRONG>
* </PRE></BLOCKQUOTE>
*
* @see Element
* @see Meta
*/
public class Header extends Meta {
// membervariables
/** This is the content of this chunk of text. */
private StringBuffer name;
// constructors
/**
* Constructs a <CODE>Meta</CODE>.
*
* @param name the name of the meta-information
* @param content the content
*/
public Header(String name, String content) {
super(HEADER, content);
this.name = new StringBuffer(name);
}
// methods to retrieve information
/**
* Returns the name of the meta information.
*
* @return a <CODE>String</CODE>
*/
public String getName() {
return name.toString();
}
}

203
src/main/java/com/fr/third/lowagie/text/HeaderFooter.java

@ -0,0 +1,203 @@
/*
* $Id: HeaderFooter.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* A <CODE>HeaderFooter</CODE>-object is a <CODE>Rectangle</CODe> with text
* that can be put above and/or below every page.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* <STRONG>HeaderFooter header = new HeaderFooter(new Phrase("This is a header."), false);</STRONG>
* <STRONG>HeaderFooter footer = new HeaderFooter(new Phrase("This is page "), new Phrase("."));</STRONG>
* document.setHeader(header);
* document.setFooter(footer);
* </PRE></BLOCKQUOTE>
*/
public class HeaderFooter extends Rectangle {
// membervariables
/** Does the page contain a pagenumber? */
private boolean numbered;
/** This is the <CODE>Phrase</CODE> that comes before the pagenumber. */
private Phrase before = null;
/** This is number of the page. */
private int pageN;
/** This is the <CODE>Phrase</CODE> that comes after the pagenumber. */
private Phrase after = null;
/** This is alignment of the header/footer. */
private int alignment;
// constructors
/**
* Constructs a <CODE>HeaderFooter</CODE>-object.
*
* @param before the <CODE>Phrase</CODE> before the pagenumber
* @param after the <CODE>Phrase</CODE> before the pagenumber
*/
public HeaderFooter(Phrase before, Phrase after) {
super(0, 0, 0, 0);
setBorder(TOP + BOTTOM);
setBorderWidth(1);
numbered = true;
this.before = before;
this.after = after;
}
/**
* Constructs a <CODE>Header</CODE>-object with a pagenumber at the end.
*
* @param before the <CODE>Phrase</CODE> before the pagenumber
* @param numbered <CODE>true</CODE> if the page has to be numbered
*/
public HeaderFooter(Phrase before, boolean numbered) {
super(0, 0, 0, 0);
setBorder(TOP + BOTTOM);
setBorderWidth(1);
this.numbered = numbered;
this.before = before;
}
// methods
/**
* Checks if the HeaderFooter contains a page number.
*
* @return true if the page has to be numbered
*/
public boolean isNumbered() {
return numbered;
}
/**
* Gets the part that comes before the pageNumber.
*
* @return a Phrase
*/
public Phrase getBefore() {
return before;
}
/**
* Gets the part that comes after the pageNumber.
*
* @return a Phrase
*/
public Phrase getAfter() {
return after;
}
/**
* Sets the page number.
*
* @param pageN the new page number
*/
public void setPageNumber(int pageN) {
this.pageN = pageN;
}
/**
* Sets the alignment.
*
* @param alignment the new alignment
*/
public void setAlignment(int alignment) {
this.alignment = alignment;
}
// methods to retrieve the membervariables
/**
* Gets the <CODE>Paragraph</CODE> that can be used as header or footer.
*
* @return a <CODE>Paragraph</CODE>
*/
public Paragraph paragraph() {
Paragraph paragraph = new Paragraph(before.getLeading());
paragraph.add(before);
if (numbered) {
paragraph.addSpecial(new Chunk(String.valueOf(pageN), before.getFont()));
}
if (after != null) {
paragraph.addSpecial(after);
}
paragraph.setAlignment(alignment);
return paragraph;
}
/**
* Gets the alignment of this HeaderFooter.
*
* @return alignment
*/
public int alignment() {
return alignment;
}
}

2056
src/main/java/com/fr/third/lowagie/text/Image.java

File diff suppressed because it is too large Load Diff

102
src/main/java/com/fr/third/lowagie/text/ImgCCITT.java

@ -0,0 +1,102 @@
/*
* $Id: ImgCCITT.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2000, 2001, 2002 by Paulo Soares.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import com.fr.third.lowagie.text.pdf.codec.TIFFFaxDecoder;
import java.net.URL;
/**
* CCITT Image data that has to be inserted into the document
*
* @see Element
* @see Image
*
* @author Paulo Soares
*/
public class ImgCCITT extends Image {
ImgCCITT(Image image) {
super(image);
}
/** Creates an Image with CCITT compression.
*
* @param width the exact width of the image
* @param height the exact height of the image
* @param reverseBits reverses the bits in <code>data</code>.
* Bit 0 is swapped with bit 7 and so on.
* @param typeCCITT the type of compression in <code>data</code>. It can be
* CCITTG4, CCITTG31D, CCITTG32D
* @param parameters parameters associated with this stream. Possible values are
* CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and CCITT_ENDOFBLOCK or a
* combination of them
* @param data the image data
* @throws BadElementException on error
*/
public ImgCCITT(int width, int height, boolean reverseBits, int typeCCITT, int parameters, byte[] data) throws BadElementException{
super((URL)null);
if (typeCCITT != CCITTG4 && typeCCITT != CCITTG3_1D && typeCCITT != CCITTG3_2D)
throw new BadElementException("The CCITT compression type must be CCITTG4, CCITTG3_1D or CCITTG3_2D");
if (reverseBits)
TIFFFaxDecoder.reverseBits(data);
type = IMGRAW;
scaledHeight = height;
setTop(scaledHeight);
scaledWidth = width;
setRight(scaledWidth);
colorspace = parameters;
bpc = typeCCITT;
rawData = data;
plainWidth = getWidth();
plainHeight = getHeight();
}
}

131
src/main/java/com/fr/third/lowagie/text/ImgJBIG2.java

@ -0,0 +1,131 @@
/*
* $Id: ImgJBIG2.java 3962 2009-06-10 11:43:19Z psoares33 $
*
* Copyright 2009 by Nigel Kerr.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.net.URL;
import java.security.MessageDigest;
/**
* Support for JBIG2 images.
* @since 2.1.5
*/
public class ImgJBIG2 extends Image {
/** JBIG2 globals */
private byte[] global;
/** A unique hash */
private byte[] globalHash;
/**
* Copy contstructor.
* @param image another Image
*/
ImgJBIG2(Image image) {
super(image);
}
/**
* Empty constructor.
*/
public ImgJBIG2() {
super((Image) null);
}
/**
* Actual constructor for ImgJBIG2 images.
* @param width the width of the image
* @param height the height of the image
* @param data the raw image data
* @param globals JBIG2 globals
*/
public ImgJBIG2(int width, int height, byte[] data, byte[] globals) {
super((URL) null);
type = JBIG2;
originalType = ORIGINAL_JBIG2;
scaledHeight = height;
setTop(scaledHeight);
scaledWidth = width;
setRight(scaledWidth);
bpc = 1;
colorspace = 1;
rawData = data;
plainWidth = getWidth();
plainHeight = getHeight();
if ( globals != null ) {
this.global = globals;
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
md.update(this.global);
this.globalHash = md.digest();
} catch (Exception e) {
//ignore
}
}
}
/**
* Getter for the JBIG2 global data.
* @return an array of bytes
*/
public byte[] getGlobalBytes() {
return this.global;
}
/**
* Getter for the unique hash.
* @return an array of bytes
*/
public byte[] getGlobalHash() {
return this.globalHash;
}
}

96
src/main/java/com/fr/third/lowagie/text/ImgRaw.java

@ -0,0 +1,96 @@
/*
* $Id: ImgRaw.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2000, 2001, 2002 by Paulo Soares.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.net.URL;
/**
* Raw Image data that has to be inserted into the document
*
* @see Element
* @see Image
*
* @author Paulo Soares
*/
public class ImgRaw extends Image {
ImgRaw(Image image) {
super(image);
}
/** Creates an Image in raw mode.
*
* @param width the exact width of the image
* @param height the exact height of the image
* @param components 1,3 or 4 for GrayScale, RGB and CMYK
* @param bpc bits per component. Must be 1,2,4 or 8
* @param data the image data
* @throws BadElementException on error
*/
public ImgRaw(int width, int height, int components, int bpc, byte[] data) throws BadElementException{
super((URL)null);
type = IMGRAW;
scaledHeight = height;
setTop(scaledHeight);
scaledWidth = width;
setRight(scaledWidth);
if (components != 1 && components != 3 && components != 4)
throw new BadElementException("Components must be 1, 3, or 4.");
if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8)
throw new BadElementException("Bits-per-component must be 1, 2, 4, or 8.");
colorspace = components;
this.bpc = bpc;
rawData = data;
plainWidth = getWidth();
plainHeight = getHeight();
}
}

92
src/main/java/com/fr/third/lowagie/text/ImgTemplate.java

@ -0,0 +1,92 @@
/*
* $Id: ImgTemplate.java 3517 2008-06-29 10:37:16Z blowagie $
*
* Copyright 2000, 2001, 2002 by Paulo Soares.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.net.URL;
import com.fr.third.lowagie.text.pdf.PdfTemplate;
/**
* PdfTemplate that has to be inserted into the document
*
* @see Element
* @see Image
*
* @author Paulo Soares
*/
public class ImgTemplate extends Image {
ImgTemplate(Image image) {
super(image);
}
/** Creates an Image from a PdfTemplate.
*
* @param template the PdfTemplate
* @throws BadElementException on error
*/
public ImgTemplate(PdfTemplate template) throws BadElementException{
super((URL)null);
if (template == null)
throw new BadElementException("The template can not be null.");
if (template.getType() == PdfTemplate.TYPE_PATTERN)
throw new BadElementException("A pattern can not be used as a template to create an image.");
type = IMGTEMPLATE;
scaledHeight = template.getHeight();
setTop(scaledHeight);
scaledWidth = template.getWidth();
setRight(scaledWidth);
setTemplateData(template);
plainWidth = getWidth();
plainHeight = getHeight();
}
}

190
src/main/java/com/fr/third/lowagie/text/ImgWMF.java

@ -0,0 +1,190 @@
/*
* $Id: ImgWMF.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Paulo Soares.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import com.fr.third.lowagie.text.pdf.PdfTemplate;
import com.fr.third.lowagie.text.pdf.codec.wmf.MetaDo;
import com.fr.third.lowagie.text.pdf.codec.wmf.InputMeta;
/**
* An <CODE>ImgWMF</CODE> is the representation of a windows metafile
* that has to be inserted into the document
*
* @see Element
* @see Image
*/
public class ImgWMF extends Image {
// Constructors
ImgWMF(Image image) {
super(image);
}
/**
* Constructs an <CODE>ImgWMF</CODE>-object, using an <VAR>url</VAR>.
*
* @param url the <CODE>URL</CODE> where the image can be found
* @throws BadElementException on error
* @throws IOException on error
*/
public ImgWMF(URL url) throws BadElementException, IOException {
super(url);
processParameters();
}
/**
* Constructs an <CODE>ImgWMF</CODE>-object, using a <VAR>filename</VAR>.
*
* @param filename a <CODE>String</CODE>-representation of the file that contains the image.
* @throws BadElementException on error
* @throws MalformedURLException on error
* @throws IOException on error
*/
public ImgWMF(String filename) throws BadElementException, MalformedURLException, IOException {
this(Utilities.toURL(filename));
}
/**
* Constructs an <CODE>ImgWMF</CODE>-object from memory.
*
* @param img the memory image
* @throws BadElementException on error
* @throws IOException on error
*/
public ImgWMF(byte[] img) throws BadElementException, IOException {
super((URL)null);
rawData = img;
originalData = img;
processParameters();
}
/**
* This method checks if the image is a valid WMF and processes some parameters.
* @throws BadElementException
* @throws IOException
*/
private void processParameters() throws BadElementException, IOException {
type = IMGTEMPLATE;
originalType = ORIGINAL_WMF;
InputStream is = null;
try {
String errorID;
if (rawData == null){
is = url.openStream();
errorID = url.toString();
}
else{
is = new java.io.ByteArrayInputStream(rawData);
errorID = "Byte array";
}
InputMeta in = new InputMeta(is);
if (in.readInt() != 0x9AC6CDD7) {
throw new BadElementException(errorID + " is not a valid placeable windows metafile.");
}
in.readWord();
int left = in.readShort();
int top = in.readShort();
int right = in.readShort();
int bottom = in.readShort();
int inch = in.readWord();
dpiX = 72;
dpiY = 72;
scaledHeight = (float)(bottom - top) / inch * 72f;
setTop(scaledHeight);
scaledWidth = (float)(right - left) / inch * 72f;
setRight(scaledWidth);
}
finally {
if (is != null) {
is.close();
}
plainWidth = getWidth();
plainHeight = getHeight();
}
}
/** Reads the WMF into a template.
* @param template the template to read to
* @throws IOException on error
* @throws DocumentException on error
*/
public void readWMF(PdfTemplate template) throws IOException, DocumentException {
setTemplateData(template);
template.setWidth(getWidth());
template.setHeight(getHeight());
InputStream is = null;
try {
if (rawData == null){
is = url.openStream();
}
else{
is = new java.io.ByteArrayInputStream(rawData);
}
MetaDo meta = new MetaDo(is, template);
meta.readAll();
}
finally {
if (is != null) {
is.close();
}
}
}
}

345
src/main/java/com/fr/third/lowagie/text/Jpeg.java

@ -0,0 +1,345 @@
/*
* $Id: Jpeg.java 3970 2009-06-16 08:09:54Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.color.ICC_Profile;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* An <CODE>Jpeg</CODE> is the representation of a graphic element (JPEG)
* that has to be inserted into the document
*
* @see Element
* @see Image
*/
public class Jpeg extends Image {
// public static final membervariables
/** This is a type of marker. */
public static final int NOT_A_MARKER = -1;
/** This is a type of marker. */
public static final int VALID_MARKER = 0;
/** Acceptable Jpeg markers. */
public static final int[] VALID_MARKERS = {0xC0, 0xC1, 0xC2};
/** This is a type of marker. */
public static final int UNSUPPORTED_MARKER = 1;
/** Unsupported Jpeg markers. */
public static final int[] UNSUPPORTED_MARKERS = {0xC3, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF};
/** This is a type of marker. */
public static final int NOPARAM_MARKER = 2;
/** Jpeg markers without additional parameters. */
public static final int[] NOPARAM_MARKERS = {0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0x01};
/** Marker value */
public static final int M_APP0 = 0xE0;
/** Marker value */
public static final int M_APP2 = 0xE2;
/** Marker value */
public static final int M_APPE = 0xEE;
/** sequence that is used in all Jpeg files */
public static final byte JFIF_ID[] = {0x4A, 0x46, 0x49, 0x46, 0x00};
private byte[][] icc;
// Constructors
Jpeg(Image image) {
super(image);
}
/**
* Constructs a <CODE>Jpeg</CODE>-object, using an <VAR>url</VAR>.
*
* @param url the <CODE>URL</CODE> where the image can be found
* @throws BadElementException
* @throws IOException
*/
public Jpeg(URL url) throws BadElementException, IOException {
super(url);
processParameters();
}
/**
* Constructs a <CODE>Jpeg</CODE>-object from memory.
*
* @param img the memory image
* @throws BadElementException
* @throws IOException
*/
public Jpeg(byte[] img) throws BadElementException, IOException {
super((URL)null);
rawData = img;
originalData = img;
processParameters();
}
/**
* Constructs a <CODE>Jpeg</CODE>-object from memory.
*
* @param img the memory image.
* @param width the width you want the image to have
* @param height the height you want the image to have
* @throws BadElementException
* @throws IOException
*/
public Jpeg(byte[] img, float width, float height) throws BadElementException, IOException {
this(img);
scaledWidth = width;
scaledHeight = height;
}
// private static methods
/**
* Reads a short from the <CODE>InputStream</CODE>.
*
* @param is the <CODE>InputStream</CODE>
* @return an int
* @throws IOException
*/
private static final int getShort(InputStream is) throws IOException {
return (is.read() << 8) + is.read();
}
/**
* Returns a type of marker.
*
* @param marker an int
* @return a type: <VAR>VALID_MARKER</CODE>, <VAR>UNSUPPORTED_MARKER</VAR> or <VAR>NOPARAM_MARKER</VAR>
*/
private static final int marker(int marker) {
for (int i = 0; i < VALID_MARKERS.length; i++) {
if (marker == VALID_MARKERS[i]) {
return VALID_MARKER;
}
}
for (int i = 0; i < NOPARAM_MARKERS.length; i++) {
if (marker == NOPARAM_MARKERS[i]) {
return NOPARAM_MARKER;
}
}
for (int i = 0; i < UNSUPPORTED_MARKERS.length; i++) {
if (marker == UNSUPPORTED_MARKERS[i]) {
return UNSUPPORTED_MARKER;
}
}
return NOT_A_MARKER;
}
// private methods
/**
* This method checks if the image is a valid JPEG and processes some parameters.
* @throws BadElementException
* @throws IOException
*/
private void processParameters() throws BadElementException, IOException {
type = JPEG;
originalType = ORIGINAL_JPEG;
InputStream is = null;
try {
String errorID;
if (rawData == null){
is = url.openStream();
errorID = url.toString();
}
else{
is = new java.io.ByteArrayInputStream(rawData);
errorID = "Byte array";
}
if (is.read() != 0xFF || is.read() != 0xD8) {
throw new BadElementException(errorID + " is not a valid JPEG-file.");
}
boolean firstPass = true;
int len;
while (true) {
int v = is.read();
if (v < 0)
throw new IOException("Premature EOF while reading JPG.");
if (v == 0xFF) {
int marker = is.read();
if (firstPass && marker == M_APP0) {
firstPass = false;
len = getShort(is);
if (len < 16) {
Utilities.skip(is, len - 2);
continue;
}
byte bcomp[] = new byte[JFIF_ID.length];
int r = is.read(bcomp);
if (r != bcomp.length)
throw new BadElementException(errorID + " corrupted JFIF marker.");
boolean found = true;
for (int k = 0; k < bcomp.length; ++k) {
if (bcomp[k] != JFIF_ID[k]) {
found = false;
break;
}
}
if (!found) {
Utilities.skip(is, len - 2 - bcomp.length);
continue;
}
Utilities.skip(is, 2);
int units = is.read();
int dx = getShort(is);
int dy = getShort(is);
if (units == 1) {
dpiX = dx;
dpiY = dy;
}
else if (units == 2) {
dpiX = (int)(dx * 2.54f + 0.5f);
dpiY = (int)(dy * 2.54f + 0.5f);
}
Utilities.skip(is, len - 2 - bcomp.length - 7);
continue;
}
if (marker == M_APPE) {
len = getShort(is) - 2;
byte[] byteappe = new byte[len];
for (int k = 0; k < len; ++k) {
byteappe[k] = (byte)is.read();
}
if (byteappe.length >= 12) {
String appe = new String(byteappe, 0, 5, "ISO-8859-1");
if (appe.equals("Adobe")) {
invert = true;
}
}
continue;
}
if (marker == M_APP2) {
len = getShort(is) - 2;
byte[] byteapp2 = new byte[len];
for (int k = 0; k < len; ++k) {
byteapp2[k] = (byte)is.read();
}
if (byteapp2.length >= 14) {
String app2 = new String(byteapp2, 0, 11, "ISO-8859-1");
if (app2.equals("ICC_PROFILE")) {
int order = byteapp2[12] & 0xff;
int count = byteapp2[13] & 0xff;
if (icc == null)
icc = new byte[count][];
icc[order - 1] = byteapp2;
}
}
continue;
}
firstPass = false;
int markertype = marker(marker);
if (markertype == VALID_MARKER) {
Utilities.skip(is, 2);
if (is.read() != 0x08) {
throw new BadElementException(errorID + " must have 8 bits per component.");
}
scaledHeight = getShort(is);
setTop(scaledHeight);
scaledWidth = getShort(is);
setRight(scaledWidth);
colorspace = is.read();
bpc = 8;
break;
}
else if (markertype == UNSUPPORTED_MARKER) {
throw new BadElementException(errorID + ": unsupported JPEG marker: " + marker);
}
else if (markertype != NOPARAM_MARKER) {
Utilities.skip(is, getShort(is) - 2);
}
}
}
}
finally {
if (is != null) {
is.close();
}
}
plainWidth = getWidth();
plainHeight = getHeight();
if (icc != null) {
int total = 0;
for (int k = 0; k < icc.length; ++k) {
if (icc[k] == null) {
icc = null;
return;
}
total += icc[k].length - 14;
}
byte[] ficc = new byte[total];
total = 0;
for (int k = 0; k < icc.length; ++k) {
System.arraycopy(icc[k], 14, ficc, total, icc[k].length - 14);
total += icc[k].length - 14;
}
try {
ICC_Profile icc_prof = ICC_Profile.getInstance(ficc);
tagICC(icc_prof);
}
catch(IllegalArgumentException e) {
// ignore ICC profile if it's invalid.
}
icc = null;
}
}
}

238
src/main/java/com/fr/third/lowagie/text/Jpeg2000.java

@ -0,0 +1,238 @@
/*
* $Id: Jpeg2000.java 3583 2008-08-12 00:00:09Z xlv $
*
* Copyright 2007 by Paulo Soares.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* An <CODE>Jpeg2000</CODE> is the representation of a graphic element (JPEG)
* that has to be inserted into the document
*
* @see Element
* @see Image
*/
public class Jpeg2000 extends Image {
// public static final membervariables
public static final int JP2_JP = 0x6a502020;
public static final int JP2_IHDR = 0x69686472;
public static final int JPIP_JPIP = 0x6a706970;
public static final int JP2_FTYP = 0x66747970;
public static final int JP2_JP2H = 0x6a703268;
public static final int JP2_COLR = 0x636f6c72;
public static final int JP2_JP2C = 0x6a703263;
public static final int JP2_URL = 0x75726c20;
public static final int JP2_DBTL = 0x6474626c;
public static final int JP2_BPCC = 0x62706363;
public static final int JP2_JP2 = 0x6a703220;
InputStream inp;
int boxLength;
int boxType;
// Constructors
Jpeg2000(Image image) {
super(image);
}
/**
* Constructs a <CODE>Jpeg2000</CODE>-object, using an <VAR>url</VAR>.
*
* @param url the <CODE>URL</CODE> where the image can be found
* @throws BadElementException
* @throws IOException
*/
public Jpeg2000(URL url) throws BadElementException, IOException {
super(url);
processParameters();
}
/**
* Constructs a <CODE>Jpeg2000</CODE>-object from memory.
*
* @param img the memory image
* @throws BadElementException
* @throws IOException
*/
public Jpeg2000(byte[] img) throws BadElementException, IOException {
super((URL)null);
rawData = img;
originalData = img;
processParameters();
}
/**
* Constructs a <CODE>Jpeg2000</CODE>-object from memory.
*
* @param img the memory image.
* @param width the width you want the image to have
* @param height the height you want the image to have
* @throws BadElementException
* @throws IOException
*/
public Jpeg2000(byte[] img, float width, float height) throws BadElementException, IOException {
this(img);
scaledWidth = width;
scaledHeight = height;
}
private int cio_read(int n) throws IOException {
int v = 0;
for (int i = n - 1; i >= 0; i--) {
v += inp.read() << (i << 3);
}
return v;
}
public void jp2_read_boxhdr() throws IOException {
boxLength = cio_read(4);
boxType = cio_read(4);
if (boxLength == 1) {
if (cio_read(4) != 0) {
throw new IOException("Cannot handle box sizes higher than 2^32");
}
boxLength = cio_read(4);
if (boxLength == 0)
throw new IOException("Unsupported box size == 0");
}
else if (boxLength == 0) {
throw new IOException("Unsupported box size == 0");
}
}
/**
* This method checks if the image is a valid JPEG and processes some parameters.
* @throws IOException
*/
private void processParameters() throws IOException {
type = JPEG2000;
originalType = ORIGINAL_JPEG2000;
inp = null;
try {
String errorID;
if (rawData == null){
inp = url.openStream();
errorID = url.toString();
}
else{
inp = new java.io.ByteArrayInputStream(rawData);
errorID = "Byte array";
}
boxLength = cio_read(4);
if (boxLength == 0x0000000c) {
boxType = cio_read(4);
if (JP2_JP != boxType) {
throw new IOException("Expected JP Marker");
}
if (0x0d0a870a != cio_read(4)) {
throw new IOException("Error with JP Marker");
}
jp2_read_boxhdr();
if (JP2_FTYP != boxType) {
throw new IOException("Expected FTYP Marker");
}
Utilities.skip(inp, boxLength - 8);
jp2_read_boxhdr();
do {
if (JP2_JP2H != boxType) {
if (boxType == JP2_JP2C) {
throw new IOException("Expected JP2H Marker");
}
Utilities.skip(inp, boxLength - 8);
jp2_read_boxhdr();
}
} while(JP2_JP2H != boxType);
jp2_read_boxhdr();
if (JP2_IHDR != boxType) {
throw new IOException("Expected IHDR Marker");
}
scaledHeight = cio_read(4);
setTop(scaledHeight);
scaledWidth = cio_read(4);
setRight(scaledWidth);
bpc = -1;
}
else if (boxLength == 0xff4fff51) {
Utilities.skip(inp, 4);
int x1 = cio_read(4);
int y1 = cio_read(4);
int x0 = cio_read(4);
int y0 = cio_read(4);
Utilities.skip(inp, 16);
colorspace = cio_read(2);
bpc = 8;
scaledHeight = y1 - y0;
setTop(scaledHeight);
scaledWidth = x1 - x0;
setRight(scaledWidth);
}
else {
throw new IOException("Not a valid Jpeg2000 file");
}
}
finally {
if (inp != null) {
try{inp.close();}catch(Exception e){}
inp = null;
}
}
plainWidth = getWidth();
plainHeight = getHeight();
}
}

85
src/main/java/com/fr/third/lowagie/text/LargeElement.java

@ -0,0 +1,85 @@
/*
* $Id: LargeElement.java 3514 2008-06-27 09:26:36Z blowagie $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* Interface implemented by Element objects that can potentially consume
* a lot of memory. Objects implementing the LargeElement interface can
* be added to a Document more than once. If you have invoked setComplete(false),
* they will be added partially and the content that was added will be
* removed until you've invoked setComplete(true);
* @since iText 2.0.8
*/
public interface LargeElement extends Element {
/**
* If you invoke setComplete(false), you indicate that the content
* of the object isn't complete yet; it can be added to the document
* partially, but more will follow. If you invoke setComplete(true),
* you indicate that you won't add any more data to the object.
* @since iText 2.0.8
* @param complete false if you'll be adding more data after
* adding the object to the document.
*/
public void setComplete(boolean complete);
/**
* Indicates if the element is complete or not.
* @since iText 2.0.8
* @return indicates if the element is complete according to the user.
*/
public boolean isComplete();
/**
* Flushes the content that has been added.
*/
public void flushContent();
}

597
src/main/java/com/fr/third/lowagie/text/List.java

@ -0,0 +1,597 @@
/*
* $Id: List.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Iterator;
import com.fr.third.lowagie.text.factories.RomanAlphabetFactory;
/**
* A <CODE>List</CODE> contains several <CODE>ListItem</CODE>s.
* <P>
* <B>Example 1:</B>
* <BLOCKQUOTE><PRE>
* <STRONG>List list = new List(true, 20);</STRONG>
* <STRONG>list.add(new ListItem("First line"));</STRONG>
* <STRONG>list.add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));</STRONG>
* <STRONG>list.add(new ListItem("Third line"));</STRONG>
* </PRE></BLOCKQUOTE>
*
* The result of this code looks like this:
* <OL>
* <LI>
* First line
* </LI>
* <LI>
* The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?
* </LI>
* <LI>
* Third line
* </LI>
* </OL>
*
* <B>Example 2:</B>
* <BLOCKQUOTE><PRE>
* <STRONG>List overview = new List(false, 10);</STRONG>
* <STRONG>overview.add(new ListItem("This is an item"));</STRONG>
* <STRONG>overview.add("This is another item");</STRONG>
* </PRE></BLOCKQUOTE>
*
* The result of this code looks like this:
* <UL>
* <LI>
* This is an item
* </LI>
* <LI>
* This is another item
* </LI>
* </UL>
*
* @see Element
* @see ListItem
*/
public class List implements TextElementArray {
// constants
/** a possible value for the numbered parameter */
public static final boolean ORDERED = true;
/** a possible value for the numbered parameter */
public static final boolean UNORDERED = false;
/** a possible value for the lettered parameter */
public static final boolean NUMERICAL = false;
/** a possible value for the lettered parameter */
public static final boolean ALPHABETICAL = true;
/** a possible value for the lettered parameter */
public static final boolean UPPERCASE = false;
/** a possible value for the lettered parameter */
public static final boolean LOWERCASE = true;
// member variables
/** This is the <CODE>ArrayList</CODE> containing the different <CODE>ListItem</CODE>s. */
protected ArrayList list = new ArrayList();
/** Indicates if the list has to be numbered. */
protected boolean numbered = false;
/** Indicates if the listsymbols are numerical or alphabetical. */
protected boolean lettered = false;
/** Indicates if the listsymbols are lowercase or uppercase. */
protected boolean lowercase = false;
public ArrayList getList() {
return list;
}
public void setList(ArrayList list) {
this.list = list;
}
/** Indicates if the indentation has to be set automatically. */
protected boolean autoindent = false;
/** Indicates if the indentation of all the items has to be aligned. */
protected boolean alignindent = false;
/** This variable indicates the first number of a numbered list. */
protected int first = 1;
/** This is the listsymbol of a list that is not numbered. */
protected Chunk symbol = new Chunk("- ");
/**
* In case you are using numbered/lettered lists, this String is added before the number/letter.
* @since iText 2.1.1
*/
protected String preSymbol = "";
/**
* In case you are using numbered/lettered lists, this String is added after the number/letter.
* @since iText 2.1.1
*/
protected String postSymbol = ". ";
/** The indentation of this list on the left side. */
protected float indentationLeft = 0;
/** The indentation of this list on the right side. */
protected float indentationRight = 0;
/** The indentation of the listitems. */
protected float symbolIndent = 0;
// constructors
/** Constructs a <CODE>List</CODE>. */
public List() {
this(false, false);
}
/**
* Constructs a <CODE>List</CODE> with a specific symbol indentation.
* @param symbolIndent the symbol indentation
* @since iText 2.0.8
*/
public List(float symbolIndent) {
this.symbolIndent = symbolIndent;
}
/**
* Constructs a <CODE>List</CODE>.
* @param numbered a boolean
*/
public List(boolean numbered) {
this(numbered, false);
}
/**
* Constructs a <CODE>List</CODE>.
* @param numbered a boolean
* @param lettered has the list to be 'numbered' with letters
*/
public List(boolean numbered, boolean lettered) {
this.numbered = numbered;
this.lettered = lettered;
this.autoindent = true;
this.alignindent = true;
}
/**
* Constructs a <CODE>List</CODE>.
* <P>
* Remark: the parameter <VAR>symbolIndent</VAR> is important for instance when
* generating PDF-documents; it indicates the indentation of the listsymbol.
* It is not important for HTML-documents.
*
* @param numbered a boolean
* @param symbolIndent the indentation that has to be used for the listsymbol
*/
public List(boolean numbered, float symbolIndent) {
this(numbered, false, symbolIndent);
}
/**
* Creates a list
* @param numbered has the list to be numbered?
* @param lettered has the list to be 'numbered' with letters
* @param symbolIndent the indentation of the symbol
*/
public List(boolean numbered, boolean lettered, float symbolIndent) {
this.numbered = numbered;
this.lettered = lettered;
this.symbolIndent = symbolIndent;
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
for (Iterator i = list.iterator(); i.hasNext(); ) {
listener.add((Element) i.next());
}
return true;
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return LIST;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
for (Iterator i = list.iterator(); i.hasNext(); ) {
tmp.addAll(((Element) i.next()).getChunks());
}
return tmp;
}
// methods to set the membervariables
/**
* Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
*
* @param o the object to add.
* @return true if adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof ListItem) {
ListItem item = (ListItem) o;
if (numbered || lettered) {
Chunk chunk = new Chunk(preSymbol, symbol.getFont());
int index = first + list.size();
if ( lettered )
chunk.append(RomanAlphabetFactory.getString(index, lowercase));
else
chunk.append(String.valueOf(index));
chunk.append(postSymbol);
item.setListSymbol(chunk);
}
else {
item.setListSymbol(new Chunk(symbol));
}
item.setIndentationLeft(symbolIndent, autoindent);
item.setIndentationRight(0);
return list.add(item);
}
else if (o instanceof List) {
List nested = (List) o;
nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
first--;
return list.add(nested);
}
else if (o instanceof String) {
return this.add(new ListItem((String) o));
}
return false;
}
// extra methods
/** Makes sure all the items in the list have the same indentation. */
public void normalizeIndentation() {
float max = 0;
Element o;
for (Iterator i = list.iterator(); i.hasNext(); ) {
o = (Element)i.next();
if (o instanceof ListItem) {
max = Math.max(max, ((ListItem)o).getIndentationLeft());
}
}
for (Iterator i = list.iterator(); i.hasNext(); ) {
o = (Element)i.next();
if (o instanceof ListItem) {
((ListItem)o).setIndentationLeft(max);
}
}
}
// setters
/**
* @param numbered the numbered to set
*/
public void setNumbered(boolean numbered) {
this.numbered = numbered;
}
/**
* @param lettered the lettered to set
*/
public void setLettered(boolean lettered) {
this.lettered = lettered;
}
/**
* @param uppercase the uppercase to set
*/
public void setLowercase(boolean uppercase) {
this.lowercase = uppercase;
}
/**
* @param autoindent the autoindent to set
*/
public void setAutoindent(boolean autoindent) {
this.autoindent = autoindent;
}
/**
* @param alignindent the alignindent to set
*/
public void setAlignindent(boolean alignindent) {
this.alignindent = alignindent;
}
/**
* Sets the number that has to come first in the list.
*
* @param first a number
*/
public void setFirst(int first) {
this.first = first;
}
/**
* Sets the listsymbol.
*
* @param symbol a <CODE>Chunk</CODE>
*/
public void setListSymbol(Chunk symbol) {
this.symbol = symbol;
}
/**
* Sets the listsymbol.
* <P>
* This is a shortcut for <CODE>setListSymbol(Chunk symbol)</CODE>.
*
* @param symbol a <CODE>String</CODE>
*/
public void setListSymbol(String symbol) {
this.symbol = new Chunk(symbol);
}
/**
* Sets the indentation of this paragraph on the left side.
*
* @param indentation the new indentation
*/
public void setIndentationLeft(float indentation) {
this.indentationLeft = indentation;
}
/**
* Sets the indentation of this paragraph on the right side.
*
* @param indentation the new indentation
*/
public void setIndentationRight(float indentation) {
this.indentationRight = indentation;
}
/**
* @param symbolIndent the symbolIndent to set
*/
public void setSymbolIndent(float symbolIndent) {
this.symbolIndent = symbolIndent;
}
// methods to retrieve information
/**
* Gets all the items in the list.
*
* @return an <CODE>ArrayList</CODE> containing <CODE>ListItem</CODE>s.
*/
public ArrayList getItems() {
return list;
}
/**
* Gets the size of the list.
*
* @return a <CODE>size</CODE>
*/
public int size() {
return list.size();
}
/**
* Returns <CODE>true</CODE> if the list is empty.
*
* @return <CODE>true</CODE> if the list is empty
*/
public boolean isEmpty() {
return list.isEmpty();
}
/**
* Gets the leading of the first listitem.
*
* @return a <CODE>leading</CODE>
*/
public float getTotalLeading() {
if (list.size() < 1) {
return -1;
}
ListItem item = (ListItem) list.get(0);
return item.getTotalLeading();
}
// getters
/**
* Checks if the list is numbered.
* @return <CODE>true</CODE> if the list is numbered, <CODE>false</CODE> otherwise.
*/
public boolean isNumbered() {
return numbered;
}
/**
* Checks if the list is lettered.
* @return <CODE>true</CODE> if the list is lettered, <CODE>false</CODE> otherwise.
*/
public boolean isLettered() {
return lettered;
}
/**
* Checks if the list lettering is lowercase.
* @return <CODE>true</CODE> if it is lowercase, <CODE>false</CODE> otherwise.
*/
public boolean isLowercase() {
return lowercase;
}
/**
* Checks if the indentation of list items is done automatically.
* @return the autoindent
*/
public boolean isAutoindent() {
return autoindent;
}
/**
* Checks if all the listitems should be aligned.
* @return the alignindent
*/
public boolean isAlignindent() {
return alignindent;
}
/**
* Gets the first number .
* @return a number
*/
public int getFirst() {
return first;
}
/**
* Gets the Chunk containing the symbol.
* @return a Chunk with a symbol
*/
public Chunk getSymbol() {
return symbol;
}
/**
* Gets the indentation of this paragraph on the left side.
* @return the indentation
*/
public float getIndentationLeft() {
return indentationLeft;
}
/**
* Gets the indentation of this paragraph on the right side.
* @return the indentation
*/
public float getIndentationRight() {
return indentationRight;
}
/**
* Gets the symbol indentation.
* @return the symbol indentation
*/
public float getSymbolIndent() {
return symbolIndent;
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
/**
* Returns the String that is after a number or letter in the list symbol.
* @return the String that is after a number or letter in the list symbol
* @since iText 2.1.1
*/
public String getPostSymbol() {
return postSymbol;
}
/**
* Sets the String that has to be added after a number or letter in the list symbol.
* @since iText 2.1.1
* @param postSymbol the String that has to be added after a number or letter in the list symbol.
*/
public void setPostSymbol(String postSymbol) {
this.postSymbol = postSymbol;
}
/**
* Returns the String that is before a number or letter in the list symbol.
* @return the String that is before a number or letter in the list symbol
* @since iText 2.1.1
*/
public String getPreSymbol() {
return preSymbol;
}
/**
* Sets the String that has to be added before a number or letter in the list symbol.
* @since iText 2.1.1
* @param preSymbol the String that has to be added before a number or letter in the list symbol.
*/
public void setPreSymbol(String preSymbol) {
this.preSymbol = preSymbol;
}
}

251
src/main/java/com/fr/third/lowagie/text/ListItem.java

@ -0,0 +1,251 @@
/*
* $Id: ListItem.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* A <CODE>ListItem</CODE> is a <CODE>Paragraph</CODE>
* that can be added to a <CODE>List</CODE>.
* <P>
* <B>Example 1:</B>
* <BLOCKQUOTE><PRE>
* List list = new List(true, 20);
* list.add(<STRONG>new ListItem("First line")</STRONG>);
* list.add(<STRONG>new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?")</STRONG>);
* list.add(<STRONG>new ListItem("Third line")</STRONG>);
* </PRE></BLOCKQUOTE>
*
* The result of this code looks like this:
* <OL>
* <LI>
* First line
* </LI>
* <LI>
* The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?
* </LI>
* <LI>
* Third line
* </LI>
* </OL>
*
* <B>Example 2:</B>
* <BLOCKQUOTE><PRE>
* List overview = new List(false, 10);
* overview.add(<STRONG>new ListItem("This is an item")</STRONG>);
* overview.add("This is another item");
* </PRE></BLOCKQUOTE>
*
* The result of this code looks like this:
* <UL>
* <LI>
* This is an item
* </LI>
* <LI>
* This is another item
* </LI>
* </UL>
*
* @see Element
* @see List
* @see Paragraph
*/
public class ListItem extends Paragraph {
// constants
private static final long serialVersionUID = 1970670787169329006L;
// member variables
/** this is the symbol that will precede the listitem. */
private Chunk symbol;
// constructors
/**
* Constructs a <CODE>ListItem</CODE>.
*/
public ListItem() {
super();
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain leading.
*
* @param leading the leading
*/
public ListItem(float leading) {
super(leading);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>Chunk</CODE>.
*
* @param chunk a <CODE>Chunk</CODE>
*/
public ListItem(Chunk chunk) {
super(chunk);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>String</CODE>.
*
* @param string a <CODE>String</CODE>
*/
public ListItem(String string) {
super(string);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>String</CODE>
* and a certain <CODE>Font</CODE>.
*
* @param string a <CODE>String</CODE>
* @param font a <CODE>String</CODE>
*/
public ListItem(String string, Font font) {
super(string, font);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>Chunk</CODE>
* and a certain leading.
*
* @param leading the leading
* @param chunk a <CODE>Chunk</CODE>
*/
public ListItem(float leading, Chunk chunk) {
super(leading, chunk);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>String</CODE>
* and a certain leading.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
*/
public ListItem(float leading, String string) {
super(leading, string);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain leading, <CODE>String</CODE>
* and <CODE>Font</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public ListItem(float leading, String string, Font font) {
super(leading, string, font);
}
/**
* Constructs a <CODE>ListItem</CODE> with a certain <CODE>Phrase</CODE>.
*
* @param phrase a <CODE>Phrase</CODE>
*/
public ListItem(Phrase phrase) {
super(phrase);
}
// implementation of the Element-methods
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return LISTITEM;
}
// methods
/**
* Sets the listsymbol.
*
* @param symbol a <CODE>Chunk</CODE>
*/
public void setListSymbol(Chunk symbol) {
if (this.symbol == null) {
this.symbol = symbol;
if (this.symbol.getFont().isStandardFont()) {
this.symbol.setFont(font);
}
}
}
/**
* Sets the indentation of this paragraph on the left side.
*
* @param indentation the new indentation
*/
public void setIndentationLeft(float indentation, boolean autoindent) {
if (autoindent) {
setIndentationLeft(getListSymbol().getWidthPoint());
}
else {
setIndentationLeft(indentation);
}
}
// methods to retrieve information
/**
* Returns the listsymbol.
*
* @return a <CODE>Chunk</CODE>
*/
public Chunk getListSymbol() {
return symbol;
}
}

470
src/main/java/com/fr/third/lowagie/text/MPL-1.1.txt

@ -0,0 +1,470 @@
MOZILLA PUBLIC LICENSE
Version 1.1
---------------
1. Definitions.
1.0.1. "Commercial Use" means distribution or otherwise making the
Covered Code available to a third party.
1.1. "Contributor" means each entity that creates or contributes to
the creation of Modifications.
1.2. "Contributor Version" means the combination of the Original
Code, prior Modifications used by a Contributor, and the Modifications
made by that particular Contributor.
1.3. "Covered Code" means the Original Code or Modifications or the
combination of the Original Code and Modifications, in each case
including portions thereof.
1.4. "Electronic Distribution Mechanism" means a mechanism generally
accepted in the software development community for the electronic
transfer of data.
1.5. "Executable" means Covered Code in any form other than Source
Code.
1.6. "Initial Developer" means the individual or entity identified
as the Initial Developer in the Source Code notice required by Exhibit
A.
1.7. "Larger Work" means a work which combines Covered Code or
portions thereof with code not governed by the terms of this License.
1.8. "License" means this document.
1.8.1. "Licensable" means having the right to grant, to the maximum
extent possible, whether at the time of the initial grant or
subsequently acquired, any and all of the rights conveyed herein.
1.9. "Modifications" means any addition to or deletion from the
substance or structure of either the Original Code or any previous
Modifications. When Covered Code is released as a series of files, a
Modification is:
A. Any addition to or deletion from the contents of a file
containing Original Code or previous Modifications.
B. Any new file that contains any part of the Original Code or
previous Modifications.
1.10. "Original Code" means Source Code of computer software code
which is described in the Source Code notice required by Exhibit A as
Original Code, and which, at the time of its release under this
License is not already Covered Code governed by this License.
1.10.1. "Patent Claims" means any patent claim(s), now owned or
hereafter acquired, including without limitation, method, process,
and apparatus claims, in any patent Licensable by grantor.
1.11. "Source Code" means the preferred form of the Covered Code for
making modifications to it, including all modules it contains, plus
any associated interface definition files, scripts used to control
compilation and installation of an Executable, or source code
differential comparisons against either the Original Code or another
well known, available Covered Code of the Contributor's choice. The
Source Code can be in a compressed or archival form, provided the
appropriate decompression or de-archiving software is widely available
for no charge.
1.12. "You" (or "Your") means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this
License or a future version of this License issued under Section 6.1.
For legal entities, "You" includes any entity which controls, is
controlled by, or is under common control with You. For purposes of
this definition, "control" means (a) the power, direct or indirect,
to cause the direction or management of such entity, whether by
contract or otherwise, or (b) ownership of more than fifty percent
(50%) of the outstanding shares or beneficial ownership of such
entity.
2. Source Code License.
2.1. The Initial Developer Grant.
The Initial Developer hereby grants You a world-wide, royalty-free,
non-exclusive license, subject to third party intellectual property
claims:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Initial Developer to use, reproduce,
modify, display, perform, sublicense and distribute the Original
Code (or portions thereof) with or without Modifications, and/or
as part of a Larger Work; and
(b) under Patents Claims infringed by the making, using or
selling of Original Code, to make, have made, use, practice,
sell, and offer for sale, and/or otherwise dispose of the
Original Code (or portions thereof).
(c) the licenses granted in this Section 2.1(a) and (b) are
effective on the date Initial Developer first distributes
Original Code under the terms of this License.
(d) Notwithstanding Section 2.1(b) above, no patent license is
granted: 1) for code that You delete from the Original Code; 2)
separate from the Original Code; or 3) for infringements caused
by: i) the modification of the Original Code or ii) the
combination of the Original Code with other software or devices.
2.2. Contributor Grant.
Subject to third party intellectual property claims, each Contributor
hereby grants You a world-wide, royalty-free, non-exclusive license
(a) under intellectual property rights (other than patent or
trademark) Licensable by Contributor, to use, reproduce, modify,
display, perform, sublicense and distribute the Modifications
created by such Contributor (or portions thereof) either on an
unmodified basis, with other Modifications, as Covered Code
and/or as part of a Larger Work; and
(b) under Patent Claims infringed by the making, using, or
selling of Modifications made by that Contributor either alone
and/or in combination with its Contributor Version (or portions
of such combination), to make, use, sell, offer for sale, have
made, and/or otherwise dispose of: 1) Modifications made by that
Contributor (or portions thereof); and 2) the combination of
Modifications made by that Contributor with its Contributor
Version (or portions of such combination).
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
effective on the date Contributor first makes Commercial Use of
the Covered Code.
(d) Notwithstanding Section 2.2(b) above, no patent license is
granted: 1) for any code that Contributor has deleted from the
Contributor Version; 2) separate from the Contributor Version;
3) for infringements caused by: i) third party modifications of
Contributor Version or ii) the combination of Modifications made
by that Contributor with other software (except as part of the
Contributor Version) or other devices; or 4) under Patent Claims
infringed by Covered Code in the absence of Modifications made by
that Contributor.
3. Distribution Obligations.
3.1. Application of License.
The Modifications which You create or to which You contribute are
governed by the terms of this License, including without limitation
Section 2.2. The Source Code version of Covered Code may be
distributed only under the terms of this License or a future version
of this License released under Section 6.1, and You must include a
copy of this License with every copy of the Source Code You
distribute. You may not offer or impose any terms on any Source Code
version that alters or restricts the applicable version of this
License or the recipients' rights hereunder. However, You may include
an additional document offering the additional rights described in
Section 3.5.
3.2. Availability of Source Code.
Any Modification which You create or to which You contribute must be
made available in Source Code form under the terms of this License
either on the same media as an Executable version or via an accepted
Electronic Distribution Mechanism to anyone to whom you made an
Executable version available; and if made available via Electronic
Distribution Mechanism, must remain available for at least twelve (12)
months after the date it initially became available, or at least six
(6) months after a subsequent version of that particular Modification
has been made available to such recipients. You are responsible for
ensuring that the Source Code version remains available even if the
Electronic Distribution Mechanism is maintained by a third party.
3.3. Description of Modifications.
You must cause all Covered Code to which You contribute to contain a
file documenting the changes You made to create that Covered Code and
the date of any change. You must include a prominent statement that
the Modification is derived, directly or indirectly, from Original
Code provided by the Initial Developer and including the name of the
Initial Developer in (a) the Source Code, and (b) in any notice in an
Executable version or related documentation in which You describe the
origin or ownership of the Covered Code.
3.4. Intellectual Property Matters
(a) Third Party Claims.
If Contributor has knowledge that a license under a third party's
intellectual property rights is required to exercise the rights
granted by such Contributor under Sections 2.1 or 2.2,
Contributor must include a text file with the Source Code
distribution titled "LEGAL" which describes the claim and the
party making the claim in sufficient detail that a recipient will
know whom to contact. If Contributor obtains such knowledge after
the Modification is made available as described in Section 3.2,
Contributor shall promptly modify the LEGAL file in all copies
Contributor makes available thereafter and shall take other steps
(such as notifying appropriate mailing lists or newsgroups)
reasonably calculated to inform those who received the Covered
Code that new knowledge has been obtained.
(b) Contributor APIs.
If Contributor's Modifications include an application programming
interface and Contributor has knowledge of patent licenses which
are reasonably necessary to implement that API, Contributor must
also include this information in the LEGAL file.
(c) Representations.
Contributor represents that, except as disclosed pursuant to
Section 3.4(a) above, Contributor believes that Contributor's
Modifications are Contributor's original creation(s) and/or
Contributor has sufficient rights to grant the rights conveyed by
this License.
3.5. Required Notices.
You must duplicate the notice in Exhibit A in each file of the Source
Code. If it is not possible to put such notice in a particular Source
Code file due to its structure, then You must include such notice in a
location (such as a relevant directory) where a user would be likely
to look for such a notice. If You created one or more Modification(s)
You may add your name as a Contributor to the notice described in
Exhibit A. You must also duplicate this License in any documentation
for the Source Code where You describe recipients' rights or ownership
rights relating to Covered Code. You may choose to offer, and to
charge a fee for, warranty, support, indemnity or liability
obligations to one or more recipients of Covered Code. However, You
may do so only on Your own behalf, and not on behalf of the Initial
Developer or any Contributor. You must make it absolutely clear than
any such warranty, support, indemnity or liability obligation is
offered by You alone, and You hereby agree to indemnify the Initial
Developer and every Contributor for any liability incurred by the
Initial Developer or such Contributor as a result of warranty,
support, indemnity or liability terms You offer.
3.6. Distribution of Executable Versions.
You may distribute Covered Code in Executable form only if the
requirements of Section 3.1-3.5 have been met for that Covered Code,
and if You include a notice stating that the Source Code version of
the Covered Code is available under the terms of this License,
including a description of how and where You have fulfilled the
obligations of Section 3.2. The notice must be conspicuously included
in any notice in an Executable version, related documentation or
collateral in which You describe recipients' rights relating to the
Covered Code. You may distribute the Executable version of Covered
Code or ownership rights under a license of Your choice, which may
contain terms different from this License, provided that You are in
compliance with the terms of this License and that the license for the
Executable version does not attempt to limit or alter the recipient's
rights in the Source Code version from the rights set forth in this
License. If You distribute the Executable version under a different
license You must make it absolutely clear that any terms which differ
from this License are offered by You alone, not by the Initial
Developer or any Contributor. You hereby agree to indemnify the
Initial Developer and every Contributor for any liability incurred by
the Initial Developer or such Contributor as a result of any such
terms You offer.
3.7. Larger Works.
You may create a Larger Work by combining Covered Code with other code
not governed by the terms of this License and distribute the Larger
Work as a single product. In such a case, You must make sure the
requirements of this License are fulfilled for the Covered Code.
4. Inability to Comply Due to Statute or Regulation.
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Code due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description
must be included in the LEGAL file described in Section 3.4 and must
be included with all distributions of the Source Code. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Application of this License.
This License applies to code to which the Initial Developer has
attached the notice in Exhibit A and to related Covered Code.
6. Versions of the License.
6.1. New Versions.
Netscape Communications Corporation ("Netscape") may publish revised
and/or new versions of the License from time to time. Each version
will be given a distinguishing version number.
6.2. Effect of New Versions.
Once Covered Code has been published under a particular version of the
License, You may always continue to use it under the terms of that
version. You may also choose to use such Covered Code under the terms
of any subsequent version of the License published by Netscape. No one
other than Netscape has the right to modify the terms applicable to
Covered Code created under this License.
6.3. Derivative Works.
If You create or use a modified version of this License (which you may
only do in order to apply it to code which is not already Covered Code
governed by this License), You must (a) rename Your license so that
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
"MPL", "NPL" or any confusingly similar phrase do not appear in your
license (except to note that your license differs from this License)
and (b) otherwise make it clear that Your version of the license
contains terms which differ from the Mozilla Public License and
Netscape Public License. (Filling in the name of the Initial
Developer, Original Code or Contributor in the notice described in
Exhibit A shall not of themselves be deemed to be modifications of
this License.)
7. DISCLAIMER OF WARRANTY.
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
8. TERMINATION.
8.1. This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to cure
such breach within 30 days of becoming aware of the breach. All
sublicenses to the Covered Code which are properly granted shall
survive any termination of this License. Provisions which, by their
nature, must remain in effect beyond the termination of this License
shall survive.
8.2. If You initiate litigation by asserting a patent infringement
claim (excluding declatory judgment actions) against Initial Developer
or a Contributor (the Initial Developer or Contributor against whom
You file such action is referred to as "Participant") alleging that:
(a) such Participant's Contributor Version directly or indirectly
infringes any patent, then any and all rights granted by such
Participant to You under Sections 2.1 and/or 2.2 of this License
shall, upon 60 days notice from Participant terminate prospectively,
unless if within 60 days after receipt of notice You either: (i)
agree in writing to pay Participant a mutually agreeable reasonable
royalty for Your past and future use of Modifications made by such
Participant, or (ii) withdraw Your litigation claim with respect to
the Contributor Version against such Participant. If within 60 days
of notice, a reasonable royalty and payment arrangement are not
mutually agreed upon in writing by the parties or the litigation claim
is not withdrawn, the rights granted by Participant to You under
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
the 60 day notice period specified above.
(b) any software, hardware, or device, other than such Participant's
Contributor Version, directly or indirectly infringes any patent, then
any rights granted to You by such Participant under Sections 2.1(b)
and 2.2(b) are revoked effective as of the date You first made, used,
sold, distributed, or had made, Modifications made by that
Participant.
8.3. If You assert a patent infringement claim against Participant
alleging that such Participant's Contributor Version directly or
indirectly infringes any patent where such claim is resolved (such as
by license or settlement) prior to the initiation of patent
infringement litigation, then the reasonable value of the licenses
granted by such Participant under Sections 2.1 or 2.2 shall be taken
into account in determining the amount or value of any payment or
license.
8.4. In the event of termination under Sections 8.1 or 8.2 above,
all end user license agreements (excluding distributors and resellers)
which have been validly granted by You or any distributor hereunder
prior to termination shall survive termination.
9. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
10. U.S. GOVERNMENT END USERS.
The Covered Code is a "commercial item," as that term is defined in
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
software" and "commercial computer software documentation," as such
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
all U.S. Government End Users acquire Covered Code with only those
rights set forth herein.
11. MISCELLANEOUS.
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License shall be governed by
California law provisions (except to the extent applicable law, if
any, provides otherwise), excluding its conflict-of-law provisions.
With respect to disputes in which at least one party is a citizen of,
or an entity chartered or registered to do business in the United
States of America, any litigation relating to this License shall be
subject to the jurisdiction of the Federal Courts of the Northern
District of California, with venue lying in Santa Clara County,
California, with the losing party responsible for costs, including
without limitation, court costs and reasonable attorneys' fees and
expenses. The application of the United Nations Convention on
Contracts for the International Sale of Goods is expressly excluded.
Any law or regulation which provides that the language of a contract
shall be construed against the drafter shall not apply to this
License.
12. RESPONSIBILITY FOR CLAIMS.
As between Initial Developer and the Contributors, each party is
responsible for claims and damages arising, directly or indirectly,
out of its utilization of rights under this License and You agree to
work with Initial Developer and Contributors to distribute such
responsibility on an equitable basis. Nothing herein is intended or
shall be deemed to constitute any admission of liability.
13. MULTIPLE-LICENSED CODE.
Initial Developer may designate portions of the Covered Code as
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
Developer permits you to utilize portions of the Covered Code under
Your choice of the NPL or the alternative licenses, if any, specified
by the Initial Developer in the file described in Exhibit A.
EXHIBIT A -Mozilla Public License.
``The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is ______________________________________.
The Initial Developer of the Original Code is ________________________.
Portions created by ______________________ are Copyright (C) ______
_______________________. All Rights Reserved.
Contributor(s): ______________________________________.
Alternatively, the contents of this file may be used under the terms
of the _____ license (the "[___] License"), in which case the
provisions of [______] License are applicable instead of those
above. If you wish to allow use of your version of this file only
under the terms of the [____] License and not to allow others to use
your version of this file under the MPL, indicate your decision by
deleting the provisions above and replace them with the notice and
other provisions required by the [___] License. If you do not delete
the provisions above, a recipient may use your version of this file
under either the MPL or the [___] License."
[NOTE: The text of this Exhibit A may differ slightly from the text of
the notices in the Source Code files of the Original Code. You should
use the text of this Exhibit A rather than the text found in the
Original Code Source Code for Your Modifications.]

150
src/main/java/com/fr/third/lowagie/text/MarkedObject.java

@ -0,0 +1,150 @@
/*
* $Id: MarkedObject.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Properties;
/**
* Wrapper that allows to add properties to 'basic building block' objects.
* Before iText 1.5 every 'basic building block' implemented the MarkupAttributes interface.
* By setting attributes, you could add markup to the corresponding XML and/or HTML tag.
* This functionality was hardly used by anyone, so it was removed, and replaced by
* the MarkedObject functionality.
*/
public class MarkedObject implements Element {
/** The element that is wrapped in a MarkedObject. */
protected Element element;
/** Contains extra markupAttributes */
protected Properties markupAttributes = new Properties();
/**
* This constructor is for internal use only.
*/
protected MarkedObject() {
element = null;
}
/**
* Creates a MarkedObject.
*/
public MarkedObject(Element element) {
this.element = element;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
return element.getChunks();
}
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(element);
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return MARKED;
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
/**
* Getter for the markup attributes.
* @return the markupAttributes
*/
public Properties getMarkupAttributes() {
return markupAttributes;
}
/**
* Adds one markup attribute.
*/
public void setMarkupAttribute(String key, String value) {
markupAttributes.setProperty(key, value);
}
}

281
src/main/java/com/fr/third/lowagie/text/MarkedSection.java

@ -0,0 +1,281 @@
/*
* $Id: MarkedSection.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.Collection;
import java.util.Iterator;
/**
* Wrapper that allows to add properties to a Chapter/Section object.
* Before iText 1.5 every 'basic building block' implemented the MarkupAttributes interface.
* By setting attributes, you could add markup to the corresponding XML and/or HTML tag.
* This functionality was hardly used by anyone, so it was removed, and replaced by
* the MarkedObject functionality.
*/
public class MarkedSection extends MarkedObject {
/** This is the title of this section. */
protected MarkedObject title = null;
/**
* Creates a MarkedObject with a Section or Chapter object.
* @param section the marked section
*/
public MarkedSection(Section section) {
super();
if (section.title != null) {
title = new MarkedObject(section.title);
section.setTitle(null);
}
this.element = section;
}
/**
* Adds a <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>
* to this <CODE>Section</CODE>.
*
* @param index index at which the specified element is to be inserted
* @param o an object of type <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>=
* @throws ClassCastException if the object is not a <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>
*/
public void add(int index, Object o) {
((Section)element).add(index, o);
}
/**
* Adds a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or another <CODE>Section</CODE>
* to this <CODE>Section</CODE>.
*
* @param o an object of type <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or another <CODE>Section</CODE>
* @return a boolean
* @throws ClassCastException if the object is not a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or <CODE>Section</CODE>
*/
public boolean add(Object o) {
return ((Section)element).add(o);
}
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
Element element;
for (Iterator i = ((Section)this.element).iterator(); i.hasNext(); ) {
element = (Element)i.next();
listener.add(element);
}
return true;
}
catch(DocumentException de) {
return false;
}
}
/**
* Adds a collection of <CODE>Element</CODE>s
* to this <CODE>Section</CODE>.
*
* @param collection a collection of <CODE>Paragraph</CODE>s, <CODE>List</CODE>s and/or <CODE>Table</CODE>s
* @return <CODE>true</CODE> if the action succeeded, <CODE>false</CODE> if not.
* @throws ClassCastException if one of the objects isn't a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE>
*/
public boolean addAll(Collection collection) {
return ((Section)element).addAll(collection);
}
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public MarkedSection addSection(float indentation, int numberDepth) {
MarkedSection section = ((Section)element).addMarkedSection();
section.setIndentation(indentation);
section.setNumberDepth(numberDepth);
return section;
}
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @return a new Section object
*/
public MarkedSection addSection(float indentation) {
MarkedSection section = ((Section)element).addMarkedSection();
section.setIndentation(indentation);
return section;
}
/**
* Creates a <CODE>Section</CODE>, add it to this <CODE>Section</CODE> and returns it.
*
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public MarkedSection addSection(int numberDepth) {
MarkedSection section = ((Section)element).addMarkedSection();
section.setNumberDepth(numberDepth);
return section;
}
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @return a new Section object
*/
public MarkedSection addSection() {
return ((Section)element).addMarkedSection();
}
// public methods
/**
* Sets the title of this section.
*
* @param title the new title
*/
public void setTitle(MarkedObject title) {
if (title.element instanceof Paragraph)
this.title = title;
}
/**
* Gets the title of this MarkedSection.
* @return a MarkObject with a Paragraph containing the title of a Section
* @since iText 2.0.8
*/
public MarkedObject getTitle() {
Paragraph result = Section.constructTitle((Paragraph)title.element, ((Section)element).numbers, ((Section)element).numberDepth, ((Section)element).numberStyle);
MarkedObject mo = new MarkedObject(result);
mo.markupAttributes = title.markupAttributes;
return mo;
}
/**
* Sets the depth of the sectionnumbers that will be shown preceding the title.
* <P>
* If the numberdepth is 0, the sections will not be numbered. If the numberdepth
* is 1, the section will be numbered with their own number. If the numberdepth is
* higher (for instance x > 1), the numbers of x - 1 parents will be shown.
*
* @param numberDepth the new numberDepth
*/
public void setNumberDepth(int numberDepth) {
((Section)element).setNumberDepth(numberDepth);
}
/**
* Sets the indentation of this <CODE>Section</CODE> on the left side.
*
* @param indentation the indentation
*/
public void setIndentationLeft(float indentation) {
((Section)element).setIndentationLeft(indentation);
}
/**
* Sets the indentation of this <CODE>Section</CODE> on the right side.
*
* @param indentation the indentation
*/
public void setIndentationRight(float indentation) {
((Section)element).setIndentationRight(indentation);
}
/**
* Sets the indentation of the content of this <CODE>Section</CODE>.
*
* @param indentation the indentation
*/
public void setIndentation(float indentation) {
((Section)element).setIndentation(indentation);
}
/** Setter for property bookmarkOpen.
* @param bookmarkOpen false if the bookmark children are not
* visible.
*/
public void setBookmarkOpen(boolean bookmarkOpen) {
((Section)element).setBookmarkOpen(bookmarkOpen);
}
/**
* Setter for property triggerNewPage.
* @param triggerNewPage true if a new page has to be triggered.
*/
public void setTriggerNewPage(boolean triggerNewPage) {
((Section)element).setTriggerNewPage(triggerNewPage);
}
/**
* Sets the bookmark title. The bookmark title is the same as the section title but
* can be changed with this method.
* @param bookmarkTitle the bookmark title
*/
public void setBookmarkTitle(String bookmarkTitle) {
((Section)element).setBookmarkTitle(bookmarkTitle);
}
/**
* Adds a new page to the section.
* @since 2.1.1
*/
public void newPage() {
((Section)element).newPage();
}
}

229
src/main/java/com/fr/third/lowagie/text/Meta.java

@ -0,0 +1,229 @@
/*
* $Id: Meta.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
/**
* This is an <CODE>Element</CODE> that contains
* some meta information about the document.
* <P>
* An object of type <CODE>Meta</CODE> can not be constructed by the user.
* User defined meta information should be placed in a <CODE>Header</CODE>-object.
* <CODE>Meta</CODE> is reserved for: Subject, Keywords, Author, Title, Producer
* and Creationdate information.
*
* @see Element
* @see Header
*/
public class Meta implements Element {
// membervariables
/** This is the type of Meta-information this object contains. */
private int type;
/** This is the content of the Meta-information. */
private StringBuffer content;
// constructors
/**
* Constructs a <CODE>Meta</CODE>.
*
* @param type the type of meta-information
* @param content the content
*/
Meta(int type, String content) {
this.type = type;
this.content = new StringBuffer(content);
}
/**
* Constructs a <CODE>Meta</CODE>.
*
* @param tag the tagname of the meta-information
* @param content the content
*/
public Meta(String tag, String content) {
this.type = Meta.getType(tag);
this.content = new StringBuffer(content);
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to a
* <CODE>ElementListener</CODE>.
*
* @param listener the <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return type;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
return new ArrayList();
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return false;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return false;
}
// methods
/**
* appends some text to this <CODE>Meta</CODE>.
*
* @param string a <CODE>String</CODE>
* @return a <CODE>StringBuffer</CODE>
*/
public StringBuffer append(String string) {
return content.append(string);
}
// methods to retrieve information
/**
* Returns the content of the meta information.
*
* @return a <CODE>String</CODE>
*/
public String getContent() {
return content.toString();
}
/**
* Returns the name of the meta information.
*
* @return a <CODE>String</CODE>
*/
public String getName() {
switch (type) {
case Element.SUBJECT:
return ElementTags.SUBJECT;
case Element.KEYWORDS:
return ElementTags.KEYWORDS;
case Element.AUTHOR:
return ElementTags.AUTHOR;
case Element.TITLE:
return ElementTags.TITLE;
case Element.PRODUCER:
return ElementTags.PRODUCER;
case Element.CREATIONDATE:
return ElementTags.CREATIONDATE;
default:
return ElementTags.UNKNOWN;
}
}
/**
* Returns the name of the meta information.
*
* @param tag iText tag for meta information
* @return the Element value corresponding with the given tag
*/
public static int getType(String tag) {
if (ElementTags.SUBJECT.equals(tag)) {
return Element.SUBJECT;
}
if (ElementTags.KEYWORDS.equals(tag)) {
return Element.KEYWORDS;
}
if (ElementTags.AUTHOR.equals(tag)) {
return Element.AUTHOR;
}
if (ElementTags.TITLE.equals(tag)) {
return Element.TITLE;
}
if (ElementTags.PRODUCER.equals(tag)) {
return Element.PRODUCER;
}
if (ElementTags.CREATIONDATE.equals(tag)) {
return Element.CREATIONDATE;
}
return Element.HEADER;
}
}

246
src/main/java/com/fr/third/lowagie/text/PageSize.java

@ -0,0 +1,246 @@
/*
* $Id: PageSize.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.lang.reflect.Field;
/**
* The <CODE>PageSize</CODE>-object contains a number of rectangles representing the most common paper sizes.
*
* @see Rectangle
*/
public class PageSize {
// membervariables
/** This is the letter format */
public static final Rectangle LETTER = new RectangleReadOnly(612,792);
/** This is the note format */
public static final Rectangle NOTE = new RectangleReadOnly(540,720);
/** This is the legal format */
public static final Rectangle LEGAL = new RectangleReadOnly(612,1008);
/** This is the tabloid format */
public static final Rectangle TABLOID = new RectangleReadOnly(792,1224);
/** This is the executive format */
public static final Rectangle EXECUTIVE = new RectangleReadOnly(522,756);
/** This is the postcard format */
public static final Rectangle POSTCARD = new RectangleReadOnly(283,416);
/** This is the a0 format */
public static final Rectangle A0 = new RectangleReadOnly(2384,3370);
/** This is the a1 format */
public static final Rectangle A1 = new RectangleReadOnly(1684,2384);
/** This is the a2 format */
public static final Rectangle A2 = new RectangleReadOnly(1191,1684);
/** This is the a3 format */
public static final Rectangle A3 = new RectangleReadOnly(842,1191);
/** This is the a4 format */
public static final Rectangle A4 = new RectangleReadOnly(595,842);
/** This is the a5 format */
public static final Rectangle A5 = new RectangleReadOnly(420,595);
/** This is the a6 format */
public static final Rectangle A6 = new RectangleReadOnly(297,420);
/** This is the a7 format */
public static final Rectangle A7 = new RectangleReadOnly(210,297);
/** This is the a8 format */
public static final Rectangle A8 = new RectangleReadOnly(148,210);
/** This is the a9 format */
public static final Rectangle A9 = new RectangleReadOnly(105,148);
/** This is the a10 format */
public static final Rectangle A10 = new RectangleReadOnly(73,105);
/** This is the b0 format */
public static final Rectangle B0 = new RectangleReadOnly(2834,4008);
/** This is the b1 format */
public static final Rectangle B1 = new RectangleReadOnly(2004,2834);
/** This is the b2 format */
public static final Rectangle B2 = new RectangleReadOnly(1417,2004);
/** This is the b3 format */
public static final Rectangle B3 = new RectangleReadOnly(1000,1417);
/** This is the b4 format */
public static final Rectangle B4 = new RectangleReadOnly(708,1000);
/** This is the b5 format */
public static final Rectangle B5 = new RectangleReadOnly(498,708);
/** This is the b6 format */
public static final Rectangle B6 = new RectangleReadOnly(354,498);
/** This is the b7 format */
public static final Rectangle B7 = new RectangleReadOnly(249,354);
/** This is the b8 format */
public static final Rectangle B8 = new RectangleReadOnly(175,249);
/** This is the b9 format */
public static final Rectangle B9 = new RectangleReadOnly(124,175);
/** This is the b10 format */
public static final Rectangle B10 = new RectangleReadOnly(87,124);
/** This is the archE format */
public static final Rectangle ARCH_E = new RectangleReadOnly(2592,3456);
/** This is the archD format */
public static final Rectangle ARCH_D = new RectangleReadOnly(1728,2592);
/** This is the archC format */
public static final Rectangle ARCH_C = new RectangleReadOnly(1296,1728);
/** This is the archB format */
public static final Rectangle ARCH_B = new RectangleReadOnly(864,1296);
/** This is the archA format */
public static final Rectangle ARCH_A = new RectangleReadOnly(648,864);
/** This is the American Foolscap format */
public static final Rectangle FLSA = new RectangleReadOnly(612,936);
/** This is the European Foolscap format */
public static final Rectangle FLSE = new RectangleReadOnly(648,936);
/** This is the halfletter format */
public static final Rectangle HALFLETTER = new RectangleReadOnly(396,612);
/** This is the 11x17 format */
public static final Rectangle _11X17 = new RectangleReadOnly(792,1224);
/** This is the ISO 7810 ID-1 format (85.60 x 53.98 mm or 3.370 x 2.125 inch) */
public static final Rectangle ID_1 = new RectangleReadOnly(242.65f,153);
/** This is the ISO 7810 ID-2 format (A7 rotated) */
public static final Rectangle ID_2 = new RectangleReadOnly(297,210);
/** This is the ISO 7810 ID-3 format (B7 rotated) */
public static final Rectangle ID_3 = new RectangleReadOnly(354,249);
/** This is the ledger format */
public static final Rectangle LEDGER = new RectangleReadOnly(1224,792);
/** This is the Crown Quarto format */
public static final Rectangle CROWN_QUARTO = new RectangleReadOnly(535,697);
/** This is the Large Crown Quarto format */
public static final Rectangle LARGE_CROWN_QUARTO = new RectangleReadOnly(569,731);
/** This is the Demy Quarto format. */
public static final Rectangle DEMY_QUARTO = new RectangleReadOnly(620,782);
/** This is the Royal Quarto format. */
public static final Rectangle ROYAL_QUARTO = new RectangleReadOnly(671,884);
/** This is the Crown Octavo format */
public static final Rectangle CROWN_OCTAVO = new RectangleReadOnly(348,527);
/** This is the Large Crown Octavo format */
public static final Rectangle LARGE_CROWN_OCTAVO = new RectangleReadOnly(365,561);
/** This is the Demy Octavo format */
public static final Rectangle DEMY_OCTAVO = new RectangleReadOnly(391,612);
/** This is the Royal Octavo format. */
public static final Rectangle ROYAL_OCTAVO = new RectangleReadOnly(442,663);
/** This is the small paperback format. */
public static final Rectangle SMALL_PAPERBACK = new RectangleReadOnly(314,504);
/** This is the Pengiun small paperback format. */
public static final Rectangle PENGUIN_SMALL_PAPERBACK = new RectangleReadOnly(314,513);
/** This is the Penguin large paperback format. */
public static final Rectangle PENGUIN_LARGE_PAPERBACK = new RectangleReadOnly(365,561);
/**
* This method returns a Rectangle based on a String.
* Possible values are the the names of a constant in this class
* (for instance "A4", "LETTER",...) or a value like "595 842"
*/
public static Rectangle getRectangle(String name) {
name = name.trim().toUpperCase();
int pos = name.indexOf(' ');
if (pos == -1) {
try {
Field field = PageSize.class.getDeclaredField(name.toUpperCase());
return (Rectangle) field.get(null);
} catch (Exception e) {
throw new RuntimeException("Can't find page size " + name);
}
}
else {
try {
String width = name.substring(0, pos);
String height = name.substring(pos + 1);
return new Rectangle(Float.parseFloat(width), Float.parseFloat(height));
} catch(Exception e) {
throw new RuntimeException(name + " is not a valid page size format; " + e.getMessage());
}
}
}
}

541
src/main/java/com/fr/third/lowagie/text/Paragraph.java

@ -0,0 +1,541 @@
/*
* $Id: Paragraph.java 3668 2009-02-01 09:08:50Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import com.fr.third.lowagie.text.html.BorderAttribute;
import java.util.HashMap;
/**
* A <CODE>Paragraph</CODE> is a series of <CODE>Chunk</CODE>s and/or <CODE>Phrases</CODE>.
* <P>
* A <CODE>Paragraph</CODE> has the same qualities of a <CODE>Phrase</CODE>, but also
* some additional layout-parameters:
* <UL>
* <LI>the indentation
* <LI>the alignment of the text
* </UL>
*
* Example:
* <BLOCKQUOTE><PRE>
* <STRONG>Paragraph p = new Paragraph("This is a paragraph",
* FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));</STRONG>
* </PRE></BLOCKQUOTE>
*
* @see Element
* @see Phrase
* @see ListItem
*/
public class Paragraph extends Phrase {
// constants
private static final long serialVersionUID = 7852314969733375514L;
// membervariables
/** The alignment of the text. */
protected int alignment = ALIGN_UNDEFINED;
/** The text leading that is multiplied by the biggest font size in the line. */
protected float multipliedLeading = 0;
/** The indentation of this paragraph on the left side. */
protected float indentationLeft;
/** The indentation of this paragraph on the right side. */
protected float indentationRight;
/** Holds value of property firstLineIndent. */
private float firstLineIndent = 0;
/** The spacing before the paragraph. */
protected float spacingBefore;
/** The spacing after the paragraph. */
protected float spacingAfter;
/** Holds value of property extraParagraphSpace. */
private float extraParagraphSpace = 0;
/** Does the paragraph has to be kept together on 1 page. */
protected boolean keeptogether = false;
protected String background;
protected HashMap attributes = new HashMap();
private BorderAttribute borderAttr;
public HashMap getAttributes() {
return attributes;
}
public void setAttributes(HashMap attributes) {
this.attributes = attributes;
}
public void setAttribute(String name, Object obj) {
if (attributes == null)
attributes = new HashMap();
attributes.put(name, obj);
}
// constructors
/**
* Constructs a <CODE>Paragraph</CODE>.
*/
public Paragraph() {
super();
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain leading.
*
* @param leading the leading
*/
public Paragraph(float leading) {
super(leading);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>Chunk</CODE>.
*
* @param chunk a <CODE>Chunk</CODE>
*/
public Paragraph(Chunk chunk) {
super(chunk);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>Chunk</CODE>
* and a certain leading.
*
* @param leading the leading
* @param chunk a <CODE>Chunk</CODE>
*/
public Paragraph(float leading, Chunk chunk) {
super(leading, chunk);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>String</CODE>.
*
* @param string a <CODE>String</CODE>
*/
public Paragraph(String string) {
super(string);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>String</CODE>
* and a certain <CODE>Font</CODE>.
*
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Paragraph(String string, Font font) {
super(string, font);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>String</CODE>
* and a certain leading.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
*/
public Paragraph(float leading, String string) {
super(leading, string);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain leading, <CODE>String</CODE>
* and <CODE>Font</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Paragraph(float leading, String string, Font font) {
super(leading, string, font);
}
/**
* Constructs a <CODE>Paragraph</CODE> with a certain <CODE>Phrase</CODE>.
*
* @param phrase a <CODE>Phrase</CODE>
*/
public Paragraph(Phrase phrase) {
super(phrase);
if (phrase instanceof Paragraph) {
Paragraph p = (Paragraph)phrase;
setAlignment(p.alignment);
setLeading(phrase.getLeading(), p.multipliedLeading);
setIndentationLeft(p.getIndentationLeft());
setIndentationRight(p.getIndentationRight());
setFirstLineIndent(p.getFirstLineIndent());
setSpacingAfter(p.spacingAfter());
setSpacingBefore(p.spacingBefore());
setExtraParagraphSpace(p.getExtraParagraphSpace());
}
}
// implementation of the Element-methods
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return PARAGRAPH;
}
// methods
/**
* Adds an <CODE>Object</CODE> to the <CODE>Paragraph</CODE>.
*
* @param o object the object to add.
* @return true is adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof List) {
List list = (List) o;
list.setIndentationLeft(list.getIndentationLeft() + indentationLeft);
list.setIndentationRight(indentationRight);
return super.add(list);
}
else if (o instanceof Image) {
super.addSpecial(o);
return true;
}
else if (o instanceof Paragraph) {
super.add(o);
java.util.List chunks = getChunks();
if (!chunks.isEmpty()) {
Chunk tmp = ((Chunk) chunks.get(chunks.size() - 1));
super.add(new Chunk("\n", tmp.getFont()));
}
else {
super.add(Chunk.NEWLINE);
}
return true;
}
return super.add(o);
}
// setting the membervariables
/**
* Sets the alignment of this paragraph.
*
* @param alignment the new alignment
*/
public void setAlignment(int alignment) {
this.alignment = alignment;
}
/**
* Sets the alignment of this paragraph.
*
* @param alignment the new alignment as a <CODE>String</CODE>
*/
public void setAlignment(String alignment) {
if (ElementTags.ALIGN_CENTER.equalsIgnoreCase(alignment)) {
this.alignment = ALIGN_CENTER;
return;
}
if (ElementTags.ALIGN_RIGHT.equalsIgnoreCase(alignment)) {
this.alignment = ALIGN_RIGHT;
return;
}
if (ElementTags.ALIGN_JUSTIFIED.equalsIgnoreCase(alignment)) {
this.alignment = ALIGN_JUSTIFIED;
return;
}
if (ElementTags.ALIGN_JUSTIFIED_ALL.equalsIgnoreCase(alignment)) {
this.alignment = ALIGN_JUSTIFIED_ALL;
return;
}
this.alignment = ALIGN_LEFT;
}
/**
* @see Phrase#setLeading(float)
*/
public void setLeading(float fixedLeading) {
this.leading = fixedLeading;
this.multipliedLeading = 0;
}
/**
* Sets the variable leading. The resultant leading will be
* multipliedLeading*maxFontSize where maxFontSize is the
* size of the biggest font in the line.
* @param multipliedLeading the variable leading
*/
public void setMultipliedLeading(float multipliedLeading) {
this.leading = 0;
this.multipliedLeading = multipliedLeading;
}
/**
* Sets the leading fixed and variable. The resultant leading will be
* fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the
* size of the biggest font in the line.
* @param fixedLeading the fixed leading
* @param multipliedLeading the variable leading
*/
public void setLeading(float fixedLeading, float multipliedLeading) {
this.leading = fixedLeading;
this.multipliedLeading = multipliedLeading;
}
/**
* Sets the indentation of this paragraph on the left side.
*
* @param indentation the new indentation
*/
public void setIndentationLeft(float indentation) {
this.indentationLeft = indentation;
}
/**
* Sets the indentation of this paragraph on the right side.
*
* @param indentation the new indentation
*/
public void setIndentationRight(float indentation) {
this.indentationRight = indentation;
}
/**
* Setter for property firstLineIndent.
* @param firstLineIndent New value of property firstLineIndent.
*/
public void setFirstLineIndent(float firstLineIndent) {
this.firstLineIndent = firstLineIndent;
}
/**
* Sets the spacing before this paragraph.
*
* @param spacing the new spacing
*/
public void setSpacingBefore(float spacing) {
this.spacingBefore = spacing;
}
/**
* Sets the spacing after this paragraph.
*
* @param spacing the new spacing
*/
public void setSpacingAfter(float spacing) {
this.spacingAfter = spacing;
}
/**
* Indicates that the paragraph has to be kept together on one page.
*
* @param keeptogether true of the paragraph may not be split over 2 pages
*/
public void setKeepTogether(boolean keeptogether) {
this.keeptogether = keeptogether;
}
/**
* Checks if this paragraph has to be kept together on one page.
*
* @return true if the paragraph may not be split over 2 pages.
*/
public boolean getKeepTogether() {
return keeptogether;
}
// methods to retrieve information
/**
* Gets the alignment of this paragraph.
*
* @return alignment
*/
public int getAlignment() {
return alignment;
}
/**
* Gets the variable leading
* @return the leading
*/
public float getMultipliedLeading() {
return multipliedLeading;
}
/**
* Gets the total leading.
* This method is based on the assumption that the
* font of the Paragraph is the font of all the elements
* that make part of the paragraph. This isn't necessarily
* true.
* @return the total leading (fixed and multiplied)
*/
public float getTotalLeading() {
float m = font == null ?
Font.DEFAULTSIZE * multipliedLeading : font.getCalculatedLeading(multipliedLeading);
if (m > 0 && !hasLeading()) {
return m;
}
return getLeading() + m;
}
/**
* Gets the indentation of this paragraph on the left side.
*
* @return the indentation
*/
public float getIndentationLeft() {
return indentationLeft;
}
/**
* Gets the indentation of this paragraph on the right side.
*
* @return the indentation
*/
public float getIndentationRight() {
return indentationRight;
}
/**
* Getter for property firstLineIndent.
* @return Value of property firstLineIndent.
*/
public float getFirstLineIndent() {
return this.firstLineIndent;
}
/**
* Gets the spacing before this paragraph.
* @return the spacing
* @since 2.1.5
*/
public float getSpacingBefore() {
return spacingBefore;
}
/**
* Gets the spacing after this paragraph.
* @return the spacing
* @since 2.1.5
*/
public float getSpacingAfter() {
return spacingAfter;
}
/**
* Getter for property extraParagraphSpace.
* @return Value of property extraParagraphSpace.
*/
public float getExtraParagraphSpace() {
return this.extraParagraphSpace;
}
/**
* Setter for property extraParagraphSpace.
* @param extraParagraphSpace New value of property extraParagraphSpace.
*/
public void setExtraParagraphSpace(float extraParagraphSpace) {
this.extraParagraphSpace = extraParagraphSpace;
}
// scheduled for removal
/**
* Gets the spacing before this paragraph.
*
* @return the spacing
* @deprecated As of iText 2.1.5, replaced by {@link #getSpacingBefore()},
* scheduled for removal at 2.3.0
*/
public float spacingBefore() {
return getSpacingBefore();
}
/**
* Gets the spacing after this paragraph.
*
* @return the spacing
* @deprecated As of iText 2.1.5, replaced by {@link #getSpacingAfter()},
* scheduled for removal at 2.3.0
*/
public float spacingAfter() {
return spacingAfter;
}
public void setBackground(String background){
this.background = background;
}
public String getBackground(){
return this.background;
}
public BorderAttribute getBorderAttr() {
return borderAttr;
}
public void setBorderAttrs(BorderAttribute borderAttrs) {
this.borderAttr = borderAttrs;
}
}

589
src/main/java/com/fr/third/lowagie/text/Phrase.java

@ -0,0 +1,589 @@
/*
* $Id: Phrase.java 3942 2009-05-28 18:14:10Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import com.fr.third.lowagie.text.pdf.HyphenationEvent;
/**
* A <CODE>Phrase</CODE> is a series of <CODE>Chunk</CODE>s.
* <P>
* A <CODE>Phrase</CODE> has a main <CODE>Font</CODE>, but some chunks
* within the phrase can have a <CODE>Font</CODE> that differs from the
* main <CODE>Font</CODE>. All the <CODE>Chunk</CODE>s in a <CODE>Phrase</CODE>
* have the same <CODE>leading</CODE>.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* // When no parameters are passed, the default leading = 16
* <STRONG>Phrase phrase0 = new Phrase();</STRONG>
* <STRONG>Phrase phrase1 = new Phrase("this is a phrase");</STRONG>
* // In this example the leading is passed as a parameter
* <STRONG>Phrase phrase2 = new Phrase(16, "this is a phrase with leading 16");</STRONG>
* // When a Font is passed (explicitly or embedded in a chunk), the default leading = 1.5 * size of the font
* <STRONG>Phrase phrase3 = new Phrase("this is a phrase with a red, normal font Courier, size 12", FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL, new Color(255, 0, 0)));</STRONG>
* <STRONG>Phrase phrase4 = new Phrase(new Chunk("this is a phrase"));</STRONG>
* <STRONG>Phrase phrase5 = new Phrase(18, new Chunk("this is a phrase", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));</STRONG>
* </PRE></BLOCKQUOTE>
*
* @see Element
* @see Chunk
* @see Paragraph
* @see Anchor
*/
public class Phrase extends ArrayList implements TextElementArray {
// constants
private static final long serialVersionUID = 2643594602455068231L;
// membervariables
/** This is the leading of this phrase. */
protected float leading = Float.NaN;
/** This is the font of this phrase. */
protected Font font;
/** Null, unless the Phrase has to be hyphenated.
* @since 2.1.2
*/
protected HyphenationEvent hyphenation = null;
// constructors
/**
* Constructs a <CODE>Phrase</CODE> without specifying a leading.
*/
public Phrase() {
this(16);
}
/**
* Copy constructor for <CODE>Phrase</CODE>.
*/
public Phrase(Phrase phrase) {
super();
this.addAll(phrase);
leading = phrase.getLeading();
font = phrase.getFont();
setHyphenation(phrase.getHyphenation());
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain leading.
*
* @param leading the leading
*/
public Phrase(float leading) {
this.leading = leading;
font = new Font();
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain <CODE>Chunk</CODE>.
*
* @param chunk a <CODE>Chunk</CODE>
*/
public Phrase(Chunk chunk) {
super.add(chunk);
font = chunk.getFont();
setHyphenation(chunk.getHyphenation());
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain <CODE>Chunk</CODE>
* and a certain leading.
*
* @param leading the leading
* @param chunk a <CODE>Chunk</CODE>
*/
public Phrase(float leading, Chunk chunk) {
this.leading = leading;
super.add(chunk);
font = chunk.getFont();
setHyphenation(chunk.getHyphenation());
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain <CODE>String</CODE>.
*
* @param string a <CODE>String</CODE>
*/
public Phrase(String string) {
this(Float.NaN, string, new Font());
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain <CODE>String</CODE> and a certain <CODE>Font</CODE>.
*
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Phrase(String string, Font font) {
this(Float.NaN, string, font);
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain leading and a certain <CODE>String</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
*/
public Phrase(float leading, String string) {
this(leading, string, new Font());
}
/**
* Constructs a <CODE>Phrase</CODE> with a certain leading, a certain <CODE>String</CODE>
* and a certain <CODE>Font</CODE>.
*
* @param leading the leading
* @param string a <CODE>String</CODE>
* @param font a <CODE>Font</CODE>
*/
public Phrase(float leading, String string, Font font) {
this.leading = leading;
this.font = font;
/* bugfix by August Detlefsen */
if (string != null && string.length() != 0) {
super.add(new Chunk(string, font));
}
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
for (Iterator i = iterator(); i.hasNext(); ) {
listener.add((Element) i.next());
}
return true;
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return Element.PHRASE;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
for (Iterator i = iterator(); i.hasNext(); ) {
tmp.addAll(((Element) i.next()).getChunks());
}
return tmp;
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
// overriding some of the ArrayList-methods
/**
* Adds a <CODE>Chunk</CODE>, an <CODE>Anchor</CODE> or another <CODE>Phrase</CODE>
* to this <CODE>Phrase</CODE>.
*
* @param index index at which the specified element is to be inserted
* @param o an object of type <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or <CODE>Phrase</CODE>
* @throws ClassCastException when you try to add something that isn't a <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or <CODE>Phrase</CODE>
*/
public void add(int index, Object o) {
if (o == null) return;
try {
Element element = (Element) o;
if (element.type() == Element.CHUNK) {
Chunk chunk = (Chunk) element;
if (!font.isStandardFont()) {
chunk.setFont(font.difference(chunk.getFont()));
}
if (hyphenation != null && chunk.getHyphenation() == null && !chunk.isEmpty()) {
chunk.setHyphenation(hyphenation);
}
super.add(index, chunk);
}
else if (element.type() == Element.PHRASE ||
element.type() == Element.ANCHOR ||
element.type() == Element.ANNOTATION ||
element.type() == Element.TABLE || // line added by David Freels
element.type() == Element.YMARK ||
element.type() == Element.MARKED) {
super.add(index, element);
}
else {
throw new ClassCastException(String.valueOf(element.type()));
}
}
catch(ClassCastException cce) {
throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage());
}
}
/**
* Adds a <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or another <CODE>Phrase</CODE>
* to this <CODE>Phrase</CODE>.
*
* @param o an object of type <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or <CODE>Phrase</CODE>
* @return a boolean
* @throws ClassCastException when you try to add something that isn't a <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or <CODE>Phrase</CODE>
*/
public boolean add(Object o) {
if (o == null) return false;
if (o instanceof String) {
return super.add(new Chunk((String) o, font));
}
if (o instanceof RtfElementInterface) {
return super.add(o);
}
try {
Element element = (Element) o;
switch(element.type()) {
case Element.CHUNK:
return addChunk((Chunk) o);
case Element.PHRASE:
case Element.PARAGRAPH:
Phrase phrase = (Phrase) o;
boolean success = true;
Element e;
for (Iterator i = phrase.iterator(); i.hasNext(); ) {
e = (Element) i.next();
if (e instanceof Chunk) {
success &= addChunk((Chunk)e);
}
else {
success &= this.add(e);
}
}
return success;
case Element.MARKED:
case Element.ANCHOR:
case Element.ANNOTATION:
case Element.TABLE: // case added by David Freels
case Element.PTABLE: // case added by mr. Karen Vardanyan
// This will only work for PDF!!! Not for RTF/HTML
case Element.LIST:
case Element.YMARK:
return super.add(o);
default:
throw new ClassCastException(String.valueOf(element.type()));
}
}
catch(ClassCastException cce) {
throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage());
}
}
/**
* Adds a collection of <CODE>Chunk</CODE>s
* to this <CODE>Phrase</CODE>.
*
* @param collection a collection of <CODE>Chunk</CODE>s, <CODE>Anchor</CODE>s and <CODE>Phrase</CODE>s.
* @return <CODE>true</CODE> if the action succeeded, <CODE>false</CODE> if not.
* @throws ClassCastException when you try to add something that isn't a <CODE>Chunk</CODE>, <CODE>Anchor</CODE> or <CODE>Phrase</CODE>
*/
public boolean addAll(Collection collection) {
for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) {
this.add(iterator.next());
}
return true;
}
/**
* Adds a Chunk.
* <p>
* This method is a hack to solve a problem I had with phrases that were split between chunks
* in the wrong place.
* @param chunk a Chunk to add to the Phrase
* @return true if adding the Chunk succeeded
*/
protected boolean addChunk(Chunk chunk) {
Font f = chunk.getFont();
String c = chunk.getContent();
if (font != null && !font.isStandardFont()) {
f = font.difference(chunk.getFont());
}
if (size() > 0 && !chunk.hasAttributes()) {
try {
Chunk previous = (Chunk) get(size() - 1);
if (!previous.hasAttributes()
&& (f == null
|| f.compareTo(previous.getFont()) == 0)
&& !"".equals(previous.getContent().trim())
&& !"".equals(c.trim())) {
previous.append(c);
return true;
}
}
catch(ClassCastException cce) {
}
}
Chunk newChunk = new Chunk(c, f);
newChunk.setAttributes(chunk.getAttributes());
if (hyphenation != null && newChunk.getHyphenation() == null && !newChunk.isEmpty()) {
newChunk.setHyphenation(hyphenation);
}
return super.add(newChunk);
}
/**
* Adds a <CODE>Object</CODE> to the <CODE>Paragraph</CODE>.
*
* @param object the object to add.
*/
protected void addSpecial(Object object) {
super.add(object);
}
// other methods that change the member variables
/**
* Sets the leading of this phrase.
*
* @param leading the new leading
*/
public void setLeading(float leading) {
this.leading = leading;
}
/**
* Sets the main font of this phrase.
* @param font the new font
*/
public void setFont(Font font) {
this.font = font;
}
// methods to retrieve information
/**
* Gets the leading of this phrase.
*
* @return the linespacing
*/
public float getLeading() {
if (Float.isNaN(leading) && font != null) {
return font.getCalculatedLeading(1.5f);
}
return leading;
}
/**
* Checks you if the leading of this phrase is defined.
*
* @return true if the leading is defined
*/
public boolean hasLeading() {
if (Float.isNaN(leading)) {
return false;
}
return true;
}
/**
* Gets the font of the first <CODE>Chunk</CODE> that appears in this <CODE>Phrase</CODE>.
*
* @return a <CODE>Font</CODE>
*/
public Font getFont() {
return font;
}
/**
* Returns the content as a String object.
* This method differs from toString because toString will return an ArrayList with the toString value of the Chunks in this Phrase.
*/
public String getContent() {
StringBuffer buf = new StringBuffer();
for (Iterator i = getChunks().iterator(); i.hasNext(); ) {
buf.append(i.next().toString());
}
return buf.toString();
}
/**
* Checks is this <CODE>Phrase</CODE> contains no or 1 empty <CODE>Chunk</CODE>.
*
* @return <CODE>false</CODE> if the <CODE>Phrase</CODE>
* contains more than one or more non-empty<CODE>Chunk</CODE>s.
*/
public boolean isEmpty() {
switch(size()) {
case 0:
return true;
case 1:
Element element = (Element) get(0);
if (element.type() == Element.CHUNK && ((Chunk) element).isEmpty()) {
return true;
}
return false;
default:
return false;
}
}
/**
* Getter for the hyphenation settings.
* @return a HyphenationEvent
* @since 2.1.2
*/
public HyphenationEvent getHyphenation() {
return hyphenation;
}
/**
* Setter for the hyphenation.
* @param hyphenation a HyphenationEvent instance
* @since 2.1.2
*/
public void setHyphenation(HyphenationEvent hyphenation) {
this.hyphenation = hyphenation;
}
// kept for historical reasons; people should use FontSelector
// eligible for deprecation, but the methods are mentioned in the book p277.
/**
* Constructs a Phrase that can be used in the static getInstance() method.
* @param dummy a dummy parameter
*/
private Phrase(boolean dummy) {
}
/**
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
* @param string
* @return a newly constructed Phrase
*/
public static final Phrase getInstance(String string) {
return getInstance(16, string, new Font());
}
/**
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
* @param leading
* @param string
* @return a newly constructed Phrase
*/
public static final Phrase getInstance(int leading, String string) {
return getInstance(leading, string, new Font());
}
/**
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
* @param leading
* @param string
* @param font
* @return a newly constructed Phrase
*/
public static final Phrase getInstance(int leading, String string, Font font) {
Phrase p = new Phrase(true);
p.setLeading(leading);
p.font = font;
if (font.getFamily() != Font.SYMBOL && font.getFamily() != Font.ZAPFDINGBATS && font.getBaseFont() == null) {
int index;
while((index = SpecialSymbol.index(string)) > -1) {
if (index > 0) {
String firstPart = string.substring(0, index);
((ArrayList)p).add(new Chunk(firstPart, font));
string = string.substring(index);
}
Font symbol = new Font(Font.SYMBOL, font.getSize(), font.getStyle(), font.getColor());
StringBuffer buf = new StringBuffer();
buf.append(SpecialSymbol.getCorrespondingSymbol(string.charAt(0)));
string = string.substring(1);
while (SpecialSymbol.index(string) == 0) {
buf.append(SpecialSymbol.getCorrespondingSymbol(string.charAt(0)));
string = string.substring(1);
}
((ArrayList)p).add(new Chunk(buf.toString(), symbol));
}
}
if (string != null && string.length() != 0) {
((ArrayList)p).add(new Chunk(string, font));
}
return p;
}
}

876
src/main/java/com/fr/third/lowagie/text/Rectangle.java

@ -0,0 +1,876 @@
/*
* $Id: Rectangle.java 3742 2009-03-03 16:42:09Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
import java.util.ArrayList;
import com.fr.third.lowagie.text.pdf.GrayColor;
/**
* A <CODE>Rectangle</CODE> is the representation of a geometric figure.
*
* Rectangles support constant width borders using
* {@link #setBorderWidth(float)}and {@link #setBorder(int)}.
* They also support borders that vary in width/color on each side using
* methods like {@link #setBorderWidthLeft(float)}or
* {@link #setBorderColorLeft(Color)}.
*
* @see Element
* @see Table
* @see Cell
* @see HeaderFooter
*/
public class Rectangle implements Element {
// CONSTANTS:
/** This is the value that will be used as <VAR>undefined </VAR>. */
public static final int UNDEFINED = -1;
/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
public static final int TOP = 1;
/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
public static final int BOTTOM = 2;
/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
public static final int LEFT = 4;
/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
public static final int RIGHT = 8;
/** This represents a rectangle without borders. */
public static final int NO_BORDER = 0;
/** This represents a type of border. */
public static final int BOX = TOP + BOTTOM + LEFT + RIGHT;
// MEMBER VARIABLES:
/** the lower left x-coordinate. */
protected float llx;
/** the lower left y-coordinate. */
protected float lly;
/** the upper right x-coordinate. */
protected float urx;
/** the upper right y-coordinate. */
protected float ury;
/** The rotation of the Rectangle */
protected int rotation = 0;
/** This is the color of the background of this rectangle. */
protected Color backgroundColor = null;
/** This represents the status of the 4 sides of the rectangle. */
protected int border = UNDEFINED;
/** Whether variable width/color borders are used. */
protected boolean useVariableBorders = false;
/** This is the width of the border around this rectangle. */
protected float borderWidth = UNDEFINED;
/** The width of the left border of this rectangle. */
protected float borderWidthLeft = UNDEFINED;
/** The width of the right border of this rectangle. */
protected float borderWidthRight = UNDEFINED;
/** The width of the top border of this rectangle. */
protected float borderWidthTop = UNDEFINED;
/** The width of the bottom border of this rectangle. */
protected float borderWidthBottom = UNDEFINED;
/** The color of the border of this rectangle. */
protected Color borderColor = null;
/** The color of the left border of this rectangle. */
protected Color borderColorLeft = null;
/** The color of the right border of this rectangle. */
protected Color borderColorRight = null;
/** The color of the top border of this rectangle. */
protected Color borderColorTop = null;
/** The color of the bottom border of this rectangle. */
protected Color borderColorBottom = null;
// CONSTRUCTORS:
/**
* Constructs a <CODE>Rectangle</CODE> -object.
*
* @param llx lower left x
* @param lly lower left y
* @param urx upper right x
* @param ury upper right y
*/
public Rectangle(float llx, float lly, float urx, float ury) {
this.llx = llx;
this.lly = lly;
this.urx = urx;
this.ury = ury;
}
/**
* Constructs a <CODE>Rectangle</CODE> -object starting from the origin
* (0, 0).
*
* @param urx upper right x
* @param ury upper right y
*/
public Rectangle(float urx, float ury) {
this(0, 0, urx, ury);
}
/**
* Constructs a <CODE>Rectangle</CODE> -object.
*
* @param rect another <CODE>Rectangle</CODE>
*/
public Rectangle(Rectangle rect) {
this(rect.llx, rect.lly, rect.urx, rect.ury);
cloneNonPositionParameters(rect);
}
// IMPLEMENTATION OF THE ELEMENT INTERFACE:e
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
}
catch (DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return Element.RECTANGLE;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
return new ArrayList();
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return false;
}
// METHODS TO GET/SET THE DIMENSIONS:
/**
* Sets the lower left x-coordinate.
*
* @param llx the new value
*/
public void setLeft(float llx) {
this.llx = llx;
}
/**
* Returns the lower left x-coordinate.
*
* @return the lower left x-coordinate
*/
public float getLeft() {
return llx;
}
/**
* Returns the lower left x-coordinate, considering a given margin.
*
* @param margin a margin
* @return the lower left x-coordinate
*/
public float getLeft(float margin) {
return llx + margin;
}
/**
* Sets the upper right x-coordinate.
*
* @param urx the new value
*/
public void setRight(float urx) {
this.urx = urx;
}
/**
* Returns the upper right x-coordinate.
*
* @return the upper right x-coordinate
*/
public float getRight() {
return urx;
}
/**
* Returns the upper right x-coordinate, considering a given margin.
*
* @param margin a margin
* @return the upper right x-coordinate
*/
public float getRight(float margin) {
return urx - margin;
}
/**
* Returns the width of the rectangle.
*
* @return the width
*/
public float getWidth() {
return urx - llx;
}
/**
* Sets the upper right y-coordinate.
*
* @param ury the new value
*/
public void setTop(float ury) {
this.ury = ury;
}
/**
* Returns the upper right y-coordinate.
*
* @return the upper right y-coordinate
*/
public float getTop() {
return ury;
}
/**
* Returns the upper right y-coordinate, considering a given margin.
*
* @param margin a margin
* @return the upper right y-coordinate
*/
public float getTop(float margin) {
return ury - margin;
}
/**
* Sets the lower left y-coordinate.
*
* @param lly the new value
*/
public void setBottom(float lly) {
this.lly = lly;
}
/**
* Returns the lower left y-coordinate.
*
* @return the lower left y-coordinate
*/
public float getBottom() {
return lly;
}
/**
* Returns the lower left y-coordinate, considering a given margin.
*
* @param margin a margin
* @return the lower left y-coordinate
*/
public float getBottom(float margin) {
return lly + margin;
}
/**
* Returns the height of the rectangle.
*
* @return the height
*/
public float getHeight() {
return ury - lly;
}
/**
* Normalizes the rectangle.
* Switches lower left with upper right if necessary.
*/
public void normalize() {
if (llx > urx) {
float a = llx;
llx = urx;
urx = a;
}
if (lly > ury) {
float a = lly;
lly = ury;
ury = a;
}
}
// METHODS TO GET/SET THE ROTATION:
/**
* Gets the rotation of the rectangle
*
* @return a rotation value
*/
public int getRotation() {
return rotation;
}
/**
* Rotates the rectangle.
* Swaps the values of llx and lly and of urx and ury.
*
* @return the rotated <CODE>Rectangle</CODE>
*/
public Rectangle rotate() {
Rectangle rect = new Rectangle(lly, llx, ury, urx);
rect.rotation = rotation + 90;
rect.rotation %= 360;
return rect;
}
// METHODS TO GET/SET THE BACKGROUND COLOR:
/**
* Gets the backgroundcolor.
*
* @return a <CODE>Color</CODE>
*/
public Color getBackgroundColor() {
return backgroundColor;
}
/**
* Sets the backgroundcolor of the rectangle.
*
* @param backgroundColor a <CODE>Color</CODE>
*/
public void setBackgroundColor(Color backgroundColor) {
this.backgroundColor = backgroundColor;
}
/**
* Gets the grayscale.
*
* @return the grayscale color of the background
* or 0 if the background has no grayscale color.
*/
public float getGrayFill() {
if (backgroundColor instanceof GrayColor)
return ((GrayColor)backgroundColor).getGray();
return 0;
}
/**
* Sets the the background color to a grayscale value.
*
* @param value the new grayscale value
*/
public void setGrayFill(float value) {
backgroundColor = new GrayColor(value);
}
// METHODS TO GET/SET THE BORDER:
/**
* Returns the exact type of the border.
*
* @return a value
*/
public int getBorder() {
return border;
}
/**
* Indicates whether some type of border is set.
*
* @return a boolean
*/
public boolean hasBorders() {
switch (border) {
case UNDEFINED:
case NO_BORDER:
return false;
default:
return borderWidth > 0 || borderWidthLeft > 0
|| borderWidthRight > 0 || borderWidthTop > 0 || borderWidthBottom > 0;
}
}
/**
* Indicates whether the specified type of border is set.
*
* @param type the type of border
* @return a boolean
*/
public boolean hasBorder(int type) {
if (border == UNDEFINED)
return false;
return (border & type) == type;
}
/**
* Enables/Disables the border on the specified sides.
* The border is specified as an integer bitwise combination of
* the constants: <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>.
*
* @see #enableBorderSide(int)
* @see #disableBorderSide(int)
* @param border the new value
*/
public void setBorder(int border) {
this.border = border;
}
/**
* Indicates whether variable width borders are being used.
* Returns true if <CODE>setBorderWidthLeft, setBorderWidthRight,
* setBorderWidthTop, or setBorderWidthBottom</CODE> has been called.
*
* @return true if variable width borders are in use
*/
public boolean isUseVariableBorders() {
return useVariableBorders;
}
/**
* Sets a parameter indicating if the rectangle has variable borders
*
* @param useVariableBorders indication if the rectangle has variable borders
*/
public void setUseVariableBorders(boolean useVariableBorders) {
this.useVariableBorders = useVariableBorders;
}
/**
* Enables the border on the specified side.
*
* @param side the side to enable.
* One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
*/
public void enableBorderSide(int side) {
if (border == UNDEFINED)
border = 0;
border |= side;
}
/**
* Disables the border on the specified side.
*
* @param side the side to disable.
* One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
*/
public void disableBorderSide(int side) {
if (border == UNDEFINED)
border = 0;
border &= ~side;
}
// METHODS TO GET/SET THE BORDER WIDTH:
/**
* Gets the borderwidth.
*
* @return a value
*/
public float getBorderWidth() {
return borderWidth;
}
/**
* Sets the borderwidth of the table.
*
* @param borderWidth the new value
*/
public void setBorderWidth(float borderWidth) {
this.borderWidth = borderWidth;
}
/**
* Helper function returning the border width of a specific side.
*
* @param variableWidthValue a variable width (could be undefined)
* @param side the border you want to check
* @return the variableWidthValue if not undefined, otherwise the borderWidth
*/
private float getVariableBorderWidth(float variableWidthValue, int side) {
if ((border & side) != 0)
return variableWidthValue != UNDEFINED ? variableWidthValue : borderWidth;
return 0;
}
/**
* Helper function updating the border flag for a side
* based on the specified width.
* A width of 0 will disable the border on that side.
* Any other width enables it.
*
* @param width width of border
* @param side border side constant
*/
private void updateBorderBasedOnWidth(float width, int side) {
useVariableBorders = true;
if (width > 0)
enableBorderSide(side);
else
disableBorderSide(side);
}
/**
* Gets the width of the left border.
*
* @return a width
*/
public float getBorderWidthLeft() {
return getVariableBorderWidth(borderWidthLeft, LEFT);
}
/**
* Sets the width of the left border.
*
* @param borderWidthLeft a width
*/
public void setBorderWidthLeft(float borderWidthLeft) {
this.borderWidthLeft = borderWidthLeft;
updateBorderBasedOnWidth(borderWidthLeft, LEFT);
}
/**
* Gets the width of the right border.
*
* @return a width
*/
public float getBorderWidthRight() {
return getVariableBorderWidth(borderWidthRight, RIGHT);
}
/**
* Sets the width of the right border.
*
* @param borderWidthRight a width
*/
public void setBorderWidthRight(float borderWidthRight) {
this.borderWidthRight = borderWidthRight;
updateBorderBasedOnWidth(borderWidthRight, RIGHT);
}
/**
* Gets the width of the top border.
*
* @return a width
*/
public float getBorderWidthTop() {
return getVariableBorderWidth(borderWidthTop, TOP);
}
/**
* Sets the width of the top border.
*
* @param borderWidthTop a width
*/
public void setBorderWidthTop(float borderWidthTop) {
this.borderWidthTop = borderWidthTop;
updateBorderBasedOnWidth(borderWidthTop, TOP);
}
/**
* Gets the width of the bottom border.
*
* @return a width
*/
public float getBorderWidthBottom() {
return getVariableBorderWidth(borderWidthBottom, BOTTOM);
}
/**
* Sets the width of the bottom border.
*
* @param borderWidthBottom a width
*/
public void setBorderWidthBottom(float borderWidthBottom) {
this.borderWidthBottom = borderWidthBottom;
updateBorderBasedOnWidth(borderWidthBottom, BOTTOM);
}
// METHODS TO GET/SET THE BORDER COLOR:
/**
* Gets the color of the border.
*
* @return a <CODE>Color</CODE>
*/
public Color getBorderColor() {
return borderColor;
}
/**
* Sets the color of the border.
*
* @param borderColor a <CODE>Color</CODE>
*/
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
/**
* Gets the color of the left border.
*
* @return a <CODE>Color</CODE>
*/
public Color getBorderColorLeft() {
if (borderColorLeft == null)
return borderColor;
return borderColorLeft;
}
/**
* Sets the color of the left border.
*
* @param borderColorLeft a <CODE>Color</CODE>
*/
public void setBorderColorLeft(Color borderColorLeft) {
this.borderColorLeft = borderColorLeft;
}
/**
* Gets the color of the right border.
*
* @return a <CODE>Color</CODE>
*/
public Color getBorderColorRight() {
if (borderColorRight == null)
return borderColor;
return borderColorRight;
}
/**
* Sets the color of the right border.
*
* @param borderColorRight a <CODE>Color</CODE>
*/
public void setBorderColorRight(Color borderColorRight) {
this.borderColorRight = borderColorRight;
}
/**
* Gets the color of the top border.
*
* @return a <CODE>Color</CODE>
*/
public Color getBorderColorTop() {
if (borderColorTop == null)
return borderColor;
return borderColorTop;
}
/**
* Sets the color of the top border.
*
* @param borderColorTop a <CODE>Color</CODE>
*/
public void setBorderColorTop(Color borderColorTop) {
this.borderColorTop = borderColorTop;
}
/**
* Gets the color of the bottom border.
*
* @return a <CODE>Color</CODE>
*/
public Color getBorderColorBottom() {
if (borderColorBottom == null)
return borderColor;
return borderColorBottom;
}
/**
* Sets the color of the bottom border.
*
* @param borderColorBottom a <CODE>Color</CODE>
*/
public void setBorderColorBottom(Color borderColorBottom) {
this.borderColorBottom = borderColorBottom;
}
// SPECIAL METHODS:
/**
* Gets a Rectangle that is altered to fit on the page.
*
* @param top the top position
* @param bottom the bottom position
* @return a <CODE>Rectangle</CODE>
*/
public Rectangle rectangle(float top, float bottom) {
Rectangle tmp = new Rectangle(this);
if (getTop() > top) {
tmp.setTop(top);
tmp.disableBorderSide(TOP);
}
if (getBottom() < bottom) {
tmp.setBottom(bottom);
tmp.disableBorderSide(BOTTOM);
}
return tmp;
}
/**
* Copies each of the parameters, except the position, from a
* <CODE>Rectangle</CODE> object
*
* @param rect <CODE>Rectangle</CODE> to copy from
*/
public void cloneNonPositionParameters(Rectangle rect) {
this.rotation = rect.rotation;
this.backgroundColor = rect.backgroundColor;
this.border = rect.border;
this.useVariableBorders = rect.useVariableBorders;
this.borderWidth = rect.borderWidth;
this.borderWidthLeft = rect.borderWidthLeft;
this.borderWidthRight = rect.borderWidthRight;
this.borderWidthTop = rect.borderWidthTop;
this.borderWidthBottom = rect.borderWidthBottom;
this.borderColor = rect.borderColor;
this.borderColorLeft = rect.borderColorLeft;
this.borderColorRight = rect.borderColorRight;
this.borderColorTop = rect.borderColorTop;
this.borderColorBottom = rect.borderColorBottom;
}
/**
* Copies each of the parameters, except the position, from a
* <CODE>Rectangle</CODE> object if the value is set there
*
* @param rect <CODE>Rectangle</CODE> to copy from
*/
public void softCloneNonPositionParameters(Rectangle rect) {
if (rect.rotation != 0)
this.rotation = rect.rotation;
if (rect.backgroundColor != null)
this.backgroundColor = rect.backgroundColor;
if (rect.border != UNDEFINED)
this.border = rect.border;
if (useVariableBorders)
this.useVariableBorders = rect.useVariableBorders;
if (rect.borderWidth != UNDEFINED)
this.borderWidth = rect.borderWidth;
if (rect.borderWidthLeft != UNDEFINED)
this.borderWidthLeft = rect.borderWidthLeft;
if (rect.borderWidthRight != UNDEFINED)
this.borderWidthRight = rect.borderWidthRight;
if (rect.borderWidthTop != UNDEFINED)
this.borderWidthTop = rect.borderWidthTop;
if (rect.borderWidthBottom != UNDEFINED)
this.borderWidthBottom = rect.borderWidthBottom;
if (rect.borderColor != null)
this.borderColor = rect.borderColor;
if (rect.borderColorLeft != null)
this.borderColorLeft = rect.borderColorLeft;
if (rect.borderColorRight != null)
this.borderColorRight = rect.borderColorRight;
if (rect.borderColorTop != null)
this.borderColorTop = rect.borderColorTop;
if (rect.borderColorBottom != null)
this.borderColorBottom = rect.borderColorBottom;
}
/**
* @return a String representation of the rectangle
* @see Object#toString()
*/
public String toString() {
StringBuffer buf = new StringBuffer("Rectangle: ");
buf.append(getWidth());
buf.append('x');
buf.append(getHeight());
buf.append(" (rot: ");
buf.append(rotation);
buf.append(" degrees)");
return buf.toString();
}
}

357
src/main/java/com/fr/third/lowagie/text/RectangleReadOnly.java

@ -0,0 +1,357 @@
/*
* $Id: RectangleReadOnly.java 3746 2009-03-04 10:13:52Z blowagie $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.awt.Color;
/**
* A <CODE>RectangleReadOnly</CODE> is the representation of a geometric figure.
* It's the same as a <CODE>Rectangle</CODE> but immutable.
* Rectangles support constant width borders using
* {@link #setBorderWidth(float)}and {@link #setBorder(int)}.
* They also support borders that vary in width/color on each side using
* methods like {@link #setBorderWidthLeft(float)}or
* {@link #setBorderColorLeft(Color)}.
*
* @see Element
* @see Table
* @see Cell
* @see HeaderFooter
* @since 2.1.2
*/
public class RectangleReadOnly extends Rectangle {
// CONSTRUCTORS
/**
* Constructs a <CODE>RectangleReadOnly</CODE> -object.
*
* @param llx lower left x
* @param lly lower left y
* @param urx upper right x
* @param ury upper right y
*/
public RectangleReadOnly(float llx, float lly, float urx, float ury) {
super(llx, lly, urx, ury);
}
/**
* Constructs a <CODE>RectangleReadOnly</CODE> -object starting from the origin
* (0, 0).
*
* @param urx upper right x
* @param ury upper right y
*/
public RectangleReadOnly(float urx, float ury) {
super(0, 0, urx, ury);
}
/**
* Constructs a <CODE>RectangleReadOnly</CODE> -object.
*
* @param rect another <CODE>Rectangle</CODE>
*/
public RectangleReadOnly(Rectangle rect) {
super(rect.llx, rect.lly, rect.urx, rect.ury);
super.cloneNonPositionParameters(rect);
}
/**
* Throws an error because of the read only nature of this object.
*/
private void throwReadOnlyError() {
throw new UnsupportedOperationException("RectangleReadOnly: this Rectangle is read only.");
}
// OVERWRITE METHODS SETTING THE DIMENSIONS:
/**
* Sets the lower left x-coordinate.
*
* @param llx the new value
*/
public void setLeft(float llx) {
throwReadOnlyError();
}
/**
* Sets the upper right x-coordinate.
*
* @param urx the new value
*/
public void setRight(float urx) {
throwReadOnlyError();
}
/**
* Sets the upper right y-coordinate.
*
* @param ury the new value
*/
public void setTop(float ury) {
throwReadOnlyError();
}
/**
* Sets the lower left y-coordinate.
*
* @param lly the new value
*/
public void setBottom(float lly) {
throwReadOnlyError();
}
/**
* Normalizes the rectangle.
* Switches lower left with upper right if necessary.
*/
public void normalize() {
throwReadOnlyError();
}
// OVERWRITE METHODS SETTING THE BACKGROUND COLOR:
/**
* Sets the backgroundcolor of the rectangle.
*
* @param value the new value
*/
public void setBackgroundColor(Color value) {
throwReadOnlyError();
}
/**
* Sets the grayscale of the rectangle.
*
* @param value the new value
*/
public void setGrayFill(float value) {
throwReadOnlyError();
}
// OVERWRITE METHODS SETTING THE BORDER:
/**
* Enables/Disables the border on the specified sides.
* The border is specified as an integer bitwise combination of
* the constants: <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>.
*
* @see #enableBorderSide(int)
* @see #disableBorderSide(int)
* @param border the new value
*/
public void setBorder(int border) {
throwReadOnlyError();
}
/**
* Sets a parameter indicating if the rectangle has variable borders
*
* @param useVariableBorders indication if the rectangle has variable borders
*/
public void setUseVariableBorders(boolean useVariableBorders) {
throwReadOnlyError();
}
/**
* Enables the border on the specified side.
*
* @param side the side to enable.
* One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
*/
public void enableBorderSide(int side) {
throwReadOnlyError();
}
/**
* Disables the border on the specified side.
*
* @param side the side to disable.
* One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
*/
public void disableBorderSide(int side) {
throwReadOnlyError();
}
// OVERWRITE METHODS SETTING THE BORDER WIDTH:
/**
* Sets the borderwidth of the table.
*
* @param borderWidth the new value
*/
public void setBorderWidth(float borderWidth) {
throwReadOnlyError();
}
/**
* Sets the width of the left border
*
* @param borderWidthLeft a width
*/
public void setBorderWidthLeft(float borderWidthLeft) {
throwReadOnlyError();
}
/**
* Sets the width of the right border
*
* @param borderWidthRight a width
*/
public void setBorderWidthRight(float borderWidthRight) {
throwReadOnlyError();
}
/**
* Sets the width of the top border
*
* @param borderWidthTop a width
*/
public void setBorderWidthTop(float borderWidthTop) {
throwReadOnlyError();
}
/**
* Sets the width of the bottom border
*
* @param borderWidthBottom a width
*/
public void setBorderWidthBottom(float borderWidthBottom) {
throwReadOnlyError();
}
// METHODS TO GET/SET THE BORDER COLOR:
/**
* Sets the color of the border.
*
* @param borderColor a <CODE>Color</CODE>
*/
public void setBorderColor(Color borderColor) {
throwReadOnlyError();
}
/**
* Sets the color of the left border.
*
* @param borderColorLeft a <CODE>Color</CODE>
*/
public void setBorderColorLeft(Color borderColorLeft) {
throwReadOnlyError();
}
/**
* Sets the color of the right border
*
* @param borderColorRight a <CODE>Color</CODE>
*/
public void setBorderColorRight(Color borderColorRight) {
throwReadOnlyError();
}
/**
* Sets the color of the top border.
*
* @param borderColorTop a <CODE>Color</CODE>
*/
public void setBorderColorTop(Color borderColorTop) {
throwReadOnlyError();
}
/**
* Sets the color of the bottom border.
*
* @param borderColorBottom a <CODE>Color</CODE>
*/
public void setBorderColorBottom(Color borderColorBottom) {
throwReadOnlyError();
}
// SPECIAL METHODS:
/**
* Copies each of the parameters, except the position, from a
* <CODE>Rectangle</CODE> object
*
* @param rect <CODE>Rectangle</CODE> to copy from
*/
public void cloneNonPositionParameters(Rectangle rect) {
throwReadOnlyError();
}
/**
* Copies each of the parameters, except the position, from a
* <CODE>Rectangle</CODE> object if the value is set there.
*
* @param rect <CODE>Rectangle</CODE> to copy from
*/
public void softCloneNonPositionParameters(Rectangle rect) {
throwReadOnlyError();
}
/**
* @return String version of the most important rectangle properties
* @see Object#toString()
*/
public String toString() {
StringBuffer buf = new StringBuffer("RectangleReadOnly: ");
buf.append(getWidth());
buf.append('x');
buf.append(getHeight());
buf.append(" (rot: ");
buf.append(rotation);
buf.append(" degrees)");
return buf.toString();
}
}

118
src/main/java/com/fr/third/lowagie/text/RomanList.java

@ -0,0 +1,118 @@
/*
* Copyright 2003 by Michael Niedermair and 2007 Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import com.fr.third.lowagie.text.factories.RomanNumberFactory;
/**
*
* A special-version of <CODE>LIST</CODE> which use roman-letters.
*
* @see List
*/
public class RomanList extends List {
// constructors
/**
* Initialization
*/
public RomanList() {
super(true);
}
/**
* Initialization
*
* @param symbolIndent indent
*/
public RomanList(int symbolIndent) {
super(true, symbolIndent);
}
/**
* Initialization
* @param lowercase roman-char in lowercase
* @param symbolIndent indent
*/
public RomanList(boolean lowercase, int symbolIndent) {
super(true, symbolIndent);
this.lowercase = lowercase;
}
// overridden method
/**
* Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
*
* @param o the object to add.
* @return true if adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof ListItem) {
ListItem item = (ListItem) o;
Chunk chunk;
chunk = new Chunk(preSymbol, symbol.getFont());
chunk.append(RomanNumberFactory.getString(first + list.size(), lowercase));
chunk.append(postSymbol);
item.setListSymbol(chunk);
item.setIndentationLeft(symbolIndent, autoindent);
item.setIndentationRight(0);
list.add(item);
} else if (o instanceof List) {
List nested = (List) o;
nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
first--;
return list.add(nested);
} else if (o instanceof String) {
return this.add(new ListItem((String) o));
}
return false;
}
}

381
src/main/java/com/fr/third/lowagie/text/Row.java

@ -0,0 +1,381 @@
/*
* $Id: Row.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
/**
* A <CODE>Row</CODE> is part of a <CODE>Table</CODE>
* and contains some <CODE>Cells</CODE>.
* <P>
* All <CODE>Row</CODE>s are constructed by a <CODE>Table</CODE>-object.
* You don't have to construct any <CODE>Row</CODE> yourself.
* In fact you can't construct a <CODE>Row</CODE> outside the package.
* <P>
* Since a <CODE>Cell</CODE> can span several rows and/or columns
* a row can contain reserved space without any content.
*
* @see Element
* @see Cell
* @see Table
*/
public class Row implements Element {
// constants
/** id of a null element in a Row*/
public static final int NULL = 0;
/** id of the Cell element in a Row*/
public static final int CELL = 1;
/** id of the Table element in a Row*/
public static final int TABLE = 2;
// member variables
/** This is the number of columns in the <CODE>Row</CODE>. */
protected int columns;
/** This is a valid position the <CODE>Row</CODE>. */
protected int currentColumn;
/** This is the array that keeps track of reserved cells. */
protected boolean[] reserved;
/** This is the array of Objects (<CODE>Cell</CODE> or <CODE>Table</CODE>). */
protected Object[] cells;
/** This is the vertical alignment. */
protected int horizontalAlignment;
// constructors
/**
* Constructs a <CODE>Row</CODE> with a certain number of <VAR>columns</VAR>.
*
* @param columns a number of columns
*/
protected Row(int columns) {
this.columns = columns;
reserved = new boolean[columns];
cells = new Object[columns];
currentColumn = 0;
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to a
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
return listener.add(this);
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return ROW;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
return new ArrayList();
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return false;
}
// method to delete a column
/**
* Returns a <CODE>Row</CODE> that is a copy of this <CODE>Row</CODE>
* in which a certain column has been deleted.
*
* @param column the number of the column to delete
*/
void deleteColumn(int column) {
if ((column >= columns) || (column < 0)) {
throw new IndexOutOfBoundsException("getCell at illegal index : " + column);
}
columns--;
boolean newReserved[] = new boolean[columns];
Object newCells[] = new Cell[columns];
for (int i = 0; i < column; i++) {
newReserved[i] = reserved[i];
newCells[i] = cells[i];
if (newCells[i] != null && (i + ((Cell) newCells[i]).getColspan() > column)) {
((Cell) newCells[i]).setColspan(((Cell) cells[i]).getColspan() - 1);
}
}
for (int i = column; i < columns; i++) {
newReserved[i] = reserved[i + 1];
newCells[i] = cells[i + 1];
}
if (cells[column] != null && ((Cell) cells[column]).getColspan() > 1) {
newCells[column] = cells[column];
((Cell) newCells[column]).setColspan(((Cell) newCells[column]).getColspan() - 1);
}
reserved = newReserved;
cells = newCells;
}
// methods
/**
* Adds a <CODE>Cell</CODE> to the <CODE>Row</CODE>.
*
* @param element the element to add (currently only Cells and Tables supported)
* @return the column position the <CODE>Cell</CODE> was added,
* or <CODE>-1</CODE> if the <CODE>element</CODE> couldn't be added.
*/
int addElement(Object element) {
return addElement(element, currentColumn);
}
/**
* Adds an element to the <CODE>Row</CODE> at the position given.
*
* @param element the element to add. (currently only Cells and Tables supported
* @param column the position where to add the cell.
* @return the column position the <CODE>Cell</CODE> was added,
* or <CODE>-1</CODE> if the <CODE>Cell</CODE> couldn't be added.
*/
int addElement(Object element, int column) {
if (element == null) throw new NullPointerException("addCell - null argument");
if ((column < 0) || (column > columns)) throw new IndexOutOfBoundsException("addCell - illegal column argument");
if ( !((getObjectID(element) == CELL) || (getObjectID(element) == TABLE)) ) throw new IllegalArgumentException("addCell - only Cells or Tables allowed");
int lColspan = ( (Cell.class.isInstance(element)) ? ((Cell) element).getColspan() : 1);
if (!reserve(column, lColspan)) {
return -1;
}
cells[column] = element;
currentColumn += lColspan - 1;
return column;
}
/**
* Puts <CODE>Cell</CODE> to the <CODE>Row</CODE> at the position given, doesn't reserve colspan.
*
* @param aElement the cell to add.
* @param column the position where to add the cell.
*/
void setElement(Object aElement, int column) {
if (reserved[column]) throw new IllegalArgumentException("setElement - position already taken");
cells[column] = aElement;
if (aElement != null) {
reserved[column] = true;
}
}
/**
* Reserves a <CODE>Cell</CODE> in the <CODE>Row</CODE>.
*
* @param column the column that has to be reserved.
* @return <CODE>true</CODE> if the column was reserved, <CODE>false</CODE> if not.
*/
boolean reserve(int column) {
return reserve(column, 1);
}
/**
* Reserves a <CODE>Cell</CODE> in the <CODE>Row</CODE>.
*
* @param column the column that has to be reserved.
* @param size the number of columns
* @return <CODE>true</CODE> if the column was reserved, <CODE>false</CODE> if not.
*/
boolean reserve(int column, int size) {
if ((column < 0) || ((column + size) > columns)) throw new IndexOutOfBoundsException("reserve - incorrect column/size");
for(int i=column; i < column + size; i++)
{
if (reserved[i]) {
// undo reserve
for(int j=i; j >= column; j--) {
reserved[j] = false;
}
return false;
}
reserved[i] = true;
}
return true;
}
// methods to retrieve information
/**
* Returns true/false when this position in the <CODE>Row</CODE> has been reserved, either filled or through a colspan of an Element.
*
* @param column the column.
* @return <CODE>true</CODE> if the column was reserved, <CODE>false</CODE> if not.
*/
boolean isReserved(int column) {
return reserved[column];
}
/**
* Returns the type-id of the element in a Row.
*
* @param column the column of which you'd like to know the type
* @return the type-id of the element in the row
*/
int getElementID(int column) {
if (cells[column] == null) return NULL;
else if (Cell.class.isInstance(cells[column])) return CELL;
else if (Table.class.isInstance(cells[column])) return TABLE;
return -1;
}
/**
* Returns the type-id of an Object.
*
* @param element the object of which you'd like to know the type-id, -1 if invalid
* @return the type-id of an object
*/
int getObjectID(Object element) {
if (element == null) return NULL;
else if (Cell.class.isInstance(element)) return CELL;
else if (Table.class.isInstance(element)) return TABLE;
return -1;
}
/**
* Gets a <CODE>Cell</CODE> or <CODE>Table</CODE> from a certain column.
*
* @param column the column the <CODE>Cell/Table</CODE> is in.
* @return the <CODE>Cell</CODE>,<CODE>Table</CODE> or <VAR>Object</VAR> if the column was
* reserved or null if empty.
*/
public Object getCell(int column) {
if ((column < 0) || (column > columns)) {
throw new IndexOutOfBoundsException("getCell at illegal index :" + column + " max is " + columns);
}
return cells[column];
}
/**
* Checks if the row is empty.
*
* @return <CODE>true</CODE> if none of the columns is reserved.
*/
public boolean isEmpty() {
for (int i = 0; i < columns; i++) {
if (cells[i] != null) {
return false;
}
}
return true;
}
/**
* Gets the number of columns.
*
* @return a value
*/
public int getColumns() {
return columns;
}
/**
* Sets the horizontal alignment.
*
* @param value the new value
*/
public void setHorizontalAlignment(int value) {
horizontalAlignment = value;
}
/**
* Gets the horizontal alignment.
*
* @return a value
*/
public int getHorizontalAlignment() {
return horizontalAlignment;
}
}

60
src/main/java/com/fr/third/lowagie/text/RtfElementInterface.java

@ -0,0 +1,60 @@
/*
* $Id: RtfElementInterface.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2008 by Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* The RTF jar depends on the iText jar, but the iText jar may not
* depend on the RTF jar. This interface offers a temporary solution
* until we find a more elegant way to solve this.
* @since 2.1.0
*/
public interface RtfElementInterface {
}

18
src/main/java/com/fr/third/lowagie/text/SafeEmptyEntityResolver.java

@ -0,0 +1,18 @@
package com.fr.third.lowagie.text;
import java.io.IOException;
import java.io.StringReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2021/4/26
*/
public class SafeEmptyEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
return new InputSource(new StringReader(""));
}
}

756
src/main/java/com/fr/third/lowagie/text/Section.java

@ -0,0 +1,756 @@
/*
* $Id: Section.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* A <CODE>Section</CODE> is a part of a <CODE>Document</CODE> containing
* other <CODE>Section</CODE>s, <CODE>Paragraph</CODE>s, <CODE>List</CODE>
* and/or <CODE>Table</CODE>s.
* <P>
* Remark: you can not construct a <CODE>Section</CODE> yourself.
* You will have to ask an instance of <CODE>Section</CODE> to the
* <CODE>Chapter</CODE> or <CODE>Section</CODE> to which you want to
* add the new <CODE>Section</CODE>.
* <P>
* Example:
* <BLOCKQUOTE><PRE>
* Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
* Chapter chapter2 = new Chapter(title2, 2);
* Paragraph someText = new Paragraph("This is some text");
* chapter2.add(someText);
* Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
* <STRONG>Section section1 = chapter2.addSection(title21);</STRONG>
* Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
* <STRONG>section1.add(someSectionText);</STRONG>
* Paragraph title211 = new Paragraph("This is SubSection 1 in Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 14, Font.BOLD, new Color(255, 0, 0)));
* <STRONG>Section section11 = section1.addSection(40, title211, 2);</STRONG>
* <STRONG>section11.add(someSectionText);</STRONG>
* </PRE></BLOCKQUOTE>
*/
public class Section extends ArrayList implements TextElementArray, LargeElement {
// constant
/**
* A possible number style. The default number style: "1.2.3."
* @since iText 2.0.8
*/
public static final int NUMBERSTYLE_DOTTED = 0;
/**
* A possible number style. For instance: "1.2.3"
* @since iText 2.0.8
*/
public static final int NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT = 1;
/** A serial version uid. */
private static final long serialVersionUID = 3324172577544748043L;
// member variables
/** The title of this section. */
protected Paragraph title;
/** The bookmark title if different from the content title */
protected String bookmarkTitle;
/** The number of sectionnumbers that has to be shown before the section title. */
protected int numberDepth;
/**
* The style for sectionnumbers.
* @since iText 2.0.8
*/
protected int numberStyle = NUMBERSTYLE_DOTTED;
/** The indentation of this section on the left side. */
protected float indentationLeft;
/** The indentation of this section on the right side. */
protected float indentationRight;
/** The additional indentation of the content of this section. */
protected float indentation;
/** false if the bookmark children are not visible */
protected boolean bookmarkOpen = true;
/** true if the section has to trigger a new page */
protected boolean triggerNewPage = false;
/** This is the number of subsections. */
protected int subsections = 0;
/** This is the complete list of sectionnumbers of this section and the parents of this section. */
protected ArrayList numbers = null;
/**
* Indicates if the Section will be complete once added to the document.
* @since iText 2.0.8
*/
protected boolean complete = true;
/**
* Indicates if the Section was added completely to the document.
* @since iText 2.0.8
*/
protected boolean addedCompletely = false;
/**
* Indicates if this is the first time the section was added.
* @since iText 2.0.8
*/
protected boolean notAddedYet = true;
// constructors
/**
* Constructs a new <CODE>Section</CODE>.
*/
protected Section() {
title = new Paragraph();
numberDepth = 1;
}
/**
* Constructs a new <CODE>Section</CODE>.
*
* @param title a <CODE>Paragraph</CODE>
* @param numberDepth the numberDepth
*/
protected Section(Paragraph title, int numberDepth) {
this.numberDepth = numberDepth;
this.title = title;
}
// implementation of the Element-methods
/**
* Processes the element by adding it (or the different parts) to an
* <CODE>ElementListener</CODE>.
*
* @param listener the <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> if the element was processed successfully
*/
public boolean process(ElementListener listener) {
try {
Element element;
for (Iterator i = iterator(); i.hasNext(); ) {
element = (Element)i.next();
listener.add(element);
}
return true;
}
catch(DocumentException de) {
return false;
}
}
/**
* Gets the type of the text element.
*
* @return a type
*/
public int type() {
return SECTION;
}
/**
* Checks if this object is a <CODE>Chapter</CODE>.
*
* @return <CODE>true</CODE> if it is a <CODE>Chapter</CODE>,
* <CODE>false</CODE> if it is a <CODE>Section</CODE>.
*/
public boolean isChapter() {
return type() == CHAPTER;
}
/**
* Checks if this object is a <CODE>Section</CODE>.
*
* @return <CODE>true</CODE> if it is a <CODE>Section</CODE>,
* <CODE>false</CODE> if it is a <CODE>Chapter</CODE>.
*/
public boolean isSection() {
return type() == SECTION;
}
/**
* Gets all the chunks in this element.
*
* @return an <CODE>ArrayList</CODE>
*/
public ArrayList getChunks() {
ArrayList tmp = new ArrayList();
for (Iterator i = iterator(); i.hasNext(); ) {
tmp.addAll(((Element) i.next()).getChunks());
}
return tmp;
}
/**
* @see Element#isContent()
* @since iText 2.0.8
*/
public boolean isContent() {
return true;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return false;
}
// overriding some of the ArrayList-methods
/**
* Adds a <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>
* to this <CODE>Section</CODE>.
*
* @param index index at which the specified element is to be inserted
* @param o an object of type <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>=
* @throws ClassCastException if the object is not a <CODE>Paragraph</CODE>, <CODE>List</CODE> or <CODE>Table</CODE>
*/
public void add(int index, Object o) {
if (isAddedCompletely()) {
throw new IllegalStateException("This LargeElement has already been added to the Document.");
}
try {
Element element = (Element) o;
if (element.isNestable()) {
super.add(index, element);
}
else {
throw new ClassCastException("You can't add a " + element.getClass().getName() + " to a Section.");
}
}
catch(ClassCastException cce) {
throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage());
}
}
/**
* Adds a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or another <CODE>Section</CODE>
* to this <CODE>Section</CODE>.
*
* @param o an object of type <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or another <CODE>Section</CODE>
* @return a boolean
* @throws ClassCastException if the object is not a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE> or <CODE>Section</CODE>
*/
public boolean add(Object o) {
if (isAddedCompletely()) {
throw new IllegalStateException("This LargeElement has already been added to the Document.");
}
try {
Element element = (Element) o;
if (element.type() == SECTION) {
Section section = (Section) o;
section.setNumbers(++subsections, numbers);
return super.add(section);
}
else if (o instanceof MarkedSection && ((MarkedObject)o).element.type() == SECTION) {
MarkedSection mo = (MarkedSection)o;
Section section = (Section)mo.element;
section.setNumbers(++subsections, numbers);
return super.add(mo);
}
else if (element.isNestable()) {
return super.add(o);
}
else {
throw new ClassCastException("You can't add a " + element.getClass().getName() + " to a Section.");
}
}
catch(ClassCastException cce) {
throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage());
}
}
/**
* Adds a collection of <CODE>Element</CODE>s
* to this <CODE>Section</CODE>.
*
* @param collection a collection of <CODE>Paragraph</CODE>s, <CODE>List</CODE>s and/or <CODE>Table</CODE>s
* @return <CODE>true</CODE> if the action succeeded, <CODE>false</CODE> if not.
* @throws ClassCastException if one of the objects isn't a <CODE>Paragraph</CODE>, <CODE>List</CODE>, <CODE>Table</CODE>
*/
public boolean addAll(Collection collection) {
for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) {
this.add(iterator.next());
}
return true;
}
// methods that return a Section
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @param title the title of the new section
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public Section addSection(float indentation, Paragraph title, int numberDepth) {
if (isAddedCompletely()) {
throw new IllegalStateException("This LargeElement has already been added to the Document.");
}
Section section = new Section(title, numberDepth);
section.setIndentation(indentation);
add(section);
return section;
}
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @param title the title of the new section
* @return a new Section object
*/
public Section addSection(float indentation, Paragraph title) {
return addSection(indentation, title, numberDepth + 1);
}
/**
* Creates a <CODE>Section</CODE>, add it to this <CODE>Section</CODE> and returns it.
*
* @param title the title of the new section
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public Section addSection(Paragraph title, int numberDepth) {
return addSection(0, title, numberDepth);
}
/**
* Adds a marked section. For use in class MarkedSection only!
*/
public MarkedSection addMarkedSection() {
MarkedSection section = new MarkedSection(new Section(null, numberDepth + 1));
add(section);
return section;
}
/**
* Creates a <CODE>Section</CODE>, adds it to this <CODE>Section</CODE> and returns it.
*
* @param title the title of the new section
* @return a new Section object
*/
public Section addSection(Paragraph title) {
return addSection(0, title, numberDepth + 1);
}
/**
* Adds a <CODE>Section</CODE> to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @param title the title of the new section
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public Section addSection(float indentation, String title, int numberDepth) {
return addSection(indentation, new Paragraph(title), numberDepth);
}
/**
* Adds a <CODE>Section</CODE> to this <CODE>Section</CODE> and returns it.
*
* @param title the title of the new section
* @param numberDepth the numberDepth of the section
* @return a new Section object
*/
public Section addSection(String title, int numberDepth) {
return addSection(new Paragraph(title), numberDepth);
}
/**
* Adds a <CODE>Section</CODE> to this <CODE>Section</CODE> and returns it.
*
* @param indentation the indentation of the new section
* @param title the title of the new section
* @return a new Section object
*/
public Section addSection(float indentation, String title) {
return addSection(indentation, new Paragraph(title));
}
/**
* Adds a <CODE>Section</CODE> to this <CODE>Section</CODE> and returns it.
*
* @param title the title of the new section
* @return a new Section object
*/
public Section addSection(String title) {
return addSection(new Paragraph(title));
}
// public methods
/**
* Sets the title of this section.
*
* @param title the new title
*/
public void setTitle(Paragraph title) {
this.title = title;
}
/**
* Returns the title, preceded by a certain number of sectionnumbers.
*
* @return a <CODE>Paragraph</CODE>
*/
public Paragraph getTitle() {
return constructTitle(title, numbers, numberDepth, numberStyle);
}
/**
* Constructs a Paragraph that will be used as title for a Section or Chapter.
* @param title the title of the section
* @param numbers a list of sectionnumbers
* @param numberDepth how many numbers have to be shown
* @param numberStyle the numbering style
* @return a Paragraph object
* @since iText 2.0.8
*/
public static Paragraph constructTitle(Paragraph title, ArrayList numbers, int numberDepth, int numberStyle) {
if (title == null) {
return null;
}
int depth = Math.min(numbers.size(), numberDepth);
if (depth < 1) {
return title;
}
StringBuffer buf = new StringBuffer(" ");
for (int i = 0; i < depth; i++) {
buf.insert(0, ".");
buf.insert(0, ((Integer) numbers.get(i)).intValue());
}
if (numberStyle == NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT) {
buf.deleteCharAt(buf.length() - 2);
}
Paragraph result = new Paragraph(title);
result.add(0, new Chunk(buf.toString(), title.getFont()));
return result;
}
/**
* Sets the depth of the sectionnumbers that will be shown preceding the title.
* <P>
* If the numberdepth is 0, the sections will not be numbered. If the numberdepth
* is 1, the section will be numbered with their own number. If the numberdepth is
* higher (for instance x > 1), the numbers of x - 1 parents will be shown.
*
* @param numberDepth the new numberDepth
*/
public void setNumberDepth(int numberDepth) {
this.numberDepth = numberDepth;
}
/**
* Returns the numberdepth of this <CODE>Section</CODE>.
*
* @return the numberdepth
*/
public int getNumberDepth() {
return numberDepth;
}
/**
* Sets the style for numbering sections.
* Possible values are NUMBERSTYLE_DOTTED: 1.2.3. (the default)
* or NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT: 1.2.3
* @since iText 2.0.8
*/
public void setNumberStyle(int numberStyle) {
this.numberStyle = numberStyle;
}
/**
* Gets the style used for numbering sections.
* @since iText 2.0.8
* @return a value corresponding with a numbering style
*/
public int getNumberStyle() {
return numberStyle;
}
/**
* Sets the indentation of this <CODE>Section</CODE> on the left side.
*
* @param indentation the indentation
*/
public void setIndentationLeft(float indentation) {
indentationLeft = indentation;
}
/**
* Returns the indentation of this <CODE>Section</CODE> on the left side.
*
* @return the indentation
*/
public float getIndentationLeft() {
return indentationLeft;
}
/**
* Sets the indentation of this <CODE>Section</CODE> on the right side.
*
* @param indentation the indentation
*/
public void setIndentationRight(float indentation) {
indentationRight = indentation;
}
/**
* Returns the indentation of this <CODE>Section</CODE> on the right side.
*
* @return the indentation
*/
public float getIndentationRight() {
return indentationRight;
}
/**
* Sets the indentation of the content of this <CODE>Section</CODE>.
*
* @param indentation the indentation
*/
public void setIndentation(float indentation) {
this.indentation = indentation;
}
/**
* Returns the indentation of the content of this <CODE>Section</CODE>.
*
* @return the indentation
*/
public float getIndentation() {
return indentation;
}
/** Setter for property bookmarkOpen.
* @param bookmarkOpen false if the bookmark children are not
* visible.
*/
public void setBookmarkOpen(boolean bookmarkOpen) {
this.bookmarkOpen = bookmarkOpen;
}
/**
* Getter for property bookmarkOpen.
* @return Value of property bookmarkOpen.
*/
public boolean isBookmarkOpen() {
return bookmarkOpen;
}
/**
* Setter for property triggerNewPage.
* @param triggerNewPage true if a new page has to be triggered.
*/
public void setTriggerNewPage(boolean triggerNewPage) {
this.triggerNewPage = triggerNewPage;
}
/**
* Getter for property bookmarkOpen.
* @return Value of property triggerNewPage.
*/
public boolean isTriggerNewPage() {
return triggerNewPage && notAddedYet;
}
/**
* Sets the bookmark title. The bookmark title is the same as the section title but
* can be changed with this method.
* @param bookmarkTitle the bookmark title
*/
public void setBookmarkTitle(String bookmarkTitle) {
this.bookmarkTitle = bookmarkTitle;
}
/**
* Gets the bookmark title.
* @return the bookmark title
*/
public Paragraph getBookmarkTitle() {
if (bookmarkTitle == null)
return getTitle();
else
return new Paragraph(bookmarkTitle);
}
/**
* Changes the Chapter number.
*/
public void setChapterNumber(int number) {
numbers.set(numbers.size() - 1, new Integer(number));
Object s;
for (Iterator i = iterator(); i.hasNext(); ) {
s = i.next();
if (s instanceof Section) {
((Section)s).setChapterNumber(number);
}
}
}
/**
* Returns the depth of this section.
*
* @return the depth
*/
public int getDepth() {
return numbers.size();
}
// private methods
/**
* Sets the number of this section.
*
* @param number the number of this section
* @param numbers an <CODE>ArrayList</CODE>, containing the numbers of the Parent
*/
private void setNumbers(int number, ArrayList numbers) {
this.numbers = new ArrayList();
this.numbers.add(new Integer(number));
this.numbers.addAll(numbers);
}
/**
* Indicates if this is the first time the section is added.
* @since iText2.0.8
* @return true if the section wasn't added yet
*/
public boolean isNotAddedYet() {
return notAddedYet;
}
/**
* Sets the indication if the section was already added to
* the document.
* @since iText2.0.8
* @param notAddedYet
*/
public void setNotAddedYet(boolean notAddedYet) {
this.notAddedYet = notAddedYet;
}
/**
* @since iText 2.0.8
*/
protected boolean isAddedCompletely() {
return addedCompletely;
}
/**
* @since iText 2.0.8
*/
protected void setAddedCompletely(boolean addedCompletely) {
this.addedCompletely = addedCompletely;
}
/**
* @since iText 2.0.8
* @see LargeElement#flushContent()
*/
public void flushContent() {
setNotAddedYet(false);
title = null;
Element element;
for (Iterator i = iterator(); i.hasNext(); ) {
element = (Element)i.next();
if (element instanceof Section) {
Section s = (Section)element;
if (!s.isComplete() && size() == 1) {
s.flushContent();
return;
}
else {
s.setAddedCompletely(true);
}
}
i.remove();
}
}
/**
* @since iText 2.0.8
* @see LargeElement#isComplete()
*/
public boolean isComplete() {
return complete;
}
/**
* @since iText 2.0.8
* @see LargeElement#setComplete(boolean)
*/
public void setComplete(boolean complete) {
this.complete = complete;
}
/**
* Adds a new page to the section.
* @since 2.1.1
*/
public void newPage() {
this.add(Chunk.NEXTPAGE);
}
}

533
src/main/java/com/fr/third/lowagie/text/SimpleCell.java

@ -0,0 +1,533 @@
/*
* $Id: SimpleCell.java 3752 2009-03-04 18:02:40Z blowagie $
*
* Copyright 2005 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Iterator;
import com.fr.third.lowagie.text.pdf.PdfContentByte;
import com.fr.third.lowagie.text.pdf.PdfPCell;
import com.fr.third.lowagie.text.pdf.PdfPCellEvent;
import com.fr.third.lowagie.text.pdf.PdfPTable;
/**
* Rectangle that can be used for Cells.
* This Rectangle is padded and knows how to draw itself in a PdfPTable or PdfPcellEvent.
*/
public class SimpleCell extends Rectangle implements PdfPCellEvent, TextElementArray {
// constants
/** the CellAttributes object represents a row. */
public static final boolean ROW = true;
/** the CellAttributes object represents a cell. */
public static final boolean CELL = false;
// member variables
/** the content of the Cell. */
private ArrayList content = new ArrayList();
/** the width of the Cell. */
private float width = 0f;
/** the widthpercentage of the Cell. */
private float widthpercentage = 0f;
/** an extra spacing variable */
private float spacing_left = Float.NaN;
/** an extra spacing variable */
private float spacing_right = Float.NaN;
/** an extra spacing variable */
private float spacing_top = Float.NaN;
/** an extra spacing variable */
private float spacing_bottom = Float.NaN;
/** an extra padding variable */
private float padding_left = Float.NaN;
/** an extra padding variable */
private float padding_right = Float.NaN;
/** an extra padding variable */
private float padding_top = Float.NaN;
/** an extra padding variable */
private float padding_bottom = Float.NaN;
/** the colspan of a Cell */
private int colspan = 1;
/** horizontal alignment inside the Cell. */
private int horizontalAlignment = ALIGN_UNDEFINED;
/** vertical alignment inside the Cell. */
private int verticalAlignment = ALIGN_UNDEFINED;
/** indicates if these are the attributes of a single Cell (false) or a group of Cells (true). */
private boolean cellgroup = false;
/** Indicates that the largest ascender height should be used to determine the
* height of the first line. Note that this only has an effect when rendered
* to PDF. Setting this to true can help with vertical alignment problems. */
protected boolean useAscender = false;
/** Indicates that the largest descender height should be added to the height of
* the last line (so characters like y don't dip into the border). Note that
* this only has an effect when rendered to PDF. */
protected boolean useDescender = false;
/**
* Adjusts the cell contents to compensate for border widths. Note that
* this only has an effect when rendered to PDF.
*/
protected boolean useBorderPadding;
/**
* A CellAttributes object is always constructed without any dimensions.
* Dimensions are defined after creation.
* @param row only true if the CellAttributes object represents a row.
*/
public SimpleCell(boolean row) {
super(0f, 0f, 0f, 0f);
cellgroup = row;
setBorder(BOX);
}
/**
* Adds content to this object.
* @param element
* @throws BadElementException
*/
public void addElement(Element element) throws BadElementException {
if (cellgroup) {
if (element instanceof SimpleCell) {
if(((SimpleCell)element).isCellgroup()) {
throw new BadElementException("You can't add one row to another row.");
}
content.add(element);
return;
}
else {
throw new BadElementException("You can only add cells to rows, no objects of type " + element.getClass().getName());
}
}
if (element.type() == PARAGRAPH
|| element.type() == PHRASE
|| element.type() == ANCHOR
|| element.type() == CHUNK
|| element.type() == LIST
|| element.type() == MARKED
|| element.type() == JPEG
|| element.type() == JPEG2000
|| element.type() == JBIG2
|| element.type() == IMGRAW
|| element.type() == IMGTEMPLATE) {
content.add(element);
}
else {
throw new BadElementException("You can't add an element of type " + element.getClass().getName() + " to a SimpleCell.");
}
}
/**
* Creates a Cell with these attributes.
* @param rowAttributes
* @return a cell based on these attributes.
* @throws BadElementException
*/
public Cell createCell(SimpleCell rowAttributes) throws BadElementException {
Cell cell = new Cell();
cell.cloneNonPositionParameters(rowAttributes);
cell.softCloneNonPositionParameters(this);
cell.setColspan(colspan);
cell.setHorizontalAlignment(horizontalAlignment);
cell.setVerticalAlignment(verticalAlignment);
cell.setUseAscender(useAscender);
cell.setUseBorderPadding(useBorderPadding);
cell.setUseDescender(useDescender);
Element element;
for (Iterator i = content.iterator(); i.hasNext(); ) {
element = (Element)i.next();
cell.addElement(element);
}
return cell;
}
/**
* Creates a PdfPCell with these attributes.
* @param rowAttributes
* @return a PdfPCell based on these attributes.
*/
public PdfPCell createPdfPCell(SimpleCell rowAttributes) {
PdfPCell cell = new PdfPCell();
cell.setBorder(NO_BORDER);
SimpleCell tmp = new SimpleCell(CELL);
tmp.setSpacing_left(spacing_left);
tmp.setSpacing_right(spacing_right);
tmp.setSpacing_top(spacing_top);
tmp.setSpacing_bottom(spacing_bottom);
tmp.cloneNonPositionParameters(rowAttributes);
tmp.softCloneNonPositionParameters(this);
cell.setCellEvent(tmp);
cell.setHorizontalAlignment(rowAttributes.horizontalAlignment);
cell.setVerticalAlignment(rowAttributes.verticalAlignment);
cell.setUseAscender(rowAttributes.useAscender);
cell.setUseBorderPadding(rowAttributes.useBorderPadding);
cell.setUseDescender(rowAttributes.useDescender);
cell.setColspan(colspan);
if (horizontalAlignment != ALIGN_UNDEFINED)
cell.setHorizontalAlignment(horizontalAlignment);
if (verticalAlignment != ALIGN_UNDEFINED)
cell.setVerticalAlignment(verticalAlignment);
if (useAscender)
cell.setUseAscender(useAscender);
if (useBorderPadding)
cell.setUseBorderPadding(useBorderPadding);
if (useDescender)
cell.setUseDescender(useDescender);
float p;
float sp_left = spacing_left;
if (Float.isNaN(sp_left)) sp_left = 0f;
float sp_right = spacing_right;
if (Float.isNaN(sp_right)) sp_right = 0f;
float sp_top = spacing_top;
if (Float.isNaN(sp_top)) sp_top = 0f;
float sp_bottom = spacing_bottom;
if (Float.isNaN(sp_bottom)) sp_bottom = 0f;
p = padding_left;
if (Float.isNaN(p)) p = 0f;
cell.setPaddingLeft(p + sp_left);
p = padding_right;
if (Float.isNaN(p)) p = 0f;
cell.setPaddingRight(p + sp_right);
p = padding_top;
if (Float.isNaN(p)) p = 0f;
cell.setPaddingTop(p + sp_top);
p = padding_bottom;
if (Float.isNaN(p)) p = 0f;
cell.setPaddingBottom(p + sp_bottom);
Element element;
for (Iterator i = content.iterator(); i.hasNext(); ) {
element = (Element)i.next();
cell.addElement(element);
}
return cell;
}
/**
* @see PdfPCellEvent#cellLayout(PdfPCell, Rectangle, PdfContentByte[])
*/
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
float sp_left = spacing_left;
if (Float.isNaN(sp_left)) sp_left = 0f;
float sp_right = spacing_right;
if (Float.isNaN(sp_right)) sp_right = 0f;
float sp_top = spacing_top;
if (Float.isNaN(sp_top)) sp_top = 0f;
float sp_bottom = spacing_bottom;
if (Float.isNaN(sp_bottom)) sp_bottom = 0f;
Rectangle rect = new Rectangle(position.getLeft(sp_left), position.getBottom(sp_bottom), position.getRight(sp_right), position.getTop(sp_top));
rect.cloneNonPositionParameters(this);
canvases[PdfPTable.BACKGROUNDCANVAS].rectangle(rect);
rect.setBackgroundColor(null);
canvases[PdfPTable.LINECANVAS].rectangle(rect);
}
/** Sets the padding parameters if they are undefined.
* @param padding
*/
public void setPadding(float padding) {
if (Float.isNaN(padding_right)) {
setPadding_right(padding);
}
if (Float.isNaN(padding_left)) {
setPadding_left(padding);
}
if (Float.isNaN(padding_top)) {
setPadding_top(padding);
}
if (Float.isNaN(padding_bottom)) {
setPadding_bottom(padding);
}
}
/**
* @return Returns the colspan.
*/
public int getColspan() {
return colspan;
}
/**
* @param colspan The colspan to set.
*/
public void setColspan(int colspan) {
if (colspan > 0) this.colspan = colspan;
}
/**
* @return Returns the padding_bottom.
*/
public float getPadding_bottom() {
return padding_bottom;
}
/**
* @param padding_bottom The padding_bottom to set.
*/
public void setPadding_bottom(float padding_bottom) {
this.padding_bottom = padding_bottom;
}
/**
* @return Returns the padding_left.
*/
public float getPadding_left() {
return padding_left;
}
/**
* @param padding_left The padding_left to set.
*/
public void setPadding_left(float padding_left) {
this.padding_left = padding_left;
}
/**
* @return Returns the padding_right.
*/
public float getPadding_right() {
return padding_right;
}
/**
* @param padding_right The padding_right to set.
*/
public void setPadding_right(float padding_right) {
this.padding_right = padding_right;
}
/**
* @return Returns the padding_top.
*/
public float getPadding_top() {
return padding_top;
}
/**
* @param padding_top The padding_top to set.
*/
public void setPadding_top(float padding_top) {
this.padding_top = padding_top;
}
/**
* @return Returns the spacing.
*/
public float getSpacing_left() {
return spacing_left;
}
/**
* @return Returns the spacing.
*/
public float getSpacing_right() {
return spacing_right;
}
/**
* @return Returns the spacing.
*/
public float getSpacing_top() {
return spacing_top;
}
/**
* @return Returns the spacing.
*/
public float getSpacing_bottom() {
return spacing_bottom;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing(float spacing) {
this.spacing_left = spacing;
this.spacing_right = spacing;
this.spacing_top = spacing;
this.spacing_bottom = spacing;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing_left(float spacing) {
this.spacing_left = spacing;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing_right(float spacing) {
this.spacing_right = spacing;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing_top(float spacing) {
this.spacing_top = spacing;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing_bottom(float spacing) {
this.spacing_bottom = spacing;
}
/**
* @return Returns the cellgroup.
*/
public boolean isCellgroup() {
return cellgroup;
}
/**
* @param cellgroup The cellgroup to set.
*/
public void setCellgroup(boolean cellgroup) {
this.cellgroup = cellgroup;
}
/**
* @return Returns the horizontal alignment.
*/
public int getHorizontalAlignment() {
return horizontalAlignment;
}
/**
* @param horizontalAlignment The horizontalAlignment to set.
*/
public void setHorizontalAlignment(int horizontalAlignment) {
this.horizontalAlignment = horizontalAlignment;
}
/**
* @return Returns the vertical alignment.
*/
public int getVerticalAlignment() {
return verticalAlignment;
}
/**
* @param verticalAlignment The verticalAligment to set.
*/
public void setVerticalAlignment(int verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
/**
* @return Returns the width.
*/
public float getWidth() {
return width;
}
/**
* @param width The width to set.
*/
public void setWidth(float width) {
this.width = width;
}
/**
* @return Returns the widthpercentage.
*/
public float getWidthpercentage() {
return widthpercentage;
}
/**
* @param widthpercentage The widthpercentage to set.
*/
public void setWidthpercentage(float widthpercentage) {
this.widthpercentage = widthpercentage;
}
/**
* @return Returns the useAscender.
*/
public boolean isUseAscender() {
return useAscender;
}
/**
* @param useAscender The useAscender to set.
*/
public void setUseAscender(boolean useAscender) {
this.useAscender = useAscender;
}
/**
* @return Returns the useBorderPadding.
*/
public boolean isUseBorderPadding() {
return useBorderPadding;
}
/**
* @param useBorderPadding The useBorderPadding to set.
*/
public void setUseBorderPadding(boolean useBorderPadding) {
this.useBorderPadding = useBorderPadding;
}
/**
* @return Returns the useDescender.
*/
public boolean isUseDescender() {
return useDescender;
}
/**
* @param useDescender The useDescender to set.
*/
public void setUseDescender(boolean useDescender) {
this.useDescender = useDescender;
}
/**
* @return Returns the content.
*/
ArrayList getContent() {
return content;
}
/**
* @see TextElementArray#add(Object)
*/
public boolean add(Object o) {
try {
addElement((Element)o);
return true;
}
catch(ClassCastException e) {
return false;
}
catch(BadElementException e) {
throw new ExceptionConverter(e);
}
}
/**
* @see Element#type()
*/
public int type() {
return Element.CELL;
}
}

354
src/main/java/com/fr/third/lowagie/text/SimpleTable.java

@ -0,0 +1,354 @@
/*
* $Id: SimpleTable.java 3752 2009-03-04 18:02:40Z blowagie $
*
* Copyright 2005 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.util.ArrayList;
import java.util.Iterator;
import com.fr.third.lowagie.text.pdf.PdfContentByte;
import com.fr.third.lowagie.text.pdf.PdfPTable;
import com.fr.third.lowagie.text.pdf.PdfPTableEvent;
/**
* Rectangle that can be used for Cells.
* This Rectangle is padded and knows how to draw itself in a PdfPTable or PdfPcellEvent.
*/
public class SimpleTable extends Rectangle implements PdfPTableEvent, TextElementArray {
/** the content of a Table. */
private ArrayList content = new ArrayList();
/** the width of the Table. */
private float width = 0f;
/** the widthpercentage of the Table. */
private float widthpercentage = 0f;
/** the spacing of the Cells. */
private float cellspacing;
/** the padding of the Cells. */
private float cellpadding;
/** the alignment of the table. */
private int alignment;
/**
* A RectangleCell is always constructed without any dimensions.
* Dimensions are defined after creation.
*/
public SimpleTable() {
super(0f, 0f, 0f, 0f);
setBorder(BOX);
setBorderWidth(2f);
}
/**
* Adds content to this object.
* @param element
* @throws BadElementException
*/
public void addElement(SimpleCell element) throws BadElementException {
if(!element.isCellgroup()) {
throw new BadElementException("You can't add cells to a table directly, add them to a row first.");
}
content.add(element);
}
/**
* Creates a Table object based on this TableAttributes object.
* @return a com.lowagie.text.Table object
* @throws BadElementException
*/
public Table createTable() throws BadElementException {
if (content.isEmpty()) throw new BadElementException("Trying to create a table without rows.");
SimpleCell row = (SimpleCell)content.get(0);
SimpleCell cell;
int columns = 0;
for (Iterator i = row.getContent().iterator(); i.hasNext(); ) {
cell = (SimpleCell)i.next();
columns += cell.getColspan();
}
float[] widths = new float[columns];
float[] widthpercentages = new float[columns];
Table table = new Table(columns);
table.setAlignment(alignment);
table.setSpacing(cellspacing);
table.setPadding(cellpadding);
table.cloneNonPositionParameters(this);
int pos;
for (Iterator rows = content.iterator(); rows.hasNext(); ) {
row = (SimpleCell)rows.next();
pos = 0;
for (Iterator cells = row.getContent().iterator(); cells.hasNext(); ) {
cell = (SimpleCell)cells.next();
table.addCell(cell.createCell(row));
if (cell.getColspan() == 1) {
if (cell.getWidth() > 0) widths[pos] = cell.getWidth();
if (cell.getWidthpercentage() > 0) widthpercentages[pos] = cell.getWidthpercentage();
}
pos += cell.getColspan();
}
}
float sumWidths = 0f;
for(int i = 0; i < columns; i++) {
if (widths[i] == 0) {
sumWidths = 0;
break;
}
sumWidths += widths[i];
}
if (sumWidths > 0) {
table.setWidth(sumWidths);
table.setLocked(true);
table.setWidths(widths);
}
else {
for(int i = 0; i < columns; i++) {
if (widthpercentages[i] == 0) {
sumWidths = 0;
break;
}
sumWidths += widthpercentages[i];
}
if (sumWidths > 0) {
table.setWidths(widthpercentages);
}
}
if (width > 0) {
table.setWidth(width);
table.setLocked(true);
}
else if (widthpercentage > 0) {
table.setWidth(widthpercentage);
}
return table;
}
/**
* Creates a PdfPTable object based on this TableAttributes object.
* @return a com.lowagie.text.pdf.PdfPTable object
* @throws DocumentException
*/
public PdfPTable createPdfPTable() throws DocumentException {
if (content.isEmpty()) throw new BadElementException("Trying to create a table without rows.");
SimpleCell row = (SimpleCell)content.get(0);
SimpleCell cell;
int columns = 0;
for (Iterator i = row.getContent().iterator(); i.hasNext(); ) {
cell = (SimpleCell)i.next();
columns += cell.getColspan();
}
float[] widths = new float[columns];
float[] widthpercentages = new float[columns];
PdfPTable table = new PdfPTable(columns);
table.setTableEvent(this);
table.setHorizontalAlignment(alignment);
int pos;
for (Iterator rows = content.iterator(); rows.hasNext(); ) {
row = (SimpleCell)rows.next();
pos = 0;
for (Iterator cells = row.getContent().iterator(); cells.hasNext(); ) {
cell = (SimpleCell)cells.next();
if (Float.isNaN(cell.getSpacing_left())) {
cell.setSpacing_left(cellspacing / 2f);
}
if (Float.isNaN(cell.getSpacing_right())) {
cell.setSpacing_right(cellspacing / 2f);
}
if (Float.isNaN(cell.getSpacing_top())) {
cell.setSpacing_top(cellspacing / 2f);
}
if (Float.isNaN(cell.getSpacing_bottom())) {
cell.setSpacing_bottom(cellspacing / 2f);
}
cell.setPadding(cellpadding);
table.addCell(cell.createPdfPCell(row));
if (cell.getColspan() == 1) {
if (cell.getWidth() > 0) widths[pos] = cell.getWidth();
if (cell.getWidthpercentage() > 0) widthpercentages[pos] = cell.getWidthpercentage();
}
pos += cell.getColspan();
}
}
float sumWidths = 0f;
for(int i = 0; i < columns; i++) {
if (widths[i] == 0) {
sumWidths = 0;
break;
}
sumWidths += widths[i];
}
if (sumWidths > 0) {
table.setTotalWidth(sumWidths);
table.setWidths(widths);
}
else {
for(int i = 0; i < columns; i++) {
if (widthpercentages[i] == 0) {
sumWidths = 0;
break;
}
sumWidths += widthpercentages[i];
}
if (sumWidths > 0) {
table.setWidths(widthpercentages);
}
}
if (width > 0) {
table.setTotalWidth(width);
}
if (widthpercentage > 0) {
table.setWidthPercentage(widthpercentage);
}
return table;
}
/**
* @see PdfPTableEvent#tableLayout(PdfPTable, float[][], float[], int, int, PdfContentByte[])
*/
public void tableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) {
float[] width = widths[0];
Rectangle rect = new Rectangle(width[0], heights[heights.length - 1], width[width.length - 1], heights[0]);
rect.cloneNonPositionParameters(this);
int bd = rect.getBorder();
rect.setBorder(NO_BORDER);
canvases[PdfPTable.BACKGROUNDCANVAS].rectangle(rect);
rect.setBorder(bd);
rect.setBackgroundColor(null);
canvases[PdfPTable.LINECANVAS].rectangle(rect);
}
/**
* @return Returns the cellpadding.
*/
public float getCellpadding() {
return cellpadding;
}
/**
* @param cellpadding The cellpadding to set.
*/
public void setCellpadding(float cellpadding) {
this.cellpadding = cellpadding;
}
/**
* @return Returns the cellspacing.
*/
public float getCellspacing() {
return cellspacing;
}
/**
* @param cellspacing The cellspacing to set.
*/
public void setCellspacing(float cellspacing) {
this.cellspacing = cellspacing;
}
/**
* @return Returns the alignment.
*/
public int getAlignment() {
return alignment;
}
/**
* @param alignment The alignment to set.
*/
public void setAlignment(int alignment) {
this.alignment = alignment;
}
/**
* @return Returns the width.
*/
public float getWidth() {
return width;
}
/**
* @param width The width to set.
*/
public void setWidth(float width) {
this.width = width;
}
/**
* @return Returns the widthpercentage.
*/
public float getWidthpercentage() {
return widthpercentage;
}
/**
* @param widthpercentage The widthpercentage to set.
*/
public void setWidthpercentage(float widthpercentage) {
this.widthpercentage = widthpercentage;
}
/**
* @see Element#type()
*/
public int type() {
return TABLE;
}
/**
* @see Element#isNestable()
* @since iText 2.0.8
*/
public boolean isNestable() {
return true;
}
/**
* @see TextElementArray#add(Object)
*/
public boolean add(Object o) {
try {
addElement((SimpleCell)o);
return true;
}
catch(ClassCastException e) {
return false;
}
catch(BadElementException e) {
throw new ExceptionConverter(e);
}
}
}

210
src/main/java/com/fr/third/lowagie/text/SpecialSymbol.java

@ -0,0 +1,210 @@
/*
* $Id: SpecialSymbol.java 3963 2009-06-11 11:45:49Z psoares33 $
*
* Copyright 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* This class contains the symbols that correspond with special symbols.
* <P>
* When you construct a <CODE>Phrase</CODE> with Phrase.getInstance using a <CODE>String</CODE>,
* this <CODE>String</CODE> can contain special Symbols. These are characters with an int value
* between 913 and 937 (except 930) and between 945 and 969. With this class the value of the
* corresponding character of the Font Symbol, can be retrieved.
*
* @see Phrase
*
* @author Bruno Lowagie
* @author Evelyne De Cordier
*/
public class SpecialSymbol {
/**
* Returns the first occurrence of a special symbol in a <CODE>String</CODE>.
*
* @param string a <CODE>String</CODE>
* @return an index of -1 if no special symbol was found
*/
public static int index(String string) {
int length = string.length();
for (int i = 0; i < length; i++) {
if (getCorrespondingSymbol(string.charAt(i)) != ' ') {
return i;
}
}
return -1;
}
/**
* Gets a chunk with a symbol character.
* @param c a character that has to be changed into a symbol
* @param font Font if there is no SYMBOL character corresponding with c
* @return a SYMBOL version of a character
*/
public static Chunk get(char c, Font font) {
char greek = SpecialSymbol.getCorrespondingSymbol(c);
if (greek == ' ') {
return new Chunk(String.valueOf(c), font);
}
Font symbol = new Font(Font.SYMBOL, font.getSize(), font.getStyle(), font.getColor());
String s = String.valueOf(greek);
return new Chunk(s, symbol);
}
/**
* Looks for the corresponding symbol in the font Symbol.
*
* @param c the original ASCII-char
* @return the corresponding symbol in font Symbol
*/
public static char getCorrespondingSymbol(char c) {
switch(c) {
case 913:
return 'A'; // ALFA
case 914:
return 'B'; // BETA
case 915:
return 'G'; // GAMMA
case 916:
return 'D'; // DELTA
case 917:
return 'E'; // EPSILON
case 918:
return 'Z'; // ZETA
case 919:
return 'H'; // ETA
case 920:
return 'Q'; // THETA
case 921:
return 'I'; // IOTA
case 922:
return 'K'; // KAPPA
case 923:
return 'L'; // LAMBDA
case 924:
return 'M'; // MU
case 925:
return 'N'; // NU
case 926:
return 'X'; // XI
case 927:
return 'O'; // OMICRON
case 928:
return 'P'; // PI
case 929:
return 'R'; // RHO
case 931:
return 'S'; // SIGMA
case 932:
return 'T'; // TAU
case 933:
return 'U'; // UPSILON
case 934:
return 'F'; // PHI
case 935:
return 'C'; // CHI
case 936:
return 'Y'; // PSI
case 937:
return 'W'; // OMEGA
case 945:
return 'a'; // alfa
case 946:
return 'b'; // beta
case 947:
return 'g'; // gamma
case 948:
return 'd'; // delta
case 949:
return 'e'; // epsilon
case 950:
return 'z'; // zeta
case 951:
return 'h'; // eta
case 952:
return 'q'; // theta
case 953:
return 'i'; // iota
case 954:
return 'k'; // kappa
case 955:
return 'l'; // lambda
case 956:
return 'm'; // mu
case 957:
return 'n'; // nu
case 958:
return 'x'; // xi
case 959:
return 'o'; // omicron
case 960:
return 'p'; // pi
case 961:
return 'r'; // rho
case 962:
return 'V'; // sigma
case 963:
return 's'; // sigma
case 964:
return 't'; // tau
case 965:
return 'u'; // upsilon
case 966:
return 'f'; // phi
case 967:
return 'c'; // chi
case 968:
return 'y'; // psi
case 969:
return 'w'; // omega
default:
return ' ';
}
}
}

96
src/main/java/com/fr/third/lowagie/text/SplitCharacter.java

@ -0,0 +1,96 @@
/*
* $Id: SplitCharacter.java 3374 2008-05-12 18:42:56Z xlv $
*
* Copyright 2001, 2002 by Paulo Soares
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import com.fr.third.lowagie.text.pdf.PdfChunk;
/** Interface for customizing the split character.
*
* @author Paulo Soares (psoares@consiste.pt)
*/
public interface SplitCharacter {
/**
* Returns <CODE>true</CODE> if the character can split a line. The splitting implementation
* is free to look ahead or look behind characters to make a decision.
* <p>
* The default implementation is:
* <p>
* <pre>
* public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
* char c;
* if (ck == null)
* c = cc[current];
* else
* c = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);
* if (c <= ' ' || c == '-') {
* return true;
* }
* if (c < 0x2e80)
* return false;
* return ((c >= 0x2e80 && c < 0xd7a0)
* || (c >= 0xf900 && c < 0xfb00)
* || (c >= 0xfe30 && c < 0xfe50)
* || (c >= 0xff61 && c < 0xffa0));
* }
* </pre>
* @param start the lower limit of <CODE>cc</CODE> inclusive
* @param current the pointer to the character in <CODE>cc</CODE>
* @param end the upper limit of <CODE>cc</CODE> exclusive
* @param cc an array of characters at least <CODE>end</CODE> sized
* @param ck an array of <CODE>PdfChunk</CODE>. The main use is to be able to call
* {@link PdfChunk#getUnicodeEquivalent(int)}. It may be <CODE>null</CODE>
* or shorter than <CODE>end</CODE>. If <CODE>null</CODE> no conversion takes place.
* If shorter than <CODE>end</CODE> the last element is used
* @return <CODE>true</CODE> if the character(s) can split a line
*/
public boolean isSplitCharacter(int start, int current, int end, char cc[], PdfChunk ck[]);
}

1494
src/main/java/com/fr/third/lowagie/text/Table.java

File diff suppressed because it is too large Load Diff

73
src/main/java/com/fr/third/lowagie/text/TextElementArray.java

@ -0,0 +1,73 @@
/*
* $Id: TextElementArray.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright (c) 1999, 2000, 2001, 2002 Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
* Interface for a text element to which other objects can be added.
*
* @see Phrase
* @see Paragraph
* @see Section
* @see ListItem
* @see Chapter
* @see Anchor
* @see Cell
*/
public interface TextElementArray extends Element {
/**
* Adds an object to the <CODE>TextElementArray</CODE>.
*
* @param o an object that has to be added
* @return <CODE>true</CODE> if the addition succeeded; <CODE>false</CODE> otherwise
*/
public boolean add(Object o);
}

342
src/main/java/com/fr/third/lowagie/text/Utilities.java

@ -0,0 +1,342 @@
/*
* $Id: Utilities.java 3514 2008-06-27 09:26:36Z blowagie $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
import com.fr.third.lowagie.text.pdf.PRTokeniser;
/**
* A collection of convenience methods that were present in many different iText
* classes.
*/
public class Utilities {
/**
* Gets the keys of a Hashtable
*
* @param table
* a Hashtable
* @return the keyset of a Hashtable (or an empty set if table is null)
*/
public static Set getKeySet(Hashtable table) {
return (table == null) ? Collections.EMPTY_SET : table.keySet();
}
/**
* Utility method to extend an array.
*
* @param original
* the original array or <CODE>null</CODE>
* @param item
* the item to be added to the array
* @return a new array with the item appended
*/
public static Object[][] addToArray(Object original[][], Object item[]) {
if (original == null) {
original = new Object[1][];
original[0] = item;
return original;
} else {
Object original2[][] = new Object[original.length + 1][];
System.arraycopy(original, 0, original2, 0, original.length);
original2[original.length] = item;
return original2;
}
}
/**
* Checks for a true/false value of a key in a Properties object.
* @param attributes
* @param key
* @return a true/false value of a key in a Properties object
*/
public static boolean checkTrueOrFalse(Properties attributes, String key) {
return "true".equalsIgnoreCase(attributes.getProperty(key));
}
/**
* Unescapes an URL. All the "%xx" are replaced by the 'xx' hex char value.
* @param src the url to unescape
* @return the unescaped value
*/
public static String unEscapeURL(String src) {
StringBuffer bf = new StringBuffer();
char[] s = src.toCharArray();
for (int k = 0; k < s.length; ++k) {
char c = s[k];
if (c == '%') {
if (k + 2 >= s.length) {
bf.append(c);
continue;
}
int a0 = PRTokeniser.getHex(s[k + 1]);
int a1 = PRTokeniser.getHex(s[k + 2]);
if (a0 < 0 || a1 < 0) {
bf.append(c);
continue;
}
bf.append((char)(a0 * 16 + a1));
k += 2;
}
else
bf.append(c);
}
return bf.toString();
}
/**
* This method makes a valid URL from a given filename.
* <P>
* This method makes the conversion of this library from the JAVA 2 platform
* to a JDK1.1.x-version easier.
*
* @param filename
* a given filename
* @return a valid URL
* @throws MalformedURLException
*/
public static URL toURL(String filename) throws MalformedURLException {
try {
return new URL(filename);
}
catch (Exception e) {
return new File(filename).toURI().toURL();
}
}
/**
* This method is an alternative for the <CODE>InputStream.skip()</CODE>
* -method that doesn't seem to work properly for big values of <CODE>size
* </CODE>.
*
* @param is
* the <CODE>InputStream</CODE>
* @param size
* the number of bytes to skip
* @throws IOException
*/
static public void skip(InputStream is, int size) throws IOException {
long n;
while (size > 0) {
n = is.skip(size);
if (n <= 0)
break;
size -= n;
}
}
/**
* Measurement conversion from millimeters to points.
* @param value a value in millimeters
* @return a value in points
* @since 2.1.2
*/
public static final float millimetersToPoints(float value) {
return inchesToPoints(millimetersToInches(value));
}
/**
* Measurement conversion from millimeters to inches.
* @param value a value in millimeters
* @return a value in inches
* @since 2.1.2
*/
public static final float millimetersToInches(float value) {
return value / 25.4f;
}
/**
* Measurement conversion from points to millimeters.
* @param value a value in points
* @return a value in millimeters
* @since 2.1.2
*/
public static final float pointsToMillimeters(float value) {
return inchesToMillimeters(pointsToInches(value));
}
/**
* Measurement conversion from points to inches.
* @param value a value in points
* @return a value in inches
* @since 2.1.2
*/
public static final float pointsToInches(float value) {
return value / 72f;
}
/**
* Measurement conversion from inches to millimeters.
* @param value a value in inches
* @return a value in millimeters
* @since 2.1.2
*/
public static final float inchesToMillimeters(float value) {
return value * 25.4f;
}
/**
* Measurement conversion from inches to points.
* @param value a value in inches
* @return a value in points
* @since 2.1.2
*/
public static final float inchesToPoints(float value) {
return value * 72f;
}
/**
* Check if the value of a character belongs to a certain interval
* that indicates it's the higher part of a surrogate pair.
* @param c the character
* @return true if the character belongs to the interval
* @since 2.1.2
*/
public static boolean isSurrogateHigh(char c) {
return c >= '\ud800' && c <= '\udbff';
}
/**
* Check if the value of a character belongs to a certain interval
* that indicates it's the lower part of a surrogate pair.
* @param c the character
* @return true if the character belongs to the interval
* @since 2.1.2
*/
public static boolean isSurrogateLow(char c) {
return c >= '\udc00' && c <= '\udfff';
}
/**
* Checks if two subsequent characters in a String are
* are the higher and the lower character in a surrogate
* pair (and therefore eligible for conversion to a UTF 32 character).
* @param text the String with the high and low surrogate characters
* @param idx the index of the 'high' character in the pair
* @return true if the characters are surrogate pairs
* @since 2.1.2
*/
public static boolean isSurrogatePair(String text, int idx) {
if (idx < 0 || idx > text.length() - 2)
return false;
return isSurrogateHigh(text.charAt(idx)) && isSurrogateLow(text.charAt(idx + 1));
}
/**
* Checks if two subsequent characters in a character array are
* are the higher and the lower character in a surrogate
* pair (and therefore eligible for conversion to a UTF 32 character).
* @param text the character array with the high and low surrogate characters
* @param idx the index of the 'high' character in the pair
* @return true if the characters are surrogate pairs
* @since 2.1.2
*/
public static boolean isSurrogatePair(char[] text, int idx) {
if (idx < 0 || idx > text.length - 2)
return false;
return isSurrogateHigh(text[idx]) && isSurrogateLow(text[idx + 1]);
}
/**
* Returns the code point of a UTF32 character corresponding with
* a high and a low surrogate value.
* @param highSurrogate the high surrogate value
* @param lowSurrogate the low surrogate value
* @return a code point value
* @since 2.1.2
*/
public static int convertToUtf32(char highSurrogate, char lowSurrogate) {
return (((highSurrogate - 0xd800) * 0x400) + (lowSurrogate - 0xdc00)) + 0x10000;
}
/**
* Converts a unicode character in a character array to a UTF 32 code point value.
* @param text a character array that has the unicode character(s)
* @param idx the index of the 'high' character
* @return the code point value
* @since 2.1.2
*/
public static int convertToUtf32(char[] text, int idx) {
return (((text[idx] - 0xd800) * 0x400) + (text[idx + 1] - 0xdc00)) + 0x10000;
}
/**
* Converts a unicode character in a String to a UTF32 code point value
* @param text a String that has the unicode character(s)
* @param idx the index of the 'high' character
* @return the codepoint value
* @since 2.1.2
*/
public static int convertToUtf32(String text, int idx) {
return (((text.charAt(idx) - 0xd800) * 0x400) + (text.charAt(idx + 1) - 0xdc00)) + 0x10000;
}
/**
* Converts a UTF32 code point value to a String with the corresponding character(s).
* @param codePoint a Unicode value
* @return the corresponding characters in a String
* @since 2.1.2
*/
public static String convertFromUtf32(int codePoint) {
if (codePoint < 0x10000)
return Character.toString((char)codePoint);
codePoint -= 0x10000;
return new String(new char[]{(char)((codePoint / 0x400) + 0xd800), (char)((codePoint % 0x400) + 0xdc00)});
}
}

134
src/main/java/com/fr/third/lowagie/text/ZapfDingbatsList.java

@ -0,0 +1,134 @@
/*
* Copyright 2003 by Michael Niedermair.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
*
* A special-version of <CODE>LIST</CODE> which use zapfdingbats-letters.
*
* @see List
* @author Michael Niedermair and Bruno Lowagie
*/
public class ZapfDingbatsList extends List {
/**
* char-number in zapfdingbats
*/
protected int zn;
/**
* Creates a ZapfDingbatsList
*
* @param zn a char-number
*/
public ZapfDingbatsList(int zn) {
super(true);
this.zn = zn;
float fontsize = symbol.getFont().getSize();
symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL));
postSymbol = " ";
}
/**
* Creates a ZapfDingbatsList
*
* @param zn a char-number
* @param symbolIndent indent
*/
public ZapfDingbatsList(int zn, int symbolIndent) {
super(true, symbolIndent);
this.zn = zn;
float fontsize = symbol.getFont().getSize();
symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL));
postSymbol = " ";
}
/**
* set the char-number
* @param zn a char-number
*/
public void setCharNumber(int zn) {
this.zn = zn;
}
/**
* get the char-number
*
* @return char-number
*/
public int getCharNumber() {
return zn;
}
/**
* Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
*
* @param o the object to add.
* @return true if adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof ListItem) {
ListItem item = (ListItem) o;
Chunk chunk = new Chunk(preSymbol, symbol.getFont());
chunk.append(String.valueOf((char)zn));
chunk.append(postSymbol);
item.setListSymbol(chunk);
item.setIndentationLeft(symbolIndent, autoindent);
item.setIndentationRight(0);
list.add(item);
} else if (o instanceof List) {
List nested = (List) o;
nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
first--;
return list.add(nested);
} else if (o instanceof String) {
return this.add(new ListItem((String) o));
}
return false;
}
}

145
src/main/java/com/fr/third/lowagie/text/ZapfDingbatsNumberList.java

@ -0,0 +1,145 @@
/*
* Copyright 2003 by Michael Niedermair.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text;
/**
*
* A special-version of <CODE>LIST</CODE> which use zapfdingbats-numbers (1..10).
*
* @see List
* @author Michael Niedermair and Bruno Lowagie
*/
public class ZapfDingbatsNumberList extends List {
/**
* which type
*/
protected int type;
/**
* Creates a ZapdDingbatsNumberList
* @param type the type of list
*/
public ZapfDingbatsNumberList(int type) {
super(true);
this.type = type;
float fontsize = symbol.getFont().getSize();
symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL));
postSymbol = " ";
}
/**
* Creates a ZapdDingbatsNumberList
* @param type the type of list
* @param symbolIndent indent
*/
public ZapfDingbatsNumberList(int type, int symbolIndent) {
super(true, symbolIndent);
this.type = type;
float fontsize = symbol.getFont().getSize();
symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL));
postSymbol = " ";
}
/**
* set the type
*
* @param type
*/
public void setType(int type) {
this.type = type;
}
/**
* get the type
*
* @return char-number
*/
public int getType() {
return type;
}
/**
* Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
*
* @param o the object to add.
* @return true if adding the object succeeded
*/
public boolean add(Object o) {
if (o instanceof ListItem) {
ListItem item = (ListItem) o;
Chunk chunk = new Chunk(preSymbol, symbol.getFont());
switch (type ) {
case 0:
chunk.append(String.valueOf((char)(first + list.size() + 171)));
break;
case 1:
chunk.append(String.valueOf((char)(first + list.size() + 181)));
break;
case 2:
chunk.append(String.valueOf((char)(first + list.size() + 191)));
break;
default:
chunk.append(String.valueOf((char)(first + list.size() + 201)));
}
chunk.append(postSymbol);
item.setListSymbol(chunk);
item.setIndentationLeft(symbolIndent, autoindent);
item.setIndentationRight(0);
list.add(item);
} else if (o instanceof List) {
List nested = (List) o;
nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
first--;
return list.add(nested);
} else if (o instanceof String) {
return this.add(new ListItem((String) o));
}
return false;
}
}

219
src/main/java/com/fr/third/lowagie/text/apache_license.txt

@ -0,0 +1,219 @@
Some files use code from different Apache projects.
The source code of these files contains the appropriate copyright notices
as described in the Appendix of http://www.apache.org/licenses/LICENSE-2.0
This is a copy of the text that can be found at that specific URL:
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
* You must give any other recipients of the Work or
Derivative Works a copy of this License; and
* You must cause any modified files to carry prominent notices
stating that You changed the files; and
* You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
* If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks.
This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

70
src/main/java/com/fr/third/lowagie/text/exceptions/BadPasswordException.java

@ -0,0 +1,70 @@
/*
* $Id: BadPasswordException.java 3665 2009-01-26 22:32:15Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.exceptions;
import java.io.IOException;
/**
* Typed exception used when opening an existing PDF document.
* Gets thrown when the document isn't a valid PDF document.
* @since 2.1.5 It was written for iText 2.0.8, but moved to another package
*/
public class BadPasswordException extends IOException {
/** Serial Version UID. */
private static final long serialVersionUID = -4333706268155063964L;
/**
* Creates an exception saying the user password was incorrect.
*/
public BadPasswordException(String message) {
super(message);
}
}

68
src/main/java/com/fr/third/lowagie/text/exceptions/IllegalPdfSyntaxException.java

@ -0,0 +1,68 @@
/*
* $Id: IllegalPdfSyntaxException.java 3820 2009-03-25 10:30:01Z blowagie $
*
* Copyright 2009 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.exceptions;
/**
* Typed exception used when creating PDF syntax that isn't valid.
* @since 2.1.6
*/
public class IllegalPdfSyntaxException extends IllegalArgumentException {
/** Serial version ID */
private static final long serialVersionUID = -643024246596031671L;
/**
* Creates an exception saying the PDF syntax isn't correct.
* @param message some extra info about the exception
*/
public IllegalPdfSyntaxException(String message) {
super(message);
}
}

71
src/main/java/com/fr/third/lowagie/text/exceptions/InvalidPdfException.java

@ -0,0 +1,71 @@
/*
* $Id: InvalidPdfException.java 3665 2009-01-26 22:32:15Z xlv $
*
* Copyright 2009 Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.exceptions;
import java.io.IOException;
/**
* Typed exception used when opening an existing PDF document.
* Gets thrown when the document isn't a valid PDF document.
* @since 2.1.5
*/
public class InvalidPdfException extends IOException {
/** a serial version UID */
private static final long serialVersionUID = -2319614911517026938L;
/**
* Creates an instance of a NoPdfException.
* @param message the reason why the document isn't a PDF document according to iText.
*/
public InvalidPdfException(String message) {
super(message);
}
}

72
src/main/java/com/fr/third/lowagie/text/exceptions/UnsupportedPdfException.java

@ -0,0 +1,72 @@
/*
* $Id: UnsupportedPdfException.java 3665 2009-01-26 22:32:15Z xlv $
*
* Copyright 2009 Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.exceptions;
/**
* Typed exception used when opening an existing PDF document.
* Gets thrown when the document isn't a valid PDF document according to iText,
* but it's different from the InvalidPdfException in the sense that it may
* be an iText limitation (most of the times it isn't but you might have
* bumped into something that has been added to the PDF specs, but that isn't
* supported in iText yet).
* @since 2.1.5
*/
public class UnsupportedPdfException extends InvalidPdfException {
/** a serial version UID */
private static final long serialVersionUID = 2180764250839096628L;
/**
* Creates an instance of an UnsupportedPdfException.
* @param message the reason why the document isn't a PDF document according to iText.
*/
public UnsupportedPdfException(String message) {
super(message);
}
}

627
src/main/java/com/fr/third/lowagie/text/factories/ElementFactory.java

@ -0,0 +1,627 @@
/*
* $Id: ElementFactory.java 3528 2008-07-07 14:46:09Z Howard_s $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* Contributions by:
* Lubos Strapko
*
* 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/
*/
package com.fr.third.lowagie.text.factories;
import java.awt.Color;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.StringTokenizer;
import com.fr.third.lowagie.text.Rectangle;
import com.fr.third.lowagie.text.Anchor;
import com.fr.third.lowagie.text.Annotation;
import com.fr.third.lowagie.text.BadElementException;
import com.fr.third.lowagie.text.Cell;
import com.fr.third.lowagie.text.ChapterAutoNumber;
import com.fr.third.lowagie.text.Chunk;
import com.fr.third.lowagie.text.ElementTags;
import com.fr.third.lowagie.text.ExceptionConverter;
import com.fr.third.lowagie.text.FontFactory;
import com.fr.third.lowagie.text.Image;
import com.fr.third.lowagie.text.List;
import com.fr.third.lowagie.text.ListItem;
import com.fr.third.lowagie.text.Paragraph;
import com.fr.third.lowagie.text.Phrase;
import com.fr.third.lowagie.text.Section;
import com.fr.third.lowagie.text.Table;
import com.fr.third.lowagie.text.Utilities;
import com.fr.third.lowagie.text.html.Markup;
/**
* This class is able to create Element objects based on a list of properties.
*/
public class ElementFactory {
/**
* Creates a Chunk object based on a list of properties.
* @param attributes
* @return a Chunk
*/
public static Chunk getChunk(Properties attributes) {
Chunk chunk = new Chunk();
chunk.setFont(FontFactory.getFont(attributes));
String value;
value = attributes.getProperty(ElementTags.ITEXT);
if (value != null) {
chunk.append(value);
}
value = attributes.getProperty(ElementTags.LOCALGOTO);
if (value != null) {
chunk.setLocalGoto(value);
}
value = attributes.getProperty(ElementTags.REMOTEGOTO);
if (value != null) {
String page = attributes.getProperty(ElementTags.PAGE);
if (page != null) {
chunk.setRemoteGoto(value, Integer.parseInt(page));
} else {
String destination = attributes
.getProperty(ElementTags.DESTINATION);
if (destination != null) {
chunk.setRemoteGoto(value, destination);
}
}
}
value = attributes.getProperty(ElementTags.LOCALDESTINATION);
if (value != null) {
chunk.setLocalDestination(value);
}
value = attributes.getProperty(ElementTags.SUBSUPSCRIPT);
if (value != null) {
chunk.setTextRise(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(Markup.CSS_KEY_VERTICALALIGN);
if (value != null && value.endsWith("%")) {
float p = Float.parseFloat(value.substring(0, value.length() - 1)
+ "f") / 100f;
chunk.setTextRise(p * chunk.getFont().getSize());
}
value = attributes.getProperty(ElementTags.GENERICTAG);
if (value != null) {
chunk.setGenericTag(value);
}
value = attributes.getProperty(ElementTags.BACKGROUNDCOLOR);
if (value != null) {
chunk.setBackground(value);
}
return chunk;
}
/**
* Creates a Phrase object based on a list of properties.
* @param attributes
* @return a Phrase
*/
public static Phrase getPhrase(Properties attributes) {
Phrase phrase = new Phrase();
phrase.setFont(FontFactory.getFont(attributes));
String value;
value = attributes.getProperty(ElementTags.LEADING);
if (value != null) {
phrase.setLeading(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(Markup.CSS_KEY_LINEHEIGHT);
if (value != null) {
phrase.setLeading(Markup.parseLength(value,
Markup.DEFAULT_FONT_SIZE));
}
value = attributes.getProperty(ElementTags.ITEXT);
if (value != null) {
Chunk chunk = new Chunk(value);
if ((value = attributes.getProperty(ElementTags.GENERICTAG)) != null) {
chunk.setGenericTag(value);
}
phrase.add(chunk);
}
return phrase;
}
/**
* Creates an Anchor object based on a list of properties.
* @param attributes
* @return an Anchor
*/
public static Anchor getAnchor(Properties attributes) {
Anchor anchor = new Anchor(getPhrase(attributes));
String value;
value = attributes.getProperty(ElementTags.NAME);
if (value != null) {
anchor.setName(value);
}
value = (String) attributes.remove(ElementTags.REFERENCE);
if (value != null) {
anchor.setReference(value);
}
return anchor;
}
/**
* Creates a Paragraph object based on a list of properties.
* @param attributes
* @return a Paragraph
*/
public static Paragraph getParagraph(Properties attributes) {
Paragraph paragraph = new Paragraph(getPhrase(attributes));
String value;
value = attributes.getProperty(ElementTags.ALIGN);
if (value != null) {
paragraph.setAlignment(value);
}
value = attributes.getProperty(ElementTags.INDENTATIONLEFT);
if (value != null) {
paragraph.setIndentationLeft(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.INDENTATIONRIGHT);
if (value != null) {
paragraph.setIndentationRight(Float.parseFloat(value + "f"));
}
return paragraph;
}
/**
* Creates a ListItem object based on a list of properties.
* @param attributes
* @return a ListItem
*/
public static ListItem getListItem(Properties attributes) {
ListItem item = new ListItem(getParagraph(attributes));
return item;
}
/**
* Creates a List object based on a list of properties.
* @param attributes
* @return the List
*/
public static List getList(Properties attributes) {
List list = new List();
list.setNumbered(Utilities.checkTrueOrFalse(attributes,
ElementTags.NUMBERED));
list.setLettered(Utilities.checkTrueOrFalse(attributes,
ElementTags.LETTERED));
list.setLowercase(Utilities.checkTrueOrFalse(attributes,
ElementTags.LOWERCASE));
list.setAutoindent(Utilities.checkTrueOrFalse(attributes,
ElementTags.AUTO_INDENT_ITEMS));
list.setAlignindent(Utilities.checkTrueOrFalse(attributes,
ElementTags.ALIGN_INDENTATION_ITEMS));
String value;
value = attributes.getProperty(ElementTags.FIRST);
if (value != null) {
char character = value.charAt(0);
if (Character.isLetter(character)) {
list.setFirst(character);
} else {
list.setFirst(Integer.parseInt(value));
}
}
value = attributes.getProperty(ElementTags.LISTSYMBOL);
if (value != null) {
list
.setListSymbol(new Chunk(value, FontFactory
.getFont(attributes)));
}
value = attributes.getProperty(ElementTags.INDENTATIONLEFT);
if (value != null) {
list.setIndentationLeft(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.INDENTATIONRIGHT);
if (value != null) {
list.setIndentationRight(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.SYMBOLINDENT);
if (value != null) {
list.setSymbolIndent(Float.parseFloat(value));
}
return list;
}
/**
* Creates a Cell object based on a list of properties.
* @param attributes
* @return a Cell
*/
public static Cell getCell(Properties attributes) {
Cell cell = new Cell();
String value;
cell.setHorizontalAlignment(attributes
.getProperty(ElementTags.HORIZONTALALIGN));
cell.setVerticalAlignment(attributes
.getProperty(ElementTags.VERTICALALIGN));
value = attributes.getProperty(ElementTags.WIDTH);
if (value != null) {
cell.setWidth(value);
}
value = attributes.getProperty(ElementTags.COLSPAN);
if (value != null) {
cell.setColspan(Integer.parseInt(value));
}
value = attributes.getProperty(ElementTags.ROWSPAN);
if (value != null) {
cell.setRowspan(Integer.parseInt(value));
}
value = attributes.getProperty(ElementTags.LEADING);
if (value != null) {
cell.setLeading(Float.parseFloat(value + "f"));
}
cell.setHeader(Utilities.checkTrueOrFalse(attributes,
ElementTags.HEADER));
if (Utilities.checkTrueOrFalse(attributes, ElementTags.NOWRAP)) {
cell.setMaxLines(1);
}
setRectangleProperties(cell, attributes);
return cell;
}
/**
* Creates an Table object based on a list of properties.
* @param attributes
* @return a Table
*/
public static Table getTable(Properties attributes) {
String value;
Table table;
try {
value = attributes.getProperty(ElementTags.WIDTHS);
if (value != null) {
StringTokenizer widthTokens = new StringTokenizer(value, ";");
ArrayList values = new ArrayList();
while (widthTokens.hasMoreTokens()) {
values.add(widthTokens.nextToken());
}
table = new Table(values.size());
float[] widths = new float[table.getColumns()];
for (int i = 0; i < values.size(); i++) {
value = (String) values.get(i);
widths[i] = Float.parseFloat(value + "f");
}
table.setWidths(widths);
} else {
value = attributes.getProperty(ElementTags.COLUMNS);
try {
table = new Table(Integer.parseInt(value));
} catch (Exception e) {
table = new Table(1);
}
}
table.setBorder(Table.BOX);
table.setBorderWidth(1);
table.getDefaultCell().setBorder(Table.BOX);
value = attributes.getProperty(ElementTags.LASTHEADERROW);
if (value != null) {
table.setLastHeaderRow(Integer.parseInt(value));
}
value = attributes.getProperty(ElementTags.ALIGN);
if (value != null) {
table.setAlignment(value);
}
value = attributes.getProperty(ElementTags.CELLSPACING);
if (value != null) {
table.setSpacing(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.CELLPADDING);
if (value != null) {
table.setPadding(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.OFFSET);
if (value != null) {
table.setOffset(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.WIDTH);
if (value != null) {
if (value.endsWith("%"))
table.setWidth(Float.parseFloat(value.substring(0, value
.length() - 1)
+ "f"));
else {
table.setWidth(Float.parseFloat(value + "f"));
table.setLocked(true);
}
}
table.setTableFitsPage(Utilities.checkTrueOrFalse(attributes,
ElementTags.TABLEFITSPAGE));
table.setCellsFitPage(Utilities.checkTrueOrFalse(attributes,
ElementTags.CELLSFITPAGE));
table.setConvert2pdfptable(Utilities.checkTrueOrFalse(attributes,
ElementTags.CONVERT2PDFP));
setRectangleProperties(table, attributes);
return table;
} catch (BadElementException e) {
throw new ExceptionConverter(e);
}
}
/**
* Sets some Rectangle properties (for a Cell, Table,...).
*/
private static void setRectangleProperties(Rectangle rect,
Properties attributes) {
String value;
value = attributes.getProperty(ElementTags.BORDERWIDTH);
if (value != null) {
rect.setBorderWidth(Float.parseFloat(value + "f"));
}
int border = 0;
if (Utilities.checkTrueOrFalse(attributes, ElementTags.LEFT)) {
border |= Rectangle.LEFT;
}
if (Utilities.checkTrueOrFalse(attributes, ElementTags.RIGHT)) {
border |= Rectangle.RIGHT;
}
if (Utilities.checkTrueOrFalse(attributes, ElementTags.TOP)) {
border |= Rectangle.TOP;
}
if (Utilities.checkTrueOrFalse(attributes, ElementTags.BOTTOM)) {
border |= Rectangle.BOTTOM;
}
rect.setBorder(border);
String r = attributes.getProperty(ElementTags.RED);
String g = attributes.getProperty(ElementTags.GREEN);
String b = attributes.getProperty(ElementTags.BLUE);
if (r != null || g != null || b != null) {
int red = 0;
int green = 0;
int blue = 0;
if (r != null)
red = Integer.parseInt(r);
if (g != null)
green = Integer.parseInt(g);
if (b != null)
blue = Integer.parseInt(b);
rect.setBorderColor(new Color(red, green, blue));
} else {
rect.setBorderColor(Markup.decodeColor(attributes
.getProperty(ElementTags.BORDERCOLOR)));
}
r = (String) attributes.remove(ElementTags.BGRED);
g = (String) attributes.remove(ElementTags.BGGREEN);
b = (String) attributes.remove(ElementTags.BGBLUE);
value = attributes.getProperty(ElementTags.BACKGROUNDCOLOR);
if (r != null || g != null || b != null) {
int red = 0;
int green = 0;
int blue = 0;
if (r != null)
red = Integer.parseInt(r);
if (g != null)
green = Integer.parseInt(g);
if (b != null)
blue = Integer.parseInt(b);
rect.setBackgroundColor(new Color(red, green, blue));
} else if (value != null) {
rect.setBackgroundColor(Markup.decodeColor(value));
} else {
value = attributes.getProperty(ElementTags.GRAYFILL);
if (value != null) {
rect.setGrayFill(Float.parseFloat(value + "f"));
}
}
}
/**
* Creates a ChapterAutoNumber object based on a list of properties.
* @param attributes
* @return a Chapter
*/
public static ChapterAutoNumber getChapter(Properties attributes) {
ChapterAutoNumber chapter = new ChapterAutoNumber("");
setSectionParameters(chapter, attributes);
return chapter;
}
/**
* Creates a Section object based on a list of properties.
* @param attributes
* @return a Section
*/
public static Section getSection(Section parent, Properties attributes) {
Section section = parent.addSection("");
setSectionParameters(section, attributes);
return section;
}
/**
* Helper method to create a Chapter/Section object.
* @param attributes
*/
private static void setSectionParameters(Section section,
Properties attributes) {
String value;
value = attributes.getProperty(ElementTags.NUMBERDEPTH);
if (value != null) {
section.setNumberDepth(Integer.parseInt(value));
}
value = attributes.getProperty(ElementTags.INDENT);
if (value != null) {
section.setIndentation(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.INDENTATIONLEFT);
if (value != null) {
section.setIndentationLeft(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.INDENTATIONRIGHT);
if (value != null) {
section.setIndentationRight(Float.parseFloat(value + "f"));
}
}
/**
* Creates an Image object based on a list of properties.
* @param attributes
* @return an Image
*/
public static Image getImage(Properties attributes)
throws BadElementException, MalformedURLException, IOException {
String value;
value = attributes.getProperty(ElementTags.URL);
if (value == null)
throw new MalformedURLException("The URL of the image is missing.");
Image image = Image.getInstance(value);
value = attributes.getProperty(ElementTags.ALIGN);
int align = 0;
if (value != null) {
if (ElementTags.ALIGN_LEFT.equalsIgnoreCase(value))
align |= Image.LEFT;
else if (ElementTags.ALIGN_RIGHT.equalsIgnoreCase(value))
align |= Image.RIGHT;
else if (ElementTags.ALIGN_MIDDLE.equalsIgnoreCase(value))
align |= Image.MIDDLE;
}
if ("true".equalsIgnoreCase(attributes
.getProperty(ElementTags.UNDERLYING)))
align |= Image.UNDERLYING;
if ("true".equalsIgnoreCase(attributes
.getProperty(ElementTags.TEXTWRAP)))
align |= Image.TEXTWRAP;
image.setAlignment(align);
value = attributes.getProperty(ElementTags.ALT);
if (value != null) {
image.setAlt(value);
}
String x = attributes.getProperty(ElementTags.ABSOLUTEX);
String y = attributes.getProperty(ElementTags.ABSOLUTEY);
if ((x != null) && (y != null)) {
image.setAbsolutePosition(Float.parseFloat(x + "f"), Float
.parseFloat(y + "f"));
}
value = attributes.getProperty(ElementTags.PLAINWIDTH);
if (value != null) {
image.scaleAbsoluteWidth(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.PLAINHEIGHT);
if (value != null) {
image.scaleAbsoluteHeight(Float.parseFloat(value + "f"));
}
value = attributes.getProperty(ElementTags.ROTATION);
if (value != null) {
image.setRotation(Float.parseFloat(value + "f"));
}
return image;
}
/**
* Creates an Annotation object based on a list of properties.
* @param attributes
* @return an Annotation
*/
public static Annotation getAnnotation(Properties attributes) {
float llx = 0, lly = 0, urx = 0, ury = 0;
String value;
value = attributes.getProperty(ElementTags.LLX);
if (value != null) {
llx = Float.parseFloat(value + "f");
}
value = attributes.getProperty(ElementTags.LLY);
if (value != null) {
lly = Float.parseFloat(value + "f");
}
value = attributes.getProperty(ElementTags.URX);
if (value != null) {
urx = Float.parseFloat(value + "f");
}
value = attributes.getProperty(ElementTags.URY);
if (value != null) {
ury = Float.parseFloat(value + "f");
}
String title = attributes.getProperty(ElementTags.TITLE);
String text = attributes.getProperty(ElementTags.CONTENT);
if (title != null || text != null) {
return new Annotation(title, text, llx, lly, urx, ury);
}
value = attributes.getProperty(ElementTags.URL);
if (value != null) {
return new Annotation(llx, lly, urx, ury, value);
}
value = attributes.getProperty(ElementTags.NAMED);
if (value != null) {
return new Annotation(llx, lly, urx, ury, Integer.parseInt(value));
}
String file = attributes.getProperty(ElementTags.FILE);
String destination = attributes.getProperty(ElementTags.DESTINATION);
String page = (String) attributes.remove(ElementTags.PAGE);
if (file != null) {
if (destination != null) {
return new Annotation(llx, lly, urx, ury, file, destination);
}
if (page != null) {
return new Annotation(llx, lly, urx, ury, file, Integer
.parseInt(page));
}
}
return new Annotation("", "", llx, lly, urx, ury);
}
}

131
src/main/java/com/fr/third/lowagie/text/factories/GreekAlphabetFactory.java

@ -0,0 +1,131 @@
/*
* $Id: GreekAlphabetFactory.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.factories;
import com.fr.third.lowagie.text.SpecialSymbol;
/**
* This class can produce String combinations representing a number built with
* Greek letters (from alpha to omega, then alpha alpha, alpha beta, alpha gamma).
* We are aware of the fact that the original Greek numbering is different;
* See http://www.cogsci.indiana.edu/farg/harry/lan/grknum.htm#ancient
* but this isn't implemented yet; the main reason being the fact that we
* need a font that has the obsolete Greek characters qoppa and sampi.
*
* @since 2.0.7 (was called GreekNumberFactory in earlier versions)
*/
public class GreekAlphabetFactory {
/**
* Changes an int into a lower case Greek letter combination.
* @param index the original number
* @return the letter combination
*/
public static final String getString(int index) {
return getString(index, true);
}
/**
* Changes an int into a lower case Greek letter combination.
* @param index the original number
* @return the letter combination
*/
public static final String getLowerCaseString(int index) {
return getString(index);
}
/**
* Changes an int into a upper case Greek letter combination.
* @param index the original number
* @return the letter combination
*/
public static final String getUpperCaseString(int index) {
return getString(index).toUpperCase();
}
/**
* Changes an int into a Greek letter combination.
* @param index the original number
* @return the letter combination
*/
public static final String getString(int index, boolean lowercase) {
if (index < 1) return "";
index--;
int bytes = 1;
int start = 0;
int symbols = 24;
while(index >= symbols + start) {
bytes++;
start += symbols;
symbols *= 24;
}
int c = index - start;
char[] value = new char[bytes];
while(bytes > 0) {
bytes--;
value[bytes] = (char)(c % 24);
if (value[bytes] > 16) value[bytes]++;
value[bytes] += (lowercase ? 945 : 913);
value[bytes] = SpecialSymbol.getCorrespondingSymbol(value[bytes]);
c /= 24;
}
return String.valueOf(value);
}
/**
* Test this class using this main method.
*/
public static void main(String[] args) {
for (int i = 1; i < 1000; i++) {
System.out.println(getString(i));
}
}
}

129
src/main/java/com/fr/third/lowagie/text/factories/RomanAlphabetFactory.java

@ -0,0 +1,129 @@
/*
* $Id: RomanAlphabetFactory.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.factories;
/**
* This class can produce String combinations representing a number.
* "a" to "z" represent 1 to 26, "AA" represents 27, "AB" represents 28,
* and so on; "ZZ" is followed by "AAA".
*/
public class RomanAlphabetFactory {
/**
* Translates a positive integer (not equal to zero)
* into a String using the letters 'a' to 'z';
* 1 = a, 2 = b, ..., 26 = z, 27 = aa, 28 = ab,...
*/
public static final String getString(int index) {
if (index < 1) throw new NumberFormatException(
"You can't translate a negative number into an alphabetical value.");
index--;
int bytes = 1;
int start = 0;
int symbols = 26;
while(index >= symbols + start) {
bytes++;
start += symbols;
symbols *= 26;
}
int c = index - start;
char[] value = new char[bytes];
while(bytes > 0) {
value[--bytes] = (char)( 'a' + (c % 26));
c /= 26;
}
return new String(value);
}
/**
* Translates a positive integer (not equal to zero)
* into a String using the letters 'a' to 'z';
* 1 = a, 2 = b, ..., 26 = z, 27 = aa, 28 = ab,...
*/
public static final String getLowerCaseString(int index) {
return getString(index);
}
/**
* Translates a positive integer (not equal to zero)
* into a String using the letters 'A' to 'Z';
* 1 = A, 2 = B, ..., 26 = Z, 27 = AA, 28 = AB,...
*/
public static final String getUpperCaseString(int index) {
return getString(index).toUpperCase();
}
/**
* Translates a positive integer (not equal to zero)
* into a String using the letters 'a' to 'z'
* (a = 1, b = 2, ..., z = 26, aa = 27, ab = 28,...).
*/
public static final String getString(int index, boolean lowercase) {
if (lowercase) {
return getLowerCaseString(index);
}
else {
return getUpperCaseString(index);
}
}
/**
* Test this class using this main method.
*/
public static void main(String[] args) {
for (int i = 1; i < 32000; i++) {
System.out.println(getString(i));
}
}
}

185
src/main/java/com/fr/third/lowagie/text/factories/RomanNumberFactory.java

@ -0,0 +1,185 @@
/*
* $Id: RomanNumberFactory.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2007 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.factories;
/**
* This class can produce String combinations representing a roman number.
*/
public class RomanNumberFactory {
/**
* Helper class for Roman Digits
*/
private static class RomanDigit {
/** part of a roman number */
public char digit;
/** value of the roman digit */
public int value;
/** can the digit be used as a prefix */
public boolean pre;
/**
* Constructs a roman digit
* @param digit the roman digit
* @param value the value
* @param pre can it be used as a prefix
*/
RomanDigit(char digit, int value, boolean pre) {
this.digit = digit;
this.value = value;
this.pre = pre;
}
}
/**
* Array with Roman digits.
*/
private static final RomanDigit[] roman = {
new RomanDigit('m', 1000, false),
new RomanDigit('d', 500, false),
new RomanDigit('c', 100, true),
new RomanDigit('l', 50, false),
new RomanDigit('x', 10, true),
new RomanDigit('v', 5, false),
new RomanDigit('i', 1, true)
};
/**
* Changes an int into a lower case roman number.
* @param index the original number
* @return the roman number (lower case)
*/
public static final String getString(int index) {
StringBuffer buf = new StringBuffer();
// lower than 0 ? Add minus
if (index < 0) {
buf.append('-');
index = -index;
}
// greater than 3000
if (index > 3000) {
buf.append('|');
buf.append(getString(index / 1000));
buf.append('|');
// remainder
index = index - (index / 1000) * 1000;
}
// number between 1 and 3000
int pos = 0;
while (true) {
// loop over the array with values for m-d-c-l-x-v-i
RomanDigit dig = roman[pos];
// adding as many digits as we can
while (index >= dig.value) {
buf.append(dig.digit);
index -= dig.value;
}
// we have the complete number
if (index <= 0) {
break;
}
// look for the next digit that can be used in a special way
int j = pos;
while (!roman[++j].pre);
// does the special notation apply?
if (index + roman[j].value >= dig.value) {
buf.append(roman[j].digit).append(dig.digit);
index -= dig.value - roman[j].value;
}
pos++;
}
return buf.toString();
}
/**
* Changes an int into a lower case roman number.
* @param index the original number
* @return the roman number (lower case)
*/
public static final String getLowerCaseString(int index) {
return getString(index);
}
/**
* Changes an int into an upper case roman number.
* @param index the original number
* @return the roman number (lower case)
*/
public static final String getUpperCaseString(int index) {
return getString(index).toUpperCase();
}
/**
* Changes an int into a roman number.
* @param index the original number
* @return the roman number (lower case)
*/
public static final String getString(int index, boolean lowercase) {
if (lowercase) {
return getLowerCaseString(index);
}
else {
return getUpperCaseString(index);
}
}
/**
* Test this class using this main method.
*/
public static void main(String[] args) {
for (int i = 1; i < 2000; i++) {
System.out.println(getString(i));
}
}
}

40
src/main/java/com/fr/third/lowagie/text/html/Border.java

@ -0,0 +1,40 @@
package com.fr.third.lowagie.text.html;
import java.awt.Color;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/6/15
*/
public class Border {
public final static int DEFAULT_WIDTH = 2;
private float width = DEFAULT_WIDTH;
private String style;
private Color color = Color.BLACK;
public float getWidth() {
return width;
}
public void setWidth(float width) {
this.width = width;
}
public String getStyle() {
return style;
}
public void setStyle(String style) {
this.style = style;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}

107
src/main/java/com/fr/third/lowagie/text/html/BorderAttribute.java

@ -0,0 +1,107 @@
package com.fr.third.lowagie.text.html;
import com.fr.stable.StringUtils;
import java.awt.Color;
import java.util.Map;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/6/15
*/
public class BorderAttribute {
protected Border top = new Border();
protected Border right = new Border();
protected Border bottom = new Border();
protected Border left = new Border();
public Border getTop() { return top; }
public Border getRight() {
return right;
}
public Border getBottom() {
return bottom;
}
public Border getLeft() {
return left;
}
/**
* 将解析好的边框属性转化为 BorderAttribute
*
* @param map
* @return
*/
public BorderAttribute applyBorderAttr(Map<String, String> map) {
if (null == map || map.isEmpty()) {
return this;
}
String topWidth = map.get(Markup.CSS_KEY_BORDERWIDTHTOP);
String style = map.get(Markup.CSS_KEY_BORDERSTYLETOP);
if (verify(style)) {
Color color = Markup.decodeColor(map.get(Markup.CSS_KEY_BORDERCOLORTOP));
top.setWidth(StringUtils.isEmpty(topWidth) ? Border.DEFAULT_WIDTH : CSSUtils.parseFloat(topWidth));
top.setStyle(style);
top.setColor(null == color ? Color.BLACK : color);
}
String rightWidth = map.get(Markup.CSS_KEY_BORDERWIDTHRIGHT);
style = map.get(Markup.CSS_KEY_BORDERSTYLERIGHT);
if (verify(style)) {
Color color = Markup.decodeColor(map.get(Markup.CSS_KEY_BORDERCOLORRIGHT));
right.setWidth(StringUtils.isEmpty(rightWidth) ? Border.DEFAULT_WIDTH : CSSUtils.parseFloat(rightWidth));
right.setStyle(style);
right.setColor(null == color ? Color.BLACK : color);
}
String bottomWidth = map.get(Markup.CSS_KEY_BORDERWIDTHBOTTOM);
style = map.get(Markup.CSS_KEY_BORDERSTYLEBOTTOM);
if (verify(style)) {
Color color = Markup.decodeColor(map.get(Markup.CSS_KEY_BORDERCOLORBOTTOM));
bottom.setWidth(StringUtils.isEmpty(bottomWidth) ? Border.DEFAULT_WIDTH : CSSUtils.parseFloat(bottomWidth));
bottom.setStyle(style);
bottom.setColor(null == color ? Color.BLACK : color);
}
String leftWidth = map.get(Markup.CSS_KEY_BORDERWIDTHLEFT);
style = map.get(Markup.CSS_KEY_BORDERSTYLELEFT);
if (verify(style)) {
Color color = Markup.decodeColor(map.get(Markup.CSS_KEY_BORDERCOLORLEFT));
left.setWidth(StringUtils.isEmpty(leftWidth) ? Border.DEFAULT_WIDTH : CSSUtils.parseFloat(leftWidth));
left.setStyle(style);
left.setColor(null == color ? Color.BLACK : color);
}
return this;
}
/**
* 将边框属性 拼接成 parse style 中的值
*
* @return
*/
public String toStyleAttr() {
StringBuffer sb = new StringBuffer();
sb.append(border2StyleAttr(Markup.CSS_KEY_BORDERTOP, top)).append(border2StyleAttr(Markup.CSS_KEY_BORDERRIGHT, right))
.append(border2StyleAttr(Markup.CSS_KEY_BORDERBOTTOM, bottom)).append(border2StyleAttr(Markup.CSS_KEY_BORDERLEFT, left));
return sb.toString();
}
private String border2StyleAttr(String key, Border border) {
if (!verify(border)) {
return "";
}
Color color = null == border.getColor() ? Color.BLACK : border.getColor();
StringBuilder sb = new StringBuilder();
sb.append(key).append(":").append(border.getWidth()).append("px ")
.append(border.getStyle()).append(" ").append(null == color ? "" : "rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");");
return sb.toString();
}
private boolean verify(String style) {
return StringUtils.isNotEmpty(style);
}
private boolean verify(Border border) {
return verify(border.getStyle());
}
}

79
src/main/java/com/fr/third/lowagie/text/html/BorderEnum.java

@ -0,0 +1,79 @@
package com.fr.third.lowagie.text.html;
import java.util.List;
import java.util.Map;
/**
* @author Hugh.C
* @version 1.0
* Created by Hugh.C on 2020/6/15
*/
public enum BorderEnum {
TOP {
@Override
public void fillAttr(Map<String, String> map, List<String> borderAttr) {
map.put(Markup.CSS_KEY_BORDERWIDTHTOP, borderAttr.get(0));
map.put(Markup.CSS_KEY_BORDERSTYLETOP, borderAttr.get(1));
map.put(Markup.CSS_KEY_BORDERCOLORTOP, borderAttr.get(2));
}
},
RIGHT {
@Override
public void fillAttr(Map<String, String> map, List<String> borderAttr) {
map.put(Markup.CSS_KEY_BORDERWIDTHRIGHT, borderAttr.get(0));
map.put(Markup.CSS_KEY_BORDERSTYLERIGHT, borderAttr.get(1));
map.put(Markup.CSS_KEY_BORDERCOLORRIGHT, borderAttr.get(2));
}
},
BOTTOM {
@Override
public void fillAttr(Map<String, String> map, List<String> borderAttr) {
map.put(Markup.CSS_KEY_BORDERWIDTHBOTTOM, borderAttr.get(0));
map.put(Markup.CSS_KEY_BORDERSTYLEBOTTOM, borderAttr.get(1));
map.put(Markup.CSS_KEY_BORDERCOLORBOTTOM, borderAttr.get(2));
}
},
LEFT {
public void fillAttr(Map<String, String> map, List<String> borderAttr) {
map.put(Markup.CSS_KEY_BORDERWIDTHLEFT, borderAttr.get(0));
map.put(Markup.CSS_KEY_BORDERSTYLELEFT, borderAttr.get(1));
map.put(Markup.CSS_KEY_BORDERCOLORLEFT, borderAttr.get(2));
}
},
DEFAULT {
@Override
public void fillAttr(Map<String, String> map, List<String> borderAttr) {
}
};
public static BorderEnum get(String str) {
switch (str) {
case Markup.CSS_KEY_BORDERTOP:
return TOP;
case Markup.CSS_KEY_BORDERRIGHT:
return RIGHT;
case Markup.CSS_KEY_BORDERBOTTOM:
return BOTTOM;
case Markup.CSS_KEY_BORDERLEFT:
return LEFT;
default:
return DEFAULT;
}
}
public abstract void fillAttr(Map<String, String> map, List<String> borderAttr);
public void dealAttr(Map<String, String> map, List<String> borderAttr) {
if (null == map || null == borderAttr || borderAttr.size() > 3 || borderAttr.size() < 2) {
return;
}
//保证 borderAttr 大小为3,即 线条粗细、样式、颜色都需要具备
if (2 == borderAttr.size()) {
borderAttr.add("black");
}
fillAttr(map,borderAttr);
}
}

200
src/main/java/com/fr/third/lowagie/text/html/CSS.java

@ -0,0 +1,200 @@
package com.fr.third.lowagie.text.html;
/**
* @author kerry
* @date 2018/5/11
*/
public class CSS{
public final class Value {
private Value(){};
public static final String THIN = "thin";
public static final String MEDIUM = "medium";
public static final String THICK = "thick";
public static final String NONE = "none";
public static final String HIDDEN = "hidden";
public static final String DOTTED = "dotted";
public static final String DASHED = "dashed";
public static final String SOLID = "solid";
public static final String DOUBLE = "double";
public static final String GROOVE = "groove";
public static final String RIDGE = "ridge";
public static final String INSET = "inset";
public static final String OUTSET = "outset";
public static final String LEFT = "left";
public static final String CENTER = "center";
public static final String JUSTIFY = "justify";
public static final String BOTTOM = "bottom";
public static final String TOP = "top";
public static final String RIGHT = "right";
public static final String REPEAT = "repeat";
public static final String NO_REPEAT = "no-repeat";
public static final String REPEAT_X = "repeat-x";
public static final String REPEAT_Y = "repeat-y";
public static final String FIXED = "fixed";
public static final String SCROLL = "scroll";
public static final String DISC = "disc";
public static final String SQUARE = "square";
public static final String CIRCLE = "circle";
public static final String DECIMAL = "decimal";
public static final String LOWER_ROMAN = "lower-roman";
public static final String UPPER_ROMAN = "upper-roman";
public static final String LOWER_GREEK = "lower-greek";
public static final String UPPER_GREEK = "upper-greek";
public static final String LOWER_ALPHA = "lower-alpha";
public static final String UPPER_ALPHA = "upper-alpha";
public static final String LOWER_LATIN = "lower-latin";
public static final String UPPER_LATIN = "upper-latin";
public static final String INSIDE = "inside";
public static final String OUTSIDE = "outside";
public static final String INHERIT = "inherit";
public static final String UNDERLINE = "underline";
public static final String BOLD = "bold";
public static final String ITALIC = "italic";
public static final String OBLIQUE = "oblique";
public static final String SUPER = "super";
public static final String SUB = "sub";
public static final String TEXT_TOP = "text-top";
public static final String TEXT_BOTTOM = "text-bottom";
public static final String LINE_THROUGH = "line-through";
public static final String RELATIVE = "relative";
public static final String HIDE = "hide";
public static final String XX_SMALL = "xx-small";
public static final String X_SMALL = "x-small";
public static final String SMALL = "small";
public static final String LARGE = "large";
public static final String X_LARGE = "x-large";
public static final String XX_LARGE = "xx-large";
public static final String SMALLER = "smaller";
public static final String LARGER = "larger";
public static final String PX = "px";
public static final String IN = "in";
public static final String CM = "cm";
public static final String MM = "mm";
public static final String PT = "pt";
public static final String PC = "pc";
public static final String PERCENTAGE = "%";
public static final String EM = "em";
public static final String EX = "ex";
public static final String ALWAYS = "always";
public static final String AVOID = "avoid";
public static final String ABSOLUTE = "absolute";
public static final String AUTO = "auto";
public static final String INLINE = "inline";
public static final String BLOCK = "block";
public static final String SEPARATE = "separate";
public static final String COLLAPSE = "collapse";
public static final String RTL = "rtl";
public static final String LTR = "ltr";
public static final String INLINE_BLOCK = "inline-block";
public static final String INLINE_TABLE = "inline-table";
public static final String LIST_ITEM = "list-item";
public static final String RUN_IN = "run-in";
public static final String TABLE = "table";
public static final String TABLE_CAPTION = "table-caption";
public static final String TABLE_CELL = "table-cell";
public static final String TABLE_COLUMN_GROUP = "table-column-group";
public static final String TABLE_COLUMN = "table-column";
public static final String TABLE_FOOTER_GROUP = "table-footer-group";
public static final String TABLE_HEADER_GROUP = "table-header-group";
public static final String TABLE_ROW = "table-row";
public static final String TABLE_ROW_GROUP = "table-row-group";
}
public final class Property {
private Property() {};
public static final String BACKGROUND = "background";
public static final String BACKGROUND_IMAGE = "background-image";
public static final String BACKGROUND_REPEAT = "background-repeat";
public static final String BACKGROUND_ATTACHMENT = "background-attachment";
public static final String BACKGROUND_POSITION = "background-position";
public static final String BACKGROUND_COLOR = "background-color";
public static final String BACKGROUND_SIZE = "background-size";
public static final String LIST_STYLE = "list-style";
public static final String LIST_STYLE_TYPE = "list-style-type";
public static final String LIST_STYLE_POSITION = "list-style-position";
public static final String LIST_STYLE_IMAGE = "list-style-image";
public static final String MARGIN = "margin";
public static final String TOP = "top";
public static final String MARGIN_LEFT = "margin-left";
public static final String MARGIN_RIGHT = "margin-right";
public static final String MARGIN_TOP = "margin-top";
public static final String MARGIN_BOTTOM = "margin-bottom";
public static final String BORDER = "border";
public static final String BORDER_LEFT = "border-left";
public static final String BORDER_TOP = "border-top";
public static final String BORDER_RIGHT = "border-right";
public static final String BORDER_BOTTOM = "border-bottom";
public static final String BORDER_WIDTH = "border-width";
public static final String BORDER_STYLE = "border-style";
public static final String BORDER_COLOR = "border-color";
public static final String BORDER_COLLAPSE = "border-collapse";
public static final String BORDER_SPACING = "border-spacing";
public static final String BORDER_TOP_WIDTH = "border-top-width";
public static final String BORDER_BOTTOM_WIDTH = "border-bottom-width";
public static final String BORDER_LEFT_WIDTH = "border-left-width";
public static final String BORDER_RIGHT_WIDTH = "border-right-width";
public static final String BORDER_TOP_COLOR = "border-top-color";
public static final String BORDER_BOTTOM_COLOR = "border-bottom-color";
public static final String BORDER_LEFT_COLOR = "border-left-color";
public static final String BORDER_RIGHT_COLOR = "border-right-color";
public static final String BORDER_TOP_STYLE = "border-top-style";
public static final String BORDER_BOTTOM_STYLE = "border-bottom-style";
public static final String BORDER_LEFT_STYLE = "border-left-style";
public static final String BORDER_RIGHT_STYLE = "border-right-style";
public static final String PADDING = "padding";
public static final String PADDING_TOP = "padding-top";
public static final String PADDING_BOTTOM = "padding-bottom";
public static final String PADDING_LEFT = "padding-left";
public static final String PADDING_RIGHT = "padding-right";
public static final String FONT = "font";
public static final String FONT_WEIGHT = "font-weight";
public static final String FONT_SIZE = "font-size";
public static final String FONT_STYLE = "font-style";
public static final String FONT_FAMILY = "font-family";
public static final String TEXT_DECORATION = "text-decoration";
public static final String COLOR = "color";
public static final String TAB_INTERVAL = "tab-interval";
public static final String XFA_TAB_COUNT = "xfa-tab-count";
public static final String XFA_FONT_HORIZONTAL_SCALE = "xfa-font-horizontal-scale";
public static final String XFA_FONT_VERTICAL_SCALE = "xfa-font-vertical-scale";
public static final String BEFORE = "before";
public static final String AFTER = "after";
public static final String HEIGHT = "height";
public static final String WIDTH = "width";
public static final String LETTER_SPACING = "letter-spacing";
public static final String VERTICAL_ALIGN = "vertical-align";
public static final String LINE_HEIGHT = "line-height";
public static final String TEXT_ALIGN = "text-align";
public static final String TEXT_VALIGN = "text-valign";
public static final String TEXT_INDENT = "text-indent";
public static final String POSITION = "position";
public static final String EMPTY_CELLS = "empty-cells";
public static final String CELLPADDING = "cellpadding";
//deprecated
public static final String CELLPADDING_LEFT = "cellpadding-left";
public static final String CELLPADDING_TOP = "cellpadding-top";
public static final String CELLPADDING_RIGHT = "cellpadding-right";
public static final String CELLPADDING_BOTTOM = "cellpadding-bottom";
public static final String CAPTION_SIDE = "caption-side";
public static final String TAB_STOPS = "tab-stops";
public static final String XFA_TAB_STOPS = "xfa-tab-stops";
public static final String PAGE_BREAK_BEFORE = "page-break-before";
public static final String PAGE_BREAK_INSIDE = "page-break-inside";
public static final String PAGE_BREAK_AFTER = "page-break-after";
public static final String REPEAT_HEADER = "repeat-header";
public static final String REPEAT_FOOTER = "repeat-footer";
public static final String LEFT = "left";
public static final String DISPLAY = "display";
public static final String MIN_WIDTH = "min-width";
public static final String MAX_WIDTH = "max-width";
public static final String MIN_HEIGHT = "min-height";
public static final String MAX_HEIGHT = "max-height";
public static final String RIGHT = "right";
public static final String BOTTOM = "bottom";
public static final String FLOAT = "float";
public static final String DIRECTION = "direction";
}
}

110
src/main/java/com/fr/third/lowagie/text/html/CSSUtils.java

@ -0,0 +1,110 @@
package com.fr.third.lowagie.text.html;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author kerry
* @date 2018/4/9
*/
public class CSSUtils {
private static final Set<String> backgroundPositions = new HashSet<String>(
Arrays.asList(new String[] { CSS.Value.LEFT, CSS.Value.CENTER, CSS.Value.BOTTOM, CSS.Value.TOP, CSS.Value.RIGHT }));
public static Map<String, String> processBackground(final String background) {
Map<String, String> rules = new HashMap<String, String>();
String[] styles = splitComplexCssStyle(background);
for(String style : styles) {
if (style.contains("url(")) {
rules.put(CSS.Property.BACKGROUND_IMAGE, style);
} else if (style.equalsIgnoreCase(CSS.Value.REPEAT)
|| style.equalsIgnoreCase(CSS.Value.NO_REPEAT)
|| style.equalsIgnoreCase(CSS.Value.REPEAT_X)
|| style.equalsIgnoreCase(CSS.Value.REPEAT_Y)) {
rules.put(CSS.Property.BACKGROUND_REPEAT, style);
} else if (style.equalsIgnoreCase(CSS.Value.FIXED) || style.equalsIgnoreCase(CSS.Value.SCROLL)) {
rules.put(CSS.Property.BACKGROUND_ATTACHMENT, style);
} else if (backgroundPositions.contains(style)) {
if(rules.get(CSS.Property.BACKGROUND_POSITION) == null) {
rules.put(CSS.Property.BACKGROUND_POSITION, style);
} else {
style = style.concat(" "+rules.get(CSS.Property.BACKGROUND_POSITION));
rules.put(CSS.Property.BACKGROUND_POSITION, style);
}
} else if (style.contains("rgb(") || style.contains("rgba(") || style.contains("#") || WebColors.NAMES.containsKey(style.toLowerCase())) {
rules.put(CSS.Property.BACKGROUND_COLOR, style);
} else if (isNumericValue(style) || isMetricValue(style) || isRelativeValue(style)) {
if(rules.get(CSS.Property.BACKGROUND_POSITION) == null) {
rules.put(CSS.Property.BACKGROUND_POSITION, style);
} else {
style = style.concat(" "+rules.get(CSS.Property.BACKGROUND_POSITION));
rules.put(CSS.Property.BACKGROUND_POSITION, style);
}
}
}
return rules;
}
public static String[] splitComplexCssStyle(String s) {
s = s.replaceAll("\\s*,\\s*", ",") ;
return s.split("\\s");
}
public static boolean isMetricValue(final String value) {
return value.contains(CSS.Value.PX) || value.contains(CSS.Value.IN) || value.contains(CSS.Value.CM)
|| value.contains(CSS.Value.MM) || value.contains(CSS.Value.PC) || value.contains(CSS.Value.PT);
}
public static boolean isRelativeValue(final String value) {
return value.contains(CSS.Value.PERCENTAGE) || value.contains(CSS.Value.EM) || value.contains(CSS.Value.EX);
}
public static boolean isNumericValue(final String value) {
return value.matches("^-?\\d\\d*\\.\\d*$") || value.matches("^-?\\d\\d*$") || value.matches("^-?\\.\\d\\d*$");
}
public static String extractUrl(final String url) {
String str = null;
if (url.startsWith("url")) {
String urlString = url.substring(3).trim().replace("(", "").replace(")", "").trim();
if (urlString.startsWith("'") && urlString.endsWith("'")) {
str = urlString.substring(urlString.indexOf("'")+1, urlString.lastIndexOf("'"));
} else if ( urlString.startsWith("\"") && urlString.endsWith("\"") ) {
str = urlString.substring(urlString.indexOf('"')+1, urlString.lastIndexOf('"'));
} else {
str = urlString;
}
} else {
str = url;
}
return str;
}
public static Float parseFloat(String str){
float result = 0.0f;
if(str == null){
return result;
}
try {
if(str.endsWith("px") || str.endsWith("pt")){
result = Float.parseFloat(str.substring(0, str.length() - 2));
}else if(str.endsWith("%")){
result = Float.parseFloat(str.substring(0, str.length() - 1));
}else {
result = Float.parseFloat(str);
}
}catch (NumberFormatException e){
return result;
}
return result;
}
}

210
src/main/java/com/fr/third/lowagie/text/html/HtmlEncoder.java

@ -0,0 +1,210 @@
/*
* $Id: HtmlEncoder.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.awt.Color;
import com.fr.third.lowagie.text.Element;
/**
* This class converts a <CODE>String</CODE> to the HTML-format of a String.
* <P>
* To convert the <CODE>String</CODE>, each character is examined:
* <UL>
* <LI>ASCII-characters from 000 till 031 are represented as &amp;#xxx;<BR>
* (with xxx = the value of the character)
* <LI>ASCII-characters from 032 t/m 127 are represented by the character itself, except for:
* <UL>
* <LI>'\n' becomes &lt;BR&gt;\n
* <LI>&quot; becomes &amp;quot;
* <LI>&amp; becomes &amp;amp;
* <LI>&lt; becomes &amp;lt;
* <LI>&gt; becomes &amp;gt;
* </UL>
* <LI>ASCII-characters from 128 till 255 are represented as &amp;#xxx;<BR>
* (with xxx = the value of the character)
* </UL>
* <P>
* Example:
* <P><BLOCKQUOTE><PRE>
* String htmlPresentation = HtmlEncoder.encode("Marie-Th&#233;r&#232;se S&#248;rensen");
* </PRE></BLOCKQUOTE><P>
* for more info: see O'Reilly; "HTML: The Definitive Guide" (page 164)
*
* @author mario.maccarini@ugent.be
*/
public final class HtmlEncoder {
// membervariables
/** List with the HTML translation of all the characters. */
private static final String[] htmlCode = new String[256];
static {
for (int i = 0; i < 10; i++) {
htmlCode[i] = "&#00" + i + ";";
}
for (int i = 10; i < 32; i++) {
htmlCode[i] = "&#0" + i + ";";
}
for (int i = 32; i < 128; i++) {
htmlCode[i] = String.valueOf((char)i);
}
// Special characters
htmlCode['\t'] = "\t";
htmlCode['\n'] = "<" + HtmlTags.NEWLINE + " />\n";
htmlCode['\"'] = "&quot;"; // double quote
htmlCode['&'] = "&amp;"; // ampersand
htmlCode['<'] = "&lt;"; // lower than
htmlCode['>'] = "&gt;"; // greater than
for (int i = 128; i < 256; i++) {
htmlCode[i] = "&#" + i + ";";
}
}
// constructors
/**
* This class will never be constructed.
* <P>
* HtmlEncoder only contains static methods.
*/
private HtmlEncoder () { }
// methods
/**
* Converts a <CODE>String</CODE> to the HTML-format of this <CODE>String</CODE>.
*
* @param string The <CODE>String</CODE> to convert
* @return a <CODE>String</CODE>
*/
public static String encode(String string) {
int n = string.length();
char character;
StringBuffer buffer = new StringBuffer();
// loop over all the characters of the String.
for (int i = 0; i < n; i++) {
character = string.charAt(i);
// the Htmlcode of these characters are added to a StringBuffer one by one
if (character < 256) {
buffer.append(htmlCode[character]);
}
else {
// Improvement posted by Joachim Eyrich
buffer.append("&#").append((int)character).append(';');
}
}
return buffer.toString();
}
/**
* Converts a <CODE>Color</CODE> into a HTML representation of this <CODE>Color</CODE>.
*
* @param color the <CODE>Color</CODE> that has to be converted.
* @return the HTML representation of this <COLOR>Color</COLOR>
*/
public static String encode(Color color) {
StringBuffer buffer = new StringBuffer("#");
if (color.getRed() < 16) {
buffer.append('0');
}
buffer.append(Integer.toString(color.getRed(), 16));
if (color.getGreen() < 16) {
buffer.append('0');
}
buffer.append(Integer.toString(color.getGreen(), 16));
if (color.getBlue() < 16) {
buffer.append('0');
}
buffer.append(Integer.toString(color.getBlue(), 16));
return buffer.toString();
}
/**
* Translates the alignment value.
*
* @param alignment the alignment value
* @return the translated value
*/
public static String getAlignment(int alignment) {
switch(alignment) {
case Element.ALIGN_LEFT:
return HtmlTags.ALIGN_LEFT;
case Element.ALIGN_CENTER:
return HtmlTags.ALIGN_CENTER;
case Element.ALIGN_RIGHT:
return HtmlTags.ALIGN_RIGHT;
case Element.ALIGN_JUSTIFIED:
case Element.ALIGN_JUSTIFIED_ALL:
return HtmlTags.ALIGN_JUSTIFIED;
case Element.ALIGN_TOP:
return HtmlTags.ALIGN_TOP;
case Element.ALIGN_MIDDLE:
return HtmlTags.ALIGN_MIDDLE;
case Element.ALIGN_BOTTOM:
return HtmlTags.ALIGN_BOTTOM;
case Element.ALIGN_BASELINE:
return HtmlTags.ALIGN_BASELINE;
default:
return "";
}
}
}

192
src/main/java/com/fr/third/lowagie/text/html/HtmlParser.java

@ -0,0 +1,192 @@
/*
* $Id: HtmlParser.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import com.fr.third.lowagie.text.ExceptionConverter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.fr.third.lowagie.text.DocListener;
import com.fr.third.lowagie.text.xml.XmlParser;
/**
* This class can be used to parse some HTML files.
*/
public class HtmlParser extends XmlParser {
/**
* Constructs an HtmlParser.
*/
public HtmlParser() {
super();
}
/**
* Parses a given file.
* @param document the document the parser will write to
* @param is the InputSource with the content
*/
public void go(DocListener document, InputSource is) {
try {
parser.parse(is, new SAXmyHtmlHandler(document));
}
catch(SAXException se) {
throw new ExceptionConverter(se);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/**
* Parses a given file that validates with the iText DTD and writes the content to a document.
* @param document the document the parser will write to
* @param is the InputSource with the content
*/
public static void parse(DocListener document, InputSource is) {
HtmlParser p = new HtmlParser();
p.go(document, is);
}
/**
* Parses a given file.
* @param document the document the parser will write to
* @param file the file with the content
*/
public void go(DocListener document, String file) {
try {
parser.parse(file, new SAXmyHtmlHandler(document));
}
catch(SAXException se) {
throw new ExceptionConverter(se);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/**
* Parses a given file that validates with the iText DTD and writes the content to a document.
* @param document the document the parser will write to
* @param file the file with the content
*/
public static void parse(DocListener document, String file) {
HtmlParser p = new HtmlParser();
p.go(document, file);
}
/**
* Parses a given file.
* @param document the document the parser will write to
* @param is the InputStream with the content
*/
public void go(DocListener document, InputStream is) {
try {
parser.parse(new InputSource(is), new SAXmyHtmlHandler(document));
}
catch(SAXException se) {
throw new ExceptionConverter(se);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/**
* Parses a given file that validates with the iText DTD and writes the content to a document.
* @param document the document the parser will write to
* @param is the InputStream with the content
*/
public static void parse(DocListener document, InputStream is) {
HtmlParser p = new HtmlParser();
p.go(document, new InputSource(is));
}
/**
* Parses a given file.
* @param document the document the parser will write to
* @param is the Reader with the content
*/
public void go(DocListener document, Reader is) {
try {
parser.parse(new InputSource(is), new SAXmyHtmlHandler(document));
}
catch(SAXException se) {
throw new ExceptionConverter(se);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
}
/**
* Parses a given file that validates with the iText DTD and writes the content to a document.
* @param document the document the parser will write to
* @param is the Reader with the content
*/
public static void parse(DocListener document, Reader is) {
HtmlParser p = new HtmlParser();
p.go(document, new InputSource(is));
}
}

111
src/main/java/com/fr/third/lowagie/text/html/HtmlPeer.java

@ -0,0 +1,111 @@
/*
* $Id: HtmlPeer.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.util.Properties;
import com.fr.third.lowagie.text.xml.XmlPeer;
import org.xml.sax.Attributes;
import com.fr.third.lowagie.text.ElementTags;
/**
* This interface is implemented by the peer of all the iText objects.
*/
public class HtmlPeer extends XmlPeer {
/**
* Creates a XmlPeer.
*
* @param name
* the iText name of the tag
* @param alias
* the Html name of the tag
*/
public HtmlPeer(String name, String alias) {
super(name, alias.toLowerCase());
}
/**
* Sets an alias for an attribute.
*
* @param name
* the iText tagname
* @param alias
* the custom tagname
*/
public void addAlias(String name, String alias) {
attributeAliases.put(alias.toLowerCase(), name);
}
/**
* @see XmlPeer#getAttributes(Attributes)
*/
public Properties getAttributes(Attributes attrs) {
Properties attributes = new Properties();
attributes.putAll(attributeValues);
if (defaultContent != null) {
attributes.put(ElementTags.ITEXT, defaultContent);
}
if (attrs != null) {
String attribute, value;
for (int i = 0; i < attrs.getLength(); i++) {
attribute = getName(attrs.getQName(i).toLowerCase());
value = attrs.getValue(i);
attributes.setProperty(attribute, value);
}
}
return attributes;
}
}

302
src/main/java/com/fr/third/lowagie/text/html/HtmlTagMap.java

@ -0,0 +1,302 @@
/*
* $Id: HtmlTagMap.java 3528 2008-07-07 14:46:09Z Howard_s $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* Contributions by:
* Lubos Strapko
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.util.HashMap;
import com.fr.third.lowagie.text.FontFactory;
import com.fr.third.lowagie.text.ElementTags;
/**
* The <CODE>Tags</CODE>-class maps several XHTML-tags to iText-objects.
*/
public class HtmlTagMap extends HashMap {
private static final long serialVersionUID = 5287430058473705350L;
/**
* Constructs an HtmlTagMap.
*/
public HtmlTagMap() {
super();
HtmlPeer peer;
peer = new HtmlPeer(ElementTags.ITEXT, HtmlTags.HTML);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.SPAN);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.CHUNK);
peer.addAlias(ElementTags.FONT, HtmlTags.FONT);
peer.addAlias(ElementTags.SIZE, HtmlTags.SIZE);
peer.addAlias(ElementTags.COLOR, HtmlTags.COLOR);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.ANCHOR, HtmlTags.ANCHOR);
peer.addAlias(ElementTags.NAME, HtmlTags.NAME);
peer.addAlias(ElementTags.REFERENCE, HtmlTags.REFERENCE);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.PARAGRAPH);
peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.DIV);
peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[0]);
peer.addValue(ElementTags.SIZE, "20");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[1]);
peer.addValue(ElementTags.SIZE, "18");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[2]);
peer.addValue(ElementTags.SIZE, "16");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[3]);
peer.addValue(ElementTags.SIZE, "14");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[4]);
peer.addValue(ElementTags.SIZE, "12");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[5]);
peer.addValue(ElementTags.SIZE, "10");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.LIST, HtmlTags.ORDEREDLIST);
peer.addValue(ElementTags.NUMBERED, "true");
peer.addValue(ElementTags.SYMBOLINDENT, "20");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.LIST, HtmlTags.UNORDEREDLIST);
peer.addValue(ElementTags.NUMBERED, "false");
peer.addValue(ElementTags.SYMBOLINDENT, "20");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.LISTITEM, HtmlTags.LISTITEM);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.I);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.EM);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.B);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.STRONG);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.S);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_LINETHROUGH);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.CODE);
peer.addValue(ElementTags.FONT, FontFactory.COURIER);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.VAR);
peer.addValue(ElementTags.FONT, FontFactory.COURIER);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.U);
peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_UNDERLINE);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUP);
peer.addValue(ElementTags.SUBSUPSCRIPT, "6.0");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUB);
peer.addValue(ElementTags.SUBSUPSCRIPT, "-6.0");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.HORIZONTALRULE, HtmlTags.HORIZONTALRULE);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.TABLE, HtmlTags.TABLE);
peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
peer.addAlias(ElementTags.COLUMNS, HtmlTags.COLUMNS);
peer.addAlias(ElementTags.CELLPADDING, HtmlTags.CELLPADDING);
peer.addAlias(ElementTags.CELLSPACING, HtmlTags.CELLSPACING);
peer.addAlias(ElementTags.BORDERWIDTH, HtmlTags.BORDERWIDTH);
peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.ROW, HtmlTags.ROW);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.CELL, HtmlTags.CELL);
peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN);
peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN);
peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP);
peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN);
peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN);
peer.addValue(ElementTags.HEADER, "false");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.CELL, HtmlTags.HEADERCELL);
peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN);
peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN);
peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP);
peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN);
peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN);
peer.addValue(ElementTags.HEADER, "true");
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.IMAGE, HtmlTags.IMAGE);
// peer.addAlias(ElementTags.URL, HtmlTags.URL);
peer.addAlias(ElementTags.URL, ElementTags.SRC); // contributed by Lubos Strapko
peer.addAlias(ElementTags.ALT, HtmlTags.ALT);
peer.addAlias(ElementTags.PLAINWIDTH, HtmlTags.PLAINWIDTH);
peer.addAlias(ElementTags.PLAINHEIGHT, HtmlTags.PLAINHEIGHT);
put(peer.getAlias(), peer);
peer = new HtmlPeer(ElementTags.NEWLINE, HtmlTags.NEWLINE);
put(peer.getAlias(), peer);
}
/**
* Checks if this is the root tag.
* @param tag a tagvalue
* @return true if tag is HTML or parse
*/
public static boolean isHtml(String tag) {
return HtmlTags.HTML.equalsIgnoreCase(tag);
}
/**
* Checks if this is the head tag.
* @param tag a tagvalue
* @return true if tag is HEAD or head
*/
public static boolean isHead(String tag) {
return HtmlTags.HEAD.equalsIgnoreCase(tag);
}
/**
* Checks if this is the meta tag.
* @param tag a tagvalue
* @return true if tag is META or meta
*/
public static boolean isMeta(String tag) {
return HtmlTags.META.equalsIgnoreCase(tag);
}
/**
* Checks if this is the link tag.
* @param tag a tagvalue
* @return true if tag is LINK or link
*/
public static boolean isLink(String tag) {
return HtmlTags.LINK.equalsIgnoreCase(tag);
}
/**
* Checks if this is the title tag.
* @param tag a tagvalue
* @return true if tag is TITLE or title
*/
public static boolean isTitle(String tag) {
return HtmlTags.TITLE.equalsIgnoreCase(tag);
}
/**
* Checks if this is the root tag.
* @param tag a tagvalue
* @return true if tag is BODY or body
*/
public static boolean isBody(String tag) {
return HtmlTags.BODY.equalsIgnoreCase(tag);
}
/**
* Checks if this is a special tag.
* @param tag a tagvalue
* @return true if tag is a HTML, HEAD, META, LINK or BODY tag (case insensitive)
*/
public static boolean isSpecialTag(String tag) {
return isHtml(tag) || isHead(tag) || isMeta(tag) || isLink(tag)
|| isBody(tag);
}
}

342
src/main/java/com/fr/third/lowagie/text/html/HtmlTags.java

@ -0,0 +1,342 @@
/*
* $Id: HtmlTags.java 3533 2008-07-07 21:27:13Z Howard_s $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* Contributions by:
* Lubos Strapko
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import com.fr.third.lowagie.text.ElementTags;
/**
* A class that contains all the possible tagnames and their attributes.
*/
public class HtmlTags {
/** the root tag. */
public static final String HTML = "html";
/** the head tag */
public static final String HEAD = "head";
/** This is a possible HTML attribute for the HEAD tag. */
public static final String CONTENT = "content";
/** the meta tag */
public static final String META = "meta";
/** attribute of the root tag */
public static final String SUBJECT = "subject";
/** attribute of the root tag */
public static final String KEYWORDS = "keywords";
/** attribute of the root tag */
public static final String AUTHOR = "author";
/** the title tag. */
public static final String TITLE = "title";
/** the script tag. */
public static final String SCRIPT = "script";
/** This is a possible HTML attribute for the SCRIPT tag. */
public static final String LANGUAGE = "language";
/** This is a possible value for the LANGUAGE attribute. */
public static final String JAVASCRIPT = "JavaScript";
/** the body tag. */
public static final String BODY = "body";
/** This is a possible HTML attribute for the BODY tag */
public static final String JAVASCRIPT_ONLOAD = "onLoad";
/** This is a possible HTML attribute for the BODY tag */
public static final String JAVASCRIPT_ONUNLOAD = "onUnLoad";
/** This is a possible HTML attribute for the BODY tag. */
public static final String TOPMARGIN = "topmargin";
/** This is a possible HTML attribute for the BODY tag. */
public static final String BOTTOMMARGIN = "bottommargin";
/** This is a possible HTML attribute for the BODY tag. */
public static final String LEFTMARGIN = "leftmargin";
/** This is a possible HTML attribute for the BODY tag. */
public static final String RIGHTMARGIN = "rightmargin";
// Phrases, Anchors, Lists and Paragraphs
/** the chunk tag */
public static final String CHUNK = "font";
/** the phrase tag */
public static final String CODE = "code";
/** the phrase tag */
public static final String VAR = "var";
/** the anchor tag */
public static final String ANCHOR = "a";
/** the list tag */
public static final String ORDEREDLIST = "ol";
/** the list tag */
public static final String UNORDEREDLIST = "ul";
/** the listitem tag */
public static final String LISTITEM = "li";
/** the paragraph tag */
public static final String PARAGRAPH = "p";
/** attribute of anchor tag */
public static final String NAME = "name";
/** attribute of anchor tag */
public static final String REFERENCE = "href";
/** attribute of anchor tag */
public static final String[] H = new String[6];
static {
H[0] = "h1";
H[1] = "h2";
H[2] = "h3";
H[3] = "h4";
H[4] = "h5";
H[5] = "h6";
}
// Chunks
/** attribute of the chunk tag */
public static final String FONT = "face";
/** attribute of the chunk tag */
public static final String SIZE = "point-size";
/** attribute of the chunk/table/cell tag */
public static final String COLOR = "color";
/** some phrase tag */
public static final String EM = "em";
/** some phrase tag */
public static final String I = "i";
/** some phrase tag */
public static final String STRONG = "strong";
/** some phrase tag */
public static final String B = "b";
/** some phrase tag */
public static final String S = "s";
/** some phrase tag */
public static final String U = "u";
/** some phrase tag */
public static final String SUB = "sub";
/** some phrase tag */
public static final String SUP = "sup";
/** the possible value of a tag */
public static final String HORIZONTALRULE = "hr";
// tables/cells
/** the table tag */
public static final String TABLE = "table";
/** the cell tag */
public static final String ROW = "tr";
/** the cell tag */
public static final String CELL = "td";
/** attribute of the cell tag */
public static final String HEADERCELL = "th";
/** attribute of the table tag */
public static final String COLUMNS = "cols";
/** attribute of the table tag */
public static final String CELLPADDING = "cellpadding";
/** attribute of the table tag */
public static final String CELLSPACING = "cellspacing";
/** attribute of the cell tag */
public static final String COLSPAN = "colspan";
/** attribute of the cell tag */
public static final String ROWSPAN = "rowspan";
/** attribute of the cell tag */
public static final String NOWRAP = "nowrap";
/** attribute of the table/cell tag */
public static final String BORDERWIDTH = "border";
/** attribute of the table/cell tag */
public static final String WIDTH = "width";
/** attribute of the table/cell tag */
public static final String BACKGROUNDCOLOR = "bgcolor";
/** attribute of the table/cell tag */
public static final String BORDERCOLOR = "bordercolor";
/** attribute of paragraph/image/table tag */
public static final String ALIGN = "align";
/** attribute of chapter/section/paragraph/table/cell tag */
public static final String LEFT = "left";
/** attribute of chapter/section/paragraph/table/cell tag */
public static final String RIGHT = "right";
/** attribute of the cell tag */
public static final String HORIZONTALALIGN = "align";
/** attribute of the cell tag */
public static final String VERTICALALIGN = "valign";
/** attribute of the table/cell tag */
public static final String TOP = "top";
/** attribute of the table/cell tag */
public static final String BOTTOM = "bottom";
// Misc
/** the image tag */
public static final String IMAGE = "img";
/** attribute of the image tag
* @see ElementTags#SRC
*/
public static final String URL = "src";
/** attribute of the image tag */
public static final String ALT = "alt";
/** attribute of the image tag */
public static final String PLAINWIDTH = "width";
/** attribute of the image tag */
public static final String PLAINHEIGHT = "height";
/** the newpage tag */
public static final String NEWLINE = "br";
// alignment attribute values
/** the possible value of an alignment attribute */
public static final String ALIGN_LEFT = "Left";
/** the possible value of an alignment attribute */
public static final String ALIGN_CENTER = "Center";
/** the possible value of an alignment attribute */
public static final String ALIGN_RIGHT = "Right";
/** the possible value of an alignment attribute */
public static final String ALIGN_JUSTIFIED = "Justify";
/** the possible value of an alignment attribute */
public static final String ALIGN_TOP = "Top";
/** the possible value of an alignment attribute */
public static final String ALIGN_MIDDLE = "Middle";
/** the possible value of an alignment attribute */
public static final String ALIGN_BOTTOM = "Bottom";
/** the possible value of an alignment attribute */
public static final String ALIGN_BASELINE = "Baseline";
/** the possible value of an alignment attribute */
public static final String DEFAULT = "Default";
/** The DIV tag. */
public static final String DIV = "div";
/** The SPAN tag. */
public static final String SPAN = "span";
/** The LINK tag. */
public static final String LINK = "link";
/** This is a possible HTML attribute for the LINK tag. */
public static final String TEXT_CSS = "text/css";
/** This is a possible HTML attribute for the LINK tag. */
public static final String REL = "rel";
/** This is used for inline css style information */
public static final String STYLE = "style";
/** This is a possible HTML attribute for the LINK tag. */
public static final String TYPE = "type";
/** This is a possible HTML attribute. */
public static final String STYLESHEET = "stylesheet";
/** This is a possible HTML attribute for auto-formated
* @since 2.1.3
*/
public static final String PRE = "pre";
}

1130
src/main/java/com/fr/third/lowagie/text/html/HtmlWriter.java

File diff suppressed because it is too large Load Diff

55
src/main/java/com/fr/third/lowagie/text/html/IndentAttribute.java

@ -0,0 +1,55 @@
package com.fr.third.lowagie.text.html;
/**
* @author kerry
* @date 2018/5/9
*/
public class IndentAttribute {
private float top = 0.0f;
private float bottom = 0.0f;
private float left = 0.0f;
private float right = 0.0f;
public float getTop() {
return top;
}
public void setTop(float top) {
this.top = top;
}
public float getBottom() {
return bottom;
}
public void setBottom(float bottom) {
this.bottom = bottom;
}
public float getLeft() {
return left;
}
public void setLeft(float left) {
this.left = left;
}
public float getRight() {
return right;
}
public void setRight(float right) {
this.right = right;
}
public IndentAttribute(float top, float left, float bottom, float right){
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public IndentAttribute(){
}
}

641
src/main/java/com/fr/third/lowagie/text/html/Markup.java

@ -0,0 +1,641 @@
/*
* $Id: Markup.java 3654 2009-01-21 16:11:00Z blowagie $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* Contributions by:
* Lubos Strapko
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import com.fr.plugin.html.parse.utils.HtmlBorderUtils;
import com.fr.stable.Constants;
import com.fr.third.lowagie.text.ElementTags;
import com.fr.third.lowagie.text.html.simpleparser.ChainedProperties;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* A class that contains all the possible tagnames and their attributes.
*/
public class Markup {
// iText specific
/** the key for any tag */
public static final String ITEXT_TAG = "tag";
// HTML tags
/** the markup for the body part of a file */
public static final String HTML_TAG_BODY = "body";
/** The DIV tag. */
public static final String HTML_TAG_DIV = "div";
/** This is a possible HTML-tag. */
public static final String HTML_TAG_LINK = "link";
/** The SPAN tag. */
public static final String HTML_TAG_SPAN = "span";
// HTML attributes
/** the height attribute. */
public static final String HTML_ATTR_HEIGHT = "height";
/** the hyperlink reference attribute. */
public static final String HTML_ATTR_HREF = "href";
/** This is a possible HTML attribute for the LINK tag. */
public static final String HTML_ATTR_REL = "rel";
/** This is used for inline css style information */
public static final String HTML_ATTR_STYLE = "style";
/** This is a possible HTML attribute for the LINK tag. */
public static final String HTML_ATTR_TYPE = "type";
/** This is a possible HTML attribute. */
public static final String HTML_ATTR_STYLESHEET = "stylesheet";
/** the width attribute. */
public static final String HTML_ATTR_WIDTH = "width";
/** attribute for specifying externally defined CSS class */
public static final String HTML_ATTR_CSS_CLASS = "class";
/** The ID attribute. */
public static final String HTML_ATTR_CSS_ID = "id";
// HTML values
/** This is a possible value for the language attribute (SCRIPT tag). */
public static final String HTML_VALUE_JAVASCRIPT = "text/javascript";
/** This is a possible HTML attribute for the LINK tag. */
public static final String HTML_VALUE_CSS = "text/css";
// CSS keys
/** the CSS tag for background color */
public static final String CSS_KEY_BGCOLOR = "background-color";
/** the CSS tag for text color */
public static final String CSS_KEY_COLOR = "color";
/** CSS key that indicate the way something has to be displayed */
public static final String CSS_KEY_DISPLAY = "display";
/** the CSS tag for the font family */
public static final String CSS_KEY_FONTFAMILY = "font-family";
/** the CSS tag for the font size */
public static final String CSS_KEY_FONTSIZE = "font-size";
/** the CSS tag for the font style */
public static final String CSS_KEY_FONTSTYLE = "font-style";
/** the CSS tag for the font weight */
public static final String CSS_KEY_FONTWEIGHT = "font-weight";
/** the CSS tag for text decorations */
public static final String CSS_KEY_LINEHEIGHT = "line-height";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_MARGIN = "margin";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_MARGINLEFT = "margin-left";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_MARGINRIGHT = "margin-right";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_MARGINTOP = "margin-top";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_MARGINBOTTOM = "margin-bottom";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_PADDING = "padding";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_PADDINGLEFT = "padding-left";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_PADDINGRIGHT = "padding-right";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_PADDINGTOP = "padding-top";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_PADDINGBOTTOM = "padding-bottom";
public static final String CSS_KEY_BORDERTOP = "border-top";
public static final String CSS_KEY_BORDERRIGHT= "border-right";
public static final String CSS_KEY_BORDERBOTTOM= "border-bottom";
public static final String CSS_KEY_BORDERLEFT= "border-left";
public static final String CSS_KEY_BORDERSTYLETOP = "border-top-style";
public static final String CSS_KEY_BORDERSTYLERIGHT= "border-right-style";
public static final String CSS_KEY_BORDERSTYLEBOTTOM= "border-bottom-style";
public static final String CSS_KEY_BORDERSTYLELEFT= "border-left-style";
public static final String CSS_KEY_BORDERCOLORTOP = "border-top-color";
public static final String CSS_KEY_BORDERCOLORRIGHT= "border-right-color";
public static final String CSS_KEY_BORDERCOLORBOTTOM= "border-bottom-color";
public static final String CSS_KEY_BORDERCOLORLEFT= "border-left-color";
public static final String CSS_KEY_BORDER = "border";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERCOLOR = "border-color";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERWIDTH = "border-width";
public static final String CSS_KEY_BORDERSTYLE = "border-style";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERWIDTHLEFT = "border-left-width";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERWIDTHRIGHT = "border-right-width";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERWIDTHTOP = "border-top-width";
/** the CSS tag for the margin of an object */
public static final String CSS_KEY_BORDERWIDTHBOTTOM = "border-bottom-width";
/** the CSS tag for adding a page break when the document is printed */
public static final String CSS_KEY_PAGE_BREAK_AFTER = "page-break-after";
/** the CSS tag for adding a page break when the document is printed */
public static final String CSS_KEY_PAGE_BREAK_BEFORE = "page-break-before";
/** the CSS tag for the horizontal alignment of an object */
public static final String CSS_KEY_TEXTALIGN = "text-align";
/** the CSS tag for the horizontal alignment of an object */
public static final String CSS_KEY_ALIGN = "align";
/** the CSS tag for text decorations */
public static final String CSS_KEY_TEXTDECORATION = "text-decoration";
/** the CSS tag for text decorations */
public static final String CSS_KEY_VERTICALALIGN = "vertical-align";
/** the CSS tag for the visibility of objects */
public static final String CSS_KEY_VISIBILITY = "visibility";
public static final String CSS_KEY_TEXTINDENT = "text-indent";
// CSS values
/**
* value for the CSS tag for adding a page break when the document is
* printed
*/
public static final String CSS_VALUE_ALWAYS = "always";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_BLOCK = "block";
/** a CSS value for text font weight */
public static final String CSS_VALUE_BOLD = "bold";
/** the value if you want to hide objects. */
public static final String CSS_VALUE_HIDDEN = "hidden";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_INLINE = "inline";
/** a CSS value for text font style */
public static final String CSS_VALUE_ITALIC = "italic";
/** a CSS value for text decoration */
public static final String CSS_VALUE_LINETHROUGH = "line-through";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_LISTITEM = "list-item";
/** a CSS value */
public static final String CSS_VALUE_NONE = "none";
/** a CSS value */
public static final String CSS_VALUE_NORMAL = "normal";
/** a CSS value for text font style */
public static final String CSS_VALUE_OBLIQUE = "oblique";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_TABLE = "table";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_TABLEROW = "table-row";
/** A possible value for the DISPLAY key */
public static final String CSS_VALUE_TABLECELL = "table-cell";
/** the CSS value for a horizontal alignment of an object */
public static final String CSS_VALUE_TEXTALIGNLEFT = "left";
/** the CSS value for a horizontal alignment of an object */
public static final String CSS_VALUE_TEXTALIGNRIGHT = "right";
/** the CSS value for a horizontal alignment of an object */
public static final String CSS_VALUE_TEXTALIGNCENTER = "center";
/** the CSS value for a horizontal alignment of an object */
public static final String CSS_VALUE_TEXTALIGNJUSTIFY = "justify";
/** a CSS value for text decoration */
public static final String CSS_VALUE_UNDERLINE = "underline";
/** a default value for font-size
* @since 2.1.3
*/
public static final float DEFAULT_FONT_SIZE = 12f;
/**
* Parses a length.
*
* @param string
* a length in the form of an optional + or -, followed by a
* number and a unit.
* @return a float
*/
public static float parseLength(String string) {
// TODO: Evaluate the effect of this.
// It may change the default behavour of the methd if this is changed.
// return parseLength(string, Markup.DEFAULT_FONT_SIZE);
int pos = 0;
int length = string.length();
boolean ok = true;
while (ok && pos < length) {
switch (string.charAt(pos)) {
case '+':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
pos++;
break;
default:
ok = false;
}
}
if (pos == 0)
return 0f;
if (pos == length)
return Float.parseFloat(string + "f");
float f = Float.parseFloat(string.substring(0, pos) + "f");
string = string.substring(pos);
// inches
if (string.startsWith("in")) {
return f * 72f;
}
// centimeters
if (string.startsWith("cm")) {
return (f / 2.54f) * 72f;
}
// millimeters
if (string.startsWith("mm")) {
return (f / 25.4f) * 72f;
}
// picas
if (string.startsWith("pc")) {
return f * 12f;
}
// default: we assume the length was measured in points
return f;
}
/**
* New method contributed by: Lubos Strapko
*
* @since 2.1.3
*/
public static float parseLength(String string, float actualFontSize) {
if (string == null)
return 0f;
int pos = 0;
int length = string.length();
boolean ok = true;
while (ok && pos < length) {
switch (string.charAt(pos)) {
case '+':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
pos++;
break;
default:
ok = false;
}
}
if (pos == 0)
return 0f;
if (pos == length)
return Float.parseFloat(string + "f");
float f = Float.parseFloat(string.substring(0, pos) + "f");
string = string.substring(pos);
// inches
if (string.startsWith("in")) {
return f * 72f;
}
// centimeters
if (string.startsWith("cm")) {
return (f / 2.54f) * 72f;
}
// millimeters
if (string.startsWith("mm")) {
return (f / 25.4f) * 72f;
}
// picas
if (string.startsWith("pc")) {
return f * 12f;
}
// 1em is equal to the current font size
if (string.startsWith("em")) {
return f * actualFontSize;
}
// one ex is the x-height of a font (x-height is usually about half the
// font-size)
if (string.startsWith("ex")) {
return f * actualFontSize / 2;
}
// default: we assume the length was measured in points
return f;
}
/**
* 解析当前字号可能是继承来的
*
* @param cprops
* @return
*/
public static float parseDefaultFontSize(ChainedProperties cprops) {
if (null == cprops) {
return DEFAULT_FONT_SIZE;
}
String size = cprops.getProperty(ElementTags.SIZE);
return null == size ? Markup.DEFAULT_FONT_SIZE : Markup.parseLength(size,
Markup.DEFAULT_FONT_SIZE);
}
/**
* Converts a <CODE>Color</CODE> into a HTML representation of this <CODE>
* Color</CODE>.
*
* @param s
* the <CODE>Color</CODE> that has to be converted.
* @return the HTML representation of this <COLOR>Color </COLOR>
*/
public static Color decodeColor(String s) {
if (s == null)
return null;
s = s.toLowerCase().trim();
try {
return WebColors.getRGBColor(s);
}
catch(Exception iae) {
return null;
}
}
/**
* This method parses a String with attributes and returns a Properties
* object.
*
* @param string
* a String of this form: 'key1="value1"; key2="value2";...
* keyN="valueN" '
* @return a Properties object
*/
public static Properties parseAttributes(String string) {
Properties result = new Properties();
if (string == null)
return result;
String key;
String value;
//换种方式解析,style中background里面也有可能会有;符号
String[] styles = string.split(";");
for (String s : styles) {
String[] part = s.split(":",2);
if (part.length == 2) {
key = stripDoubleSpacesAndTrim(part[0]).toLowerCase();
value = stripDoubleSpacesAndTrim(part[1]);
if (value.startsWith("\"") || value.startsWith("\'") )
value = value.substring(1);
if (value.endsWith("\"") || value.endsWith("\'"))
value = value.substring(0, value.length() - 1);
result.setProperty(key.toLowerCase(), value);
}
}
return result;
}
public static String stripDoubleSpacesAndTrim(final String str) {
char[] charArray = str.toCharArray();
if (str.contains(" ")) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
if (c != ' ') {
builder.append(c);
} else {
if (i + 1 < charArray.length && charArray[i + 1] != ' ') {
builder.append(' ');
}
}
}
return builder.toString().trim();
} else {
return String.valueOf(charArray).trim();
}
}
/**
* Removes the comments sections of a String.
*
* @param string
* the original String
* @param startComment
* the String that marks the start of a Comment section
* @param endComment
* the String that marks the end of a Comment section.
* @return the String stripped of its comment section
*/
public static String removeComment(String string, String startComment,
String endComment) {
StringBuffer result = new StringBuffer();
int pos = 0;
int end = endComment.length();
int start = string.indexOf(startComment, pos);
while (start > -1) {
result.append(string.substring(pos, start));
pos = string.indexOf(endComment, start) + end;
start = string.indexOf(startComment, pos);
}
result.append(string.substring(pos));
return result.toString();
}
/**
* 解析类似于 border:1px solid #000 中的值
*
* @param attr 1px solid #000 or 1px solid
* @return list: 按粗细样式颜色的顺序返回 没有则为null
*/
public static List<String> parseBorderAttr(String attr) {
if (null == attr) {
return null;
}
List<String> list = new ArrayList<String>(3);
StringTokenizer st = new StringTokenizer(attr);
while (st.hasMoreElements()) {
list.add(st.nextToken());
}
switch (list.size()) {
case 1:
if (Constants.LINE_NONE != HtmlBorderUtils.convertHtmlBorderStyle(list.get(0))) {
list.add(0, String.valueOf(Border.DEFAULT_WIDTH));
}
break;
case 2:
// 如 border:1px solid ,则默认颜色为黑色
list.add("black");
break;
case 3:
// 如 border:1px solid black ,已经写全了,不用做额外的处理
break;
default:
// 如 border:1px ,此时浏览器是无法识别的
list = null;
break;
}
return list;
}
/**
* 解析类似于 margin: 10px 5px 15px 20px中的值
* NESW:北东南西上右下左
*
* @param attr 如10px 5px 15px 20px
* @return list: 按上左下右的顺序存放 要么四个方位的值都存在要么都不存在返回null
*/
public static List<String> parseNESW(String attr) {
if (null == attr) {
return null;
}
List<String> list = new ArrayList<String>(4);
StringTokenizer st = new StringTokenizer(attr);
while (st.hasMoreElements()) {
list.add(st.nextToken());
}
switch (list.size()) {
case 1:
//如 margin:1px ,代表上下左右 的margin值都是 1px
for (int i = 0; i < 3; i++) {
list.add(list.get(0));
}
break;
case 2:
//如 margin:1px 2px ,代表上下方位的margin值为1px, 左右方位的margin值为 2px
list.add(list.get(0));
list.add(list.get(1));
break;
case 3:
//如 margin:1px 2px 3px ,代表上下方位的margin值分别为1px、3px, 左右方位的margin值为 2px
list.add(list.get(1));
break;
case 4:
//如 margin:1px 2px 3px 4px,就不用管了
break;
default:
//如 margin:1px 2px 3px 4px 5px,超了就违反了规则,在浏览器中该属性失效
list = null;
break;
}
return list;
}
}

96
src/main/java/com/fr/third/lowagie/text/html/ParseIndentAttrUtils.java

@ -0,0 +1,96 @@
package com.fr.third.lowagie.text.html;
import java.util.Iterator;
import java.util.Map;
/**
* @author kerry
* @date 2018/5/14
*/
public class ParseIndentAttrUtils {
public static IndentAttribute parseSpace(String indent){
String[] a = indent.split(" ");
if(a.length == 0){
return new IndentAttribute();
}
float indentTop = Markup.parseLength(a[0]);
if(a.length == 1){
return new IndentAttribute(indentTop, indentTop, indentTop, indentTop);
}
float indentLeft = Markup.parseLength(a[1]);
if(a.length == 2){
return new IndentAttribute(indentTop, indentLeft, indentTop, indentLeft);
}
float indentBottom = Markup.parseLength(a[2]);
if(a.length == 3){
return new IndentAttribute(indentTop, indentLeft, indentBottom, indentLeft);
}
float indentRight = Markup.parseLength(a[3]);
return new IndentAttribute(indentTop, indentLeft, indentBottom, indentRight);
}
public static IndentAttribute parsePaddingAttribute(Map map){
if (map == null){
return new IndentAttribute();
}
IndentAttribute indentAttribute = new IndentAttribute();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
if (CSS.Property.PADDING_LEFT.equals(key)) {
indentAttribute.setLeft(Markup.parseLength((String) entry.getValue()));
} else if (CSS.Property.PADDING_RIGHT.equals(key)) {
indentAttribute.setRight(Markup.parseLength((String) entry.getValue()));
} else if (CSS.Property.PADDING_TOP.equals(key)) {
indentAttribute.setTop(Markup.parseLength((String) entry.getValue()));
} else if (CSS.Property.PADDING_BOTTOM.equals(key)) {
indentAttribute.setBottom(Markup.parseLength((String) entry.getValue()));
}
}
return indentAttribute;
}
public static IndentAttribute parseMarginAttribute(Map map){
IndentAttribute indentAttribute = new IndentAttribute();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
float val = Markup.parseLength((String) entry.getValue());
if (CSS.Property.MARGIN_LEFT.equals(key)) {
indentAttribute.setLeft(val);
} else if (CSS.Property.MARGIN_RIGHT.equals(key)) {
indentAttribute.setRight(val);
} else if (CSS.Property.MARGIN_TOP.equals(key)) {
indentAttribute.setTop(val);
} else if (CSS.Property.MARGIN_BOTTOM.equals(key)) {
indentAttribute.setBottom(val);
}
}
return indentAttribute;
}
public static IndentAttribute parseBorderAttribute(BorderAttribute borderAttr) {
IndentAttribute widthAttr = new IndentAttribute();
if (null == borderAttr) {
return widthAttr;
}
widthAttr.setTop(verify(borderAttr.getTop()) ? borderAttr.getTop().getWidth() : 0);
widthAttr.setRight(verify(borderAttr.getRight()) ? borderAttr.getRight().getWidth() : 0);
widthAttr.setBottom(verify(borderAttr.getBottom()) ? borderAttr.getBottom().getWidth() : 0);
widthAttr.setLeft(verify(borderAttr.getLeft()) ? borderAttr.getLeft().getWidth() : 0);
return widthAttr;
}
private static boolean verify(Border border) {
return null != border && 0 < border.getWidth() && null != border.getStyle();
}
public static void createIndent(StringBuffer stringBuffer, String attr, IndentAttribute indentAttribute){
stringBuffer.append(attr).append("-").append("left").append(":").append(indentAttribute.getLeft()).append("px;")
.append(attr).append("-").append("right").append(":").append(indentAttribute.getRight()).append("px;")
.append(attr).append("-").append("top").append(":").append(indentAttribute.getTop()).append("px;")
.append(attr).append("-").append("bottom").append(":").append(indentAttribute.getBottom()).append("px;");
}
}

276
src/main/java/com/fr/third/lowagie/text/html/SAXmyHtmlHandler.java

@ -0,0 +1,276 @@
/*
* $Id: SAXmyHtmlHandler.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.util.HashMap;
import java.util.Properties;
import com.fr.third.lowagie.text.DocumentException;
import com.fr.third.lowagie.text.Element;
import com.fr.third.lowagie.text.ExceptionConverter;
import com.fr.third.lowagie.text.xml.SAXiTextHandler;
import com.fr.third.lowagie.text.xml.XmlPeer;
import org.xml.sax.Attributes;
import com.fr.third.lowagie.text.DocListener;
import com.fr.third.lowagie.text.ElementTags;
import com.fr.third.lowagie.text.pdf.BaseFont;
/**
* The <CODE>Tags</CODE>-class maps several XHTML-tags to iText-objects.
*/
public class SAXmyHtmlHandler extends SAXiTextHandler // SAXmyHandler
{
/** These are the properties of the body section. */
private Properties bodyAttributes = new Properties();
/** This is the status of the table border. */
private boolean tableBorder = false;
/**
* Constructs a new SAXiTextHandler that will translate all the events
* triggered by the parser to actions on the <CODE>Document</CODE>-object.
*
* @param document
* this is the document on which events must be triggered
*/
public SAXmyHtmlHandler(DocListener document) {
super(document, new HtmlTagMap());
}
/**
* Constructs a new SAXiTextHandler that will translate all the events
* triggered by the parser to actions on the <CODE>Document</CODE>-object.
*
* @param document
* this is the document on which events must be triggered
* @param bf
*/
public SAXmyHtmlHandler(DocListener document, BaseFont bf) {
super(document, new HtmlTagMap(), bf);
}
/**
* Constructs a new SAXiTextHandler that will translate all the events
* triggered by the parser to actions on the <CODE>Document</CODE>-object.
*
* @param document
* this is the document on which events must be triggered
* @param htmlTags
* a tagmap translating HTML tags to iText tags
*/
public SAXmyHtmlHandler(DocListener document, HashMap htmlTags) {
super(document, htmlTags);
}
/**
* This method gets called when a start tag is encountered.
*
* @param uri
* the Uniform Resource Identifier
* @param lname
* the local name (without prefix), or the empty string if
* Namespace processing is not being performed.
* @param name
* the name of the tag that is encountered
* @param attrs
* the list of attributes
*/
public void startElement(String uri, String lname, String name,
Attributes attrs) {
// System.err.println("Start: " + name);
// super.handleStartingTags is replaced with handleStartingTags
// suggestion by Vu Ngoc Tan/Hop
name = name.toLowerCase();
if (HtmlTagMap.isHtml(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isHead(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isTitle(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isMeta(name)) {
// we look if we can change the body attributes
String meta = null;
String content = null;
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
String attribute = attrs.getQName(i);
if (attribute.equalsIgnoreCase(HtmlTags.CONTENT))
content = attrs.getValue(i);
else if (attribute.equalsIgnoreCase(HtmlTags.NAME))
meta = attrs.getValue(i);
}
}
if (meta != null && content != null) {
bodyAttributes.put(meta, content);
}
return;
}
if (HtmlTagMap.isLink(name)) {
// we do nothing for the moment, in a later version we could extract
// the style sheet
return;
}
if (HtmlTagMap.isBody(name)) {
// maybe we could extract some info about the document: color,
// margins,...
// but that's for a later version...
XmlPeer peer = new XmlPeer(ElementTags.ITEXT, name);
peer.addAlias(ElementTags.TOP, HtmlTags.TOPMARGIN);
peer.addAlias(ElementTags.BOTTOM, HtmlTags.BOTTOMMARGIN);
peer.addAlias(ElementTags.RIGHT, HtmlTags.RIGHTMARGIN);
peer.addAlias(ElementTags.LEFT, HtmlTags.LEFTMARGIN);
bodyAttributes.putAll(peer.getAttributes(attrs));
handleStartingTags(peer.getTag(), bodyAttributes);
return;
}
if (myTags.containsKey(name)) {
XmlPeer peer = (XmlPeer) myTags.get(name);
if (ElementTags.TABLE.equals(peer.getTag()) || ElementTags.CELL.equals(peer.getTag())) {
Properties p = peer.getAttributes(attrs);
String value;
if (ElementTags.TABLE.equals(peer.getTag())
&& (value = p.getProperty(ElementTags.BORDERWIDTH)) != null) {
if (Float.parseFloat(value + "f") > 0) {
tableBorder = true;
}
}
if (tableBorder) {
p.put(ElementTags.LEFT, String.valueOf(true));
p.put(ElementTags.RIGHT, String.valueOf(true));
p.put(ElementTags.TOP, String.valueOf(true));
p.put(ElementTags.BOTTOM, String.valueOf(true));
}
handleStartingTags(peer.getTag(), p);
return;
}
handleStartingTags(peer.getTag(), peer.getAttributes(attrs));
return;
}
Properties attributes = new Properties();
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
String attribute = attrs.getQName(i).toLowerCase();
attributes.setProperty(attribute, attrs.getValue(i).toLowerCase());
}
}
handleStartingTags(name, attributes);
}
/**
* This method gets called when an end tag is encountered.
*
* @param uri
* the Uniform Resource Identifier
* @param lname
* the local name (without prefix), or the empty string if
* Namespace processing is not being performed.
* @param name
* the name of the tag that ends
*/
public void endElement(String uri, String lname, String name) {
// System.err.println("End: " + name);
name = name.toLowerCase();
if (ElementTags.PARAGRAPH.equals(name)) {
try {
document.add((Element) stack.pop());
return;
} catch (DocumentException e) {
throw new ExceptionConverter(e);
}
}
if (HtmlTagMap.isHead(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isTitle(name)) {
if (currentChunk != null) {
bodyAttributes.put(ElementTags.TITLE, currentChunk.getContent());
}
return;
}
if (HtmlTagMap.isMeta(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isLink(name)) {
// we do nothing
return;
}
if (HtmlTagMap.isBody(name)) {
// we do nothing
return;
}
if (myTags.containsKey(name)) {
XmlPeer peer = (XmlPeer) myTags.get(name);
if (ElementTags.TABLE.equals(peer.getTag())) {
tableBorder = false;
}
super.handleEndingTags(peer.getTag());
return;
}
// super.handleEndingTags is replaced with handleEndingTags
// suggestion by Ken Auer
handleEndingTags(name);
}
}

108
src/main/java/com/fr/third/lowagie/text/html/SpaceWithPunctuationBreakIterator.java

@ -0,0 +1,108 @@
package com.fr.third.lowagie.text.html;
import com.fr.third.ibm.icu.text.BreakIterator;
import java.text.CharacterIterator;
/**
* 之前性能插件里面的考虑空格和标点符号的分词iterator
*/
public class SpaceWithPunctuationBreakIterator extends BreakIterator {
private BreakIterator iterator;
private int currentPos = -1;
private int currentIndex = -1;
private boolean[] spaceIndex;
//不作为break分词的字符
private boolean[] noSwitchIndex;
public SpaceWithPunctuationBreakIterator(String text, BreakIterator iterator){
this.iterator = iterator;
iterator.setText(text);
this.spaceIndex = new boolean[text.length()];
this.noSwitchIndex = new boolean[text.length()];
int ilen = text.length() - 1;
if(ilen > 0) {
for (int i = 0; i < ilen; i++) {
char c = text.charAt(i);
//中文的标点符号都是可以直接断开的
spaceIndex[i + 1] = (c == ' ' && isPunctuation(text.charAt(i + 1)) )|| c == '-' || c == '\u2010' || c== '\n'|| isChinesePunctuation( c);
//需要保证下一个字符不是中文,下一个字符如果是中文的话,允许分行
char nextC = text.charAt(i+1);
noSwitchIndex[i + 1] = (c=='/' || c == '.' || c == ':' || c == ';') && !isChinese(nextC);
}
}
}
public boolean isPunctuation(char c) {
int code = Character.getType(c);
return code == 24 || code == 20 || code == 21 || code == 22 || code == 23;
}
public boolean isChinese(char c){
return c >= 0x4E00 && c <= 0x9FBF;
}
// 根据UnicodeBlock方法判断中文标点符号
public boolean isChinesePunctuation(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS) {
return true;
} else {
return false;
}
}
public int first() {
throw new UnsupportedOperationException();
}
public int last() {
throw new UnsupportedOperationException();
}
public int next(int n) {
throw new UnsupportedOperationException();
}
public int next() {
if(currentIndex == currentPos) {
currentPos = this.iterator.next();
}
if (currentPos > -1 && currentPos < noSwitchIndex.length && noSwitchIndex[currentPos]) {
currentIndex = currentPos;
return this.next();
}
for(int i = currentIndex + 1; i < currentPos; i++){
if(spaceIndex[i]){
currentIndex = i;
return currentIndex;
}
}
currentIndex = currentPos;
return currentIndex;
}
public int previous() {
throw new UnsupportedOperationException();
}
public int following(int offset) {
throw new UnsupportedOperationException();
}
public int current() {
throw new UnsupportedOperationException();
}
public CharacterIterator getText() {
throw new UnsupportedOperationException();
}
public void setText(CharacterIterator newText) {
throw new UnsupportedOperationException();
}
}

319
src/main/java/com/fr/third/lowagie/text/html/WebColors.java

@ -0,0 +1,319 @@
/*
* $Id: WebColors.java 3373 2008-05-12 16:21:24Z xlv $
*
* Copyright 2001, 2002 by Bruno Lowagie.
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html;
import java.awt.Color;
import java.util.HashMap;
import java.util.StringTokenizer;
/**
* This class is a HashMap that contains the names of colors as a key and the
* corresponding Color as value. (Source: Wikipedia
* http://en.wikipedia.org/wiki/Web_colors )
*
* @author blowagie
*/
public class WebColors extends HashMap {
private static final long serialVersionUID = 3542523100813372896L;
/** HashMap containing all the names and corresponding color values. */
public static final WebColors NAMES = new WebColors();
static {
//比对 https://html-color-codes.info/color-names/
//Red color names
NAMES.put("indianred", new int[]{0xcd, 0x5c, 0x5c, 0xff});
NAMES.put("lightcoral", new int[]{0xf0, 0x80, 0x80, 0xff});
NAMES.put("salmon", new int[]{0xfa, 0x80, 0x72, 0xff});
NAMES.put("darksalmon", new int[]{0xe9, 0x96, 0x7a, 0xff});
NAMES.put("lightsalmon", new int[]{0xff, 0xa0, 0x7a, 0xff});
NAMES.put("crimson", new int[]{0xdc, 0x14, 0x3c, 0xff});
NAMES.put("firebrick", new int[]{0xb2, 0x22, 0x22, 0xff});
NAMES.put("darkred", new int[]{0x8b, 0x00, 0x00, 0xff});
NAMES.put("red", new int[]{0xff, 0x00, 0x00, 0xff});
//Pink color names
NAMES.put("pink", new int[]{0xff, 0xc0, 0xcb, 0xff});
NAMES.put("lightpink", new int[]{0xff, 0xb6, 0xc1, 0xff});
NAMES.put("hotpink", new int[]{0xff, 0x69, 0xb4, 0xff});
NAMES.put("deeppink", new int[]{0xff, 0x14, 0x93, 0xff});
NAMES.put("mediumvioletred", new int[]{0xc7, 0x15, 0x85, 0xff});
NAMES.put("palevioletred", new int[]{0xdb, 0x70, 0x93, 0xff});
//Orange color names
NAMES.put("coral", new int[]{0xff, 0x7f, 0x50, 0xff});
NAMES.put("tomato", new int[]{0xff, 0x63, 0x47, 0xff});
NAMES.put("orangered", new int[]{0xff, 0x45, 0x00, 0xff});
NAMES.put("darkorange", new int[]{0xff, 0x8c, 0x00, 0xff});
NAMES.put("orange", new int[]{0xff, 0xa5, 0x00, 0xff});
//Orange color names
NAMES.put("gold", new int[]{0xff, 0xd7, 0x00, 0xff});
NAMES.put("yellow", new int[]{0xff, 0xff, 0x00, 0xff});
NAMES.put("lightyellow", new int[]{0xff, 0xff, 0xefe, 0xff});
NAMES.put("lemonchiffon", new int[]{0xff, 0xfa, 0xcd, 0xff});
NAMES.put("lightgoldenrodyellow", new int[]{0xfa, 0xfa, 0xd2, 0xff});
NAMES.put("papayawhip", new int[]{0xff, 0xef, 0xd5, 0xff});
NAMES.put("moccasin", new int[]{0xff, 0xe4, 0xb5, 0xff});
NAMES.put("peachpuff", new int[]{0xff, 0xda, 0xb9, 0xff});
NAMES.put("palegoldenrod", new int[]{0xee, 0xe8, 0xaa, 0xff});
NAMES.put("khaki", new int[]{0xf0, 0xe6, 0x8c, 0xff});
NAMES.put("darkkhaki", new int[]{0xbd, 0xb7, 0x6b, 0xff});
//Purple color names
NAMES.put("lavender", new int[]{0xe6, 0xe6, 0xfa, 0xff});
NAMES.put("thistle", new int[]{0xd8, 0xbf, 0xd8, 0xff});
NAMES.put("plum", new int[]{0xdd, 0xa0, 0xdd, 0xff});
NAMES.put("violet", new int[]{0xee, 0x82, 0xee, 0xff});
NAMES.put("orchid", new int[]{0xda, 0x70, 0xd6, 0xff});
NAMES.put("fuchsia", new int[]{0xff, 0x00, 0xff, 0xff});
NAMES.put("magenta", new int[]{0xff, 0x00, 0xff, 0xff});
NAMES.put("mediumorchid", new int[]{0xba, 0x55, 0xd3, 0xff});
NAMES.put("mediumpurple", new int[]{0x93, 0x70, 0xdb, 0xff});
NAMES.put("amethyst", new int[]{0x99, 0x66, 0xcc, 0xff});
NAMES.put("blueviolet", new int[]{0x8a, 0x2b, 0xe2, 0xff});
NAMES.put("darkviolet", new int[]{0x94, 0x00, 0xd3, 0xff});
NAMES.put("darkorchid", new int[]{0x99, 0x32, 0xcc, 0xff});
NAMES.put("darkmagenta", new int[]{0x8b, 0x00, 0x8b, 0xff});
NAMES.put("purple", new int[]{0x80, 0x00, 0x80, 0xff});
NAMES.put("indigo", new int[]{0x4b, 0x00, 0x82, 0xff});
NAMES.put("slateblue", new int[]{0x6a, 0x5a, 0xcd, 0xff});
NAMES.put("darkslateblue", new int[]{0x48, 0x3d, 0x8b, 0xff});
NAMES.put("mediumslateblue", new int[]{0x7b, 0x68, 0xee, 0xff});
//Green color names
NAMES.put("greenyellow", new int[]{0xad, 0xff, 0x2f, 0xff});
NAMES.put("chartreuse", new int[]{0x7f, 0xff, 0x00, 0xff});
NAMES.put("lawngreen", new int[]{0x7c, 0xfc, 0x00, 0xff});
NAMES.put("lime", new int[]{0x00, 0xff, 0x00, 0xff});
NAMES.put("limegreen", new int[]{0x32, 0xcd, 0x32, 0xff});
NAMES.put("palegreen", new int[]{0x98, 0xfb, 0x98, 0xff});
NAMES.put("lightgreen", new int[]{0x90, 0xee, 0x90, 0xff});
NAMES.put("mediumspringgreen", new int[]{0x00, 0xfa, 0x9a, 0xff});
NAMES.put("springgreen", new int[]{0x00, 0xff, 0x7f, 0xff});
NAMES.put("mediumseagreen", new int[]{0x3c, 0xb3, 0x71, 0xff});
NAMES.put("seagreen", new int[]{0x2e, 0x8b, 0x57, 0xff});
NAMES.put("forestgreen", new int[]{0x22, 0x8b, 0x22, 0xff});
NAMES.put("green", new int[]{0x00, 0x80, 0x00, 0xff});
NAMES.put("darkgreen", new int[]{0x00, 0x64, 0x00, 0xff});
NAMES.put("yellowgreen", new int[]{0x9a, 0xcd, 0x32, 0xff});
NAMES.put("olivedrab", new int[]{0x6b, 0x8e, 0x23, 0xff});
NAMES.put("olive", new int[]{0x80, 0x80, 0x00, 0xff});
NAMES.put("darkolivegreen", new int[]{0x55, 0x6b, 0x2f, 0xff});
NAMES.put("mediumaquamarine", new int[]{0x66, 0xcd, 0xaa, 0xff});
NAMES.put("darkseagreen", new int[]{0x8f, 0xbc, 0x8f, 0xff});
NAMES.put("lightseagreen", new int[]{0x20, 0xb2, 0xaa, 0xff});
NAMES.put("darkcyan", new int[]{0x00, 0x8b, 0x8b, 0xff});
NAMES.put("teal", new int[]{0x00, 0x80, 0x80, 0xff});
//Blue color names
NAMES.put("aqua", new int[]{0x00, 0xff, 0xff, 0xff});
NAMES.put("cyan", new int[]{0x00, 0xff, 0xff, 0xff});
NAMES.put("lightcyan", new int[]{0xe0, 0xff, 0xff, 0xff});
NAMES.put("paleturquoise", new int[]{0xaf, 0xee, 0xee, 0xff});
NAMES.put("aquamarine", new int[]{0x7f, 0xff, 0xd4, 0xff});
NAMES.put("turquoise", new int[]{0x40, 0xe0, 0xd0, 0xff});
NAMES.put("mediumturquoise", new int[]{0x48, 0xd1, 0xcc, 0xff});
NAMES.put("darkturquoise", new int[]{0x00, 0xce, 0xd1, 0xff});
NAMES.put("cadetblue", new int[]{0x5f, 0x9e, 0xa0, 0xff});
NAMES.put("steelblue", new int[]{0x46, 0x82, 0xb4, 0xff});
NAMES.put("lightsteelblue", new int[]{0xb0, 0xc4, 0xde, 0xff});
NAMES.put("powderblue", new int[]{0xb0, 0xe0, 0xe6, 0xff});
NAMES.put("lightblue", new int[]{0xad, 0xd8, 0xe6, 0xff});
NAMES.put("skyblue", new int[]{0x87, 0xce, 0xeb, 0xff});
NAMES.put("lightskyblue", new int[]{0x87, 0xce, 0xfa, 0xff});
NAMES.put("deepskyblue", new int[]{0x00, 0xbf, 0xff, 0xff});
NAMES.put("dodgerblue", new int[]{0x1e, 0x90, 0xff, 0xff});
NAMES.put("cornflowerblue", new int[]{0x64, 0x95, 0xed, 0xff});
NAMES.put("royalblue", new int[]{0x41, 0x69, 0xe1, 0xff});
NAMES.put("blue", new int[]{0x00, 0x00, 0xff, 0xff});
NAMES.put("mediumblue", new int[]{0x00, 0x00, 0xcd, 0xff});
NAMES.put("darkblue", new int[]{0x00, 0x00, 0x8b, 0xff});
NAMES.put("navy", new int[]{0x00, 0x00, 0x80, 0xff});
NAMES.put("midnightblue", new int[]{0x19, 0x19, 0x70, 0xff});
//Brown color names
NAMES.put("cornsilk", new int[]{0xff, 0xf8, 0xdc, 0xff});
NAMES.put("blanchedalmond", new int[]{0xff, 0xeb, 0xcd, 0xff});
NAMES.put("bisque", new int[]{0xff, 0xe4, 0xc4, 0xff});
NAMES.put("navajowhite", new int[]{0xff, 0xde, 0xad, 0xff});
NAMES.put("wheat", new int[]{0xf5, 0xde, 0xb3, 0xff});
NAMES.put("burlywood", new int[]{0xde, 0xb8, 0x87, 0xff});
NAMES.put("tan", new int[]{0xd2, 0xb4, 0x8c, 0xff});
NAMES.put("rosybrown", new int[]{0xbc, 0x8f, 0x8f, 0xff});
NAMES.put("sandybrown", new int[]{0xf4, 0xa4, 0x60, 0xff});
NAMES.put("goldenrod", new int[]{0xda, 0xa5, 0x20, 0xff});
NAMES.put("darkgoldenrod", new int[]{0xb8, 0x86, 0x0b, 0xff});
NAMES.put("peru", new int[]{0xcd, 0x85, 0x3f, 0xff});
NAMES.put("chocolate", new int[]{0xd2, 0x69, 0x1e, 0xff});
NAMES.put("saddlebrown", new int[]{0x8b, 0x45, 0x13, 0xff});
NAMES.put("sienna", new int[]{0xa0, 0x52, 0x2d, 0xff});
NAMES.put("brown", new int[]{0xa5, 0x2a, 0x2a, 0xff});
NAMES.put("maroon", new int[]{0x80, 0x00, 0x00, 0xff});
//White color names
NAMES.put("white", new int[]{0xff, 0xff, 0xff, 0xff});
NAMES.put("snow", new int[]{0xff, 0xfa, 0xfa, 0xff});
NAMES.put("honeydew", new int[]{0xf0, 0xff, 0xf0, 0xff});
NAMES.put("mintcream", new int[]{0xf5, 0xff, 0xfa, 0xff});
NAMES.put("azure", new int[]{0xf0, 0xff, 0xff, 0xff});
NAMES.put("aliceblue", new int[]{0xf0, 0xf8, 0xff, 0xff});
NAMES.put("ghostwhite", new int[]{0xf8, 0xf8, 0xff, 0xff});
NAMES.put("whitesmoke", new int[]{0xf5, 0xf5, 0xf5, 0xff});
NAMES.put("seashell", new int[]{0xff, 0xf5, 0xee, 0xff});
NAMES.put("beige", new int[]{0xf5, 0xf5, 0xdc, 0xff});
NAMES.put("oldlace", new int[]{0xfd, 0xf5, 0xe6, 0xff});
NAMES.put("floralwhite", new int[]{0xff, 0xfa, 0xf0, 0xff});
NAMES.put("ivory", new int[]{0xff, 0xff, 0xf0, 0xff});
NAMES.put("antiquewhite", new int[]{0xfa, 0xeb, 0xd7, 0xff});
NAMES.put("linen", new int[]{0xfa, 0xf0, 0xe6, 0xff});
NAMES.put("lavenderblush", new int[]{0xff, 0xf0, 0xf5, 0xff});
NAMES.put("mistyrose", new int[]{0xff, 0xe4, 0xe1, 0xff});
//Grey color names
NAMES.put("gainsboro", new int[]{0xdc, 0xdc, 0xdc, 0xff});
NAMES.put("lightgrey", new int[]{0xd3, 0xd3, 0xd3, 0xff});
NAMES.put("silver", new int[]{0xc0, 0xc0, 0xc0, 0xff});
NAMES.put("darkgray", new int[]{0xa9, 0xa9, 0xa9, 0xff});
NAMES.put("gray", new int[]{0x80, 0x80, 0x80, 0xff});
NAMES.put("dimgray", new int[]{0x69, 0x69, 0x69, 0xff});
NAMES.put("lightslategray", new int[]{0x77, 0x88, 0x99, 0xff});
NAMES.put("slategray", new int[]{0x70, 0x80, 0x90, 0xff});
NAMES.put("darkslategray", new int[]{0x2f, 0x4f, 0x4f, 0xff});
NAMES.put("black", new int[]{0x00, 0x00, 0x00, 0xff});
//Transparent color names
NAMES.put("transparent", new int[]{0xff, 0xff, 0xff, 0x00});
}
/**
* Gives you a Color based on a name.
*
* @param name
* a name such as black, violet, cornflowerblue or #RGB or #RRGGBB
* or rgb(R,G,B)
* @return the corresponding Color object
* @throws IllegalArgumentException
* if the String isn't a know representation of a color.
*/
public static Color getRGBColor(String name)
throws IllegalArgumentException {
int[] c = { 0, 0, 0, 255 };
if (name.startsWith("#")) {
if (name.length() == 4) {
c[0] = Integer.parseInt(name.substring(1, 2), 16) * 16;
c[1] = Integer.parseInt(name.substring(2, 3), 16) * 16;
c[2] = Integer.parseInt(name.substring(3), 16) * 16;
return new Color(c[0], c[1], c[2], c[3]);
}
if (name.length() == 7) {
c[0] = Integer.parseInt(name.substring(1, 3), 16);
c[1] = Integer.parseInt(name.substring(3, 5), 16);
c[2] = Integer.parseInt(name.substring(5), 16);
return new Color(c[0], c[1], c[2], c[3]);
}
throw new IllegalArgumentException(
"Unknown color format. Must be #RGB or #RRGGBB");
} else if (name.startsWith("rgb(")) {
StringTokenizer tok = new StringTokenizer(name, "rgb(), \t\r\n\f");
for (int k = 0; k < 3; ++k) {
c[k] = parseColorValue(tok.nextToken());
}
return new Color(c[0], c[1], c[2], c[3]);
} else if (name.startsWith("rgba(")) {
StringTokenizer tok = new StringTokenizer(name, "rgba(), \t\r\n\f");
for (int k = 0; k < 3; ++k) {
c[k] = parseColorValue(tok.nextToken());
}
try {
c[3] = parseAlphaValue(tok.nextToken());
} catch (Exception e) {
//alpha 值可写可不写
}
return new Color(c[0], c[1], c[2], c[3]);
}
name = name.toLowerCase();
if (!NAMES.containsKey(name))
throw new IllegalArgumentException("Color '" + name
+ "' not found.");
c = (int[]) NAMES.get(name);
return new Color(c[0], c[1], c[2], c[3]);
}
/**
* 转化 alpha
* @param v
* @return 0~ 255
*/
public static int parseAlphaValue(String v) {
if (v.endsWith("%")) {
return parseColorValue(v);
}
float r = Float.parseFloat(v) * 255;
if (r < 0)
r = 0;
else if (r > 255)
r = 255;
return (int) r;
}
/**
* 转化 rgb
* @param v
* @return 0~ 255
*/
public static int parseColorValue(String v) {
int r = v.endsWith("%") ? Integer.parseInt(v.substring(0, v.length() - 1)) * 255 / 100 : Integer.parseInt(v);
if (r < 0)
r = 0;
else if (r > 255)
r = 255;
return r;
}
}

57
src/main/java/com/fr/third/lowagie/text/html/simpleparser/ALink.java

@ -0,0 +1,57 @@
/*
* Copyright 2005 Paulo Soares
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or 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.
*
* 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/
*/
package com.fr.third.lowagie.text.html.simpleparser;
import com.fr.third.lowagie.text.Paragraph;
/**
*
* @author psoares
*/
public interface ALink {
boolean process(Paragraph current, ChainedProperties cprops);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save