geb.report.ExceptionToPngConverter.groovy Maven / Gradle / Ivy
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package geb.report
import javax.imageio.ImageIO
import java.awt.*
import java.awt.font.FontRenderContext
import java.awt.image.BufferedImage
import java.util.List
import static java.awt.Color.BLACK
import static java.awt.Color.WHITE
import static java.awt.Font.PLAIN
import static java.awt.image.BufferedImage.TYPE_INT_RGB
class ExceptionToPngConverter {
private static final String FONT_TYPE = 'Monospaced'
private static final int FONT_SIZE = 12
final static int LINE_SPACING = 2
Throwable throwable
ExceptionToPngConverter(Throwable t) {
throwable = t
}
byte[] convert(String headline) {
convertLines([headline] + throwableLines(throwable))
}
private List throwableLines(Throwable t) {
def lines = []
lines << t.toString()
lines += t.stackTrace.collect {
"at $it"
}
if (t.cause) {
lines << 'Caused by:'
lines += throwableLines(t.cause)
}
lines
}
private byte[] convertLines(List lines) {
def fontRenderContext = new BufferedImage(1, 1, TYPE_INT_RGB).createGraphics().fontRenderContext
def font = new Font(FONT_TYPE, PLAIN, FONT_SIZE)
def image = createImage(lines, font, fontRenderContext)
drawLines(lines, image, font, fontRenderContext)
convertToPngBytes(image)
}
private byte[] convertToPngBytes(BufferedImage image) {
def stream = new ByteArrayOutputStream()
ImageIO.write(image, 'png', stream)
stream.toByteArray()
}
private BufferedImage createImage(List lines, Font font, FontRenderContext fontRenderContext) {
def w = lines.collect { font.getStringBounds(it, fontRenderContext).width }.max() as int
def h = lines.collect { (font.getStringBounds(it, fontRenderContext).height as int) + LINE_SPACING }.sum()
new BufferedImage(w, h, TYPE_INT_RGB)
}
private byte[] drawLines(List lines, BufferedImage image, Font font, FontRenderContext fontRenderContext) {
def g = image.createGraphics()
g.color = WHITE
g.fillRect(0, 0, image.width, image.height)
g.color = BLACK
g.font = font
lines.inject(0) { totalHeight, line ->
def bounds = font.getStringBounds(line, fontRenderContext)
g.drawString(line, bounds.x as int, (totalHeight - bounds.y) as int)
totalHeight + (bounds.height as int) + LINE_SPACING
}
g.dispose()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy