Compare commits
14 commits
Author | SHA1 | Date | |
---|---|---|---|
a70b7e62cf | |||
a323076ca3 | |||
b13aa5f3ef | |||
2d6961e848 | |||
09086f9b5b | |||
2dedbc154f | |||
0564b2e934 | |||
aa08fa45f0 | |||
e81e605887 | |||
0f3f8d488a | |||
a58f1e6c83 | |||
afbe6eee2f | |||
229951349b | |||
27fd1956a1 |
181 changed files with 1423 additions and 1057 deletions
build.gradlegradle.properties
gradle
gradlew.batgraphics-barcode/src
graphics-chart/src/main/java
graphics-fonts-arabic
Google-Noto-LICENSE.txtbuild.gradle
src/main
java
resources
META-INF/services
org/xbib/graphics/fonts/arabic
graphics-fonts-cjk
Google-Noto-LICENSE.txtbuild.gradle
src/main
java
resources
META-INF/services
org/xbib/graphics/fonts/cjk
graphics-fonts-cyrillic
Google-Noto-LICENSE.txtNOTICE.txtbuild.gradle
src/main
java
resources
META-INF/services
org/xbib/graphics/fonts/cyrillic
graphics-fonts-hebrew
Google-Noto-LICENSE.txtbuild.gradle
src/main
java
resources
META-INF/services
org/xbib/graphics/fonts/hebrew
graphics-fonts-latin
Adobe-Source-LICENSE.txtGoogle-Noto-LICENSE.txtbuild.gradle
src
main
java
module-info.java
org/xbib/graphics/fonts/latin
resources
META-INF/services
org/xbib/graphics/fonts/latin
test/java/org/xbib/graphics/fonts/latin/test
graphics-fonts
build.gradle
src
graphics-ghostscript/src
graphics-pdfbox-layout
build.gradle
src/main/java
module-info.java
org/xbib/graphics/pdfbox/layout
|
@ -7,7 +7,7 @@ plugins {
|
|||
|
||||
wrapper {
|
||||
gradleVersion = libs.versions.gradle.get()
|
||||
distributionType = Wrapper.DistributionType.ALL
|
||||
distributionType = Wrapper.DistributionType.BIN
|
||||
}
|
||||
|
||||
ext {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
group = org.xbib.graphics
|
||||
name = graphics
|
||||
version = 5.4.0
|
||||
version = 5.7.0
|
||||
|
|
|
@ -2,7 +2,8 @@ repositories {
|
|||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://www.dcm4che.org/maven2/'
|
||||
//url 'https://www.dcm4che.org/maven2/'
|
||||
url 'https://maven.scijava.org/content/repositories/public/'
|
||||
}
|
||||
maven {
|
||||
url 'https://raw.githubusercontent.com/nroduit/mvn-repo/master/'
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
20
gradlew.bat
vendored
20
gradlew.bat
vendored
|
@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
|||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ module org.xbib.graphics.barcode {
|
|||
exports org.xbib.graphics.barcode;
|
||||
exports org.xbib.graphics.barcode.util;
|
||||
exports org.xbib.graphics.barcode.render;
|
||||
requires transitive java.desktop;
|
||||
requires transitive org.xbib.graphics.zxing;
|
||||
requires java.desktop;
|
||||
requires org.xbib.graphics.zxing;
|
||||
provides SymbolProvider with
|
||||
AustraliaPost.Provider,
|
||||
AztecCode.Provider,
|
||||
|
|
|
@ -17,14 +17,11 @@ import java.nio.file.Paths;
|
|||
|
||||
public class QRCodeTest {
|
||||
|
||||
/**
|
||||
* The hard way by using Okapi Barcode.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void createQRCode() throws IOException {
|
||||
//String content = "IFLA-15: Kostenlimit überschritten, erneute Bestellung, wenn Kosten akzeptiert werden";
|
||||
String content = "IFLA-16:";
|
||||
//String content = "IFLA-16:";
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = 128;
|
||||
|
@ -34,7 +31,7 @@ public class QRCodeTest {
|
|||
code.setQuietZoneHorizontal(1);
|
||||
code.setQuietZoneVertical(1);
|
||||
code.setEccMode(QrCode.EccMode.L);
|
||||
code.setContent(content);
|
||||
//code.setContent(content);
|
||||
double scalingFactor = 5.0d;
|
||||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, x, y, scalingFactor, scalingFactor);
|
||||
|
@ -56,14 +53,12 @@ public class QRCodeTest {
|
|||
/**
|
||||
* Easy way by using zxing.
|
||||
* @throws IOException
|
||||
* @throws NotFoundException
|
||||
* @throws WriterException
|
||||
*/
|
||||
@Test
|
||||
public void testQrCode() throws IOException, NotFoundException, WriterException {
|
||||
public void testQrCode() throws IOException {
|
||||
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||
try (OutputStream outputStream = Files.newOutputStream(Paths.get("build/ifla-20.png"))) {
|
||||
qrCodeWriter.write("IFLA-20: Art der gewünschten Lieferung nicht möglich",
|
||||
try (OutputStream outputStream = Files.newOutputStream(Paths.get("build/de-361-ifla-20.png"))) {
|
||||
qrCodeWriter.write("DE-361: IFLA-20: Art der gewünschten Lieferung nicht möglich",
|
||||
outputStream, "png", 200, 200);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,5 +17,5 @@ module org.xbib.graphics.chart {
|
|||
requires org.xbib.graphics.io.vector.eps;
|
||||
requires org.xbib.graphics.io.vector.pdf;
|
||||
requires org.xbib.graphics.io.vector.svg;
|
||||
requires transitive java.desktop;
|
||||
requires java.desktop;
|
||||
}
|
||||
|
|
3
graphics-fonts-arabic/build.gradle
Normal file
3
graphics-fonts-arabic/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':graphics-fonts')
|
||||
}
|
9
graphics-fonts-arabic/src/main/java/module-info.java
Normal file
9
graphics-fonts-arabic/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.fonts.arabic.ArabicFontEmbedder;
|
||||
|
||||
module org.xbib.graphics.fonts.arabic {
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
exports org.xbib.graphics.fonts.arabic;
|
||||
provides FontEmbedder with ArabicFontEmbedder;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.arabic;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ArabicFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public ArabicFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "notosansarabic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"NotoSansArabic-Regular.ttf",
|
||||
"NotoSansArabic-Bold.ttf",
|
||||
"NotoSansArabic-Regular.ttf",
|
||||
"NotoSansArabic-Bold.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.xbib.graphics.fonts.arabic.ArabicFontEmbedder
|
Binary file not shown.
Binary file not shown.
45
graphics-fonts-cjk/Google-Noto-LICENSE.txt
Normal file
45
graphics-fonts-cjk/Google-Noto-LICENSE.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
SIL Open Font License
|
||||
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
—————————————————————————————-
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
—————————————————————————————-
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
3
graphics-fonts-cjk/build.gradle
Normal file
3
graphics-fonts-cjk/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':graphics-fonts')
|
||||
}
|
9
graphics-fonts-cjk/src/main/java/module-info.java
Normal file
9
graphics-fonts-cjk/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.fonts.cjk.CJKFontEmbedder;
|
||||
|
||||
module org.xbib.graphics.fonts.cjk {
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
exports org.xbib.graphics.fonts.cjk;
|
||||
provides FontEmbedder with CJKFontEmbedder;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.cjk;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CJKFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public CJKFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "notosanscjksc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"NotoSansCJKsc-Regular.ttf",
|
||||
"NotoSansCJKsc-Bold.ttf",
|
||||
"NotoSansCJKsc-Italic.ttf",
|
||||
"NotoSansCJKsc-BoldItalic.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.xbib.graphics.fonts.cjk.CJKFontEmbedder
|
45
graphics-fonts-cyrillic/Google-Noto-LICENSE.txt
Normal file
45
graphics-fonts-cyrillic/Google-Noto-LICENSE.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
SIL Open Font License
|
||||
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
—————————————————————————————-
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
—————————————————————————————-
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
2
graphics-fonts-cyrillic/NOTICE.txt
Normal file
2
graphics-fonts-cyrillic/NOTICE.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
Identical to Noto Latin fonts. There is no need to add cyrillic Noto fonst if the latin Noto fonts are already added.
|
3
graphics-fonts-cyrillic/build.gradle
Normal file
3
graphics-fonts-cyrillic/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':graphics-fonts')
|
||||
}
|
8
graphics-fonts-cyrillic/src/main/java/module-info.java
Normal file
8
graphics-fonts-cyrillic/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.fonts.cyrillic.CyrillicFontEmbedder;
|
||||
|
||||
module org.xbib.graphics.fonts.cyrillic {
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
provides FontEmbedder with CyrillicFontEmbedder;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.cyrillic;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CyrillicFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public CyrillicFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "notosanscyrillic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"NotoSans-Regular.ttf",
|
||||
"NotoSans-Bold.ttf",
|
||||
"NotoSans-Italic.ttf",
|
||||
"NotoSans-BoldItalic.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.xbib.graphics.fonts.cyrillic.CyrillicFontEmbedder
|
45
graphics-fonts-hebrew/Google-Noto-LICENSE.txt
Normal file
45
graphics-fonts-hebrew/Google-Noto-LICENSE.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
SIL Open Font License
|
||||
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
—————————————————————————————-
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
—————————————————————————————-
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
3
graphics-fonts-hebrew/build.gradle
Normal file
3
graphics-fonts-hebrew/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':graphics-fonts')
|
||||
}
|
8
graphics-fonts-hebrew/src/main/java/module-info.java
Normal file
8
graphics-fonts-hebrew/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.fonts.hebrew.HebrewFontEmbedder;
|
||||
|
||||
module org.xbib.graphics.fonts.hebrew {
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
provides FontEmbedder with HebrewFontEmbedder;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.hebrew;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HebrewFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public HebrewFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "notosanshebrew";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"NotoSansHebrew-Regular.ttf",
|
||||
"NotoSansHebrew-Bold.ttf",
|
||||
"NotoSansHebrew-Regular.ttf",
|
||||
"NotoSansHebrew-Bold.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.xbib.graphics.fonts.hebrew.HebrewFontEmbedder
|
45
graphics-fonts-latin/Google-Noto-LICENSE.txt
Normal file
45
graphics-fonts-latin/Google-Noto-LICENSE.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
SIL Open Font License
|
||||
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
—————————————————————————————-
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
—————————————————————————————-
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
3
graphics-fonts-latin/build.gradle
Normal file
3
graphics-fonts-latin/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':graphics-fonts')
|
||||
}
|
12
graphics-fonts-latin/src/main/java/module-info.java
Normal file
12
graphics-fonts-latin/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.fonts.latin.NotoSansFontEmbedder;
|
||||
import org.xbib.graphics.fonts.latin.OpenSansFontEmbedder;
|
||||
import org.xbib.graphics.fonts.latin.SourceSansFontEmbedder;
|
||||
|
||||
module org.xbib.graphics.fonts.latin {
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
provides FontEmbedder with NotoSansFontEmbedder,
|
||||
OpenSansFontEmbedder,
|
||||
SourceSansFontEmbedder;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.latin;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NotoSansFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public NotoSansFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "notosans";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"NotoSans-Regular.ttf",
|
||||
"NotoSans-Bold.ttf",
|
||||
"NotoSans-Italic.ttf",
|
||||
"NotoSans-BoldItalic.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.xbib.graphics.fonts.latin;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OpenSansFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public OpenSansFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "opensans";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(),
|
||||
"OpenSans-Regular.ttf",
|
||||
"OpenSans-Bold.ttf",
|
||||
"OpenSans-Italic.ttf",
|
||||
"OpenSans-BoldItalic.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.xbib.graphics.fonts.latin;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.xbib.graphics.fonts.TrueTypeEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SourceSansFontEmbedder extends TrueTypeEmbedder {
|
||||
|
||||
public SourceSansFontEmbedder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "sourcesans";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embed(PDDocument pdDocument) throws IOException {
|
||||
embed(pdDocument, getAlias(), "SourceSans3-Regular.ttf",
|
||||
"SourceSans3-Bold.ttf",
|
||||
"SourceSans3-It.ttf",
|
||||
"SourceSans3-BoldIt.ttf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
org.xbib.graphics.fonts.latin.NotoSansFontEmbedder
|
||||
org.xbib.graphics.fonts.latin.OpenSansFontEmbedder
|
||||
org.xbib.graphics.fonts.latin.SourceSansFontEmbedder
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,28 @@
|
|||
package org.xbib.graphics.fonts.latin.test;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.graphics.fonts.latin.NotoSansFontEmbedder;
|
||||
import org.xbib.graphics.fonts.latin.OpenSansFontEmbedder;
|
||||
import org.xbib.graphics.fonts.latin.SourceSansFontEmbedder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LatinEmbedderTest {
|
||||
|
||||
@Test
|
||||
public void testLatin() throws IOException {
|
||||
NotoSansFontEmbedder embedder = new NotoSansFontEmbedder();
|
||||
try (PDDocument document = new PDDocument()) {
|
||||
embedder.embed(document);
|
||||
}
|
||||
OpenSansFontEmbedder openSansFontEmbedder = new OpenSansFontEmbedder();
|
||||
try (PDDocument document = new PDDocument()) {
|
||||
openSansFontEmbedder.embed(document);
|
||||
}
|
||||
SourceSansFontEmbedder sourceSansFontEmbedder = new SourceSansFontEmbedder();
|
||||
try (PDDocument document = new PDDocument()) {
|
||||
sourceSansFontEmbedder.embed(document);
|
||||
}
|
||||
}
|
||||
}
|
3
graphics-fonts/build.gradle
Normal file
3
graphics-fonts/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api libs.pdfbox
|
||||
}
|
8
graphics-fonts/src/main/java/module-info.java
Normal file
8
graphics-fonts/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
module org.xbib.graphics.fonts {
|
||||
requires java.logging;
|
||||
requires java.desktop;
|
||||
requires org.apache.fontbox;
|
||||
requires org.apache.pdfbox;
|
||||
requires org.apache.pdfbox.io;
|
||||
exports org.xbib.graphics.fonts;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* In order to easy handling with fonts, this enum bundles the
|
||||
* plain/italic/bold/bold-italic variants of the three standard font types
|
||||
* Times, Courier, Helvetica.
|
||||
*/
|
||||
public enum BaseFont implements Font {
|
||||
|
||||
TIMES("times", new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN), new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD),
|
||||
new PDType1Font(Standard14Fonts.FontName.TIMES_ITALIC), new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD_ITALIC)),
|
||||
|
||||
COURIER("courier", new PDType1Font(Standard14Fonts.FontName.COURIER), new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD),
|
||||
new PDType1Font(Standard14Fonts.FontName.COURIER_OBLIQUE), new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE)),
|
||||
|
||||
HELVETICA("helvetica", new PDType1Font(Standard14Fonts.FontName.HELVETICA), new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD),
|
||||
new PDType1Font(Standard14Fonts.FontName.HELVETICA_OBLIQUE), new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE));
|
||||
|
||||
private final String alias;
|
||||
|
||||
private final PDType1Font regularFont;
|
||||
|
||||
private final PDType1Font boldFont;
|
||||
|
||||
private final PDType1Font italicFont;
|
||||
|
||||
private final PDType1Font boldItalicFont;
|
||||
|
||||
BaseFont(String alias, PDType1Font regularFont, PDType1Font boldFont, PDType1Font italicFont, PDType1Font boldItalicFont) {
|
||||
this.alias = alias;
|
||||
this.regularFont = regularFont;
|
||||
this.boldFont = boldFont;
|
||||
this.italicFont = italicFont;
|
||||
this.boldItalicFont = boldItalicFont;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getRegularFont() {
|
||||
return regularFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldFont() {
|
||||
return boldFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getItalicFont() {
|
||||
return italicFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldItalicFont() {
|
||||
return boldItalicFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGlyph(int code) {
|
||||
try {
|
||||
return regularFont.hasGlyph(code);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
String printable = string.replaceAll("\\P{Print}|\\p{Cntrl}|\\p{Space}", "");
|
||||
if (printable.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return regularFont.getStringWidth(printable) > 0;
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.fontbox.ttf.TrueTypeCollection;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -6,7 +6,6 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
|
|||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.xbib.graphics.pdfbox.PdfBoxGraphics2D;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
|
@ -44,8 +43,7 @@ import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.ZAPF_DINGB
|
|||
|
||||
/**
|
||||
* Default implementation to draw fonts. You can reuse instances of this class
|
||||
* within a PDDocument for more then one {@link PdfBoxGraphics2D}.
|
||||
* Just ensure that you call close after you closed the PDDocument to free any
|
||||
* within a PDDocument. Just ensure that you call close after you closed the PDDocument to free any
|
||||
* temporary files.
|
||||
*/
|
||||
public class DefaultFontDrawer implements FontDrawer, Closeable {
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import java.awt.Font;
|
|
@ -1,11 +1,11 @@
|
|||
package org.xbib.graphics.pdfbox.layout.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Font {
|
||||
|
||||
String getAlias();
|
||||
|
||||
PDFont getRegularFont();
|
||||
|
||||
PDFont getBoldFont();
|
||||
|
@ -16,5 +16,5 @@ public interface Font {
|
|||
|
||||
boolean hasGlyph(int code);
|
||||
|
||||
boolean canWrite(String string);
|
||||
boolean canRender(String string);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package org.xbib.graphics.pdfbox.layout.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@ import java.util.Objects;
|
|||
*/
|
||||
public class FontDescriptor {
|
||||
|
||||
private final List<Font> fonts;
|
||||
private final Collection<Font> fonts;
|
||||
|
||||
private float size;
|
||||
|
||||
|
@ -20,11 +20,11 @@ public class FontDescriptor {
|
|||
|
||||
private boolean italic;
|
||||
|
||||
public FontDescriptor(List<Font> fonts, float size) {
|
||||
public FontDescriptor(Collection<Font> fonts, float size) {
|
||||
this(fonts, size, false, false);
|
||||
}
|
||||
|
||||
public FontDescriptor(List<Font> fonts, float size, boolean bold, boolean italic) {
|
||||
public FontDescriptor(Collection<Font> fonts, float size, boolean bold, boolean italic) {
|
||||
this.fonts = fonts;
|
||||
// we do not accept null fonts
|
||||
for (Font font : fonts) {
|
||||
|
@ -36,7 +36,7 @@ public class FontDescriptor {
|
|||
this.regular = !bold && !italic;
|
||||
}
|
||||
|
||||
public List<Font> getFonts() {
|
||||
public Collection<Font> getFonts() {
|
||||
return fonts;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class FontDescriptor {
|
|||
|
||||
public PDFont getSelectedFont(String text) {
|
||||
for (Font font : fonts) {
|
||||
if (font.canWrite(text)) {
|
||||
if (font.canRender(text)) {
|
||||
if (regular) {
|
||||
return font.getRegularFont();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
|
@ -1,10 +1,9 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.PDResources;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.xbib.graphics.pdfbox.PdfBoxGraphics2D;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
|
@ -59,7 +58,7 @@ public interface FontDrawerEnvironment {
|
|||
FontRenderContext getFontRenderContext();
|
||||
|
||||
/**
|
||||
* @return the bbox of the {@link PdfBoxGraphics2D}
|
||||
* @return the bbox
|
||||
*/
|
||||
PDRectangle getGraphicsBBox();
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface FontEmbedder {
|
||||
|
||||
String getAlias();
|
||||
|
||||
Collection<Font> getFonts();
|
||||
|
||||
void embed(PDDocument pdDocument) throws IOException;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.pdfbox.font;
|
||||
package org.xbib.graphics.fonts;
|
||||
|
||||
import java.text.AttributedCharacterIterator;
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package org.xbib.graphics.fonts;
|
||||
|
||||
import org.apache.fontbox.ttf.TTFParser;
|
||||
import org.apache.fontbox.ttf.TrueTypeFont;
|
||||
import org.apache.pdfbox.io.RandomAccessRead;
|
||||
import org.apache.pdfbox.io.RandomAccessReadBuffer;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class TrueTypeEmbedder implements FontEmbedder {
|
||||
|
||||
private final Map<String, Font> fonts = new LinkedHashMap<>();
|
||||
|
||||
public TrueTypeEmbedder() {
|
||||
}
|
||||
|
||||
public void embed(PDDocument pdDocument,
|
||||
final String name,
|
||||
final String regularFontResource,
|
||||
final String boldFontResource,
|
||||
final String italicsFontResource,
|
||||
final String boldItalicsFontResource) throws IOException {
|
||||
if (fonts.containsKey(name)) {
|
||||
return;
|
||||
}
|
||||
final PDType0Font regularFont = embedTrueTypeFont(pdDocument, regularFontResource);
|
||||
final PDType0Font boldFont = embedTrueTypeFont(pdDocument, boldFontResource);
|
||||
final PDType0Font italicsFont = embedTrueTypeFont(pdDocument, italicsFontResource);
|
||||
final PDType0Font boldItalicsFont = embedTrueTypeFont(pdDocument, boldItalicsFontResource);
|
||||
fonts.putIfAbsent(name, new Font() {
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getRegularFont() {
|
||||
return regularFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldFont() {
|
||||
return boldFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getItalicFont() {
|
||||
return italicsFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldItalicFont() {
|
||||
return boldItalicsFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGlyph(int code) {
|
||||
try {
|
||||
return regularFont.hasGlyph(code);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(String string) {
|
||||
try {
|
||||
return regularFont.getStringWidth(string) > 0;
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Font> getFonts() {
|
||||
return fonts.values();
|
||||
}
|
||||
|
||||
private PDType0Font embedTrueTypeFont(PDDocument pdDocument, String resourceName) throws IOException {
|
||||
InputStream inputStream = getClass().getResourceAsStream(resourceName);
|
||||
TTFParser ttfParser = new TTFParser();
|
||||
RandomAccessRead randomAccessRead = new RandomAccessReadBuffer(inputStream);
|
||||
TrueTypeFont trueTypeFont = ttfParser.parse(randomAccessRead);
|
||||
return PDType0Font.load(pdDocument, trueTypeFont, true);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package org.xbib.graphics.pdfbox.test;
|
||||
package org.xbib.graphics.fonts.test;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.graphics.pdfbox.font.CoreFontDrawer;
|
||||
import org.xbib.graphics.fonts.CoreFontDrawer;
|
||||
|
||||
import java.awt.Font;
|
||||
|
|
@ -2,7 +2,7 @@ module org.xbib.graphics.ghostscript {
|
|||
exports org.xbib.graphics.ghostscript;
|
||||
requires com.sun.jna;
|
||||
requires java.logging;
|
||||
requires transitive java.desktop;
|
||||
requires transitive org.apache.pdfbox;
|
||||
requires transitive org.apache.pdfbox.io;
|
||||
requires java.desktop;
|
||||
requires org.apache.pdfbox;
|
||||
requires org.apache.pdfbox.io;
|
||||
}
|
||||
|
|
|
@ -2,23 +2,20 @@ package org.xbib.graphics.ghostscript;
|
|||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.xbib.graphics.ghostscript.internal.ErrorCodes;
|
||||
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary;
|
||||
import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader;
|
||||
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
|
||||
import org.xbib.graphics.ghostscript.internal.NullOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -33,21 +30,12 @@ public class Ghostscript implements AutoCloseable {
|
|||
|
||||
private final GhostscriptLibrary libraryInstance;
|
||||
|
||||
private InputStream stdIn;
|
||||
|
||||
private OutputStream stdOut;
|
||||
|
||||
private OutputStream stdErr;
|
||||
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
public Ghostscript() throws IOException {
|
||||
prepareTmp();
|
||||
GhostscriptLibraryLoader libraryLoader = new GhostscriptLibraryLoader();
|
||||
this.libraryInstance = libraryLoader.getGhostscriptLibrary();
|
||||
Objects.requireNonNull(this.libraryInstance);
|
||||
this.stdOut = new LoggingOutputStream(logger);
|
||||
this.stdErr = new LoggingOutputStream(logger);
|
||||
this.libraryInstance = Objects.requireNonNull(libraryLoader.getGhostscriptLibrary(), "library instance must not be null");
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
|
@ -68,62 +56,7 @@ public class Ghostscript implements AutoCloseable {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error output stream of the Ghostscript interpreter (may be null
|
||||
* if not set).
|
||||
*
|
||||
* @return The OutputStream or null
|
||||
*/
|
||||
public OutputStream getStdErr() {
|
||||
return stdErr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error output stream of the Ghostscript interpreter.
|
||||
*
|
||||
* @param outputStream OutputStream object
|
||||
*/
|
||||
public void setStdErr(OutputStream outputStream) {
|
||||
stdErr = outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the standard output stream of the Ghostscript interpreter.
|
||||
*
|
||||
* @return The OutputStream or null
|
||||
*/
|
||||
public OutputStream getStdOut() {
|
||||
return stdOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the standard output stream of the Ghostscript interpreter.
|
||||
*
|
||||
* @param outputStream OutputStream object
|
||||
*/
|
||||
public void setStdOut(OutputStream outputStream) {
|
||||
stdOut = outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the standard input stream of the Ghostscript interpreter.
|
||||
*
|
||||
* @return The InputStream or null
|
||||
*/
|
||||
public InputStream getStdIn() {
|
||||
return stdIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the standard input stream of the Ghostscript interpreter.
|
||||
*
|
||||
* @param inputStream InputStream object
|
||||
*/
|
||||
public void setStdIn(InputStream inputStream) {
|
||||
stdIn = inputStream;
|
||||
}
|
||||
|
||||
public synchronized int run(String[] args) throws IOException {
|
||||
public synchronized int run(List<String> args) throws IOException {
|
||||
return run(args, null, null);
|
||||
}
|
||||
|
||||
|
@ -136,9 +69,15 @@ public class Ghostscript implements AutoCloseable {
|
|||
* @return the ghostscript return code;
|
||||
* @throws IOException if initialize fails
|
||||
*/
|
||||
public synchronized int run(String[] args,
|
||||
public synchronized int run(List<String> args,
|
||||
String runString,
|
||||
String fileName) throws IOException {
|
||||
Objects.requireNonNull(args);
|
||||
List<String> fullArgList = new LinkedList<>();
|
||||
if (!args.contains("ps2pdf")) {
|
||||
fullArgList.add("gs"); // gs or ps2pdf must be always present in the arg list
|
||||
}
|
||||
fullArgList.addAll(args);
|
||||
GhostscriptLibrary.gs_main_instance.ByReference nativeInstanceByRef = null;
|
||||
int ret = 0;
|
||||
boolean quit = false;
|
||||
|
@ -149,47 +88,16 @@ public class Ghostscript implements AutoCloseable {
|
|||
nativeInstanceByRef = null;
|
||||
throw new IOException("can not call Ghostscript gsapi_new_instance, error code = " + ret);
|
||||
}
|
||||
logger.log(Level.INFO, "ghostscript instance " + nativeInstanceByRef + " created");
|
||||
logger.log(Level.FINE, "ghostscript instance " + nativeInstanceByRef + " created");
|
||||
Pointer pointer = nativeInstanceByRef.getValue();
|
||||
GhostscriptLibrary.stdin_fn stdinCallback = null;
|
||||
if (getStdIn() != null) {
|
||||
stdinCallback = (caller_handle, buf, len) -> {
|
||||
String encoding = System.getProperty(ENCODING_PARAMETER, "UTF-8");
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int read = getStdIn().read(buffer);
|
||||
if (read != -1) {
|
||||
buf.setString(0, new String(buffer, 0, read, encoding));
|
||||
return read;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
GhostscriptLibrary.stdout_fn stdoutCallback;
|
||||
if (getStdOut() == null) {
|
||||
setStdOut(new NullOutputStream());
|
||||
}
|
||||
stdoutCallback = (caller_handle, str, len) -> {
|
||||
try {
|
||||
getStdOut().write(str.getBytes(), 0, len);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
// always 0, we never use stdin
|
||||
GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> 0;
|
||||
GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> {
|
||||
logger.log(Level.FINE, str.substring(0, len));
|
||||
return len;
|
||||
};
|
||||
GhostscriptLibrary.stderr_fn stderrCallback;
|
||||
if (getStdErr() == null) {
|
||||
setStdErr(new NullOutputStream());
|
||||
}
|
||||
stderrCallback = (caller_handle, str, len) -> {
|
||||
try {
|
||||
getStdErr().write(str.getBytes(), 0, len);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> {
|
||||
logger.log(Level.FINE, str.substring(0, len));
|
||||
return len;
|
||||
};
|
||||
logger.log(Level.FINE, "setting gsapi_set_stdio");
|
||||
|
@ -197,8 +105,8 @@ public class Ghostscript implements AutoCloseable {
|
|||
if (ret != 0) {
|
||||
throw new IOException("can not set stdio on Ghostscript interpreter, error code " + ret);
|
||||
}
|
||||
logger.log(Level.FINE, "gsapi_init_with_args = " + (args != null ? Arrays.asList(args) : "null"));
|
||||
ret = libraryInstance.gsapi_init_with_args(pointer, args != null ? args.length : 0, args);
|
||||
logger.log(Level.FINE, "gsapi_init_with_args = " + fullArgList);
|
||||
ret = libraryInstance.gsapi_init_with_args(pointer, fullArgList.size(), fullArgList.toArray(new String[0]));
|
||||
logger.log(Level.FINE, "gsapi_init_with_args return code = " + ret);
|
||||
if (ret == ErrorCodes.gs_error_Quit) {
|
||||
quit = true;
|
||||
|
@ -246,12 +154,12 @@ public class Ghostscript implements AutoCloseable {
|
|||
Pointer pointer = nativeInstanceByRef.getValue();
|
||||
if (pointer != null) {
|
||||
if (!quit && ret >= 0) {
|
||||
logger.log(Level.INFO, "exiting ghostscript instance " + libraryInstance);
|
||||
logger.log(Level.FINE, "exiting ghostscript instance " + libraryInstance);
|
||||
ret = libraryInstance.gsapi_exit(pointer);
|
||||
if (ret != 0) {
|
||||
logger.log(Level.SEVERE, "can not call Ghostscript gsapi_exit, error code " + ret);
|
||||
}
|
||||
logger.log(Level.INFO, "deleting ghostscript instance " + pointer);
|
||||
logger.log(Level.FINE, "deleting ghostscript instance " + pointer);
|
||||
libraryInstance.gsapi_delete_instance(pointer);
|
||||
}
|
||||
} else {
|
||||
|
@ -265,22 +173,10 @@ public class Ghostscript implements AutoCloseable {
|
|||
@Override
|
||||
public synchronized void close() throws IOException {
|
||||
if (closed.compareAndSet(false, true)) {
|
||||
if (stdIn != null) {
|
||||
stdIn.close();
|
||||
stdIn = null;
|
||||
}
|
||||
if (stdOut != null) {
|
||||
stdOut.close();
|
||||
stdOut = null;
|
||||
}
|
||||
if (stdErr != null) {
|
||||
stdErr.close();
|
||||
stdErr = null;
|
||||
}
|
||||
if (libraryInstance != null) {
|
||||
libraryInstance.dispose();
|
||||
System.gc();
|
||||
logger.log(Level.INFO, "ghostscript library instance disposed and gc'ed()");
|
||||
logger.log(Level.FINE, "ghostscript library instance disposed and gc'ed()");
|
||||
} else {
|
||||
logger.log(Level.WARNING, "ghostscript library instance is null");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.xbib.graphics.ghostscript;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -119,21 +118,25 @@ public class PDFConverter {
|
|||
int ret;
|
||||
Path tmpPath = createTmpPath();
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
Path input = Files.createTempFile(tmpPath, "pdf", "pdf");
|
||||
try (OutputStream sourceOutputStream = Files.newOutputStream(input)) {
|
||||
inputStream.transferTo(sourceOutputStream);
|
||||
}
|
||||
Path output = Files.createTempFile(tmpPath, "pdf", "pdf");
|
||||
List<String> gsArgs = new LinkedList<>(customGsArgs);
|
||||
gsArgs.add("-dNOSAFER");
|
||||
//gsArgs.add("-dNOPAUSE");
|
||||
//gsArgs.add("-dBATCH");
|
||||
gsArgs.add("-dNOPAUSE");
|
||||
gsArgs.add("-dBATCH");
|
||||
switch (autoRotatePages) {
|
||||
case OPTION_AUTOROTATEPAGES_ALL -> gsArgs.add("-dAutoRotatePages=/All");
|
||||
case OPTION_AUTOROTATEPAGES_PAGEBYPAGE -> gsArgs.add("-dAutoRotatePages=/PageByPage");
|
||||
default -> gsArgs.add("-dAutoRotatePages=/None");
|
||||
}
|
||||
/*switch (processColorModel) {
|
||||
switch (processColorModel) {
|
||||
case OPTION_PROCESSCOLORMODEL_CMYK -> gsArgs.add("-dProcessColorModel=/DeviceCMYK");
|
||||
case OPTION_PROCESSCOLORMODEL_GRAY -> gsArgs.add("-dProcessColorModel=/DeviceGray");
|
||||
default -> gsArgs.add("-dProcessColorModel=/DeviceRGB");
|
||||
}*/
|
||||
}
|
||||
switch (pdfsettings) {
|
||||
case OPTION_PDFSETTINGS_EBOOK -> gsArgs.add("-dPDFSETTINGS=/ebook");
|
||||
case OPTION_PDFSETTINGS_SCREEN -> gsArgs.add("-dPDFSETTINGS=/screen");
|
||||
|
@ -150,11 +153,8 @@ public class PDFConverter {
|
|||
gsArgs.add("-sDEVICE=pdfwrite");
|
||||
gsArgs.add("-sOutputFile=" + output.toAbsolutePath());
|
||||
gsArgs.add("-f");
|
||||
gsArgs.add("-");
|
||||
gs.setStdIn(inputStream);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
ret = gs.run(gsArgs.toArray(new String[0]));
|
||||
gsArgs.add(input.toString());
|
||||
ret = gs.run(gsArgs);
|
||||
Files.copy(output.toAbsolutePath(), outputStream);
|
||||
} finally {
|
||||
deleteTmpPath(tmpPath);
|
||||
|
@ -162,9 +162,6 @@ public class PDFConverter {
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static void deleteTmpPath(Path path) throws IOException {
|
||||
if (path == null) {
|
||||
return;
|
||||
|
|
|
@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedOutputStream;
|
||||
|
@ -72,8 +71,9 @@ public class PDFRasterizer {
|
|||
this.subject = subject;
|
||||
}
|
||||
|
||||
public synchronized void convert(Path source, Path target) throws IOException {
|
||||
logger.info("convert source=" + source + " target=" + target);
|
||||
public synchronized void convert(Path source,
|
||||
Path target) throws IOException {
|
||||
logger.log(Level.FINE, "convert source=" + source + " target=" + target);
|
||||
if (!Files.exists(source)) {
|
||||
throw new FileNotFoundException(source.toString());
|
||||
}
|
||||
|
@ -86,11 +86,11 @@ public class PDFRasterizer {
|
|||
Path tmpPath = createTmpPath();
|
||||
try {
|
||||
Path path = Files.createTempDirectory(tmpPath, "pdf-rasterize");
|
||||
pdfToImage(source, path, "pdf", null);
|
||||
pdfToImage(source, path, "pdf");
|
||||
Path tmpTarget = path.resolve(target.getFileName());
|
||||
mergeImagesToPDF(path, tmpTarget);
|
||||
scalePDF(tmpTarget, target);
|
||||
logger.info("convert source=" + source + " done");
|
||||
logger.log(Level.FINE, "convert source=" + source + " done");
|
||||
} finally {
|
||||
deleteTmpPath(tmpPath);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class PDFRasterizer {
|
|||
|
||||
public synchronized void screenConvert(Path source,
|
||||
Path target) throws IOException {
|
||||
logger.info("screen convert source=" + source.toAbsolutePath() + " target=" + target);
|
||||
logger.log(Level.FINE, "screen convert source=" + source.toAbsolutePath() + " target=" + target);
|
||||
if (!Files.exists(source.toAbsolutePath())) {
|
||||
throw new FileNotFoundException(source.toString());
|
||||
}
|
||||
|
@ -116,14 +116,15 @@ public class PDFRasterizer {
|
|||
mergeImagesToPDF(path, tmpTarget);
|
||||
//toPDFA(tmpTarget, target);
|
||||
scalePDF(tmpTarget, target);
|
||||
logger.info("screen convert source=" + source.toAbsolutePath() + " done");
|
||||
logger.log(Level.FINE, "screen convert source=" + source.toAbsolutePath() + " done");
|
||||
} finally {
|
||||
deleteTmpPath(tmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void pdfToGrayScreenImage(Path source, Path target) throws IOException {
|
||||
logger.info("pdfToGrayScreenImage source=" + source + " target=" + target);
|
||||
public synchronized void pdfToGrayScreenImage(Path source,
|
||||
Path target) throws IOException {
|
||||
logger.log(Level.FINE, "pdfToGrayScreenImage source=" + source + " target=" + target);
|
||||
if (!Files.exists(source.toAbsolutePath())) {
|
||||
throw new FileNotFoundException("not found: " + source);
|
||||
}
|
||||
|
@ -145,21 +146,25 @@ public class PDFRasterizer {
|
|||
gsArgs.add("-sOutputFile=" + target.resolve("screen-gray-pdf-%05d.png"));
|
||||
gsArgs.add("-f");
|
||||
gsArgs.add(source.toString());
|
||||
logger.info("pdfToImage args=" + gsArgs);
|
||||
logger.log(Level.FINE, "pdfToImage args=" + gsArgs);
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
gs.setStdIn(null);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
gs.run(gsArgs.toArray(new String[0]));
|
||||
logger.info("pdfToImage done");
|
||||
gs.run(gsArgs);
|
||||
logger.log(Level.FINE, "pdfToImage done");
|
||||
}
|
||||
}
|
||||
|
||||
public void pdfToImage(Path sourceFile,
|
||||
Path targetDir,
|
||||
String prefix) throws IOException {
|
||||
pdfToImage(sourceFile, targetDir, prefix, null, null);
|
||||
}
|
||||
|
||||
public synchronized void pdfToImage(Path sourceFile,
|
||||
Path targetDir,
|
||||
String prefix,
|
||||
String pageRange) throws IOException {
|
||||
logger.info("pdfToImage source=" + sourceFile + " target=" + targetDir + " started");
|
||||
String firstPage,
|
||||
String lastPage) throws IOException {
|
||||
logger.log(Level.FINE, "pdfToImage source=" + sourceFile + " target=" + targetDir + " started");
|
||||
List<String> gsArgs = new LinkedList<>();
|
||||
gsArgs.add("-dNOPAUSE");
|
||||
gsArgs.add("-dBATCH");
|
||||
|
@ -168,9 +173,11 @@ public class PDFRasterizer {
|
|||
gsArgs.add("-dINTERPOLATE");
|
||||
// how do we know we have a crop box or not?
|
||||
gsArgs.add("-dUseCropBox");
|
||||
// page range, if not null
|
||||
if (pageRange != null) {
|
||||
gsArgs.add("-sPageList=" + pageRange);
|
||||
if (firstPage != null) {
|
||||
gsArgs.add("-sFirstPage=" + firstPage);
|
||||
}
|
||||
if (lastPage != null) {
|
||||
gsArgs.add("-sLastPage=" + lastPage);
|
||||
}
|
||||
gsArgs.add("-sDEVICE=png16m");
|
||||
gsArgs.add("-r300");
|
||||
|
@ -182,23 +189,21 @@ public class PDFRasterizer {
|
|||
gsArgs.add("100000000 setvmthreshold");
|
||||
gsArgs.add("-f");
|
||||
gsArgs.add(sourceFile.toString());
|
||||
logger.info("pdfToImage args=" + gsArgs);
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
// reset stdin
|
||||
gs.setStdIn(null);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
gs.run(gsArgs.toArray(new String[0]));
|
||||
logger.info("pdfToImage done");
|
||||
gs.run(gsArgs);
|
||||
logger.log(Level.FINE, "pdfToImage done");
|
||||
}
|
||||
}
|
||||
|
||||
public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException {
|
||||
public int mergeImagesToPDF(Path sourceDir,
|
||||
Path targetFile) throws IOException {
|
||||
return mergeImagesToPDF(sourceDir, targetFile, "**/*");
|
||||
}
|
||||
|
||||
public synchronized int mergeImagesToPDF(Path sourceDir, Path targetFile, String globPattern) throws IOException {
|
||||
logger.info("mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern);
|
||||
public synchronized int mergeImagesToPDF(Path sourceDir,
|
||||
Path targetFile,
|
||||
String globPattern) throws IOException {
|
||||
logger.log(Level.FINE, "mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern);
|
||||
AtomicInteger pagecount = new AtomicInteger();
|
||||
PathMatcher pathMatcher = sourceDir.getFileSystem().getPathMatcher("glob:" + globPattern);
|
||||
List<PDDocument> coverPageDocs = new ArrayList<>();
|
||||
|
@ -223,7 +228,7 @@ public class PDFRasterizer {
|
|||
}
|
||||
for (Path path : entries) {
|
||||
if (path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".pdf")) {
|
||||
logger.info("found pdf " + path);
|
||||
logger.log(Level.FINE, "found pdf " + path);
|
||||
try (InputStream inputStream = Files.newInputStream(path)) {
|
||||
PDDocument doc = Loader.loadPDF(inputStream.readAllBytes());
|
||||
for (int i = 0; i < doc.getNumberOfPages(); i++) {
|
||||
|
@ -267,7 +272,7 @@ public class PDFRasterizer {
|
|||
}
|
||||
}
|
||||
pdDocument.save(outputStream);
|
||||
logger.info("mergeImagesToPDF: done, " + pagecount.get() + " pages");
|
||||
logger.log(Level.FINE, "pagesToPDF: done, " + pagecount.get() + " pages");
|
||||
} finally {
|
||||
for (PDDocument pd : coverPageDocs) {
|
||||
pd.close();
|
||||
|
@ -278,7 +283,7 @@ public class PDFRasterizer {
|
|||
|
||||
public synchronized void scalePDF(Path sourceFile,
|
||||
Path targetFile) throws IOException {
|
||||
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " starting");
|
||||
logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " starting");
|
||||
List<String> gsArgs = new LinkedList<>();
|
||||
gsArgs.add("-dNOPAUSE");
|
||||
gsArgs.add("-dBATCH");
|
||||
|
@ -293,16 +298,14 @@ public class PDFRasterizer {
|
|||
gsArgs.add("-sOutputFile=" + targetFile.toString());
|
||||
gsArgs.add(sourceFile.toString());
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
gs.setStdIn(null);
|
||||
logger.info(gsArgs.toString());
|
||||
gs.run(gsArgs.toArray(new String[0]));
|
||||
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
|
||||
gs.run(gsArgs);
|
||||
logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void downgradePDF(Path sourceFile,
|
||||
Path targetFile) throws IOException {
|
||||
logger.log(Level.INFO, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " starting");
|
||||
logger.log(Level.FINE, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " starting");
|
||||
List<String> gsArgs = new LinkedList<>();
|
||||
gsArgs.add("-dNOPAUSE");
|
||||
gsArgs.add("-dBATCH");
|
||||
|
@ -314,12 +317,8 @@ public class PDFRasterizer {
|
|||
gsArgs.add("-sOutputFile=" + targetFile.toString());
|
||||
gsArgs.add(sourceFile.toString());
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
gs.setStdIn(null);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
logger.log(Level.INFO, gsArgs.toString());
|
||||
gs.run(gsArgs.toArray(new String[0]));
|
||||
logger.log(Level.INFO, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " done");
|
||||
gs.run(gsArgs);
|
||||
logger.log(Level.FINE, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " done");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,14 +356,16 @@ public class PDFRasterizer {
|
|||
gsArgs.add("-sOutputFile=" + target.toString());
|
||||
gsArgs.add(pdfapsPath.toAbsolutePath().toString());
|
||||
gsArgs.add(source.toString());
|
||||
gs.setStdIn(null);
|
||||
gs.run(gsArgs.toArray(new String[0]));
|
||||
gs.run(gsArgs);
|
||||
} finally {
|
||||
deleteTmpPath(tmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyAndReplace(Path source, Path target, String from, String to) throws IOException {
|
||||
private static void copyAndReplace(Path source,
|
||||
Path target,
|
||||
String from,
|
||||
String to) throws IOException {
|
||||
try (BufferedReader br = Files.newBufferedReader(source); BufferedWriter bw = Files.newBufferedWriter(target)) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package org.xbib.graphics.ghostscript;
|
||||
|
||||
public class PageRaster {
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
private int raster;
|
||||
|
||||
private int format;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
public PageRaster() {
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getRaster() {
|
||||
return raster;
|
||||
}
|
||||
|
||||
public void setRaster(int raster) {
|
||||
this.raster = raster;
|
||||
}
|
||||
|
||||
public int getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(int format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
|
@ -21,23 +21,20 @@ public class GhostscriptLibraryLoader {
|
|||
};
|
||||
|
||||
private static final String[] MAC_LIBNAMES = {
|
||||
"libgs.9.54.dylib",
|
||||
"libgs.9.54",
|
||||
"gs.9.54",
|
||||
"libgs.9.25.dylib",
|
||||
"libgs.9.25",
|
||||
"gs.9.25",
|
||||
"libgs.dylib",
|
||||
"gs.9.26",
|
||||
"gs",
|
||||
};
|
||||
|
||||
private GhostscriptLibrary ghostscriptLibrary;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public GhostscriptLibraryLoader() {
|
||||
Map<String, Object> options = Map.of(Library.OPTION_CALLING_CONVENTION, Function.C_CONVENTION,
|
||||
Library.OPTION_INVOCATION_MAPPER, (InvocationMapper) (lib, m) -> {
|
||||
if (m.getName().equals("dispose")) {
|
||||
return (proxy, method, args) -> {
|
||||
// we use the deprecated dispose() call here by intention
|
||||
lib.dispose();
|
||||
return null;
|
||||
};
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package org.xbib.graphics.ghostscript.internal;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class LoggingOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public LoggingOutputStream(Logger logger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
super.flush();
|
||||
String s = new String(buf, 0, count);
|
||||
if (s.length() > 0) {
|
||||
logger.log(Level.FINE, s);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package org.xbib.graphics.ghostscript.internal;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class NullOutputStream extends OutputStream {
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
}
|
||||
}
|
|
@ -1,24 +1,24 @@
|
|||
package org.xbib.graphics.ghostscript.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.graphics.ghostscript.Ghostscript;
|
||||
import org.xbib.graphics.ghostscript.GhostscriptRevision;
|
||||
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class GhostscriptTest {
|
||||
public class BasicGhostscriptTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GhostscriptTest.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(BasicGhostscriptTest.class.getName());
|
||||
|
||||
private static final String dir = "src/test/resources/org/xbib/graphics/ghostscript/test/";
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class GhostscriptTest {
|
|||
@Test
|
||||
public void testExit() {
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
String[] args = {"-dNODISPLAY", "-dQUIET"};
|
||||
List<String> args = List.of("-dNODISPLAY", "-dQUIET");
|
||||
gs.run(args);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
|
@ -51,7 +51,7 @@ public class GhostscriptTest {
|
|||
@Test
|
||||
public void testRunString() {
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
String[] args = {"-dNODISPLAY", "-dQUIET"};
|
||||
List<String> args = List.of("-dNODISPLAY", "-dQUIET");
|
||||
gs.run(args, "devicenames ==", null);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
|
@ -64,7 +64,7 @@ public class GhostscriptTest {
|
|||
@Test
|
||||
public void testRunFile() {
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
String[] args = {"-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER"};
|
||||
List<String> args = List.of("-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER");
|
||||
gs.run(args, null, dir + "input.ps");
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
|
@ -75,33 +75,37 @@ public class GhostscriptTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testStdOut() {
|
||||
try (Ghostscript gs = new Ghostscript();
|
||||
InputStream is = new ByteArrayInputStream("devicenames ==\n".getBytes())) {
|
||||
gs.setStdIn(is);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" };
|
||||
gs.run(args);
|
||||
public void testStdOut() throws Exception {
|
||||
Path path = Paths.get("build/devicenames");
|
||||
try (OutputStream outputStream = Files.newOutputStream(path)) {
|
||||
outputStream.write("devicenames ==\n".getBytes());
|
||||
}
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
List<String> args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString());
|
||||
int ret = gs.run(args);
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
} finally {
|
||||
Files.delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStdErr() {
|
||||
try (Ghostscript gs = new Ghostscript();
|
||||
InputStream is = new ByteArrayInputStream("stupid\n".getBytes())) {
|
||||
gs.setStdIn(is);
|
||||
gs.setStdOut(new LoggingOutputStream(logger));
|
||||
gs.setStdErr(new LoggingOutputStream(logger));
|
||||
String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" };
|
||||
gs.run(args);
|
||||
public void testStdErr() throws Exception {
|
||||
Path path = Paths.get("build/broken");
|
||||
try (OutputStream outputStream = Files.newOutputStream(path)) {
|
||||
outputStream.write("foobar\n".getBytes());
|
||||
}
|
||||
try (Ghostscript gs = new Ghostscript()) {
|
||||
List<String> args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString());
|
||||
int ret = gs.run(args);
|
||||
} catch (Exception e) {
|
||||
// expect error
|
||||
if (!e.getMessage().contains("error code = -100")) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
} finally {
|
||||
Files.delete(path);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
package org.xbib.graphics.ghostscript.test;
|
||||
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary;
|
||||
import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader;
|
||||
|
||||
public class GhostScriptLibraryTester {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GhostScriptLibraryTester.class.getName());
|
||||
|
||||
private final GhostscriptLibrary ghostscriptLibrary;
|
||||
|
||||
public GhostScriptLibraryTester() {
|
||||
|
@ -33,7 +37,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
String[] args = {
|
||||
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
"gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
IntByReference exitCode = new IntByReference();
|
||||
|
@ -47,10 +51,8 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
String[] args = {
|
||||
"ps2pdf",
|
||||
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite",
|
||||
"-sOutputFile=" + output,
|
||||
"-c", ".setpdfwrite", "-f", input
|
||||
"ps2pdf", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite",
|
||||
"-sOutputFile=" + output, "-f", input
|
||||
};
|
||||
int result = ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
ghostscriptLibrary.gsapi_exit(instanceByRef.getValue());
|
||||
|
@ -62,7 +64,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
String[] args = {
|
||||
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
"gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
IntByReference exitCode = new IntByReference();
|
||||
|
@ -77,7 +79,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
String[] args = {
|
||||
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
"gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
IntByReference exitCode = new IntByReference();
|
||||
|
@ -94,7 +96,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
String[] args = {
|
||||
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
"gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
IntByReference exitCode = new IntByReference();
|
||||
|
@ -108,9 +110,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
|
||||
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
|
||||
final StringBuilder stdOutBuffer = new StringBuilder();
|
||||
final StringBuilder stdInBuffer = new StringBuilder();
|
||||
GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> {
|
||||
stdInBuffer.append("OK");
|
||||
return 0;
|
||||
};
|
||||
GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> {
|
||||
|
@ -120,8 +120,7 @@ public class GhostScriptLibraryTester {
|
|||
GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> len;
|
||||
ghostscriptLibrary.gsapi_set_stdio(instanceByRef.getValue(), stdinCallback, stdoutCallback, stderrCallback);
|
||||
String[] args = {
|
||||
"-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH",
|
||||
"-sOutputFile=%stdout", "-f", "-"
|
||||
"gs", "-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-sOutputFile=%stdout", "-f", "-"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(),
|
||||
args.length, args);
|
||||
|
@ -130,6 +129,8 @@ public class GhostScriptLibraryTester {
|
|||
ghostscriptLibrary.gsapi_run_string_with_length(instanceByRef.getValue(), command, command.length(), 0, exitCode);
|
||||
ghostscriptLibrary.gsapi_exit(instanceByRef.getValue());
|
||||
ghostscriptLibrary.gsapi_delete_instance(instanceByRef.getValue());
|
||||
logger.log(Level.FINE, stdOutBuffer.toString());
|
||||
|
||||
}
|
||||
|
||||
public String setDisplayCallback() {
|
||||
|
@ -176,7 +177,7 @@ public class GhostScriptLibraryTester {
|
|||
displayCallback.size = displayCallback.size();
|
||||
ghostscriptLibrary.gsapi_set_display_callback(instanceByRef.getValue(), displayCallback);
|
||||
String[] args = new String[]{
|
||||
"-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER",
|
||||
"gs", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER",
|
||||
"-sDEVICE=display", "-sDisplayHandle=0", "-dDisplayFormat=16#a0800"
|
||||
};
|
||||
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package org.xbib.graphics.ghostscript.test;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -19,9 +19,10 @@ public class GhostscriptLibraryTest {
|
|||
private static GhostScriptLibraryTester gslib;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
public static void setUp() {
|
||||
logger.log(Level.INFO, "setUp: loading ghostscript library");
|
||||
gslib = new GhostScriptLibraryTester();
|
||||
logger.info("setUp: ghostscript library loaded");
|
||||
logger.log(Level.INFO, "setUp: ghostscript library loaded");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -35,13 +36,10 @@ public class GhostscriptLibraryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Disabled("GPL Ghostscript 9.54.0: Unrecoverable error, exit code 1")
|
||||
public void gsapiInitWithArgs() {
|
||||
String input = dir + "input.ps";
|
||||
String output = "build/output.pdf";
|
||||
gslib.withInput(input, output);
|
||||
File outputFile = new File(output);
|
||||
assertTrue(outputFile.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,9 +68,10 @@ public class GhostscriptLibraryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void gsapiSetDisplayCallback() {
|
||||
String display = gslib.setDisplayCallback();
|
||||
assertEquals("OPEN-PRESIZE-UPDATE-SIZE-PAGE-UPDATE-SYNC-PRECLOSE-CLOSE", display);
|
||||
assertTrue(Set.of("OPEN-PRESIZE-UPDATE-SIZE-PRECLOSE-CLOSEOPEN-PRESIZE-UPDATE-SIZE-UPDATE-PAGE-PRECLOSE-CLOSE", // gs 9.54
|
||||
"OPEN-PRESIZE-UPDATE-SIZE-UPDATE-PRECLOSE-CLOSEOPEN-PRESIZE-UPDATE-SIZE-PAGE-UPDATE-PRECLOSE-CLOSE") // gs 10
|
||||
.contains(display));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public class PDFConverterTest {
|
|||
|
||||
@Test
|
||||
public void testConvertWithPS() throws Exception {
|
||||
PDFConverter converter = new PDFConverter(List.of("-ps2pdf"));
|
||||
PDFConverter converter = new PDFConverter(List.of("ps2pdf"));
|
||||
try (InputStream inputStream = getClass().getResourceAsStream("input.ps");
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
converter.convert(inputStream, outputStream);
|
||||
|
@ -34,7 +34,7 @@ public class PDFConverterTest {
|
|||
final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
|
||||
final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
final ByteArrayOutputStream baos3 = new ByteArrayOutputStream();
|
||||
final PDFConverter converter = new PDFConverter(List.of("-ps2pdf"));
|
||||
final PDFConverter converter = new PDFConverter(List.of("ps2pdf"));
|
||||
Thread thread1 = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -76,7 +76,6 @@ public class PDFConverterTest {
|
|||
baos3.close();
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void testConvertWithUnsupportedDocument() throws Exception {
|
||||
PDFConverter converter = new PDFConverter();
|
||||
|
@ -86,10 +85,9 @@ public class PDFConverterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void testConvertDistiller() throws Exception {
|
||||
PDFConverter converter = new PDFConverter(List.of("-dFIXEDMEDIA", "-dPDFFitPage", "-dPAPERSIZE=a4"));
|
||||
PDFConverter converter = new PDFConverter(List.of("-dFIXEDMEDIA", "-dPDFFitPage"));
|
||||
try (InputStream inputStream = getClass().getResourceAsStream("3977940_retrieve_74_.pdf");
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
converter.convert(inputStream, outputStream);
|
||||
|
|
|
@ -28,7 +28,7 @@ public class PDFRasterizerTest {
|
|||
Path targetFile = Paths.get("build/color.pdf");
|
||||
PDFRasterizer pdfRasterizer = new PDFRasterizer();
|
||||
int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile);
|
||||
logger.info("pagecount = " + pagecount);
|
||||
logger.log(Level.FINE, "pagecount = " + pagecount);
|
||||
assertEquals(1, pagecount);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class PDFRasterizerTest {
|
|||
Path targetFile = Paths.get("build/3656573.pdf");
|
||||
PDFRasterizer pdfRasterizer = new PDFRasterizer();
|
||||
int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile);
|
||||
logger.info("pagecount = " + pagecount);
|
||||
logger.log(Level.FINE, "pagecount = " + pagecount);
|
||||
assertEquals(9, pagecount);
|
||||
}
|
||||
|
||||
|
@ -50,10 +50,10 @@ public class PDFRasterizerTest {
|
|||
int pagecount = 0;
|
||||
try {
|
||||
PDFRasterizer pdfRasterizer = new PDFRasterizer();
|
||||
pdfRasterizer.pdfToImage(source, path, null, null);
|
||||
pdfRasterizer.pdfToImage(source, path, "test");
|
||||
Path tmpTarget = path.resolve(target.getFileName());
|
||||
pagecount = pdfRasterizer.mergeImagesToPDF(path, tmpTarget);
|
||||
logger.info("pagecount = " + pagecount);
|
||||
logger.log(Level.FINE, "pagecount = " + pagecount);
|
||||
pdfRasterizer.scalePDF(tmpTarget, target);
|
||||
} finally {
|
||||
delete(path);
|
||||
|
@ -80,7 +80,7 @@ public class PDFRasterizerTest {
|
|||
delete(target);
|
||||
Files.createDirectories(target);
|
||||
PDFRasterizer rasterizer = new PDFRasterizer();
|
||||
rasterizer.pdfToImage(p, target, "pdf-", "1-");
|
||||
rasterizer.pdfToImage(p, target, "pdf-");
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
fail(e);
|
||||
|
@ -96,7 +96,7 @@ public class PDFRasterizerTest {
|
|||
try (Stream<Path> stream = Files.list(path)) {
|
||||
stream.forEach(p -> {
|
||||
if (p.toString().endsWith(".pdf")) {
|
||||
logger.info("found " + p.toString());
|
||||
logger.log(Level.FINE, "found " + p);
|
||||
Path target = Paths.get("build/" + p.getFileName());
|
||||
try {
|
||||
delete(target);
|
||||
|
|
|
@ -2,7 +2,11 @@ dependencies {
|
|||
api project(':graphics-pdfbox')
|
||||
api project(':graphics-barcode')
|
||||
api project(':graphics-chart')
|
||||
api libs.datastructures.settings
|
||||
runtimeOnly libs.datastructures.settings.json
|
||||
runtimeOnly libs.datastructures.settings.yaml
|
||||
api project(':graphics-fonts')
|
||||
api libs.settings.api
|
||||
testImplementation testLibs.settings.json
|
||||
testRuntimeOnly project(':graphics-fonts-arabic')
|
||||
testRuntimeOnly project(':graphics-fonts-latin')
|
||||
testRuntimeOnly project(':graphics-fonts-hebrew')
|
||||
testRuntimeOnly project(':graphics-fonts-cjk')
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module org.xbib.graphics.layout.pdfbox {
|
||||
uses org.xbib.graphics.fonts.FontEmbedder;
|
||||
exports org.xbib.graphics.pdfbox.layout.boxable;
|
||||
exports org.xbib.graphics.pdfbox.layout.color;
|
||||
exports org.xbib.graphics.pdfbox.layout.element;
|
||||
exports org.xbib.graphics.pdfbox.layout.element.render;
|
||||
exports org.xbib.graphics.pdfbox.layout.font;
|
||||
exports org.xbib.graphics.pdfbox.layout.element.scripting;
|
||||
exports org.xbib.graphics.pdfbox.layout.element.scripting.command;
|
||||
exports org.xbib.graphics.pdfbox.layout.shape;
|
||||
|
@ -13,11 +13,12 @@ module org.xbib.graphics.layout.pdfbox {
|
|||
exports org.xbib.graphics.pdfbox.layout.text.annotations;
|
||||
exports org.xbib.graphics.pdfbox.layout.util;
|
||||
exports org.xbib.graphics.pdfbox.layout.position;
|
||||
requires transitive org.xbib.graphics.barcode;
|
||||
requires transitive org.xbib.graphics.pdfbox;
|
||||
requires transitive org.xbib.settings.api;
|
||||
requires org.xbib.settings.datastructures;
|
||||
requires transitive java.desktop;
|
||||
requires java.logging;
|
||||
requires org.xbib.graphics.barcode;
|
||||
requires org.xbib.graphics.pdfbox;
|
||||
requires org.xbib.settings.api;
|
||||
requires org.xbib.graphics.chart;
|
||||
requires org.xbib.graphics.fonts;
|
||||
requires org.apache.pdfbox;
|
||||
requires java.desktop;
|
||||
requires java.logging;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package org.xbib.graphics.pdfbox.layout.element;
|
||||
|
||||
import org.apache.fontbox.ttf.TTFParser;
|
||||
import org.apache.fontbox.ttf.TrueTypeFont;
|
||||
import org.apache.pdfbox.io.RandomAccessRead;
|
||||
import org.apache.pdfbox.io.RandomAccessReadBuffer;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
import org.xbib.graphics.fonts.BaseFont;
|
||||
import org.xbib.graphics.fonts.Font;
|
||||
import org.xbib.graphics.fonts.FontEmbedder;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.Layout;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.LayoutHint;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.RenderContext;
|
||||
|
@ -15,33 +12,35 @@ import org.xbib.graphics.pdfbox.layout.element.render.RenderListener;
|
|||
import org.xbib.graphics.pdfbox.layout.element.render.Renderer;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayout;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
|
||||
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
|
||||
import org.xbib.graphics.pdfbox.layout.font.Font;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* The central class for creating a document.
|
||||
*/
|
||||
public class Document implements Element, Closeable, RenderListener {
|
||||
|
||||
private final List<Entry<Element, LayoutHint>> elements;
|
||||
private static final Logger logger = Logger.getLogger(Document.class.getName());
|
||||
|
||||
private final Map<String, Font> fonts;
|
||||
private final List<Entry<Element, LayoutHint>> elements;
|
||||
|
||||
private final List<Renderer> customRenderer;
|
||||
|
||||
|
@ -53,6 +52,8 @@ public class Document implements Element, Closeable, RenderListener {
|
|||
|
||||
private final PDDocumentInformation pdDocumentInformation;
|
||||
|
||||
private final Collection<Font> fonts;
|
||||
|
||||
/**
|
||||
* Creates a Document.
|
||||
*/
|
||||
|
@ -85,22 +86,83 @@ public class Document implements Element, Closeable, RenderListener {
|
|||
public Document(PageFormat pageFormat) {
|
||||
this.pdDocument = new PDDocument();
|
||||
this.pdDocumentInformation = new PDDocumentInformation();
|
||||
this.fonts = new LinkedHashSet<>();
|
||||
this.elements = new ArrayList<>();
|
||||
this.fonts = new LinkedHashMap<>();
|
||||
this.customRenderer = new ArrayList<>();
|
||||
this.renderListener = new ArrayList<>();
|
||||
setPageFormat(pageFormat);
|
||||
registerFont("helvetica", BaseFont.HELVETICA);
|
||||
}
|
||||
|
||||
public void setPageFormat(PageFormat pageFormat) {
|
||||
this.pageFormat = pageFormat;
|
||||
}
|
||||
|
||||
public PDDocument getPdDocument() {
|
||||
return pdDocument;
|
||||
}
|
||||
|
||||
public void registerCoreFonts() {
|
||||
fonts.add(BaseFont.HELVETICA);
|
||||
fonts.add(BaseFont.TIMES);
|
||||
fonts.add(BaseFont.COURIER);
|
||||
}
|
||||
|
||||
public void embedAllFonts() {
|
||||
embedFonts(List.of(""));
|
||||
}
|
||||
|
||||
public void embedFonts(Collection<String> aliases) {
|
||||
embedFonts(aliases, List.of(getClass().getClassLoader(),
|
||||
ClassLoader.getSystemClassLoader(),
|
||||
Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
|
||||
private void embedFonts(Collection<String> aliases, Collection<ClassLoader> classLoaders) {
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
Iterable<FontEmbedder> fontEmbedders = ServiceLoader.load(FontEmbedder.class, classLoader);
|
||||
boolean serviceLoaded = false;
|
||||
for (String alias : aliases) {
|
||||
// fonts times, helvetica, courier are standard fonts without embedding
|
||||
switch (alias) {
|
||||
case "times" -> fonts.add(BaseFont.TIMES);
|
||||
case "helvetica" -> fonts.add(BaseFont.HELVETICA);
|
||||
case "courier" -> fonts.add(BaseFont.COURIER);
|
||||
case null, default -> {
|
||||
boolean found = false;
|
||||
for (FontEmbedder fontEmbedder : fontEmbedders) {
|
||||
try {
|
||||
if (alias == null || alias.isEmpty() || fontEmbedder.getAlias().equals(alias)) {
|
||||
fontEmbedder.embed(this.pdDocument);
|
||||
fonts.addAll(fontEmbedder.getFonts());
|
||||
found = true;
|
||||
serviceLoaded = true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
logger.log(Level.WARNING, "font " + alias + " not found using embedders " +
|
||||
StreamSupport.stream(fontEmbedders.spliterator(), false).toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serviceLoaded) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
logger.log(Level.FINER, "fonts: " + fonts);
|
||||
}
|
||||
|
||||
public Font getFont(String alias) {
|
||||
return fonts.stream().filter(f -> f.getAlias().equals(alias)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Collection<Font> getFonts() {
|
||||
return fonts;
|
||||
}
|
||||
|
||||
public void setPageFormat(PageFormat pageFormat) {
|
||||
this.pageFormat = pageFormat;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
pdDocumentInformation.setAuthor(author);
|
||||
}
|
||||
|
@ -145,116 +207,6 @@ public class Document implements Element, Closeable, RenderListener {
|
|||
pdDocumentInformation.setCustomMetadataValue(key, value);
|
||||
}
|
||||
|
||||
public void registerFont(String name, Font font) {
|
||||
fonts.put(name, font);
|
||||
}
|
||||
|
||||
public void registerNotoSansFont() throws IOException {
|
||||
registerFont("notosans",
|
||||
"NotoSans-Regular.ttf",
|
||||
"NotoSans-Bold.ttf",
|
||||
"NotoSans-Italic.ttf",
|
||||
"NotoSans-BoldItalic.ttf");
|
||||
}
|
||||
|
||||
public void registerNotoSansHebrewFont() throws IOException {
|
||||
registerFont("notosanshebrew",
|
||||
"NotoSansHebrew-Regular.ttf",
|
||||
"NotoSansHebrew-Bold.ttf",
|
||||
"NotoSansHebrew-Regular.ttf",
|
||||
"NotoSansHebrew-Bold.ttf");
|
||||
}
|
||||
|
||||
public void registerNotoSansCJKSCFont() throws IOException {
|
||||
registerFont("notosanscjksc",
|
||||
"NotoSansCJKsc-Regular.ttf",
|
||||
"NotoSansCJKsc-Bold.ttf",
|
||||
"NotoSansCJKsc-Italic.ttf",
|
||||
"NotoSansCJKsc-BoldItalic.ttf");
|
||||
}
|
||||
|
||||
public void registerOpenSansFont() throws IOException {
|
||||
registerFont("opensans",
|
||||
"OpenSans-Regular.ttf",
|
||||
"OpenSans-Bold.ttf",
|
||||
"OpenSans-Italic.ttf",
|
||||
"OpenSans-BoldItalic.ttf");
|
||||
}
|
||||
|
||||
public void registerSourceSansFont() throws IOException {
|
||||
registerFont("sourcesans",
|
||||
"SourceSans3-Regular.ttf",
|
||||
"SourceSans3-Bold.ttf",
|
||||
"SourceSans3-It.ttf",
|
||||
"SourceSans3-BoldIt.ttf");
|
||||
}
|
||||
|
||||
public void registerFont(String name,
|
||||
String regularFontResource,
|
||||
String boldFontResource,
|
||||
String italicsFontResource,
|
||||
String boldItalicsFontResource) throws IOException {
|
||||
final PDType0Font regularFont = loadTrueTypeFont(regularFontResource);
|
||||
final PDType0Font boldFont = loadTrueTypeFont(boldFontResource);
|
||||
final PDType0Font italicsFont = loadTrueTypeFont(italicsFontResource);
|
||||
final PDType0Font boldItalicsFont = loadTrueTypeFont(boldItalicsFontResource);
|
||||
fonts.put(name, new Font() {
|
||||
@Override
|
||||
public PDFont getRegularFont() {
|
||||
return regularFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldFont() {
|
||||
return boldFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getItalicFont() {
|
||||
return italicsFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldItalicFont() {
|
||||
return boldItalicsFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGlyph(int code) {
|
||||
try {
|
||||
return regularFont.hasGlyph(code);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(String string) {
|
||||
try {
|
||||
return regularFont.getStringWidth(string) > 0;
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private PDType0Font loadTrueTypeFont(String resourceName) throws IOException {
|
||||
InputStream inputStream = Font.class.getResourceAsStream(resourceName);
|
||||
TTFParser ttfParser = new TTFParser();
|
||||
RandomAccessRead randomAccessRead = new RandomAccessReadBuffer(inputStream);
|
||||
TrueTypeFont openTypeFont = ttfParser.parse(randomAccessRead);
|
||||
return PDType0Font.load(pdDocument, openTypeFont, true);
|
||||
}
|
||||
|
||||
public Font getFont(String name) {
|
||||
return fonts.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the document using a {@link VerticalLayoutHint}.
|
||||
*
|
||||
|
|
|
@ -7,8 +7,8 @@ import org.apache.pdfbox.util.Matrix;
|
|||
import org.xbib.graphics.pdfbox.PdfBoxGraphics2D;
|
||||
import org.xbib.graphics.pdfbox.color.DefaultColorMapper;
|
||||
import org.xbib.graphics.pdfbox.color.RGBtoCMYKColorMapper;
|
||||
import org.xbib.graphics.pdfbox.font.DefaultFontDrawer;
|
||||
import org.xbib.graphics.pdfbox.font.FontDrawer;
|
||||
import org.xbib.graphics.fonts.DefaultFontDrawer;
|
||||
import org.xbib.graphics.fonts.FontDrawer;
|
||||
import org.xbib.graphics.pdfbox.layout.element.render.Transform;
|
||||
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
|
||||
import org.xbib.graphics.pdfbox.layout.position.Position;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.xbib.graphics.pdfbox.layout.element;
|
||||
|
||||
import org.xbib.graphics.pdfbox.layout.font.Font;
|
||||
import org.xbib.graphics.fonts.Font;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
|
@ -3,10 +3,10 @@ package org.xbib.graphics.pdfbox.layout.element.scripting.command;
|
|||
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
|
||||
import org.xbib.graphics.pdfbox.layout.element.Document;
|
||||
import org.xbib.graphics.pdfbox.layout.element.Paragraph;
|
||||
import org.xbib.graphics.pdfbox.layout.font.Font;
|
||||
import org.xbib.graphics.fonts.Font;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.State;
|
||||
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
|
||||
import org.xbib.graphics.fonts.FontDescriptor;
|
||||
import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
|
||||
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
|
||||
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
|
||||
|
|
|
@ -4,11 +4,13 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
|
|||
import org.xbib.graphics.pdfbox.layout.element.PageFormat;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.State;
|
||||
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
|
||||
import org.xbib.graphics.fonts.BaseFont;
|
||||
import org.xbib.settings.Settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
|
||||
|
@ -72,18 +74,7 @@ public class DocumentCommand implements Command {
|
|||
document.setModificationDate(instant);
|
||||
}
|
||||
String[] fonts = settings.getAsArray("font");
|
||||
for (String font : fonts) {
|
||||
switch (font) {
|
||||
case "helvetica" -> document.registerFont("helvetica", BaseFont.HELVETICA);
|
||||
case "times" -> document.registerFont("times", BaseFont.TIMES);
|
||||
case "courier" -> document.registerFont("courier", BaseFont.COURIER);
|
||||
case "notosans" -> document.registerNotoSansFont();
|
||||
case "notosanshebrew" -> document.registerNotoSansHebrewFont();
|
||||
case "notosanscjksc" -> document.registerNotoSansCJKSCFont();
|
||||
case "opensans" -> document.registerOpenSansFont();
|
||||
case "sourcesans" -> document.registerSourceSansFont();
|
||||
}
|
||||
}
|
||||
document.embedFonts(Arrays.asList(fonts));
|
||||
state.getElements().push(document);
|
||||
engine.executeElements(settings);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package org.xbib.graphics.pdfbox.layout.element.scripting.command;
|
|||
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
|
||||
import org.xbib.graphics.pdfbox.layout.element.scripting.State;
|
||||
import org.xbib.graphics.pdfbox.layout.font.Font;
|
||||
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
|
||||
import org.xbib.graphics.fonts.Font;
|
||||
import org.xbib.graphics.fonts.FontDescriptor;
|
||||
import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
|
||||
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
|
||||
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
package org.xbib.graphics.pdfbox.layout.font;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_OBLIQUE;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_OBLIQUE;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD_ITALIC;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ITALIC;
|
||||
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ROMAN;
|
||||
|
||||
/**
|
||||
* In order to easy handling with fonts, this enum bundles the
|
||||
* plain/italic/bold/bold-italic variants of the three standard font types
|
||||
* Times, Courier, Helveticy.
|
||||
*/
|
||||
public enum BaseFont implements Font {
|
||||
|
||||
TIMES(new PDType1Font(TIMES_ROMAN), new PDType1Font(TIMES_BOLD),
|
||||
new PDType1Font(TIMES_ITALIC), new PDType1Font(TIMES_BOLD_ITALIC)),
|
||||
|
||||
COURIER(new PDType1Font(Standard14Fonts.FontName.COURIER), new PDType1Font(COURIER_BOLD),
|
||||
new PDType1Font(COURIER_OBLIQUE), new PDType1Font(COURIER_BOLD_OBLIQUE)),
|
||||
|
||||
HELVETICA(new PDType1Font(Standard14Fonts.FontName.HELVETICA), new PDType1Font(HELVETICA_BOLD),
|
||||
new PDType1Font(HELVETICA_OBLIQUE), new PDType1Font(HELVETICA_BOLD_OBLIQUE));
|
||||
|
||||
private final PDType1Font regularFont;
|
||||
|
||||
private final PDType1Font boldFont;
|
||||
|
||||
private final PDType1Font italicFont;
|
||||
|
||||
private final PDType1Font boldItalicFont;
|
||||
|
||||
BaseFont(PDType1Font regularFont, PDType1Font boldFont, PDType1Font italicFont, PDType1Font boldItalicFont) {
|
||||
this.regularFont = regularFont;
|
||||
this.boldFont = boldFont;
|
||||
this.italicFont = italicFont;
|
||||
this.boldItalicFont = boldItalicFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getRegularFont() {
|
||||
return regularFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldFont() {
|
||||
return boldFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getItalicFont() {
|
||||
return italicFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDFont getBoldItalicFont() {
|
||||
return boldItalicFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGlyph(int code) {
|
||||
try {
|
||||
return regularFont.hasGlyph(code);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
String printable = string.replaceAll("\\P{Print}|\\p{Cntrl}|\\p{Space}", "");
|
||||
if (printable.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return regularFont.getStringWidth(printable) > 0;
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue