Revision | 248 (tree) |
---|---|
Time | 2022-08-21 13:18:27 |
Author | hirukawa_ryo |
* fx-pdf 0.2.9
rotation が 270 に設定されている用紙が横方向に長い PDF が正しく表示されないバグを修正しました。
rotation が 180 で割り切れない場合は用紙の向きが異なるものとして用紙の縦と横の長さを入れ替えて処理するようにしました。
0.2.7 で廃止していた PdfView の renderScaleProperty と renderBounds を復活させました。(JPKI PDF SIGNERで使っていました)
依存ライブラリ pdfbox 2.0.24 -> 2.0.26
Gradle 7.0.2 -> 7.5.1
@@ -1,9 +1,13 @@ | ||
1 | 1 | package net.osdn.util.javafx.scene.control.pdf; |
2 | 2 | |
3 | 3 | import javafx.application.Platform; |
4 | +import javafx.beans.property.DoubleProperty; | |
4 | 5 | import javafx.beans.property.IntegerProperty; |
5 | 6 | import javafx.beans.property.ObjectProperty; |
7 | +import javafx.beans.property.ReadOnlyDoubleProperty; | |
6 | 8 | import javafx.beans.property.ReadOnlyIntegerProperty; |
9 | +import javafx.beans.property.ReadOnlyObjectProperty; | |
10 | +import javafx.beans.property.SimpleDoubleProperty; | |
7 | 11 | import javafx.beans.property.SimpleIntegerProperty; |
8 | 12 | import javafx.beans.property.SimpleObjectProperty; |
9 | 13 | import javafx.collections.ObservableList; |
@@ -10,6 +14,7 @@ | ||
10 | 14 | import javafx.concurrent.Task; |
11 | 15 | import javafx.embed.swing.SwingFXUtils; |
12 | 16 | import javafx.geometry.Point2D; |
17 | +import javafx.geometry.Rectangle2D; | |
13 | 18 | import javafx.scene.Node; |
14 | 19 | import javafx.scene.control.ProgressIndicator; |
15 | 20 | import javafx.scene.image.ImageView; |
@@ -97,6 +102,28 @@ | ||
97 | 102 | maxPageIndexProperty.set(value); |
98 | 103 | } |
99 | 104 | |
105 | + private DoubleProperty renderScaleProperty | |
106 | + = new SimpleDoubleProperty(this, "renderScale"); | |
107 | + | |
108 | + public ReadOnlyDoubleProperty renderScaleProperty() { | |
109 | + return renderScaleProperty; | |
110 | + } | |
111 | + | |
112 | + public final double getRenderScale() { | |
113 | + return renderScaleProperty.get(); | |
114 | + } | |
115 | + | |
116 | + private ObjectProperty<Rectangle2D> renderBounds | |
117 | + = new SimpleObjectProperty<Rectangle2D>(this, "renderBounds", Rectangle2D.EMPTY); | |
118 | + | |
119 | + public ReadOnlyObjectProperty<Rectangle2D> renderBoundsProperty() { | |
120 | + return renderBounds; | |
121 | + } | |
122 | + | |
123 | + public Rectangle2D getRenderBounds() { | |
124 | + return renderBounds.get(); | |
125 | + } | |
126 | + | |
100 | 127 | private RenderingHints renderingHints; |
101 | 128 | |
102 | 129 | private ProgressIndicator progressIndicator; |
@@ -119,8 +146,6 @@ | ||
119 | 146 | |
120 | 147 | imageView = new ImageView(); |
121 | 148 | imageView.setPreserveRatio(true); |
122 | - imageView.fitWidthProperty().bind(widthProperty()); | |
123 | - imageView.fitHeightProperty().bind(heightProperty()); | |
124 | 149 | getChildren().add(imageView); |
125 | 150 | |
126 | 151 | progressIndicator = new ProgressIndicator(); |
@@ -178,11 +203,45 @@ | ||
178 | 203 | } |
179 | 204 | isBusy = true; |
180 | 205 | } |
206 | + | |
207 | + int pageIndex = getPageIndex(); | |
208 | + | |
181 | 209 | PDDocument document = getDocument(); |
182 | 210 | if(document == null) { |
183 | 211 | imageView.setImage(null); |
212 | + imageView.setX(0.0); | |
213 | + imageView.setY(0.0); | |
214 | + imageView.setFitWidth(0.0); | |
215 | + imageView.setFitHeight(0.0); | |
216 | + renderScaleProperty.set(0.0); | |
217 | + renderBounds.set(Rectangle2D.EMPTY); | |
218 | + } else { | |
219 | + PDRectangle paper = document.getPage(pageIndex).getCropBox(); | |
220 | + int rotation = document.getPage(pageIndex).getRotation(); | |
221 | + double paperWidth = (rotation % 180 == 0) ? paper.getWidth() : paper.getHeight(); | |
222 | + double paperHeight = (rotation % 180 == 0) ? paper.getHeight() : paper.getWidth(); | |
223 | + double pdfViewWidth = getWidth(); | |
224 | + double pdfViewHeight = getHeight(); | |
225 | + double w; | |
226 | + double h; | |
227 | + if (paperWidth / paperHeight < pdfViewWidth / pdfViewHeight) { | |
228 | + w = pdfViewHeight * paperWidth / paperHeight; | |
229 | + h = pdfViewHeight; | |
230 | + } else { | |
231 | + w = pdfViewWidth; | |
232 | + h = pdfViewWidth * paperHeight / paperWidth; | |
233 | + } | |
234 | + double x = (pdfViewWidth - w) / 2; | |
235 | + double y = (pdfViewHeight - h) / 2; | |
236 | + double scale = h / paperHeight; | |
237 | + imageView.setX(x); | |
238 | + imageView.setY(y); | |
239 | + imageView.setFitWidth(w); | |
240 | + imageView.setFitHeight(h); | |
241 | + renderScaleProperty.set(scale); | |
242 | + renderBounds.set(new Rectangle2D(x, y, w, h)); | |
184 | 243 | } |
185 | - int pageIndex = getPageIndex(); | |
244 | + | |
186 | 245 | RenderingHints hints = getRenderingHints(); |
187 | 246 | |
188 | 247 | Screen screen = getScreen(this); |
@@ -196,7 +255,9 @@ | ||
196 | 255 | WritableImage image = createImage(document, pageIndex, hints, width, height); |
197 | 256 | |
198 | 257 | Platform.runLater(() -> { |
199 | - imageView.setImage(image); | |
258 | + if(image != null) { | |
259 | + imageView.setImage(image); | |
260 | + } | |
200 | 261 | }); |
201 | 262 | |
202 | 263 | synchronized (worker) { |
@@ -221,16 +282,20 @@ | ||
221 | 282 | return null; |
222 | 283 | } |
223 | 284 | PDRectangle paper = document.getPage(pageIndex).getCropBox(); |
285 | + int rotation = document.getPage(pageIndex).getRotation(); | |
286 | + double paperWidth = (rotation % 180 == 0) ? paper.getWidth() : paper.getHeight(); | |
287 | + double paperHeight = (rotation % 180 == 0) ? paper.getHeight() : paper.getWidth(); | |
288 | + | |
224 | 289 | double w; |
225 | 290 | double h; |
226 | - if (paper.getWidth() / paper.getHeight() < width / height) { | |
227 | - w = height * paper.getWidth() / paper.getHeight(); | |
291 | + if (paperWidth / paperHeight < width / height) { | |
292 | + w = height * paperWidth / paperHeight; | |
228 | 293 | h = height; |
229 | 294 | } else { |
230 | 295 | w = width; |
231 | - h = width * paper.getHeight() / paper.getWidth(); | |
296 | + h = width * paperHeight / paperWidth; | |
232 | 297 | } |
233 | - double scale = h / paper.getHeight(); | |
298 | + double scale = h / paperHeight; | |
234 | 299 | |
235 | 300 | if (bimg == null || bimg.getWidth() != (int) w || bimg.getHeight() != (int) h) { |
236 | 301 | bimg = new BufferedImage((int) w, (int) h, BufferedImage.TYPE_INT_RGB); |