Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
b73b3744
Unverified
Commit
b73b3744
authored
Oct 18, 2024
by
Artem Bobrov
Committed by
GitHub
Oct 18, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a new saveLayer method to Canvas (already exists in Skia) (#995)
Co-authored-by:
Artem Bobrov
<
artem.bobrov@jetbrains.com
>
parent
1bd3058d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
185 additions
and
7 deletions
+185
-7
Canvas.kt
skiko/src/commonMain/kotlin/org/jetbrains/skia/Canvas.kt
+86
-0
CanvasTest.kt
skiko/src/commonTest/kotlin/org/jetbrains/skia/CanvasTest.kt
+57
-7
Canvas.cc
skiko/src/jvmMain/cpp/common/Canvas.cc
+21
-0
Canvas.cc
skiko/src/nativeJsMain/cpp/Canvas.cc
+21
-0
No files found.
skiko/src/commonMain/kotlin/org/jetbrains/skia/Canvas.kt
View file @
b73b3744
...
@@ -1349,6 +1349,36 @@ open class Canvas internal constructor(ptr: NativePointer, managed: Boolean, int
...
@@ -1349,6 +1349,36 @@ open class Canvas internal constructor(ptr: NativePointer, managed: Boolean, int
}
}
}
}
fun
saveLayer
(
layerRec
:
SaveLayerRec
):
Int
{
return
try
{
Stats
.
onNativeCall
()
if
(
layerRec
.
bounds
!=
null
)
{
_nSaveLayerSaveLayerRecRect
(
_ptr
,
layerRec
.
bounds
.
left
,
layerRec
.
bounds
.
top
,
layerRec
.
bounds
.
right
,
layerRec
.
bounds
.
bottom
,
getPtr
(
layerRec
.
paint
),
getPtr
(
layerRec
.
backdrop
),
getPtr
(
layerRec
.
colorSpace
),
layerRec
.
saveLayerFlags
.
mask
)
}
else
{
_nSaveLayerSaveLayerRec
(
_ptr
,
getPtr
(
layerRec
.
paint
),
getPtr
(
layerRec
.
backdrop
),
getPtr
(
layerRec
.
colorSpace
),
layerRec
.
saveLayerFlags
.
mask
)
}
}
finally
{
reachabilityBarrier
(
this
)
reachabilityBarrier
(
layerRec
)
}
}
val
saveCount
:
Int
val
saveCount
:
Int
get
()
=
try
{
get
()
=
try
{
Stats
.
onNativeCall
()
Stats
.
onNativeCall
()
...
@@ -1369,6 +1399,39 @@ open class Canvas internal constructor(ptr: NativePointer, managed: Boolean, int
...
@@ -1369,6 +1399,39 @@ open class Canvas internal constructor(ptr: NativePointer, managed: Boolean, int
return
this
return
this
}
}
class
SaveLayerRec
(
val
bounds
:
Rect
?
=
null
,
val
paint
:
Paint
?
=
null
,
val
backdrop
:
ImageFilter
?
=
null
,
val
colorSpace
:
ColorSpace
?
=
null
,
val
saveLayerFlags
:
SaveLayerFlags
=
SaveLayerFlags
()
)
enum
class
SaveLayerFlagsSet
(
val
mask
:
Int
)
{
PreserveLCDText
(
1
shl
1
),
InitWithPrevious
(
1
shl
2
),
F16ColorType
(
1
shl
4
)
}
class
SaveLayerFlags
internal
constructor
(
internal
val
mask
:
Int
)
{
constructor
(
vararg
flagsSet
:
SaveLayerFlagsSet
)
:
this
(
flagsSet
.
fold
(
0
)
{
acc
,
flag
->
acc
or
flag
.
mask
})
operator
fun
contains
(
flag
:
SaveLayerFlagsSet
):
Boolean
=
(
mask
and
flag
.
mask
)
!=
0
override
fun
equals
(
other
:
Any
?):
Boolean
{
if
(
this
===
other
)
return
true
if
(
other
==
null
||
this
::
class
!=
other
::
class
)
return
false
other
as
SaveLayerFlags
return
mask
==
other
.
mask
}
override
fun
hashCode
():
Int
{
return
mask
}
}
private
object
_FinalizerHolder
{
private
object
_FinalizerHolder
{
val
PTR
=
Canvas_nGetFinalizer
()
val
PTR
=
Canvas_nGetFinalizer
()
}
}
...
@@ -1645,6 +1708,29 @@ private external fun _nSaveLayerRect(
...
@@ -1645,6 +1708,29 @@ private external fun _nSaveLayerRect(
paintPtr
:
NativePointer
paintPtr
:
NativePointer
):
Int
):
Int
@ExternalSymbolName
(
"org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRec"
)
@ModuleImport
(
"./skiko.mjs"
,
"org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRec"
)
private
external
fun
_nSaveLayerSaveLayerRec
(
ptr
:
NativePointer
,
paintPtr
:
NativePointer
,
backdropImageFilterPtr
:
NativePointer
,
colorSpacePtr
:
NativePointer
,
saveLayerFlags
:
Int
):
Int
@ExternalSymbolName
(
"org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRecRect"
)
@ModuleImport
(
"./skiko.mjs"
,
"org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRecRect"
)
private
external
fun
_nSaveLayerSaveLayerRecRect
(
ptr
:
NativePointer
,
left
:
Float
,
top
:
Float
,
right
:
Float
,
bottom
:
Float
,
paintPtr
:
NativePointer
,
backdropImageFilterPtr
:
NativePointer
,
colorSpacePtr
:
NativePointer
,
saveLayerFlags
:
Int
):
Int
@ExternalSymbolName
(
"org_jetbrains_skia_Canvas__1nGetSaveCount"
)
@ExternalSymbolName
(
"org_jetbrains_skia_Canvas__1nGetSaveCount"
)
@ModuleImport
(
"./skiko.mjs"
,
"org_jetbrains_skia_Canvas__1nGetSaveCount"
)
@ModuleImport
(
"./skiko.mjs"
,
"org_jetbrains_skia_Canvas__1nGetSaveCount"
)
...
...
skiko/src/commonTest/kotlin/org/jetbrains/skia/CanvasTest.kt
View file @
b73b3744
...
@@ -210,7 +210,7 @@ class CanvasTest {
...
@@ -210,7 +210,7 @@ class CanvasTest {
surface
.
canvas
.
drawBlackPixel
(
1
,
1
)
surface
.
canvas
.
drawBlackPixel
(
1
,
1
)
surface
.
assertPixelsMatch
(
surface
.
assertPixelsMatch
(
IntArray
(
16
){
index
->
IntArray
(
16
)
{
index
->
when
(
index
)
{
when
(
index
)
{
10
,
11
,
14
,
15
->
0
xff000000
.
toInt
()
10
,
11
,
14
,
15
->
0
xff000000
.
toInt
()
else
->
0
xffffffff
.
toInt
()
else
->
0
xffffffff
.
toInt
()
...
@@ -233,7 +233,7 @@ class CanvasTest {
...
@@ -233,7 +233,7 @@ class CanvasTest {
@Test
@Test
fun
testRotateXY
()
{
fun
testRotateXY
()
{
val
surface
=
whiteSurface
(
4
,
4
)
val
surface
=
whiteSurface
(
4
,
4
)
surface
.
canvas
.
rotate
(
deg
=
90f
,
x
=
2f
,
y
=
2f
)
surface
.
canvas
.
rotate
(
deg
=
90f
,
x
=
2f
,
y
=
2f
)
surface
.
canvas
.
drawBlackPixel
(
0
,
0
)
surface
.
canvas
.
drawBlackPixel
(
0
,
0
)
surface
.
assertSingleBlackPixelAt
(
3
,
0
)
surface
.
assertSingleBlackPixelAt
(
3
,
0
)
...
@@ -247,7 +247,7 @@ class CanvasTest {
...
@@ -247,7 +247,7 @@ class CanvasTest {
surface
.
canvas
.
drawBlackPixel
(
0
,
2
)
surface
.
canvas
.
drawBlackPixel
(
0
,
2
)
surface
.
assertPixelsMatch
(
surface
.
assertPixelsMatch
(
IntArray
(
16
){
index
->
IntArray
(
16
)
{
index
->
when
(
index
)
{
when
(
index
)
{
// Skewing skews the shape of the pixel itself, so it becomes a parallelogram
// Skewing skews the shape of the pixel itself, so it becomes a parallelogram
9
->
0
xff3f3f3f
.
toInt
()
9
->
0
xff3f3f3f
.
toInt
()
...
@@ -258,6 +258,56 @@ class CanvasTest {
...
@@ -258,6 +258,56 @@ class CanvasTest {
)
)
}
}
@Test
fun
testSaveLayerRecRect
()
{
val
surface
=
whiteSurface
(
5
,
5
)
surface
.
canvas
.
saveLayer
(
Canvas
.
SaveLayerRec
(
bounds
=
Rect
(
1f
,
1f
,
4f
,
4f
),
saveLayerFlags
=
Canvas
.
SaveLayerFlags
(
Canvas
.
SaveLayerFlagsSet
.
InitWithPrevious
)
)
)
val
black
=
Paint
().
also
{
it
.
setARGB
(
255
,
0
,
0
,
0
)
}
surface
.
canvas
.
drawRect
(
Rect
(
1f
,
1f
,
4f
,
4f
),
black
)
surface
.
canvas
.
restore
()
surface
.
assertPixelsMatch
(
intArrayOf
(
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
)
)
}
@Test
fun
testSaveLayerRec
()
{
val
surface
=
whiteSurface
(
5
,
5
)
surface
.
canvas
.
saveLayer
(
Canvas
.
SaveLayerRec
(
saveLayerFlags
=
Canvas
.
SaveLayerFlags
(
Canvas
.
SaveLayerFlagsSet
.
InitWithPrevious
)))
val
black
=
Paint
().
also
{
it
.
setARGB
(
255
,
0
,
0
,
0
)
}
surface
.
canvas
.
drawRect
(
Rect
(
1f
,
1f
,
4f
,
4f
),
black
)
surface
.
canvas
.
restore
()
surface
.
assertPixelsMatch
(
intArrayOf
(
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
BLACK
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
Color
.
WHITE
,
)
)
}
private
fun
whiteSurface
(
width
:
Int
,
height
:
Int
):
Surface
{
private
fun
whiteSurface
(
width
:
Int
,
height
:
Int
):
Surface
{
val
surface
=
Surface
.
makeRasterN32Premul
(
width
,
height
)
val
surface
=
Surface
.
makeRasterN32Premul
(
width
,
height
)
...
@@ -286,8 +336,8 @@ class CanvasTest {
...
@@ -286,8 +336,8 @@ class CanvasTest {
private
fun
Surface
.
assertSingleBlackPixelAt
(
x
:
Int
,
y
:
Int
)
{
private
fun
Surface
.
assertSingleBlackPixelAt
(
x
:
Int
,
y
:
Int
)
{
val
pixArray
=
IntArray
(
width
*
height
){
0
xffffffff
.
toInt
()
}
val
pixArray
=
IntArray
(
width
*
height
)
{
0
xffffffff
.
toInt
()
}
pixArray
[
y
*
width
+
x
]
=
0
xff000000
.
toInt
()
pixArray
[
y
*
width
+
x
]
=
0
xff000000
.
toInt
()
assertPixelsMatch
(
pixArray
)
assertPixelsMatch
(
pixArray
)
}
}
...
...
skiko/src/jvmMain/cpp/common/Canvas.cc
View file @
b73b3744
...
@@ -335,6 +335,27 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CanvasKt__1nSaveLayerR
...
@@ -335,6 +335,27 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CanvasKt__1nSaveLayerR
return
canvas
->
saveLayer
(
&
bounds
,
paint
);
return
canvas
->
saveLayer
(
&
bounds
,
paint
);
}
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_org_jetbrains_skia_CanvasKt__1nSaveLayerSaveLayerRec
(
JNIEnv
*
env
,
jclass
jclass
,
jlong
ptr
,
jlong
paintPtr
,
jlong
backdropImageFilterPtr
,
jlong
colorSpacePtr
,
jint
saveLayerFlags
)
{
SkCanvas
*
canvas
=
reinterpret_cast
<
SkCanvas
*>
(
static_cast
<
uintptr_t
>
(
ptr
));
SkPaint
*
paint
=
reinterpret_cast
<
SkPaint
*>
(
static_cast
<
uintptr_t
>
(
paintPtr
));
SkImageFilter
*
backdrop
=
reinterpret_cast
<
SkImageFilter
*>
(
backdropImageFilterPtr
);
SkColorSpace
*
colorSpace
=
reinterpret_cast
<
SkColorSpace
*>
(
colorSpacePtr
);
return
canvas
->
saveLayer
(
SkCanvas
::
SaveLayerRec
(
nullptr
,
paint
,
backdrop
,
colorSpace
,
saveLayerFlags
));
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_org_jetbrains_skia_CanvasKt__1nSaveLayerSaveLayerRecRect
(
JNIEnv
*
env
,
jclass
jclass
,
jlong
ptr
,
jfloat
left
,
jfloat
top
,
jfloat
right
,
jfloat
bottom
,
jlong
paintPtr
,
jlong
backdropImageFilterPtr
,
jlong
colorSpacePtr
,
jint
saveLayerFlags
)
{
SkCanvas
*
canvas
=
reinterpret_cast
<
SkCanvas
*>
(
static_cast
<
uintptr_t
>
(
ptr
));
SkRect
bounds
{
left
,
top
,
right
,
bottom
};
SkPaint
*
paint
=
reinterpret_cast
<
SkPaint
*>
(
static_cast
<
uintptr_t
>
(
paintPtr
));
SkImageFilter
*
backdrop
=
reinterpret_cast
<
SkImageFilter
*>
(
backdropImageFilterPtr
);
SkColorSpace
*
colorSpace
=
reinterpret_cast
<
SkColorSpace
*>
(
colorSpacePtr
);
return
canvas
->
saveLayer
(
SkCanvas
::
SaveLayerRec
(
&
bounds
,
paint
,
backdrop
,
colorSpace
,
saveLayerFlags
));
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_org_jetbrains_skia_CanvasKt__1nGetSaveCount
(
JNIEnv
*
env
,
jclass
jclass
,
jlong
ptr
)
{
extern
"C"
JNIEXPORT
jint
JNICALL
Java_org_jetbrains_skia_CanvasKt__1nGetSaveCount
(
JNIEnv
*
env
,
jclass
jclass
,
jlong
ptr
)
{
return
reinterpret_cast
<
SkCanvas
*>
(
static_cast
<
uintptr_t
>
(
ptr
))
->
getSaveCount
();
return
reinterpret_cast
<
SkCanvas
*>
(
static_cast
<
uintptr_t
>
(
ptr
))
->
getSaveCount
();
}
}
...
...
skiko/src/nativeJsMain/cpp/Canvas.cc
View file @
b73b3744
...
@@ -330,6 +330,27 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Canvas__1nSaveLayerRect
...
@@ -330,6 +330,27 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Canvas__1nSaveLayerRect
return
canvas
->
saveLayer
(
&
bounds
,
paint
);
return
canvas
->
saveLayer
(
&
bounds
,
paint
);
}
}
SKIKO_EXPORT
KInt
org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRec
(
KNativePointer
ptr
,
KNativePointer
paintPtr
,
KNativePointer
backdropImageFilterPtr
,
KNativePointer
colorSpacePtr
,
KInt
saveLayerFlags
)
{
SkCanvas
*
canvas
=
reinterpret_cast
<
SkCanvas
*>
((
ptr
));
SkPaint
*
paint
=
reinterpret_cast
<
SkPaint
*>
((
paintPtr
));
SkImageFilter
*
backdrop
=
reinterpret_cast
<
SkImageFilter
*>
(
backdropImageFilterPtr
);
SkColorSpace
*
colorSpace
=
reinterpret_cast
<
SkColorSpace
*>
(
colorSpacePtr
);
return
canvas
->
saveLayer
(
SkCanvas
::
SaveLayerRec
(
nullptr
,
paint
,
backdrop
,
colorSpace
,
saveLayerFlags
));
}
SKIKO_EXPORT
KInt
org_jetbrains_skia_Canvas__1nSaveLayerSaveLayerRecRect
(
KNativePointer
ptr
,
KFloat
left
,
KFloat
top
,
KFloat
right
,
KFloat
bottom
,
KNativePointer
paintPtr
,
KNativePointer
backdropImageFilterPtr
,
KNativePointer
colorSpacePtr
,
KInt
saveLayerFlags
)
{
SkCanvas
*
canvas
=
reinterpret_cast
<
SkCanvas
*>
((
ptr
));
SkRect
bounds
{
left
,
top
,
right
,
bottom
};
SkPaint
*
paint
=
reinterpret_cast
<
SkPaint
*>
((
paintPtr
));
SkImageFilter
*
backdrop
=
reinterpret_cast
<
SkImageFilter
*>
(
backdropImageFilterPtr
);
SkColorSpace
*
colorSpace
=
reinterpret_cast
<
SkColorSpace
*>
(
colorSpacePtr
);
return
canvas
->
saveLayer
(
SkCanvas
::
SaveLayerRec
(
&
bounds
,
paint
,
backdrop
,
colorSpace
,
saveLayerFlags
));
}
SKIKO_EXPORT
KInt
org_jetbrains_skia_Canvas__1nGetSaveCount
(
KNativePointer
ptr
)
{
SKIKO_EXPORT
KInt
org_jetbrains_skia_Canvas__1nGetSaveCount
(
KNativePointer
ptr
)
{
return
reinterpret_cast
<
SkCanvas
*>
((
ptr
))
->
getSaveCount
();
return
reinterpret_cast
<
SkCanvas
*>
((
ptr
))
->
getSaveCount
();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment