diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt index 22fc61c708..6a05f3988c 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt @@ -1,18 +1,11 @@ package org.catrobat.paintroid.ui.zoomwindow +import android.graphics.PointF import android.graphics.Bitmap -import android.graphics.Color -import android.graphics.Paint import android.graphics.Rect -import android.graphics.PorterDuffXfermode -import android.graphics.PorterDuff -import android.graphics.BitmapFactory -import android.graphics.BitmapShader import android.graphics.Canvas -import android.graphics.Shader -import android.graphics.Matrix -import android.graphics.PointF -import android.graphics.RectF +import android.graphics.Paint +import android.graphics.Path import android.view.View import android.widget.ImageView import android.widget.RelativeLayout @@ -24,7 +17,6 @@ import org.catrobat.paintroid.tools.Tool import org.catrobat.paintroid.tools.ToolReference import org.catrobat.paintroid.tools.ToolType import org.catrobat.paintroid.tools.Workspace -import kotlin.math.roundToInt class DefaultZoomWindowController (val activity: MainActivity, @@ -34,82 +26,64 @@ class DefaultZoomWindowController val sharedPreferences: UserPreferences) : ZoomWindowController { - private val canvasRect = Rect() - private val checkeredPattern = Paint() - private val framePaint = Paint() - + private val zoomWindow: RelativeLayout = activity.findViewById(R.id.pocketpaint_zoom_window) + private val zoomWindowImage: ImageView = activity.findViewById(R.id.pocketpaint_zoom_window_image) + private var coordinates: PointF? = null private val zoomWindowDiameter = activity.resources.getDimensionPixelSize(R.dimen.pocketpaint_zoom_window_diameter) + private var zoomWindowBitmap: Bitmap? = null - private val chequeredBackgroundBitmap = - Bitmap.createBitmap(layerModel.width, layerModel.height, Bitmap.Config.ARGB_8888) - - private val greyBackgroundBitmap = - Bitmap.createBitmap( - layerModel.width + zoomWindowDiameter, - layerModel.height + zoomWindowDiameter, - Bitmap.Config.ARGB_8888 - ) - - private val backgroundBitmap = - Bitmap.createBitmap( - layerModel.width + zoomWindowDiameter, - layerModel.height + zoomWindowDiameter, - Bitmap.Config.ARGB_8888 - ) - - init { - framePaint.color = Color.BLACK - framePaint.style = Paint.Style.STROKE - framePaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC) - val checkerboard = - BitmapFactory.decodeResource(activity.resources, R.drawable.pocketpaint_checkeredbg) - val shader = BitmapShader(checkerboard, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT) - checkeredPattern.shader = shader - checkeredPattern.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC) - - val backgroundCanvas: Canvas? = chequeredBackgroundBitmap?.let { Canvas(it) } - - canvasRect.set(0, 0, layerModel.width, layerModel.height) - - backgroundCanvas?.drawRect(canvasRect, checkeredPattern) - backgroundCanvas?.drawRect(canvasRect, framePaint) - - val greyBackgroundCanvas = Canvas(greyBackgroundBitmap) - greyBackgroundCanvas.drawColor( - activity.resources.getColor(R.color.pocketpaint_main_drawing_surface_background) - ) - - val canvasBackground = Canvas(backgroundBitmap) - - canvasBackground.drawBitmap(greyBackgroundBitmap, Matrix(), null) - canvasBackground.drawBitmap( - chequeredBackgroundBitmap, zoomWindowDiameter / 2f, zoomWindowDiameter / 2f, null) + override fun setBitmap(bitmap: Bitmap?) { + zoomWindowImage.setImageBitmap(coordinates?.let { cropBitmap(bitmap, it) }) + zoomWindowBitmap = bitmap } - private val zoomWindow: RelativeLayout = - activity.findViewById(R.id.pocketpaint_zoom_window) - private val zoomWindowImage: ImageView = - activity.findViewById(R.id.pocketpaint_zoom_window_image) - private var zoomWindowBitmap: Bitmap? = null - private var coordinates: PointF? = null + override fun getBitmap(): Bitmap? = zoomWindowBitmap + + private fun cropBitmap(bitmap: Bitmap?, coordinates: PointF): Bitmap? { + if (bitmap == null) return null + + val radius = getSizeOfZoomWindow() / 2 + val startX: Int = (coordinates.x - radius).toInt() + val startY: Int = (coordinates.y - radius).toInt() + + val croppedBitmap: Bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888) + val canvas = Canvas(croppedBitmap) + + val paint = Paint().apply { + isAntiAlias = true + } + + val path = Path().apply { + addCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), Path.Direction.CW) + } + + canvas.clipPath(path) + + bitmap.let { + canvas.drawBitmap( + it, + Rect(startX, startY, startX + radius * 2, startY + radius * 2), + Rect(0, 0, radius * 2, radius * 2), + paint + ) + } + + return croppedBitmap + } + + private fun getSizeOfZoomWindow(): Int { + val zoomIndex = (sharedPreferences.preferenceZoomWindowZoomPercentage - initialZoomValue) / zoomPercentStepValue + return zoomWindowDiameter - zoomIndex * zoomFactor + } override fun show(drawingSurfaceCoordinates: PointF, displayCoordinates: PointF) { if (checkIfToolCompatibleWithZoomWindow(toolReference.tool) == Constants.COMPATIBLE && isPointOnCanvas(drawingSurfaceCoordinates.x, drawingSurfaceCoordinates.y)) { setZoomWindowPosition(displayCoordinates) zoomWindow.visibility = View.VISIBLE - zoomWindowImage.setImageBitmap(cropBitmap(workspace.bitmapOfAllLayers, drawingSurfaceCoordinates)) } } - override fun dismiss() { - zoomWindow.visibility = View.GONE - } - - override fun dismissOnPinch() { - zoomWindow.visibility = View.GONE - } - override fun onMove(drawingSurfaceCoordinates: PointF, displayCoordinates: PointF) { if (checkIfToolCompatibleWithZoomWindow(toolReference.tool) == Constants.COMPATIBLE) { setZoomWindowPosition(displayCoordinates) @@ -124,6 +98,17 @@ class DefaultZoomWindowController } } + private fun isPointOnCanvas(pointX: Float, pointY: Float): Boolean = + pointX > 0 && pointX < layerModel.width && pointY > 0 && pointY < layerModel.height + + override fun dismiss() { + zoomWindow.visibility = View.GONE + } + + override fun dismissOnPinch() { + zoomWindow.visibility = View.GONE + } + private fun setZoomWindowPosition(displayCoordinates: PointF) { if (shouldBeInTheRight(coordinates = displayCoordinates)) { setLayoutAlignment(right = true) @@ -132,23 +117,9 @@ class DefaultZoomWindowController } } - override fun setBitmap(bitmap: Bitmap?) { - zoomWindowImage.setImageBitmap(coordinates?.let { cropBitmap(bitmap, it) }) - zoomWindowBitmap = bitmap - } - - override fun getBitmap(): Bitmap? = zoomWindowBitmap - - private fun isPointOnCanvas(pointX: Float, pointY: Float): Boolean = - pointX > 0 && pointX < layerModel.width && pointY > 0 && pointY < layerModel.height - - private fun shouldBeInTheRight(coordinates: PointF): Boolean { - if (coordinates.x < activity.resources.displayMetrics.widthPixels / 2 && - coordinates.y < activity.resources.displayMetrics.heightPixels / 2) { - return true - } - return false - } + private fun shouldBeInTheRight(coordinates: PointF): Boolean = + coordinates.x < activity.resources.displayMetrics.widthPixels / 2 && + coordinates.y < activity.resources.displayMetrics.heightPixels / 2 private fun setLayoutAlignment(right: Boolean) { val params: RelativeLayout.LayoutParams = @@ -163,60 +134,6 @@ class DefaultZoomWindowController zoomWindowImage.layoutParams = params } - private fun cropBitmap(bitmap: Bitmap?, coordinates: PointF): Bitmap? { - - val bitmapWithBackground: Bitmap? = mergeBackground(bitmap) - - val startX: Int = coordinates.x.roundToInt() + zoomWindowDiameter / 2 - getSizeOfZoomWindow() / 2 - val startY: Int = coordinates.y.roundToInt() + zoomWindowDiameter / 2 - getSizeOfZoomWindow() / 2 - - val croppedBitmap: Bitmap? = - Bitmap.createBitmap(getSizeOfZoomWindow(), getSizeOfZoomWindow(), Bitmap.Config.ARGB_8888) - - val canvas: Canvas? = croppedBitmap?.let { Canvas(it) } - - val paint = Paint() - paint.isAntiAlias = true - - val rect = Rect(0, 0, getSizeOfZoomWindow(), getSizeOfZoomWindow()) - val rectF = RectF(rect) - - canvas?.drawOval(rectF, paint) - - paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) - - bitmapWithBackground?.let { - canvas?.drawBitmap(it, - Rect(startX, startY, startX + getSizeOfZoomWindow(), startY + getSizeOfZoomWindow()), - rect, - paint - ) } - - return croppedBitmap - } - - private fun mergeBackground(bitmap: Bitmap?): Bitmap? { - - val bitmapOverlay = - Bitmap.createBitmap( - layerModel.width + zoomWindowDiameter, - layerModel.height + zoomWindowDiameter, - Bitmap.Config.ARGB_8888 - ) - val canvas = Canvas(bitmapOverlay) - - canvas.drawBitmap(backgroundBitmap, Matrix(), null) - - bitmap?.let { canvas.drawBitmap(it, zoomWindowDiameter / 2f, zoomWindowDiameter / 2f, null) } - - return bitmapOverlay - } - - private fun getSizeOfZoomWindow(): Int { - val zoomIndex = (sharedPreferences.preferenceZoomWindowZoomPercentage - initialZoomValue) / zoomPercentStepValue - return zoomWindowDiameter - zoomIndex * zoomFactor - } - override fun checkIfToolCompatibleWithZoomWindow(tool: Tool?): Constants { return when (tool?.toolType?.name) { ToolType.LINE.name,