Skip to content

Commit

Permalink
Merge pull request Catrobat#1109 from CodeChamp-SS/PAINTROID-426
Browse files Browse the repository at this point in the history
PAINTROID-426 fixed very high frequency crash in the Smudge Tool
  • Loading branch information
ThorstenBandel committed May 31, 2022
2 parents 8abd3d6 + 268a175 commit b3a4287
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class LayerPresenter(

fun resetMergeColor(layerPosition: Int) {
if (adapter != null && adapter?.getViewHolderAt(layerPosition) != null) {
if (adapter?.getViewHolderAt(layerPosition)!!.isSelected()) {
if (adapter?.getViewHolderAt(layerPosition)?.isSelected() == true) {
adapter?.getViewHolderAt(layerPosition)?.setSelected()
} else {
adapter?.getViewHolderAt(layerPosition)?.setDeselected()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ import org.catrobat.paintroid.common.CREATE_FILE_DEFAULT
import org.catrobat.paintroid.common.LOAD_IMAGE_CATROID
import org.catrobat.paintroid.common.LOAD_IMAGE_DEFAULT
import org.catrobat.paintroid.common.LOAD_IMAGE_IMPORT_PNG
import org.catrobat.paintroid.common.MainActivityConstants.PermissionRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.ActivityRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.CreateFileRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.LoadImageRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.PermissionRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.SaveImageRequestCode
import org.catrobat.paintroid.common.MainActivityConstants.ActivityRequestCode
import org.catrobat.paintroid.common.PERMISSION_EXTERNAL_STORAGE_SAVE
import org.catrobat.paintroid.common.PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_FINISH
import org.catrobat.paintroid.common.PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW
Expand Down Expand Up @@ -293,7 +293,8 @@ open class MainActivityPresenter(
FileIO.fileType = FileIO.FileType.PNG
FileIO.isCatrobatImage = false
FileIO.deleteTempFile(internalMemoryPath)
val initCommand = commandFactory.createInitCommand(metrics.widthPixels, metrics.heightPixels)
val initCommand =
commandFactory.createInitCommand(metrics.widthPixels, metrics.heightPixels)
commandManager.setInitialStateCommand(initCommand)
commandManager.reset()
}
Expand Down Expand Up @@ -885,7 +886,7 @@ open class MainActivityPresenter(
if (bottomBarViewHolder.isVisible) {
bottomBarViewHolder.hide()
} else {
if (!layerAdapter!!.presenter.getLayerItem(workspace.currentLayerIndex).isVisible) {
if (layerAdapter?.presenter?.getLayerItem(workspace.currentLayerIndex)?.isVisible == false) {
navigator.showToast(R.string.no_tools_on_hidden_layer, Toast.LENGTH_SHORT)
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,16 +169,14 @@ open class BrushTool(
return false
}

val distance = sqrt(
(
(coordinate.x - initialEventCoordinate!!.x) *
(coordinate.x - initialEventCoordinate!!.x) +
(coordinate.y - initialEventCoordinate!!.y)
).toDouble()
)
val speed = distance / drawTime
var distance: Double? = null
initialEventCoordinate?.apply {
distance =
sqrt(((coordinate.x - x) * (coordinate.x - x) + (coordinate.y - y) * (coordinate.y - y)).toDouble())
}
val speed = distance?.div(drawTime)

if (!smoothing || speed < threshold) {
if (!smoothing || speed != null && speed < threshold) {
val command = commandFactory.createPathCommand(bitmapPaint, pathToDraw)
commandManager.addCommand(command)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.catrobat.paintroid.tools.common.CommonBrushChangedListener
import org.catrobat.paintroid.tools.common.CommonBrushPreviewListener
import org.catrobat.paintroid.tools.options.SmudgeToolOptionsView
import org.catrobat.paintroid.tools.options.ToolOptionsViewController
import kotlin.math.sqrt

const val PERCENT_100 = 100f
const val BITMAP_ROTATION_FACTOR = -0.0f
Expand Down Expand Up @@ -114,12 +115,14 @@ class SmudgeTool(
Canvas(it).apply {
translate(-coordinate.x + maxSmudgeSize / 2f, -coordinate.y + maxSmudgeSize / 2f)
rotate(BITMAP_ROTATION_FACTOR, coordinate.x, coordinate.y)
drawBitmap(layerBitmap!!, 0f, 0f, null)
layerBitmap?.let { bitmap ->
drawBitmap(bitmap, 0f, 0f, null)
}
}
}

if (toolPaint.strokeCap == Paint.Cap.ROUND) {
currentBitmap = getBitmapClippedCircle(currentBitmap!!)
if (toolPaint.strokeCap == Paint.Cap.ROUND) {
currentBitmap = getBitmapClippedCircle(it)
}
}

if (!currentBitmapHasColor()) {
Expand All @@ -129,35 +132,37 @@ class SmudgeTool(
}

prevPoint = PointF(coordinate.x, coordinate.y)
pointArray.add(PointF(prevPoint!!.x, prevPoint!!.y))
prevPoint?.apply {
pointArray.add(PointF(x, y))
}

return true
}

override fun handleMove(coordinate: PointF?): Boolean {
coordinate ?: return false

if (currentBitmap != null) {
if (pressure < DRAW_THRESHOLD) { // Needed to stop drawing preview when bitmap becomes too transparent. Has no effect on final drawing.
return false
}

val x = coordinate.x - prevPoint!!.x
val y = coordinate.y - prevPoint!!.y
prevPoint?.apply {
val x1 = coordinate.x - x
val y1 = coordinate.y - y

val distance = kotlin.math.floor(kotlin.math.sqrt(x * x + y * y) / DISTANCE_SMOOTHING)
val xInterval = x / distance
val yInterval = y / distance
val distance = (sqrt(x1 * x1 + y1 * y1) / DISTANCE_SMOOTHING).toInt()
val xInterval = x1 / distance
val yInterval = y1 / distance

var i = 0
while (i < distance) {
prevPoint!!.x += xInterval
prevPoint!!.y += yInterval
repeat(distance) {
x += xInterval
y += yInterval

pressure -= PRESSURE_UPDATE_STEP
pressure -= PRESSURE_UPDATE_STEP

pointArray.add(PointF(prevPoint!!.x, prevPoint!!.y))

i++
pointArray.add(PointF(x, y))
}
}
return true
} else {
Expand All @@ -183,10 +188,12 @@ class SmudgeTool(
}

private fun currentBitmapHasColor(): Boolean {
for (x in 0 until currentBitmap!!.width) {
for (y in 0 until currentBitmap!!.height) {
if (currentBitmap!!.getPixel(x, y) != 0) {
return true
currentBitmap?.apply {
for (x in 0 until width) {
for (y in 0 until height) {
if (getPixel(x, y) != 0) {
return true
}
}
}
}
Expand All @@ -195,15 +202,17 @@ class SmudgeTool(

override fun handleUp(coordinate: PointF?): Boolean {
coordinate ?: return false
if (!pointArray.isEmpty() && currentBitmap != null) {
val command = commandFactory.createSmudgePathCommand(
currentBitmap!!,
pointArray,
maxPressure,
maxSmudgeSize,
minSmudgeSize
)
commandManager.addCommand(command)
if (pointArray.isNotEmpty() && currentBitmap != null) {
currentBitmap?.let {
val command = commandFactory.createSmudgePathCommand(
it,
pointArray,
maxPressure,
maxSmudgeSize,
minSmudgeSize
)
commandManager.addCommand(command)
}

numOfPointsOnPath = if (numOfPointsOnPath < 0) {
pointArray.size
Expand Down Expand Up @@ -235,7 +244,7 @@ class SmudgeTool(
var pressure = maxPressure
val colorMatrix = ColorMatrix()
val paint = Paint()
var bitmap = currentBitmap!!.copy(Bitmap.Config.ARGB_8888, false)
var bitmap = currentBitmap?.copy(Bitmap.Config.ARGB_8888, false)

pointPath.forEach {
colorMatrix.setScale(1f, 1f, 1f, pressure)
Expand All @@ -248,25 +257,29 @@ class SmudgeTool(
)

Canvas(newBitmap).apply {
drawBitmap(bitmap, 0f, 0f, paint)
bitmap?.let { currentBitmap ->
drawBitmap(currentBitmap, 0f, 0f, paint)
}
}

bitmap.recycle()
bitmap?.recycle()
bitmap = newBitmap

val rect = RectF(-size / 2f, -size / 2f, size / 2f, size / 2f)
with(canvas) {
save()
clipRect(0, 0, workspace.width, workspace.height)
translate(it.x, it.y)
drawBitmap(bitmap, null, rect, Paint(Paint.DITHER_FLAG))
bitmap?.let { currentBitmap ->
drawBitmap(currentBitmap, null, rect, Paint(Paint.DITHER_FLAG))
}
restore()
}
size -= step
pressure -= PRESSURE_UPDATE_STEP
}

bitmap.recycle()
bitmap?.recycle()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ class LayerAdapter(val presenter: LayerContracts.Presenter) : BaseAdapter(), Lay
val dragHandle = localConvertView?.findViewById<AppCompatImageView>(R.id.pocketpaint_layer_drag_handle)
dragHandle?.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> presenter.onStartDragging(position, localConvertView!!)
MotionEvent.ACTION_DOWN -> localConvertView?.let {
presenter.onStartDragging(position, it)
}
MotionEvent.ACTION_UP -> presenter.onStopDragging()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,16 @@ class AlphaSlider(
}

private fun moveTrackersIfNeeded(event: MotionEvent): Boolean {
if (startTouchPoint == null) {
return false
}
var update = true
val startX = startTouchPoint!!.x
val startY = startTouchPoint!!.y
if (alphaRectangle.contains(startX.toFloat(), startY.toFloat())) {
alphaValue = pointToAlpha(event.x.toInt())
} else {
update = false
var update = false
startTouchPoint?.apply {
update = true
val startX = x
val startY = y
if (alphaRectangle.contains(startX.toFloat(), startY.toFloat())) {
alphaValue = pointToAlpha(event.x.toInt())
} else {
update = false
}
}
return update
}
Expand Down

0 comments on commit b3a4287

Please sign in to comment.