mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-18 09:29:24 +00:00
update backend to support rotating and resizing about the centerpoint
This commit is contained in:
parent
b94154dea7
commit
6cdbf55264
@ -239,34 +239,54 @@ public class StampController {
|
|||||||
|
|
||||||
PDRectangle pageSize = page.getMediaBox();
|
PDRectangle pageSize = page.getMediaBox();
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
if (overrideX >= 0 && overrideY >= 0) {
|
|
||||||
// Use override values if provided
|
|
||||||
x = overrideX;
|
|
||||||
y = overrideY;
|
|
||||||
} else {
|
|
||||||
x = calculatePositionX(pageSize, position, fontSize, font, fontSize, stampText, margin);
|
|
||||||
y =
|
|
||||||
calculatePositionY(
|
|
||||||
pageSize, position, calculateTextCapHeight(font, fontSize), margin);
|
|
||||||
}
|
|
||||||
// Split the stampText into multiple lines
|
// Split the stampText into multiple lines
|
||||||
String[] lines = stampText.split("\\\\n");
|
String[] lines = stampText.split("\\r?\\n|\\\\n");
|
||||||
|
|
||||||
// Calculate dynamic line height based on font ascent and descent
|
// Calculate dynamic line height based on font ascent and descent
|
||||||
float ascent = font.getFontDescriptor().getAscent();
|
float ascent = font.getFontDescriptor().getAscent();
|
||||||
float descent = font.getFontDescriptor().getDescent();
|
float descent = font.getFontDescriptor().getDescent();
|
||||||
float lineHeight = ((ascent - descent) / 1000) * fontSize;
|
float lineHeight = ((ascent - descent) / 1000) * fontSize;
|
||||||
|
|
||||||
|
// Compute a single pivot for the entire text block to avoid line-by-line wobble
|
||||||
|
float capHeight = calculateTextCapHeight(font, fontSize);
|
||||||
|
float blockHeight = Math.max(lineHeight, lineHeight * Math.max(1, lines.length));
|
||||||
|
float maxWidth = 0f;
|
||||||
|
for (String ln : lines) {
|
||||||
|
maxWidth = Math.max(maxWidth, calculateTextWidth(ln, font, fontSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overrideX >= 0 && overrideY >= 0) {
|
||||||
|
// Use override values if provided
|
||||||
|
x = overrideX;
|
||||||
|
y = overrideY;
|
||||||
|
} else {
|
||||||
|
// Base positioning on the true multi-line block size
|
||||||
|
x = calculatePositionX(pageSize, position, maxWidth, null, 0, null, margin);
|
||||||
|
y = calculatePositionY(pageSize, position, blockHeight, margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// After anchoring the block, draw from the top line downward
|
||||||
|
float adjustedX = x;
|
||||||
|
float adjustedY = y;
|
||||||
|
float pivotX = adjustedX + maxWidth / 2f;
|
||||||
|
float pivotY = adjustedY + blockHeight / 2f;
|
||||||
|
|
||||||
|
// Apply rotation about the block center at the graphics state level
|
||||||
|
contentStream.saveGraphicsState();
|
||||||
|
contentStream.transform(Matrix.getTranslateInstance(pivotX, pivotY));
|
||||||
|
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
||||||
|
contentStream.transform(Matrix.getTranslateInstance(-pivotX, -pivotY));
|
||||||
|
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
String line = lines[i];
|
String line = lines[i];
|
||||||
// Set the text matrix for each line with rotation
|
// Start from top line: yTop = adjustedY + blockHeight - capHeight
|
||||||
contentStream.setTextMatrix(
|
float yLine = adjustedY + blockHeight - capHeight - (i * lineHeight);
|
||||||
Matrix.getRotateInstance(Math.toRadians(rotation), x, y - (i * lineHeight)));
|
contentStream.setTextMatrix(Matrix.getTranslateInstance(adjustedX, yLine));
|
||||||
contentStream.showText(line);
|
contentStream.showText(line);
|
||||||
}
|
}
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
|
contentStream.restoreGraphicsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addImageStamp(
|
private void addImageStamp(
|
||||||
@ -310,9 +330,17 @@ public class StampController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentStream.saveGraphicsState();
|
contentStream.saveGraphicsState();
|
||||||
contentStream.transform(Matrix.getTranslateInstance(x, y));
|
// Rotate and scale about the center of the image
|
||||||
|
float centerX = x + (desiredPhysicalWidth / 2f);
|
||||||
|
float centerY = y + (desiredPhysicalHeight / 2f);
|
||||||
|
contentStream.transform(Matrix.getTranslateInstance(centerX, centerY));
|
||||||
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
||||||
contentStream.drawImage(xobject, 0, 0, desiredPhysicalWidth, desiredPhysicalHeight);
|
contentStream.drawImage(
|
||||||
|
xobject,
|
||||||
|
-desiredPhysicalWidth / 2f,
|
||||||
|
-desiredPhysicalHeight / 2f,
|
||||||
|
desiredPhysicalWidth,
|
||||||
|
desiredPhysicalHeight);
|
||||||
contentStream.restoreGraphicsState();
|
contentStream.restoreGraphicsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import StampPreview from "../components/tools/addStamp/StampPreview";
|
|||||||
import LocalIcon from "../components/shared/LocalIcon";
|
import LocalIcon from "../components/shared/LocalIcon";
|
||||||
import styles from "../components/tools/addStamp/StampPreview.module.css";
|
import styles from "../components/tools/addStamp/StampPreview.module.css";
|
||||||
import { Tooltip } from "../components/shared/Tooltip";
|
import { Tooltip } from "../components/shared/Tooltip";
|
||||||
import FitText from "../components/shared/FitText";
|
|
||||||
import ButtonSelector from "../components/shared/ButtonSelector";
|
import ButtonSelector from "../components/shared/ButtonSelector";
|
||||||
|
|
||||||
const AddStamp = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
const AddStamp = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user