Compare commits

...

58 commits
4.3.4 ... main

Author SHA1 Message Date
a70b7e62cf fix settings use, fix module transitive requires 2025-03-13 13:39:34 +01:00
a323076ca3 do not assume color space is present when analyzing document images 2025-02-04 13:45:39 +01:00
b13aa5f3ef fix document font loading for scripting engine 2025-01-22 18:20:55 +01:00
2d6961e848 fix font embedder and cloass loader issues, add arabic/hebrew fonts 2025-01-22 17:52:05 +01:00
09086f9b5b move fonts to subprojects 2025-01-21 14:59:02 +01:00
2dedbc154f QR code test 2025-01-15 11:55:14 +01:00
0564b2e934 try to fix wrong space recognition in StyledText 2024-11-18 17:37:10 +01:00
aa08fa45f0 trim only if more than one space 2024-10-18 15:27:55 +02:00
e81e605887 use always trimmed text so that getSelectedFont() works 2024-10-18 14:39:18 +02:00
0f3f8d488a trim text in TextLine drawAligned 2024-10-18 14:07:34 +02:00
a58f1e6c83 update to datastructures 5.1.1 2024-07-04 09:14:02 +02:00
afbe6eee2f add test success for gs 9.54 on RHEL 9.4 2024-05-02 11:30:47 +02:00
229951349b fixes for ghostscript 9.54+ 2024-04-30 22:57:10 +02:00
27fd1956a1 update to gradle 8.7 2024-04-29 08:13:37 +02:00
55ae303d70 make build successful 2024-03-07 16:16:11 +01:00
e42bdecb99 trying some jpeg2000 stuff without success 2024-03-06 17:53:56 +01:00
047fee7798 add JPEG2000 image i/o 2024-02-19 16:01:17 +01:00
b906e7533b add test for showing jbig2 support 2024-01-04 11:48:08 +01:00
6e82a0fbbd add jbig2-imageio 2024-01-03 14:42:12 +01:00
840cdc36f8 remove user gradle preferences from project files 2023-12-18 10:06:11 +01:00
ca2df9023f update datastructures to 5.0.6 2023-12-17 16:24:24 +01:00
e88864e843 update to Gradle 8.5 2023-12-10 16:10:33 +01:00
1cfc5b2989 add code39 and qrcode writer based on zxing 2023-12-08 08:46:23 +01:00
45b783c90a add code39 writer 2023-12-07 14:46:25 +01:00
64bbee5cd3 remove truetype files and remove obsolete ghostscript font analysis 2023-12-07 14:28:52 +01:00
7b624e8f30 add colorspaces to documetn analysis, improve barcode analysis 2023-12-07 13:47:58 +01:00
734cdfc90c add zxing and barcode analyzer 2023-12-06 16:33:37 +01:00
75c123bd6e add zxing core 2023-12-06 10:46:30 +01:00
3b02aa2b75 use testLibs 2023-12-04 20:53:12 +01:00
923e63ccbe document analyzer test 2023-12-04 18:54:00 +01:00
67609394cc enhance document analyzer 2023-12-04 15:16:22 +01:00
b08fa2d137 add color/gray detection in document analyzer 2023-11-27 18:44:24 +01:00
319dd41658 add color/gray detection 2023-11-24 23:20:48 +01:00
2fdccf2c79 add java version of document analyzer 2023-10-24 15:01:25 +02:00
ff5512b813 typo in gradle settings - unrecognized by gradle 2023-10-19 18:24:34 +02:00
e1266a3b44 add logging.properties 2023-10-18 15:46:06 +02:00
dabbf89e5d update to pdfbox 4.0.0-SNAPSHOT 2023-10-18 14:51:07 +02:00
c76b419657 update to OpenJDK 21, Gradle 8.4 2023-10-18 10:09:16 +02:00
ae7ea4d1ba update to PDFbox 3.0.0 2023-09-27 14:38:37 +02:00
2b9ff08296 repair pdf 2023-09-26 16:32:47 +02:00
ba25c5ed3b add some diagnostics in case of table error 2023-09-01 15:10:31 +02:00
0162464b0f catch IllegalArgumentException in StyledText when font is selected 2023-08-31 17:57:34 +02:00
1df6a1ea16 fix table font handling with base font's notorious illegal argument exception, fix other table font bugs 2023-08-28 17:55:45 +02:00
b62aacfe59 table cells use font descriptor now 2023-08-26 09:38:03 +02:00
26d8f2756a fix linespacing in table cells, add max height to table rendering 2023-08-25 15:25:33 +02:00
b3167d16ce add transform to underline annotations 2023-08-23 11:24:05 +02:00
97ed576828 skip empty texts, add hebrew font 2023-08-22 18:57:34 +02:00
d07aca4465 fix value to text renaming 2023-08-09 22:38:22 +02:00
8475f64388 change value to text in cell element 2023-08-09 18:20:15 +02:00
ddb5db7b84 fix font setup in document command 2023-08-07 18:16:12 +02:00
9eeebfac01 fallback to second font, CJK demo 2023-08-04 22:53:39 +02:00
53a27c5792 switch to multi font parameter, this allows for fallback fonts 2023-08-04 11:26:48 +02:00
ba2641b774 working on fonts in pdfbox layout documents 2023-08-02 17:57:52 +02:00
b1e6a4dc9b add Noto Sans CJK SC 2023-08-01 18:06:59 +02:00
134343ba47 update to PDFbox 3.0.0 beta1, fix cmap ttf font bug in two consecutive script engine runs by removing cache from org.xbib.graphics.pdfbox.layout.font.Fonts 2023-07-31 16:09:11 +02:00
ca317f41ec embed notosans 2023-07-31 10:41:46 +02:00
11bc5a9393 use plain text and markup text in scripting engine 2023-07-28 16:19:34 +02:00
6f5b5f396d move to forgejo 2023-05-26 10:11:40 +02:00
3399 changed files with 142962 additions and 2028 deletions
build.gradlegradle.properties
gradle
gradlewgradlew.bat
graphics-barcode
graphics-chart/src
main/java
test/resources
graphics-fonts-arabic
graphics-fonts-cjk
graphics-fonts-cyrillic
graphics-fonts-hebrew
graphics-fonts-latin
graphics-fonts

View file

@ -1,22 +1,24 @@
plugins {
id "de.marcphilipp.nexus-publish" version "0.4.0"
id "io.codearte.nexus-staging" version "0.21.1"
id 'maven-publish'
id 'signing'
id "io.github.gradle-nexus.publish-plugin" version "2.0.0-rc-1"
}
wrapper {
gradleVersion = libs.versions.gradle.get()
distributionType = Wrapper.DistributionType.ALL
distributionType = Wrapper.DistributionType.BIN
}
ext {
user = 'jprante'
user = 'joerg'
name = 'graphics'
description = 'A collection of graphics libraries for Java'
inceptionYear = '2020'
url = 'https://github.com/' + user + '/' + name
scmUrl = 'https://github.com/' + user + '/' + name
scmConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git'
scmDeveloperConnection = 'scm:git:ssh://git@github.com:' + user + '/' + name + '.git'
url = 'https://xbib.org/' + user + '/' + name
scmUrl = 'https://xbib.org/' + user + '/' + name
scmConnection = 'scm:git:git://xbib.org/' + user + '/' + name + '.git'
scmDeveloperConnection = 'scm:git:ssh://forgejo@xbib.org:' + user + '/' + name + '.git'
issueManagementSystem = 'Github'
issueManagementUrl = ext.scmUrl + '/issues'
licenseName = 'The GNU General Public License, Version 3'
@ -24,9 +26,10 @@ ext {
}
subprojects {
apply from: rootProject.file('gradle/ide/idea.gradle')
apply from: rootProject.file('gradle/repositories/maven.gradle')
apply from: rootProject.file('gradle/compile/java.gradle')
apply from: rootProject.file('gradle/test/junit5.gradle')
apply from: rootProject.file('gradle/publishing/publication.gradle')
apply from: rootProject.file('gradle/publish/maven.gradle')
}
apply from: rootProject.file('gradle/publishing/sonatype.gradle')
apply from: rootProject.file('gradle/publish/sonatype.gradle')
apply from: rootProject.file('gradle/publish/forgejo.gradle')

View file

@ -1,5 +1,3 @@
group = org.xbib.graphics
name = graphics
version = 4.3.4
org.gradle.warning.mode = ALL
version = 5.7.0

View file

@ -2,17 +2,12 @@
apply plugin: 'java-library'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
modularity.inferModulePath.set(true)
}
compileJava {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
withSourcesJar()
withJavadocJar()
}
jar {
@ -21,24 +16,9 @@ jar {
}
}
task sourcesJar(type: Jar) {
dependsOn classes
classifier 'sources'
from sourceSets.main.allSource
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
task javadocJar(type: Jar) {
dependsOn javadoc
classifier 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar, javadocJar
}
tasks.withType(JavaCompile) {
options.fork = true
options.forkOptions.jvmArgs += ['-Duser.language=en','-Duser.country=US']
options.compilerArgs.add('-Xlint:all,-exports')
options.encoding = 'UTF-8'
}

View file

@ -0,0 +1,16 @@
if (project.hasProperty('forgeJoToken')) {
publishing {
repositories {
maven {
url 'https://xbib.org/api/packages/joerg/maven'
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token ${project.property('forgeJoToken')}"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
}

27
gradle/publish/ivy.gradle Normal file
View file

@ -0,0 +1,27 @@
apply plugin: 'ivy-publish'
publishing {
repositories {
ivy {
url = "https://xbib.org/repo"
}
}
publications {
ivy(IvyPublication) {
from components.java
descriptor {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
author {
name = 'Jörg Prante'
url = 'http://example.com/users/jane'
}
descriptor.description {
text = rootProject.ext.description
}
}
}
}
}

View file

@ -1,14 +1,10 @@
import java.time.Duration
apply plugin: "de.marcphilipp.nexus-publish"
publishing {
publications {
mavenJava(MavenPublication) {
"${project.name}"(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
pom {
artifactId = project.name
name = project.name
description = rootProject.ext.description
url = rootProject.ext.url
@ -50,19 +46,6 @@ publishing {
if (project.hasProperty("signing.keyId")) {
apply plugin: 'signing'
signing {
sign publishing.publications.mavenJava
sign publishing.publications."${project.name}"
}
}
if (project.hasProperty('ossrhUsername')) {
nexusPublishing {
repositories {
sonatype {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
}
clientTimeout = Duration.ofSeconds(600)
}
}

View file

@ -0,0 +1,11 @@
if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
nexusPublishing {
repositories {
sonatype {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
}
}
}

View file

@ -1,11 +0,0 @@
if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
apply plugin: 'io.codearte.nexus-staging'
nexusStaging {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
}

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!-- For Debug Only -->
<!-- <suppress files=".+\.(?:txt|xml|csv|sh|thrift|html|sql|eot|ttf|woff|css|png|java|jar|zip|war|class|tar|bin|gif|jpg|jpeg|properties)$" checks=".*"/> -->
<!-- Suppressions for Javadoc in Test classes -->
<suppress checks="JavadocMethod" files="src[/\\]test[/\\]java"/>
<suppress checks="JavadocType" files="src[/\\]test[/\\]java"/>
<!-- Suppressions for resources -->
<suppress checks=".*" files="src[/\\]main[/\\]resources" />
<!-- Suppressions for generated source files -->
<suppress checks=".*" files="build[/\\]" />
<!-- Disables Javadoc requirement for all public methods. This suppression
is not recommended, but may be needed (temporarily) to allow checkstyle
to be applied to existing codebases. -->
<suppress checks="JavadocMethod" files="src[/\\]main[/\\]java"/>
<!-- No tab characters ('\t') allowed in the source code -->
<suppress checks="FileTabCharacter" files="src"/>
<!-- No Trailing Whitespace, except on lines that only have an asterisk (e.g. Javadoc comments) -->
<suppress checks="RegexpSingleline" files=".*\.java"/>
<!-- Maximum line length is 120 characters -->
<suppress checks="LineLength" files=".*\.java"/>
<!-- Highlight any TODO or FIXME comments in info messages -->
<suppress checks="TodoComment" files=".*\.java"/>
<!-- ##### Import statement requirements ##### -->
<!-- Star imports (e.g. import java.util.*) are NOT ALLOWED -->
<suppress checks="AvoidStarImport" files=".*\.java"/>
<!-- Redundant import statements are NOT ALLOWED -->
<suppress checks="RedundantImport" files=".*\.java"/>
<!-- Unused import statements are NOT ALLOWED -->
<suppress checks="UnusedImports" files=".*\.java"/>
<!-- Ensure imports appear alphabetically and grouped -->
<suppress checks="CustomImportOrder" files=".*\.java"/>
<!-- ##### Requirements for K&R Style braces ##### -->
<!-- Code blocks MUST HAVE braces, even single line statements (if, while, etc) -->
<suppress checks="NeedBraces" files=".*\.java"/>
<!-- Left braces should be at the end of current line (default value)-->
<suppress checks="LeftCurly" files=".*\.java"/>
<!-- Right braces should be on start of a new line (default value) -->
<suppress checks="RightCurly" files=".*\.java"/>
<!-- ##### Indentation / Whitespace requirements ##### -->
<!-- Require 4-space indentation (default value) -->
<suppress checks="Indentation" files=".*\.java"/>
<!-- Whitespace should exist around all major tokens -->
<suppress checks="WhitespaceAround" files=".*\.java"/>
<!-- Validate whitespace around Generics (angle brackets) per typical conventions
http://checkstyle.sourceforge.net/config_whitespace.html#GenericWhitespace -->
<suppress checks="GenericWhitespace" files=".*\.java"/>
<!-- ##### Blank line requirements ##### -->
<suppress checks="EmptyLineSeparator" files=".*\.java"/>
<!-- ##### Requirements for "switch" statements ##### -->
<!-- "switch" statements MUST have a "default" clause -->
<suppress checks="MissingSwitchDefault" files=".*\.java"/>
<!-- "case" clauses in switch statements MUST include break, return, throw or continue -->
<suppress checks="FallThrough" files=".*\.java"/>
<!-- ##### Other / Miscellaneous requirements ##### -->
<!-- Require utility classes do not have a public constructor -->
<suppress checks="HideUtilityClassConstructor" files=".*\.java"/>
<!-- Require each variable declaration is its own statement on its own line -->
<suppress checks="MultipleVariableDeclarations" files=".*\.java"/>
<!-- Each line of code can only include one statement -->
<suppress checks="OneStatementPerLine" files=".*\.java"/>
<!-- Require that "catch" statements are not empty (must at least contain a comment) -->
<suppress checks="EmptyCatchBlock" files=".*\.java"/>
<!-- Require that 'final' used on variables and parameters -->
<suppress checks="FinalLocalVariable" files=".*.java"/>
<suppress checks="FinalParameters" files=".*.java"/>
</suppressions>

View file

@ -0,0 +1,20 @@
apply plugin: 'checkstyle'
tasks.withType(Checkstyle) {
ignoreFailures = true
reports {
xml.getRequired().set(true)
html.getRequired().set(true)
}
}
checkstyle {
configFile = rootProject.file('gradle/quality/checkstyle.xml')
ignoreFailures = true
showViolations = true
checkstyleMain {
source = sourceSets.main.allSource
}
configProperties = [ "suppressionFile" : rootProject.file('gradle/quality/checkstyle-suppressions.xml') ]
}

View file

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value=".*(Example|Test|module-info)(\$.*)?"/>
</module>
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<!-- <property name="tokens" value="IMPORT, STATIC_IMPORT"/> -->
<property name="separated" value="false"/>
<property name="groups" value="*"/>
<!-- <property name="option" value="above"/> -->
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<module name="CustomImportOrder">
<!-- <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/> -->
<!-- <property name="specialImportsRegExp" value="^javax\."/> -->
<!-- <property name="standardPackageRegExp" value="^java\."/> -->
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="false"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="accessModifiers" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="SuppressionFilter">
<property name="file" value="${suppressionFile}" default="checkstyle-suppressions.xml"/>
</module>
</module>

View file

@ -0,0 +1,11 @@
cyclonedxBom {
includeConfigs = [ 'runtimeClasspath' ]
skipConfigs = [ 'compileClasspath', 'testCompileClasspath' ]
projectType = "library"
schemaVersion = "1.4"
destination = file("build/reports")
outputName = "bom"
outputFormat = "json"
includeBomSerialNumber = true
componentVersion = "2.0.0"
}

17
gradle/quality/pmd.gradle Normal file
View file

@ -0,0 +1,17 @@
apply plugin: 'pmd'
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.getRequired().set(true)
html.getRequired().set(true)
}
}
pmd {
ignoreFailures = true
consoleOutput = false
toolVersion = "6.51.0"
ruleSetFiles = rootProject.files('gradle/quality/pmd/category/java/bestpractices.xml')
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
rulesets.filenames=\
category/java/bestpractices.xml,\
category/java/codestyle.xml,\
category/java/design.xml,\
category/java/documentation.xml,\
category/java/errorprone.xml,\
category/java/multithreading.xml,\
category/java/performance.xml,\
category/java/security.xml

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,144 @@
<?xml version="1.0"?>
<ruleset name="Documentation"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that are related to code documentation.
</description>
<rule name="CommentContent"
since="5.0"
message="Invalid words or phrases found"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentContentRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentcontent">
<description>
A rule for the politically correct... we don't want to offend anyone.
</description>
<priority>3</priority>
<example>
<![CDATA[
//OMG, this is horrible, Bob is an idiot !!!
]]>
</example>
</rule>
<rule name="CommentRequired"
since="5.1"
message="Comment is required"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentRequiredRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentrequired">
<description>
Denotes whether comments are required (or unwanted) for specific language elements.
</description>
<priority>3</priority>
<example>
<![CDATA[
/**
*
*
* @author Jon Doe
*/
]]>
</example>
</rule>
<rule name="CommentSize"
since="5.0"
message="Comment is too large"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentSizeRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentsize">
<description>
Determines whether the dimensions of non-header comments found are within the specified limits.
</description>
<priority>3</priority>
<example>
<![CDATA[
/**
*
* too many lines!
*
*
*
*
*
*
*
*
*
*
*
*
*/
]]>
</example>
</rule>
<rule name="UncommentedEmptyConstructor"
language="java"
since="3.4"
message="Document empty constructor"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptyconstructor">
<description>
Uncommented Empty Constructor finds instances where a constructor does not
contain statements, but there is no comment. By explicitly commenting empty
constructors it is easier to distinguish between intentional (commented)
and unintentional empty constructors.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ConstructorDeclaration[@Private='false']
[count(BlockStatement) = 0 and ($ignoreExplicitConstructorInvocation = 'true' or not(ExplicitConstructorInvocation)) and @containsComment = 'false']
[not(../Annotation/MarkerAnnotation/Name[pmd-java:typeIs('javax.inject.Inject')])]
]]>
</value>
</property>
<property name="ignoreExplicitConstructorInvocation" type="Boolean" description="Ignore explicit constructor invocation when deciding whether constructor is empty or not" value="false"/>
</properties>
<example>
<![CDATA[
public Foo() {
// This constructor is intentionally empty. Nothing special is needed here.
}
]]>
</example>
</rule>
<rule name="UncommentedEmptyMethodBody"
language="java"
since="3.4"
message="Document empty method body"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptymethodbody">
<description>
Uncommented Empty Method Body finds instances where a method body does not contain
statements, but there is no comment. By explicitly commenting empty method bodies
it is easier to distinguish between intentional (commented) and unintentional
empty methods.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//MethodDeclaration/Block[count(BlockStatement) = 0 and @containsComment = 'false']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public void doSomething() {
}
]]>
</example>
</rule>
</ruleset>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,393 @@
<?xml version="1.0"?>
<ruleset name="Multithreading"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that flag issues when dealing with multiple threads of execution.
</description>
<rule name="AvoidSynchronizedAtMethodLevel"
language="java"
since="3.0"
message="Use block level rather than method level synchronization"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedatmethodlevel">
<description>
Method-level synchronization can cause problems when new code is added to the method.
Block-level synchronization helps to ensure that only the code that needs synchronization
gets it.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//MethodDeclaration[@Synchronized='true']</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
// Try to avoid this:
synchronized void foo() {
}
// Prefer this:
void bar() {
synchronized(this) {
}
}
// Try to avoid this for static methods:
static synchronized void fooStatic() {
}
// Prefer this:
static void barStatic() {
synchronized(Foo.class) {
}
}
}
]]>
</example>
</rule>
<rule name="AvoidThreadGroup"
language="java"
since="3.6"
message="Avoid using java.lang.ThreadGroup; it is not thread safe"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidthreadgroup">
<description>
Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment
it contains methods that are not thread-safe.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.ThreadGroup')]|
//PrimarySuffix[contains(@Image, 'getThreadGroup')]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Bar {
void buz() {
ThreadGroup tg = new ThreadGroup("My threadgroup");
tg = new ThreadGroup(tg, "my thread group");
tg = Thread.currentThread().getThreadGroup();
tg = System.getSecurityManager().getThreadGroup();
}
}
]]>
</example>
</rule>
<rule name="AvoidUsingVolatile"
language="java"
since="4.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="Use of modifier volatile is not recommended."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidusingvolatile">
<description>
Use of the keyword 'volatile' is generally used to fine tune a Java application, and therefore, requires
a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore,
the volatile keyword should not be used for maintenance purpose and portability.
</description>
<priority>2</priority>
<properties>
<property name="xpath">
<value>//FieldDeclaration[contains(@Volatile,'true')]</value>
</property>
</properties>
<example>
<![CDATA[
public class ThrDeux {
private volatile String var1; // not suggested
private String var2; // preferred
}
]]>
</example>
</rule>
<rule name="DoNotUseThreads"
language="java"
since="4.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="To be compliant to J2EE, a webapp should not use any thread."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#donotusethreads">
<description>
The J2EE specification explicitly forbids the use of threads.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//ClassOrInterfaceType[@Image = 'Thread' or @Image = 'Runnable']</value>
</property>
</properties>
<example>
<![CDATA[
// This is not allowed
public class UsingThread extends Thread {
}
// Neither this,
public class OtherThread implements Runnable {
// Nor this ...
public void methode() {
Runnable thread = new Thread(); thread.run();
}
}
]]>
</example>
</rule>
<rule name="DontCallThreadRun"
language="java"
since="4.3"
message="Don't call Thread.run() explicitly, use Thread.start()"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#dontcallthreadrun">
<description>
Explicitly calling Thread.run() method will execute in the caller's thread of control. Instead, call Thread.start() for the intended behavior.
</description>
<priority>4</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//StatementExpression/PrimaryExpression
[
PrimaryPrefix
[
./Name[ends-with(@Image, '.run') or @Image = 'run']
and substring-before(Name/@Image, '.') =//VariableDeclarator/VariableDeclaratorId/@Image
[../../../Type/ReferenceType/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]]
or (./AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]
and ../PrimarySuffix[@Image = 'run'])
]
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
Thread t = new Thread();
t.run(); // use t.start() instead
new Thread().run(); // same violation
]]>
</example>
</rule>
<rule name="DoubleCheckedLocking"
language="java"
since="1.04"
message="Double checked locking is not thread safe in Java."
class="net.sourceforge.pmd.lang.java.rule.multithreading.DoubleCheckedLockingRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#doublecheckedlocking">
<description>
Partially created objects can be returned by the Double Checked Locking pattern when used in Java.
An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the
reference points to.
Note: With Java 5, you can make Double checked locking work, if you declare the variable to be `volatile`.
For more details refer to: &lt;http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html>
or &lt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
</description>
<priority>1</priority>
<example>
<![CDATA[
public class Foo {
/*volatile */ Object baz = null; // fix for Java5 and later: volatile
Object bar() {
if (baz == null) { // baz may be non-null yet not fully created
synchronized(this) {
if (baz == null) {
baz = new Object();
}
}
}
return baz;
}
}
]]>
</example>
</rule>
<rule name="NonThreadSafeSingleton"
since="3.4"
message="Singleton is not thread safe"
class="net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#nonthreadsafesingleton">
<description>
Non-thread safe singletons can result in bad state changes. Eliminate
static singletons if possible by instantiating the object directly. Static
singletons are usually not needed as only a single instance exists anyway.
Other possible fixes are to synchronize the entire method or to use an
[initialize-on-demand holder class](https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom).
Refrain from using the double-checked locking pattern. The Java Memory Model doesn't
guarantee it to work unless the variable is declared as `volatile`, adding an uneeded
performance penalty. [Reference](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html)
See Effective Java, item 48.
</description>
<priority>3</priority>
<example>
<![CDATA[
private static Foo foo = null;
//multiple simultaneous callers may see partially initialized objects
public static Foo getFoo() {
if (foo==null) {
foo = new Foo();
}
return foo;
}
]]>
</example>
</rule>
<rule name="UnsynchronizedStaticDateFormatter"
since="3.6"
deprecated="true"
message="Static DateFormatter objects should be accessed in a synchronized manner"
class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticDateFormatterRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticdateformatter">
<description>
SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances
for each thread. If multiple threads must access a static formatter, the formatter must be
synchronized either on method or block level.
This rule has been deprecated in favor of the rule {% rule UnsynchronizedStaticFormatter %}.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private static final SimpleDateFormat sdf = new SimpleDateFormat();
void bar() {
sdf.format(); // poor, no thread-safety
}
synchronized void foo() {
sdf.format(); // preferred
}
}
]]>
</example>
</rule>
<rule name="UnsynchronizedStaticFormatter"
since="6.11.0"
message="Static Formatter objects should be accessed in a synchronized manner"
class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticFormatterRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticformatter">
<description>
Instances of `java.text.Format` are generally not synchronized.
Sun recommends using separate format instances for each thread.
If multiple threads must access a static formatter, the formatter must be
synchronized either on method or block level.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private static final SimpleDateFormat sdf = new SimpleDateFormat();
void bar() {
sdf.format(); // poor, no thread-safety
}
synchronized void foo() {
sdf.format(); // preferred
}
}
]]>
</example>
</rule>
<rule name="UseConcurrentHashMap"
language="java"
minimumLanguageVersion="1.5"
since="4.2.6"
message="If you run in Java5 or newer and have concurrent access, you should use the ConcurrentHashMap implementation"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#useconcurrenthashmap">
<description>
Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can
perform efficient map reads without blocking other threads.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Type[../VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[@Image != 'ConcurrentHashMap']]
/ReferenceType/ClassOrInterfaceType[@Image = 'Map']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class ConcurrentApp {
public void getMyInstance() {
Map map1 = new HashMap(); // fine for single-threaded access
Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
// the following case will be ignored by this rule
Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
}
}
]]>
</example>
</rule>
<rule name="UseNotifyAllInsteadOfNotify"
language="java"
since="3.0"
message="Call Thread.notifyAll() rather than Thread.notify()"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#usenotifyallinsteadofnotify">
<description>
Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only
one is chosen. The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//StatementExpression/PrimaryExpression
[PrimarySuffix/Arguments[@ArgumentCount = '0']]
[
PrimaryPrefix[
./Name[@Image='notify' or ends-with(@Image,'.notify')]
or ../PrimarySuffix/@Image='notify'
or (./AllocationExpression and ../PrimarySuffix[@Image='notify'])
]
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
void bar() {
x.notify();
// If many threads are monitoring x, only one (and you won't know which) will be notified.
// use instead:
x.notifyAll();
}
]]>
</example>
</rule>
</ruleset>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that flag potential security flaws.
</description>
<rule name="HardCodedCryptoKey"
since="6.4.0"
message="Do not use hard coded encryption keys"
class="net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#hardcodedcryptokey">
<description>
Do not use hard coded values for cryptographic operations. Please store keys outside of source code.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
}
void bad() {
SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
}
}
]]>
</example>
</rule>
<rule name="InsecureCryptoIv"
since="6.3.0"
message="Do not use hard coded initialization vector in crypto operations"
class="net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#insecurecryptoiv">
<description>
Do not use hard coded initialization vector in cryptographic operations. Please use a randomly generated IV.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
SecureRandom random = new SecureRandom();
byte iv[] = new byte[16];
random.nextBytes(bytes);
}
void bad() {
byte[] iv = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, };
}
void alsoBad() {
byte[] iv = "secret iv in here".getBytes();
}
}
]]>
</example>
</rule>
</ruleset>

View file

@ -0,0 +1,37 @@
subprojects {
sonarqube {
properties {
property "sonar.projectName", "${project.group} ${project.name}"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
property "sonar.junit.reportsPath", "build/test-results/test/"
}
}
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
spotbugs {
effort = "max"
reportLevel = "low"
//includeFilter = file("findbugs-exclude.xml")
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
ignoreFailures = true
reports {
xml.enabled = false
html.enabled = true
}
}
}

View file

@ -0,0 +1,15 @@
apply plugin: 'com.github.spotbugs'
spotbugs {
effort = "max"
reportLevel = "low"
ignoreFailures = true
}
spotbugsMain {
reports {
xml.getRequired().set(false)
html.getRequired().set(true)
}
}

View file

@ -0,0 +1,11 @@
repositories {
mavenLocal()
mavenCentral()
maven {
//url 'https://www.dcm4che.org/maven2/'
url 'https://maven.scijava.org/content/repositories/public/'
}
maven {
url 'https://raw.githubusercontent.com/nroduit/mvn-repo/master/'
}
}

33
gradle/test/junit4.gradle Normal file
View file

@ -0,0 +1,33 @@
dependencies {
testImplementation testLibs.junit.jupiter.api
testImplementation testLibs.junit.jupiter.params
testImplementation testLibs.hamcrest
testRuntimeOnly testLibs.junit.jupiter.engine
testRuntimeOnly testLibs.junit.jupiter.platform.launcher
}
test {
useJUnitPlatform()
failFast = false
environment 'TMPDIR', '/var/tmp/gs'
file('/var/tmp/gs').mkdirs()
systemProperty 'java.awt.headless', 'true'
systemProperty 'java.io.tmpdir', '/var/tmp/'
systemProperty 'pdfbox.fontcache', '/var/tmp/pdfbox'
systemProperty 'jna.tmpdir', '/var/tmp/'
systemProperty 'jna.debug', 'true'
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
testLogging {
events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED'
showStandardStreams = true
}
afterSuite { desc, result ->
if (!desc.parent) {
println "\nTest result: ${result.resultType}"
println "Test summary: ${result.testCount} tests, " +
"${result.successfulTestCount} succeeded, " +
"${result.failedTestCount} failed, " +
"${result.skippedTestCount} skipped"
}
}
}

View file

@ -1,17 +1,19 @@
dependencies {
testImplementation libs.junit.jupiter.api
testImplementation libs.junit.jupiter.params
testImplementation libs.hamcrest
testRuntimeOnly libs.junit.jupiter.engine
testImplementation testLibs.junit.jupiter.api
testImplementation testLibs.junit.jupiter.params
testImplementation testLibs.hamcrest
testRuntimeOnly testLibs.junit.jupiter.engine
testRuntimeOnly testLibs.junit.jupiter.platform.launcher
}
test {
useJUnitPlatform()
failFast = true
failFast = false
environment 'TMPDIR', '/var/tmp/gs'
file('/var/tmp/gs').mkdirs()
systemProperty 'java.awt.headless', 'true'
systemProperty 'java.io.tmpdir', '/var/tmp/'
systemProperty 'pdfbox.fontcache', '/var/tmp/pdfbox'
systemProperty 'jna.tmpdir', '/var/tmp/'
systemProperty 'jna.debug', 'true'
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'

Binary file not shown.

View file

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

35
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +80,11 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -133,22 +131,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

21
gradlew.bat vendored
View file

@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@ -42,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
@ -56,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

View file

@ -1,10 +1,10 @@
dependencies {
api project(':graphics-zxing')
testImplementation project(':graphics-vector')
testImplementation project(':graphics-vector-eps')
testImplementation project(':graphics-vector-pdf')
testImplementation project(':graphics-vector-svg')
testImplementation libs.junit.jupiter.params
testImplementation libs.junit4
testImplementation libs.zxing
testImplementation libs.reflections
testImplementation testLibs.junit.jupiter.params
testImplementation testLibs.junit4
testImplementation testLibs.reflections
}

View file

@ -46,7 +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 java.desktop;
requires org.xbib.graphics.zxing;
provides SymbolProvider with
AustraliaPost.Provider,
AztecCode.Provider,

View file

@ -132,6 +132,8 @@ public class QrCode extends AbstractSymbol {
private int inputLength;
private EccMode preferredEccLevel = EccMode.L;
private int autosize;
/**
* Sets the preferred symbol size. This value may be ignored if the data
* string is too large to fit into the specified symbol. Input values
@ -402,7 +404,6 @@ public class QrCode extends AbstractSymbol {
int est_binlen;
EccMode ecc_level;
int max_cw;
int autosize;
int targetCwCount, version, blocks;
int size;
int bitmask;

View file

@ -0,0 +1,48 @@
package org.xbib.graphics.barcode.render;
import org.xbib.graphics.zxing.BarcodeFormat;
import org.xbib.graphics.zxing.MultiFormatWriter;
import org.xbib.graphics.zxing.WriterException;
import org.xbib.graphics.zxing.common.BitMatrix;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
public class Code39Writer {
public Code39Writer() {
}
public void write(String content, Path path, String format, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.CODE_39, width, height);
MatrixToImageWriter.writeToPath(matrix, format, path);
} catch (WriterException e) {
throw new IOException(e);
}
}
public void write(String content, OutputStream outputStream, String format, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.CODE_39, width, height);
MatrixToImageWriter.writeToStream(matrix, format, outputStream);
} catch (WriterException e) {
throw new IOException(e);
}
}
public BufferedImage write(String content, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.CODE_39, width, height);
return MatrixToImageWriter.toBufferedImage(matrix);
} catch (WriterException e) {
throw new IOException(e);
}
}
}

View file

@ -0,0 +1,58 @@
package org.xbib.graphics.barcode.render;
import java.awt.image.BufferedImage;
/**
* Encapsulates custom configuration used in methods of {@link MatrixToImageWriter}.
*/
public final class MatrixToImageConfig {
public static final int BLACK = 0xFF000000;
public static final int WHITE = 0xFFFFFFFF;
private final int onColor;
private final int offColor;
/**
* Creates a default config with on color {@link #BLACK} and off color {@link #WHITE}, generating normal
* black-on-white barcodes.
*/
public MatrixToImageConfig() {
this(BLACK, WHITE);
}
/**
* @param onColor pixel on color, specified as an ARGB value as an int
* @param offColor pixel off color, specified as an ARGB value as an int
*/
public MatrixToImageConfig(int onColor, int offColor) {
this.onColor = onColor;
this.offColor = offColor;
}
public int getPixelOnColor() {
return onColor;
}
public int getPixelOffColor() {
return offColor;
}
int getBufferedImageColorModel() {
if (onColor == BLACK && offColor == WHITE) {
// Use faster BINARY if colors match default
return BufferedImage.TYPE_BYTE_BINARY;
}
if (hasTransparency(onColor) || hasTransparency(offColor)) {
// Use ARGB representation if colors specify non-opaque alpha
return BufferedImage.TYPE_INT_ARGB;
}
// Default otherwise to RGB representation with ignored alpha channel
return BufferedImage.TYPE_INT_RGB;
}
private static boolean hasTransparency(int argb) {
return (argb & 0xFF000000) != 0xFF000000;
}
}

View file

@ -0,0 +1,147 @@
package org.xbib.graphics.barcode.render;
import org.xbib.graphics.zxing.common.BitArray;
import org.xbib.graphics.zxing.common.BitMatrix;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.nio.file.Path;
/**
* Writes a {@link BitMatrix} to {@link BufferedImage},
* file or stream. Provided here instead of core since it depends on
* Java SE libraries.
*
* @author Sean Owen
*/
public final class MatrixToImageWriter {
private static final MatrixToImageConfig DEFAULT_CONFIG = new MatrixToImageConfig();
private MatrixToImageWriter() {}
/**
* Renders a {@link BitMatrix} as an image, where "false" bits are rendered
* as white, and "true" bits are rendered as black. Uses default configuration.
*
* @param matrix {@link BitMatrix} to write
* @return {@link BufferedImage} representation of the input
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
return toBufferedImage(matrix, DEFAULT_CONFIG);
}
/**
* As {@link #toBufferedImage(BitMatrix)}, but allows customization of the output.
*
* @param matrix {@link BitMatrix} to write
* @param config output configuration
* @return {@link BufferedImage} representation of the input
*/
public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
int onColor = config.getPixelOnColor();
int offColor = config.getPixelOffColor();
int[] rowPixels = new int[width];
BitArray row = new BitArray(width);
for (int y = 0; y < height; y++) {
row = matrix.getRow(y, row);
for (int x = 0; x < width; x++) {
rowPixels[x] = row.get(x) ? onColor : offColor;
}
image.setRGB(0, y, width, 1, rowPixels, 0, width);
}
return image;
}
/**
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param file file {@link File} to write image to
* @throws IOException if writes to the file fail
* @deprecated use {@link #writeToPath(BitMatrix, String, Path)}
*/
@Deprecated
public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
writeToPath(matrix, format, file.toPath());
}
/**
* Writes a {@link BitMatrix} to a file with default configuration.
*
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param file file {@link Path} to write image to
* @throws IOException if writes to the stream fail
* @see #toBufferedImage(BitMatrix)
*/
public static void writeToPath(BitMatrix matrix, String format, Path file) throws IOException {
writeToPath(matrix, format, file, DEFAULT_CONFIG);
}
/**
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param file file {@link File} to write image to
* @param config output configuration
* @throws IOException if writes to the file fail
* @deprecated use {@link #writeToPath(BitMatrix, String, Path, MatrixToImageConfig)}
*/
@Deprecated
public static void writeToFile(BitMatrix matrix, String format, File file, MatrixToImageConfig config)
throws IOException {
writeToPath(matrix, format, file.toPath(), config);
}
/**
* As {@link #writeToPath(BitMatrix, String, Path)}, but allows customization of the output.
*
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param file file {@link Path} to write image to
* @param config output configuration
* @throws IOException if writes to the file fail
*/
public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config)
throws IOException {
BufferedImage image = toBufferedImage(matrix, config);
if (!ImageIO.write(image, format, file.toFile())) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
/**
* Writes a {@link BitMatrix} to a stream with default configuration.
*
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param stream {@link OutputStream} to write image to
* @throws IOException if writes to the stream fail
* @see #toBufferedImage(BitMatrix)
*/
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
writeToStream(matrix, format, stream, DEFAULT_CONFIG);
}
/**
* As {@link #writeToStream(BitMatrix, String, OutputStream)}, but allows customization of the output.
*
* @param matrix {@link BitMatrix} to write
* @param format image format
* @param stream {@link OutputStream} to write image to
* @param config output configuration
* @throws IOException if writes to the stream fail
*/
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream, MatrixToImageConfig config)
throws IOException {
BufferedImage image = toBufferedImage(matrix, config);
if (!ImageIO.write(image, format, stream)) {
throw new IOException("Could not write an image of format " + format);
}
}
}

