1
1
package com.opensource.svgaplayer
2
2
3
3
import android.graphics.*
4
+ import android.text.StaticLayout
4
5
import android.widget.ImageView
5
6
6
7
@@ -17,6 +18,7 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
17
18
private val sharedPath = Path ()
18
19
private val sharedPath2 = Path ()
19
20
private val sharedContentTransform = Matrix ()
21
+ private val textBitmapCache: HashMap <String , Bitmap > = hashMapOf()
20
22
21
23
override fun drawFrame (frameIndex : Int , scaleType : ImageView .ScaleType ) {
22
24
super .drawFrame(frameIndex, scaleType)
@@ -45,7 +47,8 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
45
47
46
48
private fun drawImage (sprite : SVGADrawerSprite ) {
47
49
val canvas = this .canvas ? : return
48
- (dynamicItem.dynamicImage[sprite.imageKey] ? : videoItem.images[sprite.imageKey])?.let {
50
+ val imageKey = sprite.imageKey ? : return
51
+ (dynamicItem.dynamicImage[imageKey] ? : videoItem.images[imageKey])?.let {
49
52
sharedPaint.reset()
50
53
sharedPaint.isAntiAlias = videoItem.antiAlias
51
54
sharedPaint.isFilterBitmap = videoItem.antiAlias
@@ -72,40 +75,64 @@ class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
72
75
}
73
76
74
77
private fun drawText (drawingBitmap : Bitmap , sprite : SVGADrawerSprite ) {
78
+ if (dynamicItem.isTextDirty) {
79
+ this .textBitmapCache.clear()
80
+ dynamicItem.isTextDirty = false
81
+ }
75
82
val canvas = this .canvas ? : return
76
- dynamicItem.dynamicText[sprite.imageKey]?.let { drawingText ->
77
- dynamicItem.dynamicTextPaint[sprite.imageKey]?.let { drawingTextPaint ->
78
- val textBitmap = Bitmap .createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap .Config .ARGB_8888 )
79
- val textCanvas = Canvas (textBitmap)
80
- drawingTextPaint.isAntiAlias = true
81
- val bounds = Rect ()
82
- drawingTextPaint.getTextBounds(drawingText, 0 , drawingText.length, bounds)
83
- val x = (drawingBitmap.width - bounds.width()) / 2.0
84
- val targetRectTop = 0
85
- val targetRectBottom = drawingBitmap.height
86
- val y = (targetRectBottom + targetRectTop - drawingTextPaint.fontMetrics.bottom - drawingTextPaint.fontMetrics.top) / 2
87
- textCanvas.drawText(drawingText, x.toFloat(), y, drawingTextPaint)
88
-
89
- sharedPaint.reset()
90
- sharedPaint.isAntiAlias = videoItem.antiAlias
91
- if (sprite.frameEntity.maskPath != null ) {
92
- val maskPath = sprite.frameEntity.maskPath ? : return @let
93
- canvas.save()
94
- canvas.concat(sharedContentTransform)
95
- canvas.clipRect(0 , 0 , drawingBitmap.width, drawingBitmap.height)
96
- val bitmapShader = BitmapShader (textBitmap, Shader .TileMode .REPEAT , Shader .TileMode .REPEAT )
97
- sharedPaint.shader = bitmapShader
98
- sharedPath.reset()
99
- maskPath.buildPath(sharedPath)
100
- canvas.drawPath(sharedPath, sharedPaint)
101
- canvas.restore()
102
- }
103
- else {
104
- sharedPaint.isFilterBitmap = videoItem.antiAlias
105
- canvas.drawBitmap(textBitmap, sharedContentTransform, sharedPaint)
83
+ val imageKey = sprite.imageKey ? : return
84
+ var textBitmap: Bitmap ? = null
85
+ dynamicItem.dynamicText[imageKey]?.let { drawingText ->
86
+ dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
87
+ textBitmapCache[imageKey]?.let {
88
+ textBitmap = it
89
+ } ? : kotlin.run {
90
+ textBitmap = Bitmap .createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap .Config .ARGB_8888 )
91
+ val textCanvas = Canvas (textBitmap)
92
+ drawingTextPaint.isAntiAlias = true
93
+ val bounds = Rect ()
94
+ drawingTextPaint.getTextBounds(drawingText, 0 , drawingText.length, bounds)
95
+ val x = (drawingBitmap.width - bounds.width()) / 2.0
96
+ val targetRectTop = 0
97
+ val targetRectBottom = drawingBitmap.height
98
+ val y = (targetRectBottom + targetRectTop - drawingTextPaint.fontMetrics.bottom - drawingTextPaint.fontMetrics.top) / 2
99
+ textCanvas.drawText(drawingText, x.toFloat(), y, drawingTextPaint)
100
+ textBitmapCache.put(imageKey, textBitmap as Bitmap )
106
101
}
107
102
}
108
103
}
104
+ dynamicItem.dynamicLayoutText[imageKey]?.let {
105
+ textBitmapCache[imageKey]?.let {
106
+ textBitmap = it
107
+ } ? : kotlin.run {
108
+ var layout = StaticLayout (it.text, 0 , it.text.length, it.paint, drawingBitmap.width, it.alignment, it.spacingMultiplier, it.spacingAdd, false )
109
+ textBitmap = Bitmap .createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap .Config .ARGB_8888 )
110
+ val textCanvas = Canvas (textBitmap)
111
+ textCanvas.translate(0f , ((drawingBitmap.height - layout.height) / 2 ).toFloat())
112
+ layout.draw(textCanvas)
113
+ textBitmapCache.put(imageKey, textBitmap as Bitmap )
114
+ }
115
+ }
116
+ textBitmap?.let { textBitmap ->
117
+ sharedPaint.reset()
118
+ sharedPaint.isAntiAlias = videoItem.antiAlias
119
+ if (sprite.frameEntity.maskPath != null ) {
120
+ val maskPath = sprite.frameEntity.maskPath ? : return @let
121
+ canvas.save()
122
+ canvas.concat(sharedContentTransform)
123
+ canvas.clipRect(0 , 0 , drawingBitmap.width, drawingBitmap.height)
124
+ val bitmapShader = BitmapShader (textBitmap, Shader .TileMode .REPEAT , Shader .TileMode .REPEAT )
125
+ sharedPaint.shader = bitmapShader
126
+ sharedPath.reset()
127
+ maskPath.buildPath(sharedPath)
128
+ canvas.drawPath(sharedPath, sharedPaint)
129
+ canvas.restore()
130
+ }
131
+ else {
132
+ sharedPaint.isFilterBitmap = videoItem.antiAlias
133
+ canvas.drawBitmap(textBitmap, sharedContentTransform, sharedPaint)
134
+ }
135
+ }
109
136
}
110
137
111
138
private fun drawShape (sprite : SVGADrawerSprite ) {
0 commit comments