Skip to content

Commit

Permalink
Implement HtmlCanvas; move some tests to commonTest
Browse files Browse the repository at this point in the history
  • Loading branch information
iSoron committed Apr 9, 2019
1 parent 7ba7edb commit 5c402b5
Show file tree
Hide file tree
Showing 17 changed files with 288 additions and 64 deletions.
1 change: 0 additions & 1 deletion core/gradle.properties

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.isoron.platform.concurrency

import java.util.concurrent.*
import kotlin.test.*

class ObservableTest {
Expand All @@ -29,20 +28,19 @@ class ObservableTest {
}

@Test
fun test() {
val latch = CountDownLatch(1)
fun testNotifyListeners() {
var wasCalled = false

val listener = object : TestListener {
override fun onDataChanged(data: Int) {
assertEquals(42, data)
latch.countDown()
wasCalled = true
}
}

val observable = Observable<TestListener>()
observable.addListener(listener)
observable.notifyListeners { l ->
l.onDataChanged(42)
}
observable.removeListener(listener)
assertTrue(latch.await(3, TimeUnit.SECONDS))
observable.notifyListeners { it.onDataChanged(42) }
assertTrue(wasCalled)
}
}
71 changes: 71 additions & 0 deletions core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.isoron.platform.gui

class CanvasTest(val platform: Platform) {
interface Platform {
fun createCanvas(width: Int, height: Int): Canvas
fun writePng(canvas: Canvas, filename: String)
}

fun testDrawing() {
val canvas = platform.createCanvas(500, 400)

canvas.setColor(Color(0x303030))
canvas.fillRect(0.0, 0.0, 500.0, 400.0)

canvas.setColor(Color(0x606060))
canvas.setStrokeWidth(25.0)
canvas.drawRect(100.0, 100.0, 300.0, 200.0)

canvas.setColor(Color(0xFFFF00))
canvas.setStrokeWidth(1.0)
canvas.drawRect(0.0, 0.0, 100.0, 100.0)
canvas.fillCircle(50.0, 50.0, 30.0)
canvas.drawRect(0.0, 100.0, 100.0, 100.0)
canvas.fillArc(50.0, 150.0, 30.0, 90.0, 135.0)
canvas.drawRect(0.0, 200.0, 100.0, 100.0)
canvas.fillArc(50.0, 250.0, 30.0, 90.0, -135.0)
canvas.drawRect(0.0, 300.0, 100.0, 100.0)
canvas.fillArc(50.0, 350.0, 30.0, 45.0, 90.0)

canvas.setColor(Color(0xFF0000))
canvas.setStrokeWidth(2.0)
canvas.drawLine(0.0, 0.0, 500.0, 400.0)
canvas.drawLine(500.0, 0.0, 0.0, 400.0)

canvas.setFont(Font.BOLD)
canvas.setFontSize(50.0)
canvas.setColor(Color(0x00FF00))
canvas.setTextAlign(TextAlign.CENTER)
canvas.drawText("HELLO", 250.0, 100.0)

canvas.setTextAlign(TextAlign.RIGHT)
canvas.drawText("HELLO", 250.0, 150.0)

canvas.setTextAlign(TextAlign.LEFT)
canvas.drawText("HELLO", 250.0, 200.0)

canvas.setFont(Font.FONT_AWESOME)
canvas.drawText(FontAwesome.CHECK, 250.0, 300.0)

platform.writePng(canvas, "CanvasTest.png")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@
package org.isoron.uhabits.models

import org.isoron.platform.time.*
import org.isoron.uhabits.*
import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_AUTOMATIC
import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_MANUAL
import org.isoron.uhabits.models.Checkmark.Companion.UNCHECKED
import org.junit.Test
import kotlin.test.*

class CheckmarkListTest : BaseTest() {
class CheckmarkListTest {

private val today = LocalDate(2019, 1, 30)

Expand Down
File renamed without changes.
110 changes: 110 additions & 0 deletions core/src/jsMain/kotlin/org/isoron/platform/gui/HtmlCanvas.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.isoron.platform.gui

import org.w3c.dom.*
import kotlin.browser.*
import kotlin.math.*

class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas {

val ctx = canvas.getContext("2d") as CanvasRenderingContext2D
var fontSize = 12.0
var fontWeight = ""
var fontFamily = "sans-serif"
var align = CanvasTextAlign.CENTER

override fun setColor(color: Color) {
val c = "rgb(${color.red * 255}, ${color.green * 255}, ${color.blue * 255})"
ctx.fillStyle = c;
ctx.strokeStyle = c;
}

override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) {
ctx.beginPath()
ctx.moveTo(x1 + 0.5, y1 + 0.5)
ctx.lineTo(x2 + 0.5, y2 + 0.5)
ctx.stroke()
}

override fun drawText(text: String, x: Double, y: Double) {
ctx.font = "${fontWeight} ${fontSize}px ${fontFamily}"
ctx.textAlign = align
ctx.textBaseline = CanvasTextBaseline.MIDDLE
ctx.fillText(text, x, y)
}

override fun fillRect(x: Double, y: Double, width: Double, height: Double) {
ctx.fillRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0)
}

override fun drawRect(x: Double, y: Double, width: Double, height: Double) {
ctx.strokeRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0)
}

override fun getHeight(): Double {
return canvas.height.toDouble()
}

override fun getWidth(): Double {
return canvas.width.toDouble()
}

override fun setFont(font: Font) {
fontWeight = if (font == Font.BOLD) "bold" else ""
fontFamily = if (font == Font.FONT_AWESOME) "FontAwesome" else "sans-serif"
}

override fun setFontSize(size: Double) {
fontSize = size
}

override fun setStrokeWidth(size: Double) {
ctx.lineWidth = size
}

override fun fillArc(centerX: Double,
centerY: Double,
radius: Double,
startAngle: Double,
swipeAngle: Double) {
val from = startAngle / 180 * PI
val to = (startAngle + swipeAngle) / 180 * PI
ctx.beginPath()
ctx.moveTo(centerX, centerY)
ctx.arc(centerX, centerY, radius, -from, -to, swipeAngle >= 0)
ctx.lineTo(centerX, centerY)
ctx.fill()
}

override fun fillCircle(centerX: Double, centerY: Double, radius: Double) {
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0.0, 2 * PI)
ctx.fill()
}

override fun setTextAlign(align: TextAlign) {
this.align = when(align) {
TextAlign.LEFT -> CanvasTextAlign.LEFT
TextAlign.CENTER -> CanvasTextAlign.CENTER
TextAlign.RIGHT -> CanvasTextAlign.RIGHT
}
}
}
37 changes: 37 additions & 0 deletions core/src/jsTest/kotlin/org/isoron/platform/gui/HtmlCanvasTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.isoron.platform.gui

import org.w3c.dom.*

class HtmlCanvasTest(val canvas: HTMLCanvasElement) : CanvasTest.Platform {

override fun createCanvas(width: Int, height: Int): Canvas {
return HtmlCanvas(canvas)
}

override fun writePng(canvas: Canvas, filename: String) {
}

fun testDrawing() {
val test = CanvasTest(this)
test.testDrawing()
}
}
8 changes: 5 additions & 3 deletions core/src/jvmMain/kotlin/org/isoron/platform/gui/JavaCanvas.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.isoron.platform.io.*
import java.awt.*
import java.awt.RenderingHints.*
import java.awt.font.*
import java.awt.image.*
import kotlin.math.*

fun createFont(path: String): java.awt.Font {
Expand All @@ -34,15 +35,16 @@ private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf")
private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf")
private val FONT_AWESOME_FONT = createFont("fonts/FontAwesome.ttf")

class JavaCanvas(val g2d: Graphics2D,
val widthPx: Int,
val heightPx: Int,
class JavaCanvas(val image: BufferedImage,
val pixelScale: Double = 2.0) : Canvas {

private val frc = FontRenderContext(null, true, true)
private var fontSize = 12.0
private var font = Font.REGULAR
private var textAlign = TextAlign.CENTER
val widthPx = image.width
val heightPx = image.height
val g2d = image.createGraphics()

init {
g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
Expand Down
53 changes: 11 additions & 42 deletions core/src/jvmTest/kotlin/org/isoron/platform/JavaCanvasTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,50 +26,19 @@ import java.io.*
import javax.imageio.*


class JavaCanvasTest {
@Test
fun testDrawing() {
val image = BufferedImage(500, 400, BufferedImage.TYPE_INT_RGB)
val canvas = JavaCanvas(image.createGraphics(), 500, 400, pixelScale=1.0)

canvas.setColor(Color(0x303030))
canvas.fillRect(0.0, 0.0, 500.0, 400.0)

canvas.setColor(Color(0x606060))
canvas.setStrokeWidth(25.0)
canvas.drawRect(100.0, 100.0, 300.0, 200.0)

canvas.setColor(Color(0xFFFF00))
canvas.setStrokeWidth(1.0)
canvas.drawRect(0.0, 0.0, 100.0, 100.0)
canvas.fillCircle(50.0, 50.0, 30.0)
canvas.drawRect(0.0, 100.0, 100.0, 100.0)
canvas.fillArc(50.0, 150.0, 30.0, 90.0, 135.0)
canvas.drawRect(0.0, 200.0, 100.0, 100.0)
canvas.fillArc(50.0, 250.0, 30.0, 90.0, -135.0)
canvas.drawRect(0.0, 300.0, 100.0, 100.0)
canvas.fillArc(50.0, 350.0, 30.0, 45.0, 90.0)

canvas.setColor(Color(0xFF0000))
canvas.setStrokeWidth(2.0)
canvas.drawLine(0.0, 0.0, 500.0, 400.0)
canvas.drawLine(500.0, 0.0, 0.0, 400.0)
class JavaCanvasTest : CanvasTest.Platform {
private val commonTest = CanvasTest(this)

canvas.setFont(Font.BOLD)
canvas.setFontSize(50.0)
canvas.setColor(Color(0x00FF00))
canvas.setTextAlign(TextAlign.CENTER)
canvas.drawText("HELLO", 250.0, 100.0)

canvas.setTextAlign(TextAlign.RIGHT)
canvas.drawText("HELLO", 250.0, 150.0)

canvas.setTextAlign(TextAlign.LEFT)
canvas.drawText("HELLO", 250.0, 200.0)
@Test
fun testDrawing() = commonTest.testDrawing()

canvas.setFont(Font.FONT_AWESOME)
canvas.drawText(FontAwesome.CHECK, 250.0, 300.0)
override fun createCanvas(width: Int, height: Int): Canvas {
val image = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
return JavaCanvas(image, pixelScale=1.0)
}

ImageIO.write(image, "png", File("/tmp/JavaCanvasTest.png"))
override fun writePng(canvas: Canvas, filename: String) {
val javaCanvas = canvas as JavaCanvas
ImageIO.write(javaCanvas.image, "png", File("/tmp/JavaCanvasTest.png"))
}
}
2 changes: 1 addition & 1 deletion core/src/jvmTest/kotlin/org/isoron/uhabits/Base.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ open class BaseViewTest {
component: Component,
threshold: Double = 1e-3) {
val actual = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
val canvas = JavaCanvas(actual.createGraphics(), width, height)
val canvas = JavaCanvas(actual)
val expectedFile: JavaResourceFile
val actualPath = "/tmp/${expectedPath}"

Expand Down
2 changes: 1 addition & 1 deletion ios/Tests/Platform/IosCanvasTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import UIKit
class IosCanvasTest : XCTestCase {
func testDraw() {
UIGraphicsBeginImageContext(CGSize(width: 500, height: 400))

let canvas = IosCanvas(withBounds: CGRect(x: 0, y: 0, width: 500, height: 400))

canvas.setColor(color: Color(rgb: 0x303030))
canvas.fillRect(x: 0.0, y: 0.0, width: 500.0, height: 400.0)

Expand Down
Loading

0 comments on commit 5c402b5

Please sign in to comment.