View file

@ -0,0 +1,49 @@
package org.xbib.graphics.barcode.render;
import org.xbib.graphics.zxing.BarcodeFormat;
import org.xbib.graphics.zxing.MultiFormatWriter;
import org.xbib.graphics.zxing.NotFoundException;
import org.xbib.graphics.zxing.common.BitMatrix;
import org.xbib.graphics.zxing.WriterException;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
public class QRCodeWriter {
public QRCodeWriter() {
}
public void write(String content, Path path, String format, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height);
MatrixToImageWriter.writeToPath(matrix, format, path);
} catch (WriterException e) {
throw new IOException(e);
}
}
public void write(String content, OutputStream outputStream, String format, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height);
MatrixToImageWriter.writeToStream(matrix, format, outputStream);
} catch (WriterException e) {
throw new IOException(e);
}
}
public BufferedImage write(String content, int width, int height)
throws IOException {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height);
return MatrixToImageWriter.toBufferedImage(matrix);
} catch (WriterException e) {
throw new IOException(e);
}
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xbib.graphics.barcode;
import org.xbib.graphics.zxing.LuminanceSource;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
/**
* This LuminanceSource implementation is meant for J2SE clients and our blackbox unit tests.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
* @author code@elektrowolle.de (Wolfgang Jung)
*/
public final class BufferedImageLuminanceSource extends LuminanceSource {
private static final double MINUS_45_IN_RADIANS = -0.7853981633974483; // Math.toRadians(-45.0)
private final BufferedImage image;
private final int left;
private final int top;
public BufferedImageLuminanceSource(BufferedImage image) {
this(image, 0, 0, image.getWidth(), image.getHeight());
}
public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
super(width, height);
if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) {
this.image = image;
} else {
int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight();
if (left + width > sourceWidth || top + height > sourceHeight) {
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
}
this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
WritableRaster raster = this.image.getRaster();
int[] buffer = new int[width];
for (int y = top; y < top + height; y++) {
image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);
for (int x = 0; x < width; x++) {
int pixel = buffer[x];
// The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
// black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
// barcode image. Force any such pixel to be white:
if ((pixel & 0xFF000000) == 0) {
// white, so we know its luminance is 255
buffer[x] = 0xFF;
} else {
// .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
// (306*R) >> 10 is approximately equal to R*0.299, and so on.
// 0x200 >> 10 is 0.5, it implements rounding.
buffer[x] =
(306 * ((pixel >> 16) & 0xFF) +
601 * ((pixel >> 8) & 0xFF) +
117 * (pixel & 0xFF) +
0x200) >> 10;
}
}
raster.setPixels(left, y, width, 1, buffer);
}
}
this.left = left;
this.top = top;
}
@Override
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
// The underlying raster of image consists of bytes with the luminance values
image.getRaster().getDataElements(left, top + y, width, 1, row);
return row;
}
@Override
public byte[] getMatrix() {
int width = getWidth();
int height = getHeight();
int area = width * height;
byte[] matrix = new byte[area];
// The underlying raster of image consists of area bytes with the luminance values
image.getRaster().getDataElements(left, top, width, height, matrix);
return matrix;
}
@Override
public boolean isCropSupported() {
return true;
}
@Override
public LuminanceSource crop(int left, int top, int width, int height) {
return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
}
/**
* This is always true, since the image is a gray-scale image.
*
* @return true
*/
@Override
public boolean isRotateSupported() {
return true;
}
@Override
public LuminanceSource rotateCounterClockwise() {
int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight();
// Rotate 90 degrees counterclockwise.
AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
// Note width/height are flipped since we are rotating 90 degrees.
BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
// Draw the original image into rotated, via transformation
Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform, null);
g.dispose();
// Maintain the cropped region, but rotate it too.
int width = getWidth();
return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
}
@Override
public LuminanceSource rotateCounterClockwise45() {
int width = getWidth();
int height = getHeight();
int oldCenterX = left + width / 2;
int oldCenterY = top + height / 2;
// Rotate 45 degrees counterclockwise.
AffineTransform transform = AffineTransform.getRotateInstance(MINUS_45_IN_RADIANS, oldCenterX, oldCenterY);
int sourceDimension = Math.max(image.getWidth(), image.getHeight());
BufferedImage rotatedImage = new BufferedImage(sourceDimension, sourceDimension, BufferedImage.TYPE_BYTE_GRAY);
// Draw the original image into rotated, via transformation
Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform, null);
g.dispose();
int halfDimension = Math.max(width, height) / 2;
int newLeft = Math.max(0, oldCenterX - halfDimension);
int newTop = Math.max(0, oldCenterY - halfDimension);
int newRight = Math.min(sourceDimension - 1, oldCenterX + halfDimension);
int newBottom = Math.min(sourceDimension - 1, oldCenterY + halfDimension);
return new BufferedImageLuminanceSource(rotatedImage, newLeft, newTop, newRight - newLeft, newBottom - newTop);
}
}

View file

@ -3,24 +3,23 @@ package org.xbib.graphics.barcode;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.oned.CodaBarReader;
import com.google.zxing.oned.Code39Reader;
import com.google.zxing.oned.Code93Reader;
import com.google.zxing.oned.EAN13Reader;
import com.google.zxing.oned.EAN8Reader;
import com.google.zxing.oned.UPCAReader;
import com.google.zxing.oned.UPCEReader;
import com.google.zxing.pdf417.PDF417Reader;
import com.google.zxing.qrcode.QRCodeReader;
import org.xbib.graphics.zxing.BinaryBitmap;
import org.xbib.graphics.zxing.DecodeHintType;
import org.xbib.graphics.zxing.FormatException;
import org.xbib.graphics.zxing.LuminanceSource;
import org.xbib.graphics.zxing.Reader;
import org.xbib.graphics.zxing.ReaderException;
import org.xbib.graphics.zxing.Result;
import org.xbib.graphics.zxing.common.HybridBinarizer;
import org.xbib.graphics.zxing.oned.CodaBarReader;
import org.xbib.graphics.zxing.oned.Code39Reader;
import org.xbib.graphics.zxing.oned.Code93Reader;
import org.xbib.graphics.zxing.oned.EAN13Reader;
import org.xbib.graphics.zxing.oned.EAN8Reader;
import org.xbib.graphics.zxing.oned.UPCAReader;
import org.xbib.graphics.zxing.oned.UPCEReader;
import org.xbib.graphics.zxing.pdf417.PDF417Reader;
import org.xbib.graphics.zxing.qrcode.QRCodeReader;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;

View file

@ -4,6 +4,11 @@ import org.junit.jupiter.api.Test;
import org.xbib.graphics.barcode.Code3Of9;
import org.xbib.graphics.barcode.HumanReadableLocation;
import org.xbib.graphics.barcode.render.BarcodeGraphicsRenderer;
import org.xbib.graphics.barcode.render.Code39Writer;
import org.xbib.graphics.barcode.render.QRCodeWriter;
import org.xbib.graphics.zxing.NotFoundException;
import org.xbib.graphics.zxing.WriterException;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
@ -73,4 +78,13 @@ public class Code39Test {
return new BarcodeGraphicsRenderer(g2d, rectangle, scalingFactorX, scalingFactorY,
Color.WHITE, Color.BLACK, false, false);
}
@Test
public void testQrCode() throws IOException, NotFoundException, WriterException {
Code39Writer codeWriter = new Code39Writer();
try (OutputStream outputStream = Files.newOutputStream(Paths.get("build/code39.png"))) {
codeWriter.write("123456789", outputStream, "png", 200, 50);
}
}
}

View file

@ -0,0 +1,65 @@
package org.xbib.graphics.barcode.output;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.barcode.QrCode;
import org.xbib.graphics.barcode.render.BarcodeGraphicsRenderer;
import org.xbib.graphics.barcode.render.QRCodeWriter;
import org.xbib.graphics.zxing.NotFoundException;
import org.xbib.graphics.zxing.WriterException;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class QRCodeTest {
@Test
public void createQRCode() throws IOException {
//String content = "IFLA-15: Kostenlimit überschritten, erneute Bestellung, wenn Kosten akzeptiert werden";
//String content = "IFLA-16:";
int x = 0;
int y = 0;
int width = 128;
int height = 128;
QrCode code = new QrCode();
code.setBarHeight(height - 2);
code.setQuietZoneHorizontal(1);
code.setQuietZoneVertical(1);
code.setEccMode(QrCode.EccMode.L);
//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);
renderer.render(code);
renderer.close();
try (OutputStream outputStream = Files.newOutputStream(Paths.get("build/qrcode.png"))) {
ImageIO.write(bufferedImage, "png", outputStream);
}
}
private BarcodeGraphicsRenderer createRenderer(BufferedImage bufferedImage,
int x, int y, double scalingFactorX, double scalingFactorY) {
Graphics2D g2d = bufferedImage.createGraphics();
Rectangle rectangle = new Rectangle(x, y, bufferedImage.getWidth(), bufferedImage.getHeight());
return new BarcodeGraphicsRenderer(g2d, rectangle, scalingFactorX, scalingFactorY,
Color.WHITE, Color.BLACK, false, false);
}
/**
* Easy way by using zxing.
* @throws IOException
*/
@Test
public void testQrCode() throws IOException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
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);
}
}
}

View file

@ -0,0 +1,8 @@
handlers=java.util.logging.ConsoleHandler
.level=ALL
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s %6$s%n
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
org.apache.fontbox.ttf.level=OFF
org.apache.fontbox.util.autodetect.FontFileFinder.level=OFF
org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.level=OFF

View file

@ -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;
}

View file

@ -0,0 +1,8 @@
handlers=java.util.logging.ConsoleHandler
.level=ALL
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s %6$s%n
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
org.apache.fontbox.ttf.level=OFF
org.apache.fontbox.util.autodetect.FontFileFinder.level=OFF
org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.level=OFF

View 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.

View file

@ -0,0 +1,3 @@
dependencies {
api project(':graphics-fonts')
}

View 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;
}

View file

@ -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");
}
}

View file

@ -0,0 +1 @@
org.xbib.graphics.fonts.arabic.ArabicFontEmbedder

View 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.

View file

@ -0,0 +1,3 @@
dependencies {
api project(':graphics-fonts')
}

View 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;
}

View file

@ -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");
}
}

View file

@ -0,0 +1 @@
org.xbib.graphics.fonts.cjk.CJKFontEmbedder

View 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.

View 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.

View file

@ -0,0 +1,3 @@
dependencies {
api project(':graphics-fonts')
}

View 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;
}

View file

@ -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");
}
}

View file

@ -0,0 +1 @@
org.xbib.graphics.fonts.cyrillic.CyrillicFontEmbedder

View 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.

View file

@ -0,0 +1,3 @@
dependencies {
api project(':graphics-fonts')
}

View 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;
}

View file

@ -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");
}
}

View file

@ -0,0 +1 @@
org.xbib.graphics.fonts.hebrew.HebrewFontEmbedder

View file

@ -0,0 +1,96 @@
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font
Name 'Source'. Source is a trademark of Adobe in the United States
and/or other countries.
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.

View 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.

View file

@ -0,0 +1,3 @@
dependencies {
api project(':graphics-fonts')
}

View 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;
}

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -0,0 +1,3 @@
org.xbib.graphics.fonts.latin.NotoSansFontEmbedder
org.xbib.graphics.fonts.latin.OpenSansFontEmbedder
org.xbib.graphics.fonts.latin.SourceSansFontEmbedder

View file

@ -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);
}
}
}

View file

@ -0,0 +1,3 @@
dependencies {
api libs.pdfbox
}

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