Update PDF generation library.

- Added the PDFjet library as a Java Library module to the project and moved all the logic to create the transactions PDF in the TransactionsFragment to use the new PDF lib instead of the old one.
- Fixed the time formatter that was being used to format the transaction's times in exported PDF/CSV files, it was printing months in the place of minutes.
master
Severiano Jaramillo 2019-10-01 16:39:35 -05:00
parent 72fc8b2ea9
commit 5c6c727b00
108 changed files with 26509 additions and 93 deletions

1
PDFJet/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

8
PDFJet/build.gradle Normal file
View File

@ -0,0 +1,8 @@
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "7"
targetCompatibility = "7"

View File

@ -0,0 +1,41 @@
/**
* A3.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to specify PDF page with size <strong>A3</strong>.
* For more information about the page size classes - A3, A4, A5, B5, Executive, Letter, Legal and Tabloid - see the Page class.
*
*/
public class A3 {
public static final float[] PORTRAIT = new float[] {842.0f, 1191.0f};
public static final float[] LANDSCAPE = new float[] {1191.0f, 842.0f};
}

View File

@ -0,0 +1,41 @@
/**
* A4.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to specify PDF page with size <strong>A4</strong>.
* For more information about the page size classes - A3, A4, A5, B5, Executive, Letter, Legal and Tabloid - see the Page class.
*
*/
public class A4 {
public static final float[] PORTRAIT = new float[] {595.0f, 842.0f};
public static final float[] LANDSCAPE = new float[] {842.0f, 595.0f};
}

View File

@ -0,0 +1,42 @@
/**
* A5.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to specify PDF page with size <strong>A5</strong>.
* For more information about the page size classes - A3, A4, A5, B5, Executive, Letter, Legal and Tabloid - see the Page class.
*
*/
public class A5 {
public static final float[] PORTRAIT = new float[] {420.0f, 595.0f};
public static final float[] LANDSCAPE = new float[] {595.0f, 420.0f};
}

View File

@ -0,0 +1,47 @@
/**
* Align.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to specify the text alignment in paragraphs.
* See the Paragraph class for more details.
*
*
*/
public class Align {
public static final int LEFT = 0x00000000;
public static final int CENTER = 0x00100000;
public static final int RIGHT = 0x00200000;
public static final int JUSTIFY = 0x00300000;
public static final int TOP = 0x00400000;
public static final int BOTTOM = 0x00500000;
}

View File

@ -0,0 +1,87 @@
/**
* Annotation.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to create PDF annotation objects.
*
*
*/
class Annotation {
protected int objNumber;
protected String uri;
protected String key;
protected float x1;
protected float y1;
protected float x2;
protected float y2;
protected String language = null;
protected String altDescription = null;
protected String actualText = null;
protected FileAttachment fileAttachment = null;
/**
* This class is used to create annotation objects.
*
* @param uri the URI string.
* @param key the destination name.
* @param x1 the x coordinate of the top left corner.
* @param y1 the y coordinate of the top left corner.
* @param x2 the x coordinate of the bottom right corner.
* @param y2 the y coordinate of the bottom right corner.
*
*/
protected Annotation(
String uri,
String key,
float x1,
float y1,
float x2,
float y2,
String language,
String altDescription,
String actualText) {
this.uri = uri;
this.key = key;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.language = language;
this.altDescription = (altDescription == null) ? uri : altDescription;
this.actualText = (actualText == null) ? uri : actualText;
}
}

View File

@ -0,0 +1,41 @@
/**
* B5.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to specify PDF page with size <strong>B5</strong>.
* For more information about the page size classes - A3, A4, A5, B5, Executive, Letter, Legal and Tabloid - see the Page class.
*
*/
public class B5 {
public static final float[] PORTRAIT = new float[] {516.0f, 729.0f};
public static final float[] LANDSCAPE = new float[] {729.0f, 516.0f};
}

View File

@ -0,0 +1,282 @@
/**
*
* Copyright (c) 2018, Jonas Krogsboll
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
class BMPImage {
int w = 0; // Image width in pixels
int h = 0; // Image height in pixels
byte[] image; // The reconstructed image data
byte[] deflated; // The deflated reconstructed image data
private int bpp;
private byte palette[][];
private boolean r5g6b5; // If 16 bit image two encodings can occur
private static final int m10000000 = 0x80;
private static final int m01000000 = 0x40;
private static final int m00100000 = 0x20;
private static final int m00010000 = 0x10;
private static final int m00001000 = 0x08;
private static final int m00000100 = 0x04;
private static final int m00000010 = 0x02;
private static final int m00000001 = 0x01;
private static final int m11110000 = 0xF0;
private static final int m00001111 = 0x0F;
/* Tested with images created from GIMP */
public BMPImage( java.io.InputStream is ) throws Exception {
palette = null;
byte bm[] = getBytes(is, 2);
// From Wikipedia
if((bm[0] == 'B' && bm[1] == 'M')||
(bm[0] == 'B' && bm[1] == 'A')||
(bm[0] == 'C' && bm[1] == 'I')||
(bm[0] == 'C' && bm[1] == 'P')||
(bm[0] == 'I' && bm[1] == 'C')||
(bm[0] == 'P' && bm[1] == 'T')) {
skipNBytes(is, 8);
int offset = readSignedInt(is);
int sizeOfHeader = readSignedInt(is);
w = readSignedInt(is);
h = readSignedInt(is);
skipNBytes(is, 2);
bpp = read2BytesLE(is);
int compression = readSignedInt(is);
if (bpp > 8) {
r5g6b5 = (compression == 3);
skipNBytes(is, 20);
if (offset > 54) {
skipNBytes(is, offset-54);
}
}
else {
skipNBytes(is, 12);
int numpalcol = readSignedInt(is);
if (numpalcol == 0) {
numpalcol = (int) Math.pow(2, bpp);
}
skipNBytes(is, 4);
parsePalette(is, numpalcol);
}
parseData(is);
}
else {
throw new Exception("BMP data could not be parsed!");
}
}
private void parseData(java.io.InputStream is) throws Exception {
// rowsize is 4 * ceil (bpp*width/32.0)
image = new byte[w * h * 3];
int rowsize = 4 * (int)Math.ceil(bpp*w/32.0); // 4 byte alignment
byte row[];
int index;
try {
for (int i = 0; i < h; i++) {
row = getBytes(is, rowsize);
switch (bpp) {
case 1: row = bit1to8(row, w); break; // opslag i palette
case 4: row = bit4to8(row, w); break; // opslag i palette
case 8: break; // opslag i palette
case 16:
if (r5g6b5)
row = bit16to24(row, w); // 5,6,5 bit
else
row = bit16to24b(row, w);
break;
case 24: break; // bytes are correct
case 32: row = bit32to24(row, w); break;
default:
throw new Exception(
"Can only parse 1 bit, 4bit, 8bit, 16bit, 24bit and 32bit images");
}
index = w*(h-i-1)*3;
if (palette != null) { // indexed
for (int j = 0; j < w; j++) {
image[index++] = palette[(row[j]<0)?row[j]+256:row[j]][2];
image[index++] = palette[(row[j]<0)?row[j]+256:row[j]][1];
image[index++] = palette[(row[j]<0)?row[j]+256:row[j]][0];
}
} else { // not indexed
for (int j = 0; j < w*3; j+=3) {
image[index++] = row[j+2];
image[index++] = row[j+1];
image[index++] = row[j];
}
}
}
} catch (ArrayIndexOutOfBoundsException aiobe) {
throw new Exception ("BMP parse error: imagedata not correct");
}
ByteArrayOutputStream data2 = new ByteArrayOutputStream(32768);
DeflaterOutputStream dos = new DeflaterOutputStream(data2, new Deflater());
dos.write(image, 0, image.length);
dos.finish();
deflated = data2.toByteArray();
}
// 5 + 6 + 5 in B G R format 2 bytes to 3 bytes
private static byte[] bit16to24(byte[] row, int width) {
byte[] ret = new byte[width * 3];
int j = 0;
for (int i = 0; i < width*2; i+=2) {
ret[j++] = (byte)((row[i] & 0x1F)<<3);
ret[j++] = (byte)(((row[i+1] & 0x07)<<5)+((row[i] & 0xE0)>>3));
ret[j++] = (byte)((row[i+1] & 0xF8));
}
return ret;
}
// 5 + 5 + 5 in B G R format 2 bytes to 3 bytes
private static byte[] bit16to24b(byte[] row, int width) {
byte[] ret = new byte[width * 3];
int j = 0;
for (int i = 0; i < width*2; i+=2) {
ret[j++] = (byte)((row[i] & 0x1F)<<3);
ret[j++] = (byte)(((row[i+1] & 0x03)<<6)+((row[i] & 0xE0)>>2));
ret[j++] = (byte)((row[i+1] & 0x7C)<<1);
}
return ret;
}
/* alpha first? */
private static byte[] bit32to24(byte[] row, int width) {
byte[] ret = new byte[width * 3];
int j = 0;
for (int i = 0; i < width*4; i+=4) {
ret[j++] = row[i+1];
ret[j++] = row[i+2];
ret[j++] = row[i+3];
}
return ret;
}
private static byte[] bit4to8(byte[] row, int width) {
byte[] ret = new byte[width];
for(int i = 0; i < width; i++) {
if (i % 2 == 0) {
ret[i] =(byte) ((row[i/2] & m11110000)>>4);
}
else {
ret[i] =(byte) ((row[i/2] & m00001111));
}
}
return ret;
}
private static byte[] bit1to8(byte[] row, int width) {
byte[] ret = new byte[width];
for(int i = 0; i < width; i++) {
switch (i % 8) {
case 0: ret[i] = (byte) ((row[i/8] & m10000000)>>7); break;
case 1: ret[i] = (byte) ((row[i/8] & m01000000)>>6); break;
case 2: ret[i] = (byte) ((row[i/8] & m00100000)>>5); break;
case 3: ret[i] = (byte) ((row[i/8] & m00010000)>>4); break;
case 4: ret[i] = (byte) ((row[i/8] & m00001000)>>3); break;
case 5: ret[i] = (byte) ((row[i/8] & m00000100)>>2); break;
case 6: ret[i] = (byte) ((row[i/8] & m00000010)>>1); break;
case 7: ret[i] = (byte) ((row[i/8] & m00000001)); break;
}
}
return ret;
}
private void parsePalette(java.io.InputStream is, int size)
throws Exception {
palette = new byte[size][];
for (int i = 0; i < size; i++) {
palette[i] = getBytes(is, 4);
}
}
private void skipNBytes(java.io.InputStream inputStream, int n) {
try {
getBytes(inputStream, n);
}
catch (Exception e) {
e.printStackTrace();
}
}
private byte[] getBytes(java.io.InputStream inputStream, int length)
throws Exception {
byte[] buf = new byte[length];
inputStream.read(buf, 0, buf.length);
return buf;
}
private int read2BytesLE(java.io.InputStream inputStream)
throws Exception {
byte[] buf = getBytes(inputStream, 2);
int val = 0;
val |= buf[ 1 ] & 0xff;
val <<= 8;
val |= buf[ 0 ] & 0xff;
return val;
}
private int readSignedInt(java.io.InputStream inputStream)
throws Exception {
byte[] buf = getBytes(inputStream, 4);
long val = 0L;
val |= buf[ 3 ] & 0xff;
val <<= 8;
val |= buf[ 2 ] & 0xff;
val <<= 8;
val |= buf[ 1 ] & 0xff;
val <<= 8;
val |= buf[ 0 ] & 0xff;
return (int)val;
}
public int getWidth() {
return this.w;
}
public int getHeight() {
return this.h;
}
public byte[] getData() {
return this.deflated;
}
}

