-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPdfRenderSession.java
More file actions
91 lines (80 loc) · 2.6 KB
/
PdfRenderSession.java
File metadata and controls
91 lines (80 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.demcha.compose.engine.render.pdf;
import com.demcha.compose.engine.render.RenderPassSession;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* PDF render-pass session that reuses one content stream per page.
*
* <p>One {@link PdfRenderSession} exists for one renderer {@code process(...)}
* invocation. Handlers obtain session-owned page surfaces from here and must
* restore any graphics/text state they change before returning.</p>
*/
final class PdfRenderSession implements RenderPassSession<PDPageContentStream> {
private final PdfStream streamFactory;
private final Map<Integer, PDPageContentStream> pageSurfaces = new LinkedHashMap<>();
private boolean closed;
PdfRenderSession(PdfStream streamFactory) {
this.streamFactory = streamFactory;
}
@Override
public void ensurePage(int pageIndex) throws IOException {
assertOpen();
streamFactory.ensurePage(pageIndex);
}
@Override
public PDPageContentStream pageSurface(int pageIndex) throws IOException {
assertOpen();
PDPageContentStream surface = pageSurfaces.get(pageIndex);
if (surface != null) {
return surface;
}
ensurePage(pageIndex);
PDPageContentStream opened = streamFactory.openPageSurface(pageIndex);
pageSurfaces.put(pageIndex, opened);
return opened;
}
/**
* Returns the number of page surfaces currently cached by this session.
* Visible for testing only.
*/
int cachedPageCount() {
return pageSurfaces.size();
}
/**
* Returns whether this session has been closed. After closing, no further
* page surfaces can be obtained. Visible for testing only.
*/
boolean isClosed() {
return closed;
}
@Override
public void close() throws IOException {
if (closed) {
return;
}
IOException failure = null;
for (PDPageContentStream surface : pageSurfaces.values()) {
try {
surface.close();
} catch (IOException ex) {
if (failure == null) {
failure = ex;
} else {
failure.addSuppressed(ex);
}
}
}
pageSurfaces.clear();
closed = true;
if (failure != null) {
throw failure;
}
}
private void assertOpen() {
if (closed) {
throw new IllegalStateException("PdfRenderSession is already closed");
}
}
}