Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 125 additions & 17 deletions src/main/scala/hevs/graphics/FunGraphics.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import hevs.graphics.utils.RepeatingReleasedEventsFixer
import javax.imageio.ImageIO
import java.awt._
import java.awt.event._
import java.awt.font.TextLayout
import java.awt.geom.AffineTransform
import java.awt.font.{LineMetrics, TextLayout}
import java.awt.geom.{AffineTransform, Rectangle2D}
import java.io._
import javax.swing.SwingConstants

/**
* Factory for [[hevs.graphics.FunGraphics]].
Expand Down Expand Up @@ -282,33 +283,138 @@ class FunGraphics(val width: Int, val height: Int, val xoffset: Int, val yoffset
g2d.fillOval(posX, posY, width, height)
}

override def drawString(posX: Int, posY: Int, str: String): Unit = {
g2d.drawString(str, posX, posY)
override def getStringSize(str: String, font: Font): Rectangle2D = {
val metrics: LineMetrics = font.getLineMetrics(str, g2d.getFontRenderContext)
val rect: Rectangle2D = font.getStringBounds(str, g2d.getFontRenderContext)
val height: Double = rect.getHeight - metrics.getDescent - metrics.getLeading
new Rectangle(rect.getWidth.toInt, height.toInt)
}

override def drawString(posX: Int, posY: Int, str: String, color: Color, size: Int): Unit = {
override def getStringSize(str: String): Rectangle2D = getStringSize(str, g2d.getFont)

override def drawString(posX: Int, posY: Int, str: String, font: Font, color: Color): Unit = {
val oldFont = g2d.getFont
val oldColor = g2d.getColor
val font = new Font("SansSerif", Font.PLAIN, size)

g2d.setFont(font)
g2d.setColor(color)
g2d.drawString(str, posX, posY)
g2d.setFont(oldFont)
g2d.setColor(oldColor)
}

override def drawString(posX: Int,
posY: Int,
str: String,
font: Font,
color: Color,
halign: Int,
valign: Int): Unit = {

val bounds: Rectangle2D = getStringSize(str, font)
val w: Double = bounds.getWidth
val h: Double = bounds.getHeight

var x: Double = posX
var y: Double = posY

if (halign == SwingConstants.CENTER) {
x -= w / 2.0
} else if (halign == SwingConstants.RIGHT) {
x -= w
}

if (valign == SwingConstants.CENTER) {
y += h / 2.0
} else if (valign == SwingConstants.TOP) {
y += h
}

drawString(math.round(x).toInt, math.round(y).toInt, str, font, color)
}

override def drawString(posX: Int,
posY: Int,
str: String,
fontFamily: String = "SansSerif",
fontStyle: Int = Font.PLAIN,
fontSize: Int = 20,
color: Color = Color.BLACK,
halign: Int = SwingConstants.LEFT,
valign: Int = SwingConstants.BOTTOM): Unit = {

val font = new Font(fontFamily, fontStyle, fontSize)
drawString(posX, posY, str, font, color, halign, valign)
}

override def drawString(posX: Int, posY: Int, str: String, color: Color, size: Int): Unit = {
drawString(posX, posY, str, fontSize = size, color = color)
}

override def drawFancyString(posX: Int, posY: Int, str: String, color: Color, size: Int): Unit = {
val g2 = g2d
val oldFont = g2d.getFont
val oldColor = g2d.getColor
val font = new Font("Georgia", Font.BOLD, size)
val textLayout = new TextLayout(str, font, g2.getFontRenderContext)
g2.setColor(Color.GRAY)
textLayout.draw(g2, (posX + 2).toFloat, (posY + 2).toFloat)
g2.setColor(color)
textLayout.draw(g2, posX.toFloat, posY.toFloat)
g2.setFont(oldFont)
g2.setColor(oldColor)
val font: Font = new Font("Georgia", Font.BOLD, size)
drawString(posX+2, posY+2, str, font, color = Color.GRAY)
drawString(posX, posY, str, fontSize = size, color = color)
}

override def drawFancyString(posX: Int,
posY: Int,
str: String,
fontFamily: String = "Georgia",
fontStyle: Int = Font.BOLD,
fontSize: Int = 20,
color: Color = Color.BLACK,
halign: Int = SwingConstants.LEFT,
valign: Int = SwingConstants.BOTTOM,
shadowX: Int = 0,
shadowY: Int = 0,
shadowColor: Color = Color.GRAY,
shadowThickness: Int = 0,
outlineColor: Color = Color.WHITE,
outlineThickness: Int = 0): Unit = {

val font: Font = new Font(fontFamily, fontStyle, fontSize)

if (shadowThickness > 0) {
val bounds: Rectangle2D = getStringSize(str, font)
val w: Double = bounds.getWidth
val h: Double = bounds.getHeight

var cx: Double = posX
var cy: Double = posY

if (halign == SwingConstants.LEFT) {
cx += w / 2.0
} else if (halign == SwingConstants.RIGHT) {
cx -= w / 2.0
}

if (valign == SwingConstants.TOP) {
cy += h / 2.0
} else if (valign == SwingConstants.BOTTOM) {
cy -= h / 2.0
}

val font2: Font = new Font(fontFamily, fontStyle, fontSize+shadowThickness)
drawString(
math.round(cx + shadowX).toInt,
math.round(cy + shadowY).toInt,
str,
font2,
shadowColor,
SwingConstants.CENTER,
SwingConstants.CENTER)
}

if (outlineThickness > 0) {
for (dy: Int <- -outlineThickness to outlineThickness) {
for (dx: Int <- -outlineThickness to outlineThickness) {
drawString(posX + dx, posY + dy, str, font, outlineColor, halign, valign)
}
}
}

drawString(posX, posY, str, font, color, halign, valign)
}

override def drawPicture(posX: Int, posY: Int, bitmap: GraphicsBitmap): Unit = {
Expand Down Expand Up @@ -347,6 +453,8 @@ class FunGraphics(val width: Int, val height: Int, val xoffset: Int, val yoffset
override def getFrameWidth(): Int = fWidth
override def getFrameHeight(): Int = fHeight

override def getAvailableFonts(): Array[String] = GraphicsEnvironment.getLocalGraphicsEnvironment.getAvailableFontFamilyNames

/**
* A sample game loop using explicit synchronization (if display flickers)
*/
Expand Down
134 changes: 130 additions & 4 deletions src/main/scala/hevs/graphics/interfaces/Graphics.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package hevs.graphics.interfaces

import hevs.graphics.FunGraphics
import hevs.graphics.utils.GraphicsBitmap
import java.awt.Color
import java.awt.Polygon
import java.awt.Rectangle

import java.awt.geom.Rectangle2D
import java.awt.{Color, Font, Polygon, Rectangle}


/**
Expand Down Expand Up @@ -181,6 +181,71 @@ trait Graphics {
*/
def drawFilledOval(posX: Int, posY: Int, width: Int, height: Int): Unit

/**
* Computes the size necessary to render a string with the given font
* @param str
* the string
* @param font
* the font
* @return the bounding box of the rendered string
*/
def getStringSize(str: String, font: Font): Rectangle2D


/**
* Computes the size necessary to render a string with the current font
* @param str
* the string
* @return the bounding box of the rendered string
*/
def getStringSize(str: String): Rectangle2D

/**
* Draws a string at a given location with the given font and color. Note that the boundaries are not
* checked and text may be painted outside the window
* @param posX
* X position of string
* @param posY
* Y position of string
* @param str
* the string to write
* @param font
* the font
* @param color
* the text color
*/
def drawString(posX: Int,
posY: Int,
str: String,
font: Font,
color: Color): Unit

/**
* Draws a string at a given location with the given font, color and alignments. Note that the boundaries are not
* checked and text may be painted outside the window
* @param posX
* X position of string
* @param posY
* Y position of string
* @param str
* the string to write
* @param font
* the font
* @param color
* the text color
* @param halign
* the horizontal alignment (see {@link javax.swing.SwingConstants})
* @param valign
* the vertical alignment (see {@link javax.swing.SwingConstants})
*/
def drawString(posX: Int,
posY: Int,
str: String,
font: Font,
color: Color,
halign: Int,
valign: Int): Unit

/**
* Draws a string at a given location. Note that the boundaries are not
* checked and text may be painted outside the window
Expand All @@ -191,8 +256,28 @@ trait Graphics {
* Y position of string
* @param str
* the string to write
* @param fontFamily
* the font family
* @param fontStyle
* the font style (plain, bold, italics, ...)
* @param fontSize
* the font size
* @param color
* the text color
* @param halign
* the horizontal alignment (see {@link javax.swing.SwingConstants})
* @param valign
* the vertical alignment (see {@link javax.swing.SwingConstants})
*/
def drawString(posX: Int, posY: Int, str: String): Unit
def drawString(posX: Int,
posY: Int,
str: String,
fontFamily: String,
fontStyle: Int,
fontSize: Int,
color: Color,
halign: Int,
valign: Int): Unit

/**
* Write the given string at <code>posX, posY</code>
Expand Down Expand Up @@ -221,6 +306,41 @@ trait Graphics {
*/
def drawFancyString(posX: Int, posY: Int, str: String, color: Color, size: Int): Unit

/**
* Draws a text with a shadow or outline
* @param posX
* X position of the string
* @param posY
* Y position of the string
* @param str
* the string to draw
* @param fontFamily
* the font family
* @param fontStyle
* the font style (plain, bold, italics, ...)
* @param fontSize
* the font size
* @param color
* the text color
* @param halign
* the horizontal alignment (see {@link javax.swing.SwingConstants})
* @param valign
* the vertical alignment (see {@link javax.swing.SwingConstants})
* @param shadowX
* the shadow's X offset
* @param shadowY
* the shadow's Y offset
* @param shadowColor
* the shadow color
* @param shadowThickness
* the shadow thickness
* @param outlineColor
* the outline color
* @param outlineThickness
* the outline thickness
*/
def drawFancyString(posX: Int, posY: Int, str: String, fontFamily: String, fontStyle: Int, fontSize: Int, color: Color, halign: Int, valign: Int, shadowX: Int, shadowY: Int, shadowColor: Color, shadowThickness: Int, outlineColor: Color, outlineThickness: Int): Unit

/**
* Draw a centered picture from a file (gif, jpg, png) to <code>(posX, posY)</code>
*
Expand Down Expand Up @@ -289,4 +409,10 @@ trait Graphics {
* @return the frame height
*/
def getFrameHeight(): Int

/**
* Returns a list of available font names on the device
* @return the list of available font names
*/
def getAvailableFonts(): Array[String]
}
Loading