org.nspl.awtutil.scala Maven / Gradle / Ivy
The newest version!
package org.nspl
import java.awt.{Graphics2D}
import java.io._
trait JavaAWTUtil {
private[nspl] def shape2awt(s: Shape): java.awt.Shape = s match {
case Rectangle(x, y, w, h, _, _) =>
new java.awt.geom.Rectangle2D.Double(x, y, w, h)
case Ellipse(x, y, w, h, _) =>
new java.awt.geom.Ellipse2D.Double(x, y, w, h)
case Line(x1, y1, x2, y2, _) =>
new java.awt.geom.Line2D.Double(x1, y1, x2, y2)
case SimplePath(points, _) => {
val path = new java.awt.geom.GeneralPath()
path.moveTo(points.head.x, points.head.y)
points.drop(1).foreach { p =>
path.lineTo(p.x, p.y)
}
path.closePath
path
}
case Path(ops, _) => {
val path = new java.awt.geom.GeneralPath()
ops foreach {
case PathOperation.MoveTo(Point(x, y)) => path.moveTo(x, y)
case PathOperation.LineTo(Point(x, y)) => path.lineTo(x, y)
case PathOperation.QuadTo(Point(x2, y2), Point(x1, y1)) =>
path.quadTo(x1, y1, x2, y2)
case PathOperation.CubicTo(Point(x3, y3), Point(x1, y1), Point(x2, y2)) =>
path.curveTo(x1, y1, x2, y2, x3, y3)
}
path.closePath
path
}
}
private[nspl] def col2col(c: Color): java.awt.Paint =
new java.awt.Color(c.r, c.g, c.b, c.a)
private[nspl] def str2str(s: Stroke): java.awt.BasicStroke =
new java.awt.BasicStroke(
s.width.toFloat,
s.cap match {
case Cap.Butt => java.awt.BasicStroke.CAP_BUTT
case Cap.Square => java.awt.BasicStroke.CAP_SQUARE
case Cap.Round => java.awt.BasicStroke.CAP_ROUND
},
java.awt.BasicStroke.JOIN_MITER,
1f,
if (s.dash.count(_ > 0) == 0) null else s.dash.map(_.toFloat).toArray,
0f
)
private[nspl] def rec2bounds(r: java.awt.geom.Rectangle2D): Bounds =
Bounds(r.getX, r.getY, r.getWidth, r.getHeight)
private[nspl] def bounds2rec(r: Bounds): java.awt.geom.Rectangle2D.Double =
new java.awt.geom.Rectangle2D.Double(r.x, r.y, r.w, r.h)
private[nspl] def tx2tx(tx: AffineTransform): java.awt.geom.AffineTransform =
new java.awt.geom.AffineTransform(
tx.m0,
tx.m3,
tx.m1,
tx.m4,
tx.m2,
tx.m5
)
def show[K <: Renderable[K]](elem: Build[K])(implicit
er: Renderer[K, JavaRC]
) = {
import javax.swing._
import java.awt.Graphics
val frame = new JFrame("");
var paintableElem = elem.build
val update = (build: Build[K]) => {
synchronized {
paintableElem = build.build
}
frame.repaint()
}
frame.setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
frame
.getContentPane()
.add(
new JComponent {
override def paintComponent(g: Graphics) = {
super.paintComponent(g)
val g2 = g.asInstanceOf[Graphics2D]
val renderingContext = new JavaRC(g2,true)
val bounds = getBounds()
renderingContext
.render(fitToBounds(paintableElem, rec2bounds(bounds)))
}
},
java.awt.BorderLayout.CENTER
);
val d = new java.awt.Dimension(
(paintableElem.bounds.w * 3).toInt,
(paintableElem.bounds.h * 3).toInt
)
frame.setSize(d);
frame.setVisible(true);
(frame, update)
}
def writeVector[K <: Renderable[K]](
build: Build[K],
os: java.io.OutputStream,
width: Int = 500,
format: String = "pdf"
)(implicit
er: Renderer[K, JavaRC]
) = {
import de.erichseifert.vectorgraphics2d._
import de.erichseifert.vectorgraphics2d.pdf._
import de.erichseifert.vectorgraphics2d.svg._
import de.erichseifert.vectorgraphics2d.eps._
import util._
val elem = build.build
val aspect = elem.bounds.h / elem.bounds.w
val height = (width * aspect).toInt
val g2d = new VectorGraphics2D()
val renderingContext = new JavaRC(g2d,true)
val processor =
format match {
case "pdf" => new PDFProcessor()
case "svg" => new SVGProcessor()
case "eps" => new EPSProcessor()
}
val bounds = Bounds(0, 0, width, height)
renderingContext.render(fitToBounds(elem, bounds))
val document =
processor.getDocument(g2d.getCommands, new PageSize(width, height))
document.writeTo(os)
}
def write[K <: Renderable[K]](
elem: Build[K],
os: java.io.OutputStream,
width: Int = 1000,
mimeType: String = "image/png"
)(implicit
er: Renderer[K, JavaRC]
) = {
mimeType.split("/").last match {
case "pdf" | "svg" | "eps" | "svg+xml" =>
writeVector(elem, os, width, mimeType.split("/").last)
case _ => writeBitmap(elem, os, width, mimeType)
}
}
def writeBitmap[K <: Renderable[K]](
build: Build[K],
os: java.io.OutputStream,
width: Int = 1000,
mimeType: String = "image/png"
)(implicit
er: Renderer[K, JavaRC]
) = {
import java.awt.image.BufferedImage
import javax.imageio.ImageIO;
import java.awt.RenderingHints
val elem = build.build
val aspect = elem.bounds.h / elem.bounds.w
val height = math.max((width * aspect).toInt, 1)
val bimage = new BufferedImage(
width,
height,
BufferedImage.TYPE_INT_ARGB
);
val g2d = bimage.createGraphics();
val renderingContext = new JavaRC(g2d, true)
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON
);
val bounds = Bounds(0, 0, width, height)
renderingContext.render(fitToBounds(elem, bounds))
{
val imageWriter = ImageIO.getImageWritersByMIMEType(mimeType).next
val ios = ImageIO.createImageOutputStream(os);
imageWriter.setOutput(ios)
try {
imageWriter.write(bimage);
} finally {
ios.close();
}
}
}
private[nspl] def bench[K <: Renderable[K]](
build: => K,
width: Int = 1000,
render: Boolean = true
)(implicit
er: Renderer[K, JavaRC]
) = {
import java.awt.image.BufferedImage
import java.awt.RenderingHints
var elem = build
val aspect = elem.bounds.h / elem.bounds.w
val height = math.max((width * aspect).toInt, 1)
val bimage = new BufferedImage(
width,
height,
BufferedImage.TYPE_INT_ARGB
);
val g2d = bimage.createGraphics();
val renderingContext = new JavaRC(g2d,render)
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON
);
val bounds = Bounds(0, 0, width, height)
var i = 0
val N = 50000
while (i <= N) {
elem = build
renderingContext.render(fitToBounds(elem, bounds))
i += 1
}
i = 0
val t1 = System.nanoTime()
while (i <= N) {
elem = build
renderingContext.render(fitToBounds(elem, bounds))
i += 1
}
println((System.nanoTime - t1).toDouble / N * 1e-9)
}
def renderToByteArray[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000,
mimeType: String = "image/png"
)(implicit
er: Renderer[K, JavaRC]
): Array[Byte] = {
val bs = new java.io.ByteArrayOutputStream()
write(elem, bs, width, mimeType);
bs.toByteArray
}
def renderToFile[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000,
mimeType: String = "image/png"
)(implicit
er: Renderer[K, JavaRC]
) = {
val f = java.io.File.createTempFile("nspl", "." + mimeType.split("/").last)
val os = new BufferedOutputStream(new FileOutputStream(f))
try {
write(elem, os, width, mimeType)
} finally {
os.close
}
f
}
def renderToFile[K <: Renderable[K]](
f: File,
elem: Build[K],
width: Int,
mimeType: String
)(implicit
er: Renderer[K, JavaRC]
): File = {
val os = new BufferedOutputStream(new FileOutputStream(f))
try {
write(elem, os, width, mimeType)
} finally {
os.close
}
f
}
def svgToFile[K <: Renderable[K]](
f: File,
elem: Build[K],
width: Int
)(implicit
er: Renderer[K, JavaRC]
): File = {
renderToFile(f, elem, width, "svg")
f
}
def pdfToFile[K <: Renderable[K]](
f: File,
elem: Build[K],
width: Int
)(implicit
er: Renderer[K, JavaRC]
): File = {
renderToFile(f, elem, width, "application/pdf")
f
}
def pdfToFile[K <: Renderable[K]](
f: File,
elem: Build[K]
)(implicit
er: Renderer[K, JavaRC]
): File = pdfToFile(f, elem, 500)
def pdfToFile[K <: Renderable[K]](
elem: Build[K],
width: Int = 500
)(implicit
er: Renderer[K, JavaRC]
) = {
val f = java.io.File.createTempFile("nspl", ".pdf")
renderToFile(f, elem, width, "application/pdf")
f
}
def pngToFile[K <: Renderable[K]](
f: File,
elem: Build[K],
width: Int
)(implicit
er: Renderer[K, JavaRC]
): File = {
renderToFile(f, elem, width, "image/png")
f
}
def pngToFile[K <: Renderable[K]](
f: File,
elem: Build[K]
)(implicit
er: Renderer[K, JavaRC]
): File = pngToFile(f, elem, 1000)
def pngToFile[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000
)(implicit
er: Renderer[K, JavaRC]
): File = {
renderToFile(elem, width, "image/png")
}
def pngToByteArray[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000
)(implicit
er: Renderer[K, JavaRC]
): Array[Byte] = {
renderToByteArray(elem, width, "image/png")
}
def pdfToByteArray[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000
)(implicit
er: Renderer[K, JavaRC]
): Array[Byte] = {
renderToByteArray(elem, width, "application/pdf")
}
def svgToByteArray[K <: Renderable[K]](
elem: Build[K],
width: Int = 1000
)(implicit
er: Renderer[K, JavaRC]
): Array[Byte] = {
renderToByteArray(elem, width, "svg")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy