| author | wenzelm | 
| Sat, 30 Dec 2023 15:50:18 +0100 | |
| changeset 79389 | 10925576fbb4 | 
| parent 75394 | 42267c650205 | 
| child 80368 | 9db395953106 | 
| permissions | -rw-r--r-- | 
| 51098 | 1  | 
/* Title: Pure/General/graphics_file.scala  | 
2  | 
Author: Makarius  | 
|
3  | 
||
4  | 
File system operations for Graphics2D output.  | 
|
5  | 
*/  | 
|
6  | 
||
7  | 
package isabelle  | 
|
8  | 
||
9  | 
||
| 58451 | 10  | 
import java.io.{FileOutputStream, BufferedOutputStream, File => JFile}
 | 
| 51098 | 11  | 
import java.awt.Graphics2D  | 
| 51127 | 12  | 
import java.awt.geom.Rectangle2D  | 
| 58451 | 13  | 
import java.awt.image.BufferedImage  | 
14  | 
import javax.imageio.ImageIO  | 
|
| 51098 | 15  | 
|
| 51127 | 16  | 
import org.jfree.chart.JFreeChart  | 
17  | 
||
| 61177 | 18  | 
import com.lowagie.text.pdf.{PdfWriter, BaseFont, FontMapper, DefaultFontMapper}
 | 
19  | 
||
| 51098 | 20  | 
|
| 75393 | 21  | 
object Graphics_File {
 | 
| 58451 | 22  | 
/* PNG */  | 
23  | 
||
| 73340 | 24  | 
def write_png(  | 
| 75393 | 25  | 
file: JFile,  | 
26  | 
paint: Graphics2D => Unit,  | 
|
27  | 
width: Int,  | 
|
28  | 
height: Int,  | 
|
29  | 
dpi: Int = 72  | 
|
30  | 
  ): Unit = {
 | 
|
| 58451 | 31  | 
val scale = dpi / 72.0f  | 
32  | 
val w = (width * scale).round  | 
|
33  | 
val h = (height * scale).round  | 
|
34  | 
||
35  | 
val img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)  | 
|
36  | 
val gfx = img.createGraphics  | 
|
37  | 
    try {
 | 
|
38  | 
gfx.scale(scale, scale)  | 
|
39  | 
paint(gfx)  | 
|
40  | 
ImageIO.write(img, "png", file)  | 
|
41  | 
}  | 
|
42  | 
    finally { gfx.dispose }
 | 
|
43  | 
}  | 
|
44  | 
||
45  | 
||
| 51098 | 46  | 
/* PDF */  | 
47  | 
||
| 75393 | 48  | 
  private def font_mapper(): FontMapper = {
 | 
| 61177 | 49  | 
val mapper = new DefaultFontMapper  | 
| 69360 | 50  | 
    for (entry <- Isabelle_Fonts.fonts()) {
 | 
51  | 
val params = new DefaultFontMapper.BaseFontParameters(File.platform_path(entry.path))  | 
|
52  | 
params.encoding = BaseFont.IDENTITY_H  | 
|
53  | 
params.embedded = true  | 
|
| 
69365
 
c5b3860d29ef
avoid loading of font file, to eliminate "Illegal reflective access by com.lowagie.text.pdf.MappedRandomAccessFile$1 (iText-2.1.5.jar) to method java.nio.DirectByteBuffer.cleaner()" -- due to com.lowagie.text.pdf.TrueTypeFont.process() / RandomAccessFileOrArray;
 
wenzelm 
parents: 
69360 
diff
changeset
 | 
54  | 
params.ttfAfm = entry.bytes.array  | 
| 69360 | 55  | 
mapper.putName(entry.name, params)  | 
| 61177 | 56  | 
}  | 
57  | 
mapper  | 
|
58  | 
}  | 
|
59  | 
||
| 75393 | 60  | 
  def write_pdf(file: JFile, paint: Graphics2D => Unit, width: Int, height: Int): Unit = {
 | 
| 51098 | 61  | 
    import com.lowagie.text.{Document, Rectangle}
 | 
62  | 
||
| 75394 | 63  | 
    using(new BufferedOutputStream(new FileOutputStream(file))) { out =>
 | 
| 51098 | 64  | 
val document = new Document()  | 
65  | 
      try {
 | 
|
| 
73343
 
d0378baf7d06
tuned --- avoid deprecated conversions between certain number type;
 
wenzelm 
parents: 
73340 
diff
changeset
 | 
66  | 
document.setPageSize(new Rectangle(width.toFloat, height.toFloat))  | 
| 51098 | 67  | 
val writer = PdfWriter.getInstance(document, out)  | 
68  | 
document.open()  | 
|
69  | 
||
70  | 
val cb = writer.getDirectContent()  | 
|
| 
73343
 
d0378baf7d06
tuned --- avoid deprecated conversions between certain number type;
 
wenzelm 
parents: 
73340 
diff
changeset
 | 
71  | 
val tp = cb.createTemplate(width.toFloat, height.toFloat)  | 
| 
 
d0378baf7d06
tuned --- avoid deprecated conversions between certain number type;
 
wenzelm 
parents: 
73340 
diff
changeset
 | 
72  | 
val gfx = tp.createGraphics(width.toFloat, height.toFloat, font_mapper())  | 
| 51098 | 73  | 
|
74  | 
paint(gfx)  | 
|
75  | 
gfx.dispose  | 
|
76  | 
||
77  | 
cb.addTemplate(tp, 1, 0, 0, 1, 0, 0)  | 
|
78  | 
}  | 
|
79  | 
      finally { document.close() }
 | 
|
| 75394 | 80  | 
}  | 
| 51098 | 81  | 
}  | 
82  | 
||
| 65862 | 83  | 
|
84  | 
/* JFreeChart */  | 
|
85  | 
||
86  | 
def paint_chart(gfx: Graphics2D, chart: JFreeChart, width: Int, height: Int): Unit =  | 
|
87  | 
chart.draw(gfx, new Rectangle2D.Double(0, 0, width, height))  | 
|
| 51127 | 88  | 
|
| 65862 | 89  | 
def write_chart_png(file: JFile, chart: JFreeChart, width: Int, height: Int): Unit =  | 
90  | 
write_png(file, paint_chart(_, chart, width, height), width, height)  | 
|
| 51127 | 91  | 
|
| 65862 | 92  | 
def write_chart_pdf(file: JFile, chart: JFreeChart, width: Int, height: Int): Unit =  | 
93  | 
write_pdf(file, paint_chart(_, chart, width, height), width, height)  | 
|
| 51098 | 94  | 
}  |