@@ -10,69 +10,74 @@ import android.widget.ImageView
10
10
11
11
class SVGACanvasDrawer (videoItem : SVGAVideoEntity , val dynamicItem : SVGADynamicEntity ) : SGVADrawer(videoItem) {
12
12
13
- var canvas: Canvas ? = null
14
- var scaleEntity: ScaleEntity = ScaleEntity ()
15
-
13
+ private var canvasW = 0
14
+ private var canvasH = 0
16
15
private val sharedPaint = Paint ()
17
16
private val sharedPath = Path ()
18
17
private val sharedPath2 = Path ()
19
- private val sharedContentTransform = Matrix ()
18
+ private val sharedShapeMatrix= Matrix ()
19
+ private val sharedFrameMatrix= Matrix ()
20
+ private val sharedPathMap = HashMap <SVGAVideoShapeEntity ,Path >()
21
+
22
+ override fun drawFrame (canvas : Canvas , frameIndex : Int , scaleType : ImageView .ScaleType ) {
23
+ super .drawFrame(canvas,frameIndex, scaleType)
24
+ resetCachePath(canvas)
20
25
21
- override fun drawFrame (frameIndex : Int , scaleType : ImageView .ScaleType ) {
22
- super .drawFrame(frameIndex, scaleType)
23
26
val sprites = requestFrameSprites(frameIndex)
24
- performScaleType(scaleType)
25
27
sprites.forEach {
26
- drawSprite(it)
28
+ drawSprite(it,canvas )
27
29
}
28
30
}
29
31
30
- private fun enableScaleEntity (){
31
- sharedContentTransform.reset()
32
- sharedContentTransform.postScale(scaleEntity.scaleFx, scaleEntity.scaleFy)
33
- sharedContentTransform.postTranslate(scaleEntity.tranFx, scaleEntity.tranFy)
32
+ private fun resetCachePath (canvas : Canvas ){
33
+ if (canvasW != canvas.width || canvasH != canvas.height){
34
+ sharedPathMap.clear()
35
+ }
36
+ canvasW = canvas.width
37
+ canvasH = canvas.height
34
38
}
35
39
36
- private fun performScaleType (scaleType : ImageView .ScaleType ) {
37
- val canvas = this .canvas ? : return
38
- scaleEntity.performScaleType(canvas.width.toFloat(),canvas.height.toFloat(),videoItem.videoSize.width.toFloat(),videoItem.videoSize.height.toFloat(),scaleType)
40
+ private fun resetShareMatrix (transform : Matrix ){
41
+ sharedFrameMatrix.reset()
42
+ sharedFrameMatrix.postScale(scaleEntity.scaleFx, scaleEntity.scaleFy)
43
+ sharedFrameMatrix.postTranslate(scaleEntity.tranFx, scaleEntity.tranFy)
44
+ sharedFrameMatrix.preConcat(transform)
39
45
}
40
46
41
- private fun drawSprite (sprite : SVGADrawerSprite ) {
42
- drawImage(sprite)
43
- drawShape(sprite)
47
+ private fun drawSprite (sprite : SVGADrawerSprite , canvas : Canvas ) {
48
+ drawImage(sprite, canvas )
49
+ drawShape(sprite, canvas )
44
50
}
45
51
46
- private fun drawImage (sprite : SVGADrawerSprite ) {
47
- val canvas = this .canvas ? : return
52
+ private fun drawImage (sprite : SVGADrawerSprite , canvas : Canvas ) {
48
53
(dynamicItem.dynamicImage[sprite.imageKey] ? : videoItem.images[sprite.imageKey])?.let {
54
+ resetShareMatrix(sprite.frameEntity.transform)
55
+
49
56
sharedPaint.reset()
50
57
sharedPaint.isAntiAlias = videoItem.antiAlias
51
58
sharedPaint.isFilterBitmap = videoItem.antiAlias
52
59
sharedPaint.alpha = (sprite.frameEntity.alpha * 255 ).toInt()
53
- enableScaleEntity()
54
- sharedContentTransform.preConcat(sprite.frameEntity.transform)
60
+
55
61
if (sprite.frameEntity.maskPath != null ) {
56
62
val maskPath = sprite.frameEntity.maskPath ? : return @let
57
63
canvas.save()
58
64
sharedPath.reset()
59
65
maskPath.buildPath(sharedPath)
60
- sharedPath.transform(sharedContentTransform )
66
+ sharedPath.transform(sharedFrameMatrix )
61
67
canvas.clipPath(sharedPath)
62
- sharedContentTransform .preScale((sprite.frameEntity.layout.width / it.width).toFloat(), (sprite.frameEntity.layout.width / it.width).toFloat())
63
- canvas.drawBitmap(it, sharedContentTransform , sharedPaint)
68
+ sharedFrameMatrix .preScale((sprite.frameEntity.layout.width / it.width).toFloat(), (sprite.frameEntity.layout.width / it.width).toFloat())
69
+ canvas.drawBitmap(it, sharedFrameMatrix , sharedPaint)
64
70
canvas.restore()
65
71
}
66
72
else {
67
- sharedContentTransform .preScale((sprite.frameEntity.layout.width / it.width).toFloat(), (sprite.frameEntity.layout.width / it.width).toFloat())
68
- canvas.drawBitmap(it, sharedContentTransform , sharedPaint)
73
+ sharedFrameMatrix .preScale((sprite.frameEntity.layout.width / it.width).toFloat(), (sprite.frameEntity.layout.width / it.width).toFloat())
74
+ canvas.drawBitmap(it, sharedFrameMatrix , sharedPaint)
69
75
}
70
- drawText(it, sprite)
76
+ drawText(canvas, it, sprite)
71
77
}
72
78
}
73
79
74
- private fun drawText (drawingBitmap : Bitmap , sprite : SVGADrawerSprite ) {
75
- val canvas = this .canvas ? : return
80
+ private fun drawText (canvas : Canvas , drawingBitmap : Bitmap , sprite : SVGADrawerSprite ) {
76
81
dynamicItem.dynamicText[sprite.imageKey]?.let { drawingText ->
77
82
dynamicItem.dynamicTextPaint[sprite.imageKey]?.let { drawingTextPaint ->
78
83
val textBitmap = Bitmap .createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap .Config .ARGB_8888 )
@@ -91,7 +96,7 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
91
96
if (sprite.frameEntity.maskPath != null ) {
92
97
val maskPath = sprite.frameEntity.maskPath ? : return @let
93
98
canvas.save()
94
- canvas.concat(sharedContentTransform )
99
+ canvas.concat(sharedFrameMatrix )
95
100
canvas.clipRect(0 , 0 , drawingBitmap.width, drawingBitmap.height)
96
101
val bitmapShader = BitmapShader (textBitmap, Shader .TileMode .REPEAT , Shader .TileMode .REPEAT )
97
102
sharedPaint.shader = bitmapShader
@@ -102,63 +107,72 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
102
107
}
103
108
else {
104
109
sharedPaint.isFilterBitmap = videoItem.antiAlias
105
- canvas.drawBitmap(textBitmap, sharedContentTransform , sharedPaint)
110
+ canvas.drawBitmap(textBitmap, sharedFrameMatrix , sharedPaint)
106
111
}
107
112
}
108
113
}
109
114
}
110
115
111
- private fun drawShape (sprite : SVGADrawerSprite ) {
112
- val canvas = this .canvas ? : return
113
- enableScaleEntity()
114
- sharedContentTransform.preConcat(sprite.frameEntity.transform)
116
+ private fun drawShape (sprite : SVGADrawerSprite , canvas : Canvas ) {
117
+ resetShareMatrix(sprite.frameEntity.transform)
115
118
sprite.frameEntity.shapes.forEach { shape ->
116
- sharedPath.reset()
117
119
shape.buildPath()
118
120
shape.shapePath?.let {
119
- sharedPath.addPath(it)
120
- }
121
- if (! sharedPath.isEmpty) {
122
- sharedPath.transform(sharedContentTransform)
123
121
sharedPaint.reset()
124
122
sharedPaint.isAntiAlias = videoItem.antiAlias
125
123
sharedPaint.alpha = (sprite.frameEntity.alpha * 255 ).toInt()
124
+
125
+ if (! sharedPathMap.containsKey(shape)){
126
+ sharedShapeMatrix.reset()
127
+ shape.transform?.let {
128
+ sharedShapeMatrix.postConcat(it)
129
+ }
130
+ sharedShapeMatrix.postConcat(sharedFrameMatrix)
131
+
132
+ val path = Path ()
133
+ path.set(shape.shapePath)
134
+ path.transform(sharedShapeMatrix)
135
+ sharedPathMap.put(shape,path)
136
+ }
137
+
126
138
shape.styles?.fill?.let {
127
139
if (it != 0x00000000 ) {
128
140
sharedPaint.color = it
129
141
if (sprite.frameEntity.maskPath != = null ) canvas.save()
130
142
sprite.frameEntity.maskPath?.let { maskPath ->
131
143
sharedPath2.reset()
132
144
maskPath.buildPath(sharedPath2)
133
- sharedPath2.transform(this .sharedContentTransform )
145
+ sharedPath2.transform(this .sharedFrameMatrix )
134
146
canvas.clipPath(sharedPath2)
135
147
}
136
- canvas.drawPath(sharedPath , sharedPaint)
148
+ canvas.drawPath(sharedPathMap.get(shape) , sharedPaint)
137
149
if (sprite.frameEntity.maskPath != = null ) canvas.restore()
138
150
}
139
151
}
152
+
140
153
shape.styles?.strokeWidth?.let {
141
154
if (it > 0 ) {
142
155
resetShapeStrokePaint(shape)
143
156
if (sprite.frameEntity.maskPath != = null ) canvas.save()
144
157
sprite.frameEntity.maskPath?.let { maskPath ->
145
158
sharedPath2.reset()
146
159
maskPath.buildPath(sharedPath2)
147
- sharedPath2.transform(this .sharedContentTransform )
160
+ sharedPath2.transform(this .sharedFrameMatrix )
148
161
canvas.clipPath(sharedPath2)
149
162
}
150
- canvas.drawPath(sharedPath , sharedPaint)
163
+ canvas.drawPath(sharedPathMap.get(shape) , sharedPaint)
151
164
if (sprite.frameEntity.maskPath != = null ) canvas.restore()
152
165
}
153
166
}
154
167
}
168
+
155
169
}
156
170
}
157
171
158
172
private val tValues = FloatArray (16 )
159
173
160
174
private fun requestScale (): Float {
161
- this .sharedContentTransform .getValues(tValues)
175
+ this .sharedFrameMatrix .getValues(tValues)
162
176
if (tValues[0 ] == 0f ) {
163
177
return 0f
164
178
}
@@ -190,7 +204,7 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
190
204
shape.styles?.stroke?.let {
191
205
sharedPaint.color = it
192
206
}
193
-
207
+
194
208
val scale = requestScale()
195
209
shape.styles?.strokeWidth?.let {
196
210
sharedPaint.strokeWidth = it * scale
@@ -213,7 +227,7 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
213
227
sharedPaint.strokeMiter = it.toFloat() * scale
214
228
}
215
229
shape.styles?.lineDash?.let {
216
- if (it.size == 3 && it[0 ] > 0 && it[1 ] > 0 ) {
230
+ if (it.size == 3 && ( it[0 ] > 0 || it[1 ] > 0 ) ) {
217
231
sharedPaint.pathEffect = DashPathEffect (floatArrayOf(
218
232
(if (it[0 ] < 1.0f ) 1.0f else it[0 ]) * scale,
219
233
(if (it[1 ] < 0.1f ) 0.1f else it[1 ]) * scale
0 commit comments