1
1
package com.opensource.svgaplayer.drawer
2
2
3
+ import android.annotation.TargetApi
3
4
import android.graphics.*
5
+ import android.os.Build
4
6
import android.text.BoringLayout
5
7
import android.text.StaticLayout
8
+ import android.widget.FrameLayout
6
9
import android.widget.ImageView
7
10
import com.opensource.svgaplayer.SVGADynamicEntity
8
11
import com.opensource.svgaplayer.SVGAVideoEntity
@@ -18,68 +21,134 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
18
21
private val drawTextCache: HashMap <String , Bitmap > = hashMapOf()
19
22
private val pathCache = PathCache ()
20
23
24
+ private var beginIndexList: Array <Boolean >? = null
25
+ private var endIndexList: Array <Boolean >? = null
26
+
27
+ @TargetApi(Build .VERSION_CODES .LOLLIPOP )
21
28
override fun drawFrame (canvas : Canvas , frameIndex : Int , scaleType : ImageView .ScaleType ) {
22
29
super .drawFrame(canvas,frameIndex, scaleType)
23
30
this .pathCache.onSizeChanged(canvas)
24
31
val sprites = requestFrameSprites(frameIndex)
25
32
val matteSprites = mutableMapOf<String , SVGADrawerSprite >()
26
-
27
- var isMatteing = false
28
-
33
+ var saveID = 0
34
+ beginIndexList = null
35
+ endIndexList = null
36
+
37
+ // Filte no matte layer
38
+ var hasMatteLayer = false
39
+ sprites.get(0 ).imageKey?.let {
40
+ if (it.endsWith(" .matte" )) {
41
+ hasMatteLayer = true
42
+ }
43
+ }
29
44
sprites.forEachIndexed { index, svgaDrawerSprite ->
30
45
46
+ val iimageKey = svgaDrawerSprite.imageKey
47
+ val mmatteKey = svgaDrawerSprite.matteKey
48
+
31
49
// save matte sprite
32
50
svgaDrawerSprite.imageKey?.let {
33
-
34
- // no matte
35
- sprites.get(0 ).imageKey?.let {
36
- if (! it.endsWith(" .matte" )) {
37
- drawSprite(svgaDrawerSprite, canvas, frameIndex)
38
- // continue
39
- return @forEachIndexed
40
- }
51
+ // / No matte layer included
52
+ if (! hasMatteLayer) {
53
+ // Normal sprite
54
+ drawSprite(svgaDrawerSprite, canvas, frameIndex)
55
+ // Continue
56
+ return @forEachIndexed
41
57
}
42
-
58
+ // / Cache matte sprite
43
59
if (it.endsWith(" .matte" )) {
44
60
matteSprites.put(it, svgaDrawerSprite)
45
- // continue
61
+ // Continue
46
62
return @forEachIndexed
47
63
}
48
64
}
49
-
50
- sprites.get(index - 1 )?.let { lastSprite ->
51
- if (isMatteing && (svgaDrawerSprite.matteKey == null || svgaDrawerSprite.matteKey != lastSprite.matteKey)) {
52
- isMatteing = false
53
-
54
- matteSprites.get(svgaDrawerSprite.matteKey)?.let {
55
- drawSprite(it, this .sharedValues.shareMatteCanvas(canvas.width, canvas.height), frameIndex)
56
-
57
- canvas.drawBitmap(this .sharedValues.sharedMatteBitmap(), 0f , 0f , this .sharedValues.shareMattePaint())
58
- canvas.restore()
59
- }
60
- }
61
- if (svgaDrawerSprite.matteKey != null && (lastSprite.matteKey == null || lastSprite.matteKey != svgaDrawerSprite.matteKey)) {
62
- isMatteing = true
63
- canvas.save()
64
- }
65
+ // / Is matte begin
66
+ if (isMatteBegin(index, sprites)) {
67
+ saveID = canvas.saveLayer(0f , 0f , canvas.width.toFloat(), canvas.height.toFloat(), null )
65
68
}
66
69
70
+ // / Normal matte
67
71
drawSprite(svgaDrawerSprite, canvas, frameIndex)
68
72
69
- // if current sprite is the last one and isMatteing
70
- if (isMatteing && index == sprites.count() - 1 ) {
73
+ // / Is matte end
74
+ if (isMatteEnd( index, sprites) ) {
71
75
matteSprites.get(svgaDrawerSprite.matteKey)?.let {
72
76
drawSprite(it, this .sharedValues.shareMatteCanvas(canvas.width, canvas.height), frameIndex)
73
-
74
77
canvas.drawBitmap(this .sharedValues.sharedMatteBitmap(), 0f , 0f , this .sharedValues.shareMattePaint())
75
- canvas.restore()
78
+ canvas.restoreToCount(saveID)
79
+ // Continue
80
+ return @forEachIndexed
76
81
}
77
82
}
78
-
79
83
}
80
84
playAudio(frameIndex)
81
85
}
82
86
87
+ private fun isMatteBegin (spriteIndex : Int , sprites : List <SVGADrawerSprite >): Boolean {
88
+ if (beginIndexList == null ) {
89
+ val boolArray = Array (sprites.count()){false }
90
+ sprites.forEachIndexed { index, svgaDrawerSprite ->
91
+ svgaDrawerSprite.imageKey?.let {
92
+ // / Filter matte sprite
93
+ if (it.endsWith(" .matte" )) {
94
+ // Continue
95
+ return @forEachIndexed
96
+ }
97
+ }
98
+ svgaDrawerSprite.matteKey?.let {
99
+ if (it.length > 0 ) {
100
+ sprites.get(index - 1 )?.let { lastSprite ->
101
+ if (lastSprite.matteKey == null || lastSprite.matteKey.length == 0 ) {
102
+ boolArray[index] = true
103
+ } else {
104
+ if (lastSprite.matteKey != svgaDrawerSprite.matteKey) {
105
+ boolArray[index] = true
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ beginIndexList = boolArray
113
+ }
114
+ return beginIndexList?.get(spriteIndex) ? : false
115
+ }
116
+
117
+ private fun isMatteEnd (spriteIndex : Int , sprites : List <SVGADrawerSprite >): Boolean {
118
+ if (endIndexList == null ) {
119
+ val boolArray = Array (sprites.count()){false }
120
+ sprites.forEachIndexed { index, svgaDrawerSprite ->
121
+ svgaDrawerSprite.imageKey?.let {
122
+ // / Filter matte sprite
123
+ if (it.endsWith(" .matte" )) {
124
+ // Continue
125
+ return @forEachIndexed
126
+ }
127
+ }
128
+ svgaDrawerSprite.matteKey?.let {
129
+ if (it.length > 0 ) {
130
+ // Last one
131
+ if (index == sprites.count() - 1 ) {
132
+ boolArray[index] = true
133
+ } else {
134
+ sprites.get(index + 1 )?.let { nextSprite ->
135
+ if (nextSprite.matteKey == null || nextSprite.matteKey.length == 0 ) {
136
+ boolArray[index] = true
137
+ } else {
138
+ if (nextSprite.matteKey != svgaDrawerSprite.matteKey) {
139
+ boolArray[index] = true
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ endIndexList = boolArray
148
+ }
149
+ return endIndexList?.get(spriteIndex) ? : false
150
+ }
151
+
83
152
private fun playAudio (frameIndex : Int ) {
84
153
this .videoItem.audios.forEach { audio ->
85
154
if (audio.startFrame == frameIndex) {
@@ -371,7 +440,7 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
371
440
372
441
private val shareMattePaint = Paint ()
373
442
private var shareMatteCanvas: Canvas ? = null
374
- private var sharedMatteBitmap = Bitmap .createBitmap( 1 , 1 , Bitmap . Config . ALPHA_8 )
443
+ private var sharedMatteBitmap: Bitmap ? = null
375
444
376
445
fun sharedPaint (): Paint {
377
446
sharedPaint.reset()
@@ -404,17 +473,18 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
404
473
}
405
474
406
475
fun sharedMatteBitmap (): Bitmap {
407
- return sharedMatteBitmap
476
+ return sharedMatteBitmap as Bitmap
408
477
}
409
478
410
479
fun shareMatteCanvas (width : Int , height : Int ): Canvas {
411
480
if (shareMatteCanvas == null ) {
412
481
sharedMatteBitmap = Bitmap .createBitmap(width, height, Bitmap .Config .ALPHA_8 )
413
- shareMatteCanvas = Canvas (sharedMatteBitmap)
482
+ // shareMatteCanvas = Canvas(sharedMatteBitmap)
414
483
}
415
- val matteCanvas = shareMatteCanvas as Canvas
416
- matteCanvas.drawColor(Color .TRANSPARENT , PorterDuff .Mode .CLEAR );
417
- return matteCanvas
484
+ // val matteCanvas = shareMatteCanvas as Canvas
485
+ // matteCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
486
+ // return matteCanvas
487
+ return Canvas (sharedMatteBitmap)
418
488
}
419
489
}
420
490
0 commit comments