appending .pro to package name

This commit is contained in:
tibbi
2018-11-04 20:19:58 +01:00
parent 1e48edfe39
commit c9fa997fc0
24 changed files with 59 additions and 93 deletions

View File

@ -0,0 +1,41 @@
package com.simplemobiletools.draw.pro.models
import android.os.Parcel
import android.os.Parcelable
import android.view.View
import java.util.*
internal class MyParcelable : View.BaseSavedState {
var paths = LinkedHashMap<MyPath, PaintOptions>()
constructor(superState: Parcelable) : super(superState)
constructor(parcel: Parcel) : super(parcel) {
val size = parcel.readInt()
for (i in 0 until size) {
val key = parcel.readSerializable() as MyPath
val paintOptions = PaintOptions(parcel.readInt(), parcel.readFloat(), parcel.readInt() == 1)
paths[key] = paintOptions
}
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(paths.size)
for ((path, paintOptions) in paths) {
out.writeSerializable(path)
out.writeInt(paintOptions.color)
out.writeFloat(paintOptions.strokeWidth)
out.writeInt(if (paintOptions.isEraser) 1 else 0)
}
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<MyParcelable> = object : Parcelable.Creator<MyParcelable> {
override fun createFromParcel(source: Parcel) = MyParcelable(source)
override fun newArray(size: Int) = arrayOf<MyParcelable>()
}
}
}

View File

@ -0,0 +1,82 @@
package com.simplemobiletools.draw.pro.models
import android.app.Activity
import android.graphics.Path
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.draw.pro.R
import com.simplemobiletools.draw.pro.actions.Action
import com.simplemobiletools.draw.pro.actions.Line
import com.simplemobiletools.draw.pro.actions.Move
import com.simplemobiletools.draw.pro.actions.Quad
import java.io.ObjectInputStream
import java.io.Serializable
import java.security.InvalidParameterException
import java.util.*
// https://stackoverflow.com/a/8127953
class MyPath : Path(), Serializable {
val actions = LinkedList<Action>()
private fun readObject(inputStream: ObjectInputStream) {
inputStream.defaultReadObject()
val copiedActions = actions.map { it }
copiedActions.forEach {
it.perform(this)
}
}
fun readObject(pathData: String, activity: Activity) {
val tokens = pathData.split("\\s+".toRegex()).dropLastWhile(String::isEmpty).toTypedArray()
var i = 0
try {
while (i < tokens.size) {
when (tokens[i][0]) {
'M' -> addAction(Move(tokens[i]))
'L' -> addAction(Line(tokens[i]))
'Q' -> {
// Quad actions are of the following form:
// "Qx1,y1 x2,y2"
// Since we split the tokens by whitespace, we need to join them again
if (i + 1 >= tokens.size)
throw InvalidParameterException("Error parsing the data for a Quad.")
addAction(Quad(tokens[i] + " " + tokens[i + 1]))
++i
}
}
++i
}
} catch (e: Exception) {
activity.toast(R.string.unknown_error_occurred)
}
}
override fun reset() {
actions.clear()
super.reset()
}
private fun addAction(action: Action) {
when (action) {
is Move -> moveTo(action.x, action.y)
is Line -> lineTo(action.x, action.y)
is Quad -> quadTo(action.x1, action.y1, action.x2, action.y2)
}
}
override fun moveTo(x: Float, y: Float) {
actions.add(Move(x, y))
super.moveTo(x, y)
}
override fun lineTo(x: Float, y: Float) {
actions.add(Line(x, y))
super.lineTo(x, y)
}
override fun quadTo(x1: Float, y1: Float, x2: Float, y2: Float) {
actions.add(Quad(x1, y1, x2, y2))
super.quadTo(x1, y1, x2, y2)
}
}

View File

@ -0,0 +1,7 @@
package com.simplemobiletools.draw.pro.models
import android.graphics.Color
data class PaintOptions(var color: Int = Color.BLACK, var strokeWidth: Float = 5f, var isEraser: Boolean = false) {
fun getColorToExport() = if (isEraser) "none" else "#${Integer.toHexString(color).substring(2)}"
}

View File

@ -0,0 +1,141 @@
package com.simplemobiletools.draw.pro.models
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.sax.RootElement
import android.util.Xml
import com.simplemobiletools.commons.extensions.getFileOutputStream
import com.simplemobiletools.commons.extensions.getFilenameFromPath
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.draw.pro.R
import com.simplemobiletools.draw.pro.activities.MainActivity
import com.simplemobiletools.draw.pro.activities.SimpleActivity
import com.simplemobiletools.draw.pro.views.MyCanvas
import java.io.*
import java.util.*
object Svg {
fun saveSvg(activity: SimpleActivity, path: String, canvas: MyCanvas) {
val backgroundColor = (canvas.background as ColorDrawable).color
activity.getFileOutputStream(FileDirItem(path, path.getFilenameFromPath()), true) {
if (it != null) {
val writer = BufferedWriter(OutputStreamWriter(it))
writeSvg(writer, backgroundColor, canvas.mPaths, canvas.width, canvas.height)
writer.close()
activity.toast(R.string.file_saved)
} else {
activity.toast(R.string.unknown_error_occurred)
}
}
}
private fun writeSvg(writer: Writer, backgroundColor: Int, paths: Map<MyPath, PaintOptions>, width: Int, height: Int) {
writer.apply {
write("<svg width=\"$width\" height=\"$height\" xmlns=\"http://www.w3.org/2000/svg\">")
write("<rect width=\"$width\" height=\"$height\" fill=\"#${Integer.toHexString(backgroundColor).substring(2)}\"/>")
for ((key, value) in paths) {
writePath(this, key, value)
}
write("</svg>")
}
}
private fun writePath(writer: Writer, path: MyPath, options: PaintOptions) {
writer.apply {
write("<path d=\"")
path.actions.forEach {
it.perform(this)
write(" ")
}
write("\" fill=\"none\" stroke=\"")
write(options.getColorToExport())
write("\" stroke-width=\"")
write(options.strokeWidth.toString())
write("\" stroke-linecap=\"round\"/>")
}
}
fun loadSvg(activity: MainActivity, fileOrUri: Any, canvas: MyCanvas) {
val svg = parseSvg(activity, fileOrUri)
canvas.clearCanvas()
activity.setBackgroundColor(svg.background!!.color)
svg.paths.forEach {
val path = MyPath()
path.readObject(it.data, activity)
val options = PaintOptions(it.color, it.strokeWidth, it.isEraser)
canvas.addPath(path, options)
}
}
private fun parseSvg(activity: MainActivity, fileOrUri: Any): SSvg {
var inputStream: InputStream? = null
val svg = SSvg()
try {
inputStream = when (fileOrUri) {
is File -> FileInputStream(fileOrUri)
is Uri -> activity.contentResolver.openInputStream(fileOrUri)
else -> null
}
// Actual parsing (http://stackoverflow.com/a/4828765)
val ns = "http://www.w3.org/2000/svg"
val root = RootElement(ns, "svg")
val rectElement = root.getChild(ns, "rect")
val pathElement = root.getChild(ns, "path")
root.setStartElementListener { attributes ->
val width = attributes.getValue("width").toInt()
val height = attributes.getValue("height").toInt()
svg.setSize(width, height)
}
rectElement.setStartElementListener { attributes ->
val width = attributes.getValue("width").toInt()
val height = attributes.getValue("height").toInt()
val color = Color.parseColor(attributes.getValue("fill"))
if (svg.background != null)
throw UnsupportedOperationException("Unsupported SVG, should only have one <rect>.")
svg.background = SRect(width, height, color)
}
pathElement.setStartElementListener { attributes ->
val d = attributes.getValue("d")
val width = attributes.getValue("stroke-width").toFloat()
val stroke = attributes.getValue("stroke")
val isEraser = stroke == "none"
val color = if (isEraser) 0 else Color.parseColor(stroke)
svg.paths.add(SPath(d, color, width, isEraser))
}
Xml.parse(inputStream, Xml.Encoding.UTF_8, root.contentHandler)
} finally {
inputStream?.close()
}
return svg
}
private class SSvg : Serializable {
var background: SRect? = null
val paths: ArrayList<SPath> = ArrayList()
private var width = 0
private var height = 0
internal fun setSize(w: Int, h: Int) {
width = w
height = h
}
}
private class SRect(val width: Int, val height: Int, val color: Int) : Serializable
private class SPath(var data: String, var color: Int, var strokeWidth: Float, var isEraser: Boolean) : Serializable
}