private void DrawTextGlyphs(DocumentData documentData, Matrix3X3 parentMatrix, Font font, BitmapCanvas canvas) { var fontScale = (float)documentData.Size / 100; var parentScale = Utils.GetScale(parentMatrix); var text = documentData.Text; for (var i = 0; i < text.Length; i++) { var c = text[i]; var characterHash = FontCharacter.HashFor(c, font.Family, font.Style); if (!_composition.Characters.TryGetValue(characterHash, out var character)) { // Something is wrong. Potentially, they didn't export the text as a glyph. continue; } DrawCharacterAsGlyph(character, parentMatrix, fontScale, documentData, canvas); var tx = (float)character.Width * fontScale * _composition.DpScale * parentScale; // Add tracking var tracking = documentData.Tracking / 10f; if (_trackingAnimation?.Value != null) { tracking += _trackingAnimation.Value.Value; } tx += tracking * parentScale; canvas.Translate(tx, 0); } }
private void DrawTextWithFont(DocumentData documentData, Font font, Matrix3X3 parentMatrix, BitmapCanvas canvas) { var parentScale = Utils.GetScale(parentMatrix); var typeface = _lottieDrawable.GetTypeface(font.Family, font.Style); if (typeface == null) { return; } var text = documentData.Text; var textDelegate = _lottieDrawable.TextDelegate; if (textDelegate != null) { text = textDelegate.GetTextInternal(text); } _fillPaint.Typeface = typeface; _fillPaint.TextSize = documentData.Size * _composition.DpScale; _strokePaint.Typeface = _fillPaint.Typeface; _strokePaint.TextSize = _fillPaint.TextSize; for (var i = 0; i < text.Length; i++) { var character = text[i]; var size = DrawCharacterFromFont(character, documentData, canvas); // Add tracking var tracking = documentData.Tracking / 10f; if (_trackingAnimation?.Value != null) { tracking += _trackingAnimation.Value.Value; } var tx = (float)size.Width + tracking * parentScale; canvas.Translate(tx, 0); } }
//public int Opacity //{ // get // { // return PixelFormat.TRANSLUCENT; // } //} private void CanvasControlOnDraw(ICanvasAnimatedControl canvasControl, CanvasAnimatedDrawEventArgs args) { lock (this) { using (_bitmapCanvas.CreateSession(canvasControl.Device, canvasControl.Size.Width, canvasControl.Size.Height, args.DrawingSession)) { _bitmapCanvas.Clear(Colors.Transparent); LottieLog.BeginSection("Drawable.Draw"); if (_compositionLayer == null) { return; } var scale = _scale; float extraScale = 1f; float maxScale = GetMaxScale(_bitmapCanvas); if (scale > maxScale) { scale = maxScale; extraScale = _scale / scale; } if (extraScale > 1) { // This is a bit tricky... // We can't draw on a canvas larger than ViewConfiguration.get(context).getScaledMaximumDrawingCacheSize() // which works out to be roughly the size of the screen because Android can't generate a // bitmap large enough to render to. // As a result, we cap the scale such that it will never be wider/taller than the screen // and then only render in the top left corner of the canvas. We then use extraScale // to scale up the rest of the scale. However, since we rendered the animation to the top // left corner, we need to scale up and translate the canvas to zoom in on the top left // corner. _bitmapCanvas.Save(); float halfWidth = (float)_composition.Bounds.Width / 2f; float halfHeight = (float)_composition.Bounds.Height / 2f; float scaledHalfWidth = halfWidth * scale; float scaledHalfHeight = halfHeight * scale; _bitmapCanvas.Translate( Scale * halfWidth - scaledHalfWidth, Scale * halfHeight - scaledHalfHeight); _bitmapCanvas.Scale(extraScale, extraScale, scaledHalfWidth, scaledHalfHeight); } _matrix.Reset(); _matrix = MatrixExt.PreScale(_matrix, scale, scale); _compositionLayer.Draw(_bitmapCanvas, _matrix, _alpha); LottieLog.EndSection("Drawable.Draw"); if (extraScale > 1) { _bitmapCanvas.Restore(); } } } }
private static void Draw(CanvasDevice device, BitmapCanvas bitmapCanvas, CompositionLayer compositionLayer, Rect bounds, float scale, byte alpha, Matrix3X3 matrix, double width, double height, CanvasDrawingSession canvasDrawingSession) { using (bitmapCanvas.CreateSession(device, width, height, canvasDrawingSession)) { bitmapCanvas.Clear(Colors.Transparent); LottieLog.BeginSection("Drawable.Draw"); if (compositionLayer == null) { return; } var localScale = scale; float extraScale = 1f; float maxScale = GetMaxScale(bitmapCanvas, bounds); if (localScale > maxScale) { localScale = maxScale; extraScale = scale / localScale; } if (extraScale > 1) { // This is a bit tricky... // We can't draw on a canvas larger than ViewConfiguration.get(context).getScaledMaximumDrawingCacheSize() // which works out to be roughly the size of the screen because Android can't generate a // bitmap large enough to render to. // As a result, we cap the scale such that it will never be wider/taller than the screen // and then only render in the top left corner of the canvas. We then use extraScale // to scale up the rest of the scale. However, since we rendered the animation to the top // left corner, we need to scale up and translate the canvas to zoom in on the top left // corner. bitmapCanvas.Save(); float halfWidth = (float)bounds.Width / 2f; float halfHeight = (float)bounds.Height / 2f; float scaledHalfWidth = halfWidth * localScale; float scaledHalfHeight = halfHeight * localScale; bitmapCanvas.Translate( scale * halfWidth - scaledHalfWidth, scale * halfHeight - scaledHalfHeight); bitmapCanvas.Scale(extraScale, extraScale, scaledHalfWidth, scaledHalfHeight); } matrix.Reset(); matrix = MatrixExt.PreScale(matrix, localScale, localScale); compositionLayer.Draw(bitmapCanvas, matrix, alpha); LottieLog.EndSection("Drawable.Draw"); if (extraScale > 1) { bitmapCanvas.Restore(); } } }