diff --git a/build.gradle b/build.gradle index 8bf6062c..5f75b486 100644 --- a/build.gradle +++ b/build.gradle @@ -62,10 +62,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-core' - // https://mvnrepository.com/artifact/com.cybozu.labs/langdetect -implementation group: 'com.cybozu.labs', name: 'langdetect', version: '1.1-20120112' - - developmentOnly("org.springframework.boot:spring-boot-devtools") } diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java index 63bf6476..4ef8604b 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java @@ -5,6 +5,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.pdfbox.pdmodel.PDDocument; @@ -23,14 +25,11 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import com.cybozu.labs.langdetect.Detector; -import com.cybozu.labs.langdetect.DetectorFactory; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import stirling.software.SPDF.utils.WebResponseUtils; - +import io.swagger.v3.oas.annotations.media.Schema; @RestController @Tag(name = "Security", description = "Security APIs") public class WatermarkController { @@ -42,6 +41,12 @@ public class WatermarkController { @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to add a watermark") MultipartFile pdfFile, + @RequestParam(defaultValue = "roman", name = "alphabet") + @Parameter(description = "The selected alphabet", + schema = @Schema(type = "string", + allowableValues = {"roman","arabic","japanese","korean","chinese"}, + defaultValue = "roman")) + String alphabet, @RequestParam("watermarkText") @Parameter(description = "The watermark text to add to the PDF file") String watermarkText, @@ -63,7 +68,7 @@ public class WatermarkController { // Load the input PDF PDDocument document = PDDocument.load(pdfFile.getInputStream()); - + String producer = document.getDocumentInformation().getProducer(); // Create a page in the document for (PDPage page : document.getPages()) { @@ -75,42 +80,39 @@ public class WatermarkController { graphicsState.setNonStrokingAlphaConstant(opacity); contentStream.setGraphicsStateParameters(graphicsState); - DetectorFactory.loadProfile("profiles"); + + String resourceDir = ""; + PDFont font = PDType1Font.HELVETICA_BOLD; + switch (alphabet) { + case "arabic": + resourceDir = "static/fonts/NotoSansArabic-Regular.ttf"; + break; + case "japanese": + resourceDir = "static/fonts/Meiryo.ttf"; + break; + case "korean": + resourceDir = "static/fonts/malgun.ttf"; + break; + case "chinese": + resourceDir = "static/fonts/SimSun.ttf"; + break; + case "roman": + default: + resourceDir = "static/fonts/NotoSans-Regular.ttf"; + break; + } + - Detector detector = DetectorFactory.create(); - detector.append(watermarkText); - String lang = detector.detect(); - - System.out.println("Detected lang" + lang); - // Set font of watermark - // Load NotoSans-Regular font from resources - String resourceDir = ""; - PDFont font = PDType1Font.HELVETICA_BOLD; - switch (lang) { - case "ar": - resourceDir = "src/main/resources/static/fonts/NotoSansArabic-Regular.ttf"; - break; - case "ja": - resourceDir = "src/main/resources/static/fonts/NotoSansJP-Regular.otf"; - break; - case "ko": - resourceDir = "src/main/resources/static/fonts/NotoSansKR-Regular.otf"; - break; - case "zh-cn": - resourceDir = "src/main/resources/static/fonts/NotoSansSC-Regular.otf"; - break; - default: - font = PDType1Font.HELVETICA_BOLD; - } - if(!resourceDir.equals("")) { - ClassPathResource classPathResource = new ClassPathResource("static/fonts/NotoSans-Regular.ttf"); - File tempFile = File.createTempFile("NotoSans-Regular", ".ttf"); + ClassPathResource classPathResource = new ClassPathResource(resourceDir); + String fileExtension = resourceDir.substring(resourceDir.lastIndexOf(".")); + File tempFile = File.createTempFile("NotoSansFont", fileExtension); try (InputStream is = classPathResource.getInputStream(); FileOutputStream os = new FileOutputStream(tempFile)) { IOUtils.copy(is, os); } font = PDType0Font.load(document, tempFile); + tempFile.deleteOnExit(); } contentStream.beginText(); contentStream.setFont(font, fontSize); @@ -127,11 +129,19 @@ public class WatermarkController { // Add the watermark text for (int i = 0; i < watermarkRows; i++) { for (int j = 0; j < watermarkCols; j++) { - contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation), j * watermarkWidth, i * watermarkHeight)); + + if(producer.contains("Google Docs")) { + //This fixes weird unknown google docs y axis rotation/flip issue + //TODO: Long term fix one day + //contentStream.setTextMatrix(1, 0, 0, -1, j * watermarkWidth, pageHeight - i * watermarkHeight); + Matrix matrix = new Matrix(1, 0, 0, -1, j * watermarkWidth, pageHeight - i * watermarkHeight); + contentStream.setTextMatrix(matrix); + } else { + contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation), j * watermarkWidth, i * watermarkHeight)); + } contentStream.showTextWithPositioning(new Object[] { watermarkText }); } } - contentStream.endText(); // Close the content stream diff --git a/src/main/resources/static/fonts/Meiryo.ttf b/src/main/resources/static/fonts/Meiryo.ttf new file mode 100644 index 00000000..a608fbb4 Binary files /dev/null and b/src/main/resources/static/fonts/Meiryo.ttf differ diff --git a/src/main/resources/static/fonts/NotoSansArabic-Regular.ttf b/src/main/resources/static/fonts/NotoSansArabic-Regular.ttf new file mode 100644 index 00000000..79359c46 Binary files /dev/null and b/src/main/resources/static/fonts/NotoSansArabic-Regular.ttf differ diff --git a/src/main/resources/static/fonts/NotoSansJP-Regular.ttf b/src/main/resources/static/fonts/NotoSansJP-Regular.ttf new file mode 100644 index 00000000..1583096a Binary files /dev/null and b/src/main/resources/static/fonts/NotoSansJP-Regular.ttf differ diff --git a/src/main/resources/static/fonts/NotoSansKR-Regular.otf b/src/main/resources/static/fonts/NotoSansKR-Regular.otf deleted file mode 100644 index 7c5c2fae..00000000 Binary files a/src/main/resources/static/fonts/NotoSansKR-Regular.otf and /dev/null differ diff --git a/src/main/resources/static/fonts/NotoSansSC-Regular.otf b/src/main/resources/static/fonts/NotoSansSC-Regular.otf deleted file mode 100644 index d350ffa7..00000000 Binary files a/src/main/resources/static/fonts/NotoSansSC-Regular.otf and /dev/null differ diff --git a/src/main/resources/static/fonts/NotoSansSC-Regular.ttf b/src/main/resources/static/fonts/NotoSansSC-Regular.ttf new file mode 100644 index 00000000..c10d2aa1 Binary files /dev/null and b/src/main/resources/static/fonts/NotoSansSC-Regular.ttf differ diff --git a/src/main/resources/static/fonts/SimSun.ttf b/src/main/resources/static/fonts/SimSun.ttf new file mode 100644 index 00000000..e0115abe Binary files /dev/null and b/src/main/resources/static/fonts/SimSun.ttf differ diff --git a/src/main/resources/static/fonts/malgun.ttf b/src/main/resources/static/fonts/malgun.ttf new file mode 100644 index 00000000..6d8645bc Binary files /dev/null and b/src/main/resources/static/fonts/malgun.ttf differ diff --git a/src/main/resources/templates/security/add-watermark.html b/src/main/resources/templates/security/add-watermark.html index 4dfeade7..b689b8e0 100644 --- a/src/main/resources/templates/security/add-watermark.html +++ b/src/main/resources/templates/security/add-watermark.html @@ -18,6 +18,17 @@
+ +
+ + +