| 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 | 
 | 
|  |     21 | object Graphics_File
 | 
|  |     22 | {
 | 
| 58451 |     23 |   /* PNG */
 | 
|  |     24 | 
 | 
|  |     25 |   def write_png(file: JFile, paint: Graphics2D => Unit, width: Int, height: Int, dpi: Int = 72)
 | 
|  |     26 |   {
 | 
|  |     27 |     val scale = dpi / 72.0f
 | 
|  |     28 |     val w = (width * scale).round
 | 
|  |     29 |     val h = (height * scale).round
 | 
|  |     30 | 
 | 
|  |     31 |     val img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
 | 
|  |     32 |     val gfx = img.createGraphics
 | 
|  |     33 |     try {
 | 
|  |     34 |       gfx.scale(scale, scale)
 | 
|  |     35 |       paint(gfx)
 | 
|  |     36 |       ImageIO.write(img, "png", file)
 | 
|  |     37 |     }
 | 
|  |     38 |     finally { gfx.dispose }
 | 
|  |     39 |   }
 | 
|  |     40 | 
 | 
|  |     41 | 
 | 
| 51098 |     42 |   /* PDF */
 | 
|  |     43 | 
 | 
| 61177 |     44 |   private def font_mapper(): FontMapper =
 | 
|  |     45 |   {
 | 
|  |     46 |     val mapper = new DefaultFontMapper
 | 
|  |     47 |     for {
 | 
| 65086 |     48 |       font <- Isabelle_System.fonts()
 | 
| 65999 |     49 |       name <- Library.try_unsuffix(".ttf", font.base_name)
 | 
| 61177 |     50 |     } {
 | 
|  |     51 |       val parameters = new DefaultFontMapper.BaseFontParameters(File.platform_path(font))
 | 
|  |     52 |       parameters.encoding = BaseFont.IDENTITY_H
 | 
|  |     53 |       mapper.putName(name, parameters)
 | 
|  |     54 |     }
 | 
|  |     55 |     mapper
 | 
|  |     56 |   }
 | 
|  |     57 | 
 | 
| 65862 |     58 |   def write_pdf(file: JFile, paint: Graphics2D => Unit, width: Int, height: Int)
 | 
| 51098 |     59 |   {
 | 
|  |     60 |     import com.lowagie.text.{Document, Rectangle}
 | 
|  |     61 | 
 | 
|  |     62 |     val out = new BufferedOutputStream(new FileOutputStream(file))
 | 
|  |     63 |     try {
 | 
|  |     64 |       val document = new Document()
 | 
|  |     65 |       try {
 | 
|  |     66 |         document.setPageSize(new Rectangle(width, height))
 | 
|  |     67 |         val writer = PdfWriter.getInstance(document, out)
 | 
|  |     68 |         document.open()
 | 
|  |     69 | 
 | 
|  |     70 |         val cb = writer.getDirectContent()
 | 
|  |     71 |         val tp = cb.createTemplate(width, height)
 | 
| 61177 |     72 |         val gfx = tp.createGraphics(width, height, 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() }
 | 
|  |     80 |     }
 | 
|  |     81 |     finally { out.close }
 | 
|  |     82 |   }
 | 
|  |     83 | 
 | 
| 65862 |     84 | 
 | 
|  |     85 |   /* JFreeChart */
 | 
|  |     86 | 
 | 
|  |     87 |   def paint_chart(gfx: Graphics2D, chart: JFreeChart, width: Int, height: Int): Unit =
 | 
|  |     88 |     chart.draw(gfx, new Rectangle2D.Double(0, 0, width, height))
 | 
| 51127 |     89 | 
 | 
| 65862 |     90 |   def write_chart_png(file: JFile, chart: JFreeChart, width: Int, height: Int): Unit =
 | 
|  |     91 |     write_png(file, paint_chart(_, chart, width, height), width, height)
 | 
| 51127 |     92 | 
 | 
| 65862 |     93 |   def write_chart_pdf(file: JFile, chart: JFreeChart, width: Int, height: Int): Unit =
 | 
|  |     94 |     write_pdf(file, paint_chart(_, chart, width, height), width, height)
 | 
| 51098 |     95 | }
 |