11package com.opensource.svgaplayer.drawer
22
3+ import android.annotation.TargetApi
34import android.graphics.*
5+ import android.os.Build
46import android.text.BoringLayout
57import android.text.StaticLayout
8+ import android.widget.FrameLayout
69import android.widget.ImageView
710import com.opensource.svgaplayer.SVGADynamicEntity
811import com.opensource.svgaplayer.SVGAVideoEntity
@@ -18,68 +21,134 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
1821 private val drawTextCache: HashMap <String , Bitmap > = hashMapOf()
1922 private val pathCache = PathCache ()
2023
24+ private var beginIndexList: Array <Boolean >? = null
25+ private var endIndexList: Array <Boolean >? = null
26+
27+ @TargetApi(Build .VERSION_CODES .LOLLIPOP )
2128 override fun drawFrame (canvas : Canvas , frameIndex : Int , scaleType : ImageView .ScaleType ) {
2229 super .drawFrame(canvas,frameIndex, scaleType)
2330 this .pathCache.onSizeChanged(canvas)
2431 val sprites = requestFrameSprites(frameIndex)
2532 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+ }
2944 sprites.forEachIndexed { index, svgaDrawerSprite ->
3045
46+ val iimageKey = svgaDrawerSprite.imageKey
47+ val mmatteKey = svgaDrawerSprite.matteKey
48+
3149 // save matte sprite
3250 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
4157 }
42-
58+ // / Cache matte sprite
4359 if (it.endsWith(" .matte" )) {
4460 matteSprites.put(it, svgaDrawerSprite)
45- // continue
61+ // Continue
4662 return @forEachIndexed
4763 }
4864 }
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 )
6568 }
6669
70+ // / Normal matte
6771 drawSprite(svgaDrawerSprite, canvas, frameIndex)
6872
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) ) {
7175 matteSprites.get(svgaDrawerSprite.matteKey)?.let {
7276 drawSprite(it, this .sharedValues.shareMatteCanvas(canvas.width, canvas.height), frameIndex)
73-
7477 canvas.drawBitmap(this .sharedValues.sharedMatteBitmap(), 0f , 0f , this .sharedValues.shareMattePaint())
75- canvas.restore()
78+ canvas.restoreToCount(saveID)
79+ // Continue
80+ return @forEachIndexed
7681 }
7782 }
78-
7983 }
8084 playAudio(frameIndex)
8185 }
8286
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+
83152 private fun playAudio (frameIndex : Int ) {
84153 this .videoItem.audios.forEach { audio ->
85154 if (audio.startFrame == frameIndex) {
@@ -371,7 +440,7 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
371440
372441 private val shareMattePaint = Paint ()
373442 private var shareMatteCanvas: Canvas ? = null
374- private var sharedMatteBitmap = Bitmap .createBitmap( 1 , 1 , Bitmap . Config . ALPHA_8 )
443+ private var sharedMatteBitmap: Bitmap ? = null
375444
376445 fun sharedPaint (): Paint {
377446 sharedPaint.reset()
@@ -404,17 +473,18 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
404473 }
405474
406475 fun sharedMatteBitmap (): Bitmap {
407- return sharedMatteBitmap
476+ return sharedMatteBitmap as Bitmap
408477 }
409478
410479 fun shareMatteCanvas (width : Int , height : Int ): Canvas {
411480 if (shareMatteCanvas == null ) {
412481 sharedMatteBitmap = Bitmap .createBitmap(width, height, Bitmap .Config .ALPHA_8 )
413- shareMatteCanvas = Canvas (sharedMatteBitmap)
482+ // shareMatteCanvas = Canvas(sharedMatteBitmap)
414483 }
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)
418488 }
419489 }
420490
0 commit comments