View File

@ -0,0 +1,235 @@
/**
* Bidi.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
import java.util.*;
/**
* Provides BIDI processing for Arabic and Hebrew.
*
* Please see Example_27.
*/
public class Bidi {
/*
General,Isolated,End,Middle,Beginning
*/
private static char[] forms = new char[] {
'\u0623','\uFE83','\uFE84','\u0623','\u0623',
'\u0628','\uFE8F','\uFE90','\uFE92','\uFE91',
'\u062A','\uFE95','\uFE96','\uFE98','\uFE97',
'\u062B','\uFE99','\uFE9A','\uFE9C','\uFE9B',
'\u062C','\uFE9D','\uFE9E','\uFEA0','\uFE9F',
'\u062D','\uFEA1','\uFEA2','\uFEA4','\uFEA3',
'\u062E','\uFEA5','\uFEA6','\uFEA8','\uFEA7',
'\u062F','\uFEA9','\uFEAA','\u062F','\u062F',
'\u0630','\uFEAB','\uFEAC','\u0630','\u0630',
'\u0631','\uFEAD','\uFEAE','\u0631','\u0631',
'\u0632','\uFEAF','\uFEB0','\u0632','\u0632',
'\u0633','\uFEB1','\uFEB2','\uFEB4','\uFEB3',
'\u0634','\uFEB5','\uFEB6','\uFEB8','\uFEB7',
'\u0635','\uFEB9','\uFEBA','\uFEBC','\uFEBB',
'\u0636','\uFEBD','\uFEBE','\uFEC0','\uFEBF',
'\u0637','\uFEC1','\uFEC2','\uFEC4','\uFEC3',
'\u0638','\uFEC5','\uFEC6','\uFEC8','\uFEC7',
'\u0639','\uFEC9','\uFECA','\uFECC','\uFECB',
'\u063A','\uFECD','\uFECE','\uFED0','\uFECF',
'\u0641','\uFED1','\uFED2','\uFED4','\uFED3',
'\u0642','\uFED5','\uFED6','\uFED8','\uFED7',
'\u0643','\uFED9','\uFEDA','\uFEDC','\uFEDB',
'\u0644','\uFEDD','\uFEDE','\uFEE0','\uFEDF',
'\u0645','\uFEE1','\uFEE2','\uFEE4','\uFEE3',
'\u0646','\uFEE5','\uFEE6','\uFEE8','\uFEE7',
'\u0647','\uFEE9','\uFEEA','\uFEEC','\uFEEB',
'\u0648','\uFEED','\uFEEE','\u0648','\u0648',
'\u064A','\uFEF1','\uFEF2','\uFEF4','\uFEF3',
'\u0622','\uFE81','\uFE82','\u0622','\u0622',
'\u0629','\uFE93','\uFE94','\u0629','\u0629',
'\u0649','\uFEEF','\uFEF0','\u0649','\u0649',
};
private static boolean isArabicLetter(char ch) {
for (int i = 0; i < forms.length; i += 5) {
if (ch == forms[i]) {
return true;
}
}
return false;
}
/**
* Reorders the string so that Arabic and Hebrew text flows from right
* to left while numbers and Latin text flows from left to right.
*
* @param str the input string.
* @return the reordered string.
*/
public static String reorderVisually(String str) {
StringBuilder buf1 = new StringBuilder();
StringBuilder buf2 = new StringBuilder();
boolean right_to_left = true;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == '\u200E') {
// LRM U+200E LEFT-TO-RIGHT MARK Left-to-right zero-width character
right_to_left = false;
continue;
}
if (ch == '\u200F' || ch == '\u061C') {
// RLM U+200F RIGHT-TO-LEFT MARK Right-to-left zero-width non-Arabic character
// ALM U+061C ARABIC LETTER MARK Right-to-left zero-width Arabic character
right_to_left = true;
continue;
}
if (isArabic(ch) ||
isHebrew(ch) ||
ch == '«' || ch == '»' ||
ch == '(' || ch == ')' ||
ch == '[' || ch == ']') {
right_to_left = true;
if (buf2.length() > 0) {
buf1.append(process(buf2));
buf2.setLength(0);
}
if (ch == '«') {
buf1.append('»');
}
else if (ch == '»') {
buf1.append('«');
}
else if (ch == '(') {
buf1.append(')');
}
else if (ch == ')') {
buf1.append('(');
}
else if (ch == '[') {
buf1.append(']');
}
else if (ch == ']') {
buf1.append('[');
}
else {
buf1.append(ch);
}
}
else if (isAlphaNumeric(ch)) {
right_to_left = false;
buf2.append(ch);
}
else {
if (right_to_left) {
buf1.append(ch);
}
else {
buf2.append(ch);
}
}
}
if (buf2.length() > 0) {
buf1.append(process(buf2));
}
StringBuilder buf3 = new StringBuilder();
for (int i = (buf1.length() - 1); i >= 0; i--) {
char ch = buf1.charAt(i);
if (isArabicLetter(ch)) {
char prev_ch = (i > 0) ? buf1.charAt(i - 1) : '\u0000';
char next_ch = (i < (buf1.length() - 1)) ? buf1.charAt(i + 1) : '\u0000';
for (int j = 0; j < forms.length; j += 5) {
if (ch == forms[j]) {
if (!isArabicLetter(prev_ch) && !isArabicLetter(next_ch)) {
buf3.append(forms[j + 1]); // Isolated
}
else if (isArabicLetter(prev_ch) && !isArabicLetter(next_ch)) {
buf3.append(forms[j + 2]); // End
}
else if (isArabicLetter(prev_ch) && isArabicLetter(next_ch)) {
buf3.append(forms[j + 3]); // Middle
}
else if (!isArabicLetter(prev_ch) && isArabicLetter(next_ch)) {
buf3.append(forms[j + 4]); // Beginning
}
}
}
}
else {
buf3.append(ch);
}
}
return buf3.toString();
}
public static boolean isArabic(char ch) {
return (ch >= 0x600 && ch <= 0x6FF);
}
private static boolean isHebrew(char ch) {
return (ch >= 0x0591 && ch <= 0x05F4);
}
private static boolean isAlphaNumeric(char ch) {
if (ch >= '0' && ch <= '9') {
return true;
}
if (ch >= 'a' && ch <= 'z') {
return true;
}
if (ch >= 'A' && ch <= 'Z') {
return true;
}
return false;
}
private static StringBuilder process(StringBuilder buf) {
StringBuilder buf1 = buf.reverse();
StringBuilder buf2 = new StringBuilder();
StringBuilder buf3 = new StringBuilder();
for (int i = 0; i < buf1.length(); i++) {
char ch = buf1.charAt(i);
if (ch == ' ' || ch == ',' || ch == '.' || ch == '-') {
buf2.append(ch);
continue;
}
buf3.append(buf1.substring(i));
buf3.append(buf2.reverse());
break;
}
return buf3;
}
}

View File

@ -0,0 +1,62 @@
/**
*
Copyright (c) 2009 Kazuhiko Arase
URL: http://www.d-project.com/
Licensed under the MIT license:
http://www.opensource.org/licenses/mit-license.php
The word "QR Code" is registered trademark of
DENSO WAVE INCORPORATED
http://www.denso-wave.com/qrcode/faqpatent-e.html
*/
package com.pdfjet;
/**
* BitBuffer
* @author Kazuhiko Arase
*/
class BitBuffer {
private byte[] buffer;
private int length;
private int increments = 32;
public BitBuffer() {
buffer = new byte[increments];
length = 0;
}
public byte[] getBuffer() {
return buffer;
}
public int getLengthInBits() {
return length;
}
public void put(int num, int length) {
for (int i = 0; i < length; i++) {
put(((num >>> (length - i - 1)) & 1) == 1);
}
}
public void put(boolean bit) {
if (length == buffer.length * 8) {
byte[] newBuffer = new byte[buffer.length + increments];
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer;
}
if (bit) {
buffer[length / 8] |= (0x80 >>> (length % 8));
}
length++;
}
}

View File

@ -0,0 +1,200 @@
/**
* Bookmark.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
import java.lang.*;
import java.util.*;
/**
* Please see Example_51 and Example_52
*
*/
public class Bookmark {
private int destNumber = 0;
private Page page = null;
private float y = 0f;
private String key = null;
private String title = null;
private Bookmark parent = null;
private Bookmark prev = null;
private Bookmark next = null;
private List<Bookmark> children = null;
private Destination dest = null;
protected int objNumber = 0;
protected String prefix = null;
public Bookmark(PDF pdf) {
pdf.toc = this;
}
private Bookmark(Page page, float y, String key, String title) {
this.page = page;
this.y = y;
this.key = key;
this.title = title;
}
public Bookmark addBookmark(Page page, Title title) {
return addBookmark(page, title.text.getY(), title.text.getText());
}
public Bookmark addBookmark(Page page, float y, String title) {
Bookmark bm = this;
while (bm.parent != null) {
bm = bm.getParent();
}
String key = bm.next();
Bookmark bookmark = new Bookmark(page, y, key, title.replaceAll("\\s+"," "));
bookmark.parent = this;
bookmark.dest = page.addDestination(key, y);
if (children == null) {
children = new ArrayList<Bookmark>();
}
else {
bookmark.prev = children.get(children.size() - 1);
children.get(children.size() - 1).next = bookmark;
}
children.add(bookmark);
return bookmark;
}
public String getDestKey() {
return this.key;
}
public String getTitle() {
return this.title;
}
public Bookmark getParent() {
return this.parent;
}
public Bookmark autoNumber(TextLine text) {
Bookmark bm = getPrevBookmark();
if (bm == null) {
bm = getParent();
if (bm.prefix == null) {
prefix = "1";
}
else {
prefix = bm.prefix + ".1";
}
}
else {
if (bm.prefix == null) {
if (bm.getParent().prefix == null) {
prefix = "1";
}
else {
prefix = bm.getParent().prefix + ".1";
}
}
else {
int index = bm.prefix.lastIndexOf('.');
if (index == -1) {
prefix = String.valueOf(Integer.valueOf(bm.prefix) + 1);
}
else {
prefix = bm.prefix.substring(0, index) + ".";
prefix += String.valueOf(Integer.valueOf(bm.prefix.substring(index + 1)) + 1);
}
}
}
text.setText(prefix);
title = prefix + " " + title;
return this;
}
protected List<Bookmark> toArrayList() {
int objNumber = 0;
List<Bookmark> list = new ArrayList<Bookmark>();
Queue<Bookmark> queue = new LinkedList<Bookmark>();
queue.add(this);
while (!queue.isEmpty()) {
Bookmark bm = queue.poll();
bm.objNumber = objNumber++;
list.add(bm);
if (bm.getChildren() != null) {
queue.addAll(bm.getChildren());
}
}
return list;
}
protected List<Bookmark> getChildren() {
return this.children;
}
protected Bookmark getPrevBookmark() {
return this.prev;
}
protected Bookmark getNextBookmark() {
return this.next;
}
protected Bookmark getFirstChild() {
return this.children.get(0);
}
protected Bookmark getLastChild() {
return children.get(children.size() - 1);
}
protected Destination getDestination() {
return this.dest;
}
private String next() {
++destNumber;
return "dest#" + String.valueOf(destNumber);
}
} // End of Bookmark.java

View File

@ -0,0 +1,43 @@
/**
* Border.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to control the visibility of cell borders.
* See the Cell class for more information.
*
*/
public class Border {
public static final int TOP = 0x00010000;
public static final int BOTTOM = 0x00020000;
public static final int LEFT = 0x00040000;
public static final int RIGHT = 0x00080000;
}

View File

@ -0,0 +1,369 @@
/**
* Box.java
*
Copyright (c) 2018, Innovatics Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.pdfjet;
/**
* Used to create rectangular boxes on a page.
* Also used to for layout purposes. See the placeIn method in the Image and TextLine classes.
*
*/
public class Box implements Drawable {
protected float x;
protected float y;
private float w;
private float h;
private int color = Color.black;
private float width = 0.3f;
private String pattern = "[] 0";
private boolean fill_shape = false;
private String language = null;
private String altDescription = Single.space;
private String actualText = Single.space;
protected String uri = null;
protected String key = null;
/**
* The default constructor.
*
*/
public Box() {
}
/**
* Creates a box object.
*
* @param x the x coordinate of the top left corner of this box when drawn on the page.
* @param y the y coordinate of the top left corner of this box when drawn on the page.
* @param w the width of this box.
* @param h the height of this box.
*/
public Box(double x, double y, double w, double h) {
this.x = (float) x;
this.y = (float) y;
this.w = (float) w;
this.h = (float) h;
}
/**
* Creates a box object.
*
* @param x the x coordinate of the top left corner of this box when drawn on the page.
* @param y the y coordinate of the top left corner of this box when drawn on the page.
* @param w the width of this box.
* @param h the height of this box.
*/
public Box(float x, float y, float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
/**
* Sets the position of this box on the page.
*
* @param x the x coordinate of the top left corner of this box when drawn on the page.
* @param y the y coordinate of the top left corner of this box when drawn on the page.
*/
public Box setPosition(double x, double y) {
return setLocation((float) x, (float) y);
}
/**
* Sets the position of this box on the page.
*
* @param x the x coordinate of the top left corner of this box when drawn on the page.
* @param y the y coordinate of the top left corner of this box when drawn on the page.
*/
public Box setPosition(float x, float y) {
return setLocation(x, y);
}
/**
* Sets the location of this box on the page.
*
* @param x the x coordinate of the top left corner of this box when drawn on the page.
* @param y the y coordinate of the top left corner of this box when drawn on the page.
*/
public Box setLocation(float x, float y) {
this.x = x;
this.y = y;
return this;
}
/**
* Sets the size of this box.
*
* @param w the width of this box.
* @param h the height of this box.
*/
public void setSize(double w, double h) {
this.w = (float) w;
this.h = (float) h;
}
/**
* Sets the size of this box.
*
* @param w the width of this box.
* @param h the height of this box.
*/
public void setSize(float w, float h) {
this.w = w;
this.h = h;
}
/**
* Sets the color for this box.
*
* @param color the color specified as an integer.
*/
public void setColor(int color) {
this.color = color;
}
/**
* Sets the width of this line.
*
* @param width the width.
*/
public void setLineWidth(double width) {
this.width = (float) width;
}
/**
* Sets the width of this line.
*
* @param width the width.
*/
public void setLineWidth(float width) {
this.width = width;
}
/**
* Sets the URI for the "click box" action.
*
* @param uri the URI
*/
public void setURIAction(String uri) {
this.uri = uri;
}
/**
* Sets the destination key for the action.
*
* @param key the destination name.
*/
public void setGoToAction(String key) {
this.key = key;
}
/**
* Sets the alternate description of this box.
*
* @param altDescription the alternate description of the box.
* @return this Box.
*/
public Box setAltDescription(String altDescription) {
this.altDescription = altDescription;
return this;
}
/**
* Sets the actual text for this box.
*
* @param actualText the actual text for the box.
* @return this Box.
*/
public Box setActualText(String actualText) {
this.actualText = actualText;
return this;
}
/**
* The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
* It is specified by a dash array and a dash phase.
* The elements of the dash array are positive numbers that specify the lengths of
* alternating dashes and gaps.
* The dash phase specifies the distance into the dash pattern at which to start the dash.
* The elements of both the dash array and the dash phase are expressed in user space units.
* <pre>
* Examples of line dash patterns:
*
* "[Array] Phase" Appearance Description
* _______________ _________________ ____________________________________
*
* "[] 0" ----------------- Solid line
* "[3] 0" --- --- --- 3 units on, 3 units off, ...
* "[2] 1" - -- -- -- -- 1 on, 2 off, 2 on, 2 off, ...
* "[2 1] 0" -- -- -- -- -- -- 2 on, 1 off, 2 on, 1 off, ...
* "[3 5] 6" --- --- 2 off, 3 on, 5 off, 3 on, 5 off, ...
* "[2 3] 11" - -- -- -- 1 on, 3 off, 2 on, 3 off, 2 on, ...
* </pre>
*
* @param pattern the line dash pattern.