watermark fix

This commit is contained in:
Anthony Stirling 2023-07-01 21:08:33 +01:00
parent f7832774d9
commit c140052822
11 changed files with 57 additions and 40 deletions

View file

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

View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -18,6 +18,17 @@
<label th:text="#{watermark.selectText.1}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
</div>
<div class="form-group">
<label for="fontSize" th:text="#{alphabet}"></label>
<select class="form-control" name="alphabet" id="alphabet-select">
<option value="romain">Roman</option>
<option value="arabic">العربية</option>
<option value="japanese">日本語</option>
<option value="korean">한국어</option>
<option value="chinese">简体中文</option>
</select>
</div>
<div class="form-group">
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />