Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import androidx.compose.ui.input.key.type
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import androidx.compose.ui.window.PopupProperties
Expand All @@ -75,7 +76,7 @@ internal fun DefaultOpenContextMenu(

Popup(
properties = PopupProperties(focusable = true),
onDismissRequest = { session.close() },
onDismissRequest = session::close,
popupPositionProvider = popupPositionProvider,
onKeyEvent = {
if (it.type == KeyEventType.KeyDown) {
Expand Down Expand Up @@ -105,7 +106,7 @@ internal fun DefaultOpenContextMenu(
.width(IntrinsicSize.Max)
.verticalScroll(rememberScrollState())
) {
components.forEach { component ->
components.fastForEach { component ->
when (component) {
is TextContextMenuSeparator ->
MenuSeparator(colors.textColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.isSpecified
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.ResolvedTextDirection
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
Expand Down Expand Up @@ -113,28 +115,28 @@ internal fun SelectionHandleIcon(
isLeft: Boolean,
) {
val density = LocalDensity.current
val handleColor = LocalTextSelectionColors.current.handleColor
val lineHeightDp = with(density) { lineHeight.toDp() }
Spacer(
modifier
.size(
width = (PADDING + RADIUS) * 2,
height = RADIUS * 2 + PADDING + lineHeightDp
)
.drawSelectionHandle(iconVisible, lineHeight, isLeft)
.drawSelectionHandle(iconVisible, lineHeight, isLeft, handleColor, density)
)
}

internal fun Modifier.drawSelectionHandle(
iconVisible: () -> Boolean,
lineHeight: Float,
isLeft: Boolean
): Modifier = composed {
val density = LocalDensity.current
isLeft: Boolean,
handleColor: Color,
density: Density
): Modifier = drawWithCache {
val paddingPx = with(density) { PADDING.toPx() }
val radiusPx = with(density) { RADIUS.toPx() }
val thicknessPx = with(density) { THICKNESS.toPx() }
val handleColor = LocalTextSelectionColors.current.handleColor
this.drawWithCache {
onDrawWithContent {
drawContent()
if (!iconVisible()) return@onDrawWithContent
Expand All @@ -158,7 +160,6 @@ internal fun Modifier.drawSelectionHandle(
)
}
}
}

@Composable
internal fun HandlePopup(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@
package androidx.compose.ui.graphics

import androidx.compose.runtime.InternalComposeApi
import org.jetbrains.skia.ClipMode as SkClipMode
import org.jetbrains.skia.RRect as SkRRect
import org.jetbrains.skia.Rect as SkRect
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach
import org.jetbrains.skia.ClipMode as SkClipMode
import org.jetbrains.skia.CubicResampler
import org.jetbrains.skia.FilterMipmap
import org.jetbrains.skia.FilterMode
Expand Down Expand Up @@ -112,7 +109,14 @@ internal class SkiaBackedCanvas(val skia: org.jetbrains.skia.Canvas) : Canvas {

override fun clipRect(left: Float, top: Float, right: Float, bottom: Float, clipOp: ClipOp) {
val antiAlias = true
skia.clipRect(SkRect.makeLTRB(left, top, right, bottom), clipOp.toSkia(), antiAlias)
skia.clipRect(
left = left,
top = top,
right = right,
bottom = bottom,
mode = clipOp.toSkia(),
antiAlias = antiAlias
)
}

override fun clipPath(path: Path, clipOp: ClipOp) {
Expand All @@ -125,7 +129,7 @@ internal class SkiaBackedCanvas(val skia: org.jetbrains.skia.Canvas) : Canvas {
}

override fun drawRect(left: Float, top: Float, right: Float, bottom: Float, paint: Paint) {
skia.drawRect(SkRect.makeLTRB(left, top, right, bottom), paint.skia)
skia.drawRect(left = left, top = top, right = right, bottom = bottom, paint = paint.skia)
}

override fun drawRoundRect(
Expand All @@ -138,20 +142,17 @@ internal class SkiaBackedCanvas(val skia: org.jetbrains.skia.Canvas) : Canvas {
paint: Paint
) {
skia.drawRRect(
SkRRect.makeLTRB(
left,
top,
right,
bottom,
radiusX,
radiusY
),
paint.skia
left = left,
top = top,
right = right,
bottom = bottom,
radii = floatArrayOf(radiusX, radiusY),
paint = paint.skia
)
}

override fun drawOval(left: Float, top: Float, right: Float, bottom: Float, paint: Paint) {
skia.drawOval(SkRect.makeLTRB(left, top, right, bottom), paint.skia)
skia.drawOval(left = left, top = top, right = right, bottom = bottom, paint = paint.skia)
}

override fun drawCircle(center: Offset, radius: Float, paint: Paint) {
Expand Down Expand Up @@ -185,8 +186,18 @@ internal class SkiaBackedCanvas(val skia: org.jetbrains.skia.Canvas) : Canvas {
}

override fun drawImage(image: ImageBitmap, topLeftOffset: Offset, paint: Paint) {
val size = Size(image.width.toFloat(), image.height.toFloat())
drawImageRect(image, Offset.Zero, size, topLeftOffset, size, paint)
drawImageRect(
image,
0f,
0f,
image.width.toFloat(),
image.height.toFloat(),
topLeftOffset.x,
topLeftOffset.y,
image.width.toFloat(),
image.height.toFloat(),
paint
)
}

override fun drawImageRect(
Expand All @@ -198,41 +209,45 @@ internal class SkiaBackedCanvas(val skia: org.jetbrains.skia.Canvas) : Canvas {
paint: Paint
) {
drawImageRect(
image,
Offset(srcOffset.x.toFloat(), srcOffset.y.toFloat()),
Size(srcSize.width.toFloat(), srcSize.height.toFloat()),
Offset(dstOffset.x.toFloat(), dstOffset.y.toFloat()),
Size(dstSize.width.toFloat(), dstSize.height.toFloat()),
paint
image = image,
srcLeft = srcOffset.x.toFloat(),
srcTop = srcOffset.y.toFloat(),
srcRight = srcSize.width.toFloat(),
srcBottom = srcSize.height.toFloat(),
dstLeft = dstOffset.x.toFloat(),
dstTop = dstOffset.y.toFloat(),
dstRight = dstSize.width.toFloat(),
dstBottom = dstSize.height.toFloat(),
paint = paint
)
}

// TODO(demin): probably this method should be in the common Canvas
private fun drawImageRect(
image: ImageBitmap,
srcOffset: Offset,
srcSize: Size,
dstOffset: Offset,
dstSize: Size,
srcLeft: Float,
srcTop: Float,
srcRight: Float,
srcBottom: Float,
dstLeft: Float,
dstTop: Float,
dstRight: Float,
dstBottom: Float,
paint: Paint
) {
val bitmap = image.asSkiaBitmap()

Image.makeFromBitmap(bitmap).use { skiaImage ->
skia.drawImageRect(
skiaImage,
SkRect.makeXYWH(
srcOffset.x,
srcOffset.y,
srcSize.width,
srcSize.height
),
SkRect.makeXYWH(
dstOffset.x,
dstOffset.y,
dstSize.width,
dstSize.height
),
srcLeft,
srcTop,
srcRight,
srcBottom,
dstLeft,
dstTop,
dstRight,
dstBottom,
paint.filterQuality.toSkia(),
paint.skia,
true
Expand Down