<commit_before>/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.ui.graphics

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach

actual typealias NativeCanvas = android.graphics.Canvas

/**
 * Create a new Canvas instance that targets its drawing commands
 * to the provided [ImageBitmap]
 */
internal actual fun ActualCanvas(image: ImageBitmap): Canvas =
    AndroidCanvas().apply {
        internalCanvas = android.graphics.Canvas(image.asAndroidBitmap())
    }

fun Canvas(c: android.graphics.Canvas): Canvas =
    AndroidCanvas().apply { internalCanvas = c }

/**
 * Holder class that is used to issue scoped calls to a [Canvas] from the framework
 * equivalent canvas without having to allocate an object on each draw call
 */
class CanvasHolder {
    @PublishedApi internal val androidCanvas = AndroidCanvas()

    inline fun drawInto(targetCanvas: android.graphics.Canvas, block: Canvas.() -> Unit) {
        val previousCanvas = androidCanvas.internalCanvas
        androidCanvas.internalCanvas = targetCanvas
        androidCanvas.block()
        androidCanvas.internalCanvas = previousCanvas
    }
}

/**
 * Return an instance of the native primitive that implements the Canvas interface
 */
actual val Canvas.nativeCanvas: NativeCanvas
    get() = (this as AndroidCanvas).internalCanvas

// Stub canvas instance used to keep the internal canvas parameter non-null during its
// scoped usage and prevent unnecessary byte code null checks from being generated
private val EmptyCanvas = android.graphics.Canvas()

@PublishedApi internal class AndroidCanvas() : Canvas {

    // Keep the internal canvas as a var prevent having to allocate an AndroidCanvas
    // instance on each draw call
    @PublishedApi internal var internalCanvas: NativeCanvas = EmptyCanvas

    private val srcRect: android.graphics.Rect by lazy(LazyThreadSafetyMode.NONE) {
        android.graphics.Rect()
    }

    private val dstRect: android.graphics.Rect by lazy(LazyThreadSafetyMode.NONE) {
        android.graphics.Rect()
    }

    /**
     * @see Canvas.save
     */<commit_msg>Remove lazy overhead for Rects in AndroidCanvas<commit_after>/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.ui.graphics

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach

actual typealias NativeCanvas = android.graphics.Canvas

/**
 * Create a new Canvas instance that targets its drawing commands
 * to the provided [ImageBitmap]
 */
internal actual fun ActualCanvas(image: ImageBitmap): Canvas =
    AndroidCanvas().apply {
        internalCanvas = android.graphics.Canvas(image.asAndroidBitmap())
    }

fun Canvas(c: android.graphics.Canvas): Canvas =
    AndroidCanvas().apply { internalCanvas = c }

/**
 * Holder class that is used to issue scoped calls to a [Canvas] from the framework
 * equivalent canvas without having to allocate an object on each draw call
 */
class CanvasHolder {
    @PublishedApi internal val androidCanvas = AndroidCanvas()

    inline fun drawInto(targetCanvas: android.graphics.Canvas, block: Canvas.() -> Unit) {
        val previousCanvas = androidCanvas.internalCanvas
        androidCanvas.internalCanvas = targetCanvas
        androidCanvas.block()
        androidCanvas.internalCanvas = previousCanvas
    }
}

/**
 * Return an instance of the native primitive that implements the Canvas interface
 */
actual val Canvas.nativeCanvas: NativeCanvas
    get() = (this as AndroidCanvas).internalCanvas

// Stub canvas instance used to keep the internal canvas parameter non-null during its
// scoped usage and prevent unnecessary byte code null checks from being generated
private val EmptyCanvas = android.graphics.Canvas()

@PublishedApi internal class AndroidCanvas() : Canvas {

    // Keep the internal canvas as a var prevent having to allocate an AndroidCanvas
    // instance on each draw call
    @PublishedApi internal var internalCanvas: NativeCanvas = EmptyCanvas

    private val srcRect = android.graphics.Rect()

    private val dstRect = android.graphics.Rect()

    /**
     * @see Canvas.save
     */
{'fraction_non_alphanumeric': 0.07553306830502349, 'fraction_numerical': 0.0028912179255511385, 'mean_word_length': 3.851007887817704, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5665267', 'n_tokens_mistral': 1403, 'n_tokens_neox': 1368, 'n_words': 550}