Пример #1
0
 public SkiaDrawingContext(int width, int height, SKColor background, float scale, SKTypeface typeface)
 {
     this.typeface = typeface;
     surface       = SKSurface.Create(new SKImageInfo((int)(width * scale), (int)(height * scale), SKImageInfo.PlatformColorType, SKAlphaType.Opaque));
     surface.Canvas.Clear(background);
     surface.Canvas.Scale(scale);
 }
Пример #2
0
        /// <summary>
        /// 创建验证码的图片
        /// </summary>
        public byte[] CreateValidationCodeGraphic(string validationCode)
        {
            if (validationCode.IsNullOrWhiteSpace())
            {
                throw new Exception($"验证码参数 {nameof(validationCode)} 为空。");
            }
            var rand = new Random(Guid.NewGuid().GetHashCode());

            var randAngle = 40;
            var mapWidth  = validationCode.Length * 18;
            var mapHeight = 28;

            using (var bitmap = new SKBitmap(mapWidth, mapHeight))
            {
                using (var canvas = new SKCanvas(bitmap))
                {
                    canvas.Clear(SKColors.AliceBlue);

                    var paint = new SKPaint()
                    {
                        Color = SKColors.LightGray,
                    };
                    for (int i = 0; i < 50; i++)
                    {
                        int x = rand.Next(0, bitmap.Width);
                        int y = rand.Next(0, bitmap.Height);

                        canvas.DrawRect(new SKRect(x, y, x + 1, y + 1), paint);
                    }

                    var chars  = validationCode.ToCharArray();
                    var colors = new[] { SKColors.Black, SKColors.Red, SKColors.DarkBlue, SKColors.Green, SKColors.Orange, SKColors.Brown, SKColors.DarkCyan, SKColors.Purple };
                    var fonts  = new[]
                    {
                        SKTypeface.FromFamilyName("Verdana"),
                        SKTypeface.FromFamilyName("Microsoft Sans Serif"),
                        SKTypeface.FromFamilyName("Comic Sans MS"),
                        SKTypeface.FromFamilyName("Arial")
                    };

                    canvas.Translate(-4, 0);

                    for (int i = 0; i < chars.Length; i++)
                    {
                        int colorIndex = rand.Next(colors.Length);
                        int fontIndex  = rand.Next(fonts.Length);

                        var   fontColor = colors[colorIndex];
                        var   foneSize  = rand.Next(18, 25);
                        float angle     = rand.Next(-randAngle, randAngle);

                        SKPoint point = new SKPoint(16, 28 / 2 + 4);

                        canvas.Translate(point);
                        canvas.RotateDegrees(angle);

                        var textPaint = new SKPaint()
                        {
                            TextAlign = SKTextAlign.Center,
                            Color     = fontColor,
                            TextSize  = foneSize,
                            Typeface  = fonts[fontIndex],

                            //IsAntialias = rand.Next(1) == 1 ? true : false,
                            //FakeBoldText = true,
                            //FilterQuality = SKFilterQuality.High,
                            //HintingLevel = SKPaintHinting.Full,

                            //IsEmbeddedBitmapText = true,
                            //LcdRenderText = true,
                            //Style = SKPaintStyle.StrokeAndFill,
                            //TextEncoding = SKTextEncoding.Utf8,
                        };

                        canvas.DrawText(chars[i].ToString(), new SKPoint(0, 0), textPaint);
                        canvas.RotateDegrees(-angle);
                        canvas.Translate(0, -point.Y);
                    }

                    using (var image = SKImage.FromBitmap(bitmap))
                    {
                        using (var ms = new MemoryStream())
                        {
                            image.Encode(SKEncodedImageFormat.Png, 90).SaveTo(ms);
                            return(ms.ToArray());
                        }
                    }
                }
            }
        }
Пример #3
0
        public FormattedTextImpl(
            string text,
            Typeface typeface,
            TextAlignment textAlignment,
            TextWrapping wrapping,
            Size constraint,
            IReadOnlyList <FormattedTextStyleSpan> spans)
        {
            Text = text ?? string.Empty;

            // Replace 0 characters with zero-width spaces (200B)
            Text = Text.Replace((char)0, (char)0x200B);

            SKTypeface skiaTypeface = TypefaceCache.Default;

            if (typeface.FontFamily.Key != null)
            {
                var typefaces = SKTypefaceCollectionCache.GetOrAddTypefaceCollection(typeface.FontFamily);
                skiaTypeface = typefaces.GetTypeFace(typeface);
            }
            else
            {
                if (typeface.FontFamily.FamilyNames.HasFallbacks)
                {
                    foreach (var familyName in typeface.FontFamily.FamilyNames)
                    {
                        skiaTypeface = TypefaceCache.GetTypeface(
                            familyName,
                            typeface.Style,
                            typeface.Weight);
                        if (skiaTypeface != TypefaceCache.Default)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    skiaTypeface = TypefaceCache.GetTypeface(
                        typeface.FontFamily.Name,
                        typeface.Style,
                        typeface.Weight);
                }
            }

            _paint = new SKPaint();

            //currently Skia does not measure properly with Utf8 !!!
            //Paint.TextEncoding = SKTextEncoding.Utf8;
            _paint.TextEncoding  = SKTextEncoding.Utf16;
            _paint.IsStroke      = false;
            _paint.IsAntialias   = true;
            _paint.LcdRenderText = true;
            _paint.SubpixelText  = true;
            _paint.Typeface      = skiaTypeface;
            _paint.TextSize      = (float)typeface.FontSize;
            _paint.TextAlign     = textAlignment.ToSKTextAlign();

            _wrapping   = wrapping;
            _constraint = constraint;

            if (spans != null)
            {
                foreach (var span in spans)
                {
                    if (span.ForegroundBrush != null)
                    {
                        SetForegroundBrush(span.ForegroundBrush, span.StartIndex, span.Length);
                    }
                }
            }

            Rebuild();
        }
Пример #4
0
        public override void DrawView(SKSurface surface)
        {
            var canvas = surface.Canvas;

            // Fill color for Group Style
            var GroupStyleFillColor = SKColors.Aqua;

            // New Group Style fill paint
            var GroupStyleFillPaint = new SKPaint()
            {
                Style       = SKPaintStyle.Fill,
                Color       = GroupStyleFillColor,
                BlendMode   = SKBlendMode.SrcOver,
                IsAntialias = true
            };

            // Frame color for Group Style
            var GroupStyleFrameColor = SKColors.Black;

            // New Group Style frame paint
            var GroupStyleFramePaint = new SKPaint()
            {
                Style       = SKPaintStyle.Stroke,
                Color       = GroupStyleFrameColor,
                BlendMode   = SKBlendMode.SrcOver,
                IsAntialias = true,
                StrokeWidth = 1f,
                StrokeMiter = 4f,
                StrokeJoin  = SKStrokeJoin.Miter,
                StrokeCap   = SKStrokeCap.Butt
            };

            //-----------------------------------------------------------------------------
            // Draw Group shape group
            // Fill color for Round Rectangle Style
            var RoundRectangleStyleFillColor = _touched ? SKColors.Purple : SKColors.Aqua;

            // New Round Rectangle Style fill paint
            var RoundRectangleStyleFillPaint = new SKPaint()
            {
                Style       = SKPaintStyle.Fill,
                Color       = RoundRectangleStyleFillColor,
                BlendMode   = SKBlendMode.SrcOver,
                IsAntialias = true
            };

            // Frame color for Round Rectangle Style
            var RoundRectangleStyleFrameColor = SKColors.Black;

            // New Round Rectangle Style frame paint
            var RoundRectangleStyleFramePaint = new SKPaint()
            {
                Style       = SKPaintStyle.Stroke,
                Color       = RoundRectangleStyleFrameColor,
                BlendMode   = SKBlendMode.SrcOver,
                IsAntialias = true,
                StrokeWidth = 1f,
                StrokeMiter = 4f,
                StrokeJoin  = SKStrokeJoin.Miter,
                StrokeCap   = SKStrokeCap.Butt
            };

            // Draw Round Rectangle shape
            canvas.DrawRoundRect(new SKRect(100, 300, 600, 200), 32f, 32f, RoundRectangleStyleFillPaint);
            canvas.DrawRoundRect(new SKRect(100, 300, 600, 200), 32f, 32f, RoundRectangleStyleFramePaint);

            // Fill color for Text Style
            var TextStyleFillColor = SKColors.Black;

            // New Text Style fill paint
            var TextStyleFillPaint = new SKPaint()
            {
                Style          = SKPaintStyle.Fill,
                Color          = TextStyleFillColor,
                BlendMode      = SKBlendMode.SrcOver,
                IsAntialias    = true,
                Typeface       = SKTypeface.FromFamilyName("System", SKTypefaceStyle.Normal),
                TextSize       = 36f,
                TextAlign      = SKTextAlign.Center,
                IsVerticalText = false,
                TextScaleX     = 1f,
                TextSkewX      = 0f
            };

            // Draw Text shape
            canvas.DrawText(Element.Text, 340, 265, TextStyleFillPaint);
        }
Пример #5
0
        private static SKTypeface CreateDefaultTypeface()
        {
            var defaultTypeface = SKTypeface.FromFamilyName(FontFamily.Default.Name) ?? SKTypeface.FromFamilyName(null);

            return(defaultTypeface);
        }
Пример #6
0
        public static void DrawCaptionLabels(this SKCanvas canvas, string label, SKColor labelColor, string value, SKColor valueColor, float textSize, SKPoint point, SKTextAlign horizontalAlignment, SKTypeface typeface, out SKRect totalBounds)
        {
            var hasLabel      = !string.IsNullOrEmpty(label);
            var hasValueLabel = !string.IsNullOrEmpty(value);

            totalBounds = new SKRect();

            if (hasLabel || hasValueLabel)
            {
                var hasOffset     = hasLabel && hasValueLabel;
                var captionMargin = textSize * 0.60f;
                var space         = hasOffset ? captionMargin : 0;

                if (hasLabel)
                {
                    using (var paint = new SKPaint
                    {
                        TextSize = textSize,
                        IsAntialias = true,
                        Color = labelColor,
                        IsStroke = false,
                        TextAlign = horizontalAlignment,
                        Typeface = typeface
                    })
                    {
                        var bounds = new SKRect();
                        var text   = label;
                        paint.MeasureText(text, ref bounds);

                        var y = point.Y - ((bounds.Top + bounds.Bottom) / 2) - space;

                        canvas.DrawText(text, point.X, point.Y + space / 2, paint);

                        var labelBounds = GetAbsolutePositionRect(point.X, point.Y + space / 2, bounds, horizontalAlignment);
                        totalBounds = labelBounds.Standardized;
                    }
                }

                if (hasValueLabel)
                {
                    using (var paint = new SKPaint()
                    {
                        TextSize = textSize,
                        IsAntialias = true,
                        FakeBoldText = true,
                        Color = valueColor,
                        IsStroke = false,
                        TextAlign = horizontalAlignment,
                        Typeface = typeface
                    })
                    {
                        var bounds = new SKRect();
                        var text   = value;
                        paint.MeasureText(text, ref bounds);

                        var y = point.Y - ((bounds.Top + bounds.Bottom) / 2) + space;

                        canvas.DrawText(text, point.X + textSize * 3 + space, point.Y + space / 2, paint);

                        var valueBounds = GetAbsolutePositionRect(point.X + textSize * 3, point.Y + space / 2, bounds, horizontalAlignment);

                        if (totalBounds.IsEmpty)
                        {
                            totalBounds = valueBounds;
                        }
                        else
                        {
                            totalBounds.Union(valueBounds);
                        }
                    }
                }
            }
        }
Пример #7
0
 public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
 {
     return(new GlyphTypefaceImpl(SKTypeface.FromFamilyName(_defaultTypeface.FontFamily.Name)));
 }
Пример #8
0
        /// <summary>
        /// Shape an array of utf-32 code points
        /// </summary>
        /// <param name="bufferSet">A re-usable text shaping buffer set that results will be allocated from</param>
        /// <param name="codePoints">The utf-32 code points to be shaped</param>
        /// <param name="style">The user style for the text</param>
        /// <param name="direction">LTR or RTL direction</param>
        /// <param name="clusterAdjustment">A value to add to all reported cluster numbers</param>
        /// <param name="asFallbackFor">The type face this font is a fallback for</param>
        /// <returns>A TextShaper.Result representing the shaped text</returns>
        public Result Shape(ResultBufferSet bufferSet, Slice <int> codePoints, IStyle style, TextDirection direction, int clusterAdjustment, SKTypeface asFallbackFor)
        {
            // Work out if we need to force this to a fixed pitch and if
            // so the unscale character width we need to use
            float forceFixedPitchWidth = 0;

            if (asFallbackFor != _typeface && asFallbackFor != null)
            {
                var originalTypefaceShaper = ForTypeface(asFallbackFor);
                if (originalTypefaceShaper._isFixedPitch)
                {
                    forceFixedPitchWidth = originalTypefaceShaper._fixedCharacterWidth;
                }
            }

            using (var buffer = new HarfBuzzSharp.Buffer())
            {
                // Setup buffer
                unsafe
                {
                    fixed(int *pCodePoints = codePoints.Underlying)
                    {
                        hb_buffer_add_utf32(buffer.Handle, (IntPtr)(pCodePoints + codePoints.Start), codePoints.Length, 0, -1);
                    }
                }

                // Setup directionality (if supplied)
                switch (direction)
                {
                case TextDirection.LTR:
                    buffer.Direction = Direction.LeftToRight;
                    break;

                case TextDirection.RTL:
                    buffer.Direction = Direction.RightToLeft;
                    break;

                default:
                    throw new ArgumentException(nameof(direction));
                }

                // Guess other attributes
                buffer.GuessSegmentProperties();

                // Shape it
                _font.Shape(buffer);

                // RTL?
                bool rtl = buffer.Direction == Direction.RightToLeft;

                // Work out glyph scaling and offsetting for super/subscript
                float glyphScale   = style.FontSize / overScale;
                float glyphVOffset = 0;
                if (style.FontVariant == FontVariant.SuperScript)
                {
                    glyphScale   *= 0.65f;
                    glyphVOffset -= style.FontSize * 0.35f;
                }
                if (style.FontVariant == FontVariant.SubScript)
                {
                    glyphScale   *= 0.65f;
                    glyphVOffset += style.FontSize * 0.1f;
                }

                // Create results and get buffes
                var r = new Result();
                r.GlyphIndicies    = bufferSet.GlyphIndicies.Add((int)buffer.Length, false);
                r.GlyphPositions   = bufferSet.GlyphPositions.Add((int)buffer.Length, false);
                r.Clusters         = bufferSet.Clusters.Add((int)buffer.Length, false);
                r.CodePointXCoords = bufferSet.CodePointXCoords.Add(codePoints.Length, false);

                // Convert points
                var   gp             = buffer.GlyphPositions;
                var   gi             = buffer.GlyphInfos;
                float cursorX        = 0;
                float cursorY        = 0;
                float cursorXCluster = 0;
                for (int i = 0; i < buffer.Length; i++)
                {
                    r.GlyphIndicies[i] = (ushort)gi[i].Codepoint;
                    r.Clusters[i]      = (int)gi[i].Cluster + clusterAdjustment;

                    // Update code point positions
                    if (!rtl)
                    {
                        // First cluster, different cluster, or same cluster with lower x-coord
                        if (i == 0 ||
                            (r.Clusters[i] != r.Clusters[i - 1]) ||
                            (cursorX < r.CodePointXCoords[r.Clusters[i] - clusterAdjustment]))
                        {
                            r.CodePointXCoords[r.Clusters[i] - clusterAdjustment] = cursorX;
                        }
                    }

                    // Get the position
                    var pos = gp[i];

                    // Update glyph position
                    r.GlyphPositions[i] = new SKPoint(
                        cursorX + pos.XOffset * glyphScale,
                        cursorY - pos.YOffset * glyphScale + glyphVOffset
                        );

                    // Update cursor position
                    cursorX += pos.XAdvance * glyphScale;
                    cursorY += pos.YAdvance * glyphScale;

                    // Are we falling back for a fixed pitch font and is the next character a
                    // new cluster?  If so advance by the width of the original font, not this
                    // fallback font
                    if (forceFixedPitchWidth != 0)
                    {
                        // New cluster?
                        if (i + 1 >= buffer.Length || gi[i].Cluster != gi[i + 1].Cluster)
                        {
                            // Work out fixed pitch position of next cluster
                            cursorXCluster += forceFixedPitchWidth * glyphScale;
                            if (cursorXCluster > cursorX)
                            {
                                // Nudge characters to center them in the fixed pitch width
                                if (i == 0 || gi[i - 1].Cluster != gi[i].Cluster)
                                {
                                    r.GlyphPositions[i].X += (cursorXCluster - cursorX) / 2;
                                }

                                // Use fixed width character position
                                cursorX = cursorXCluster;
                            }
                            else
                            {
                                // Character is wider (probably an emoji) so we
                                // allow it to exceed the fixed pitch character width
                                cursorXCluster = cursorX;
                            }
                        }
                    }

                    // Store RTL cursor position
                    if (rtl)
                    {
                        // First cluster, different cluster, or same cluster with lower x-coord
                        if (i == 0 ||
                            (r.Clusters[i] != r.Clusters[i - 1]) ||
                            (cursorX > r.CodePointXCoords[r.Clusters[i] - clusterAdjustment]))
                        {
                            r.CodePointXCoords[r.Clusters[i] - clusterAdjustment] = cursorX;
                        }
                    }
                }

                // Finalize cursor positions by filling in any that weren't
                // referenced by a cluster
                if (rtl)
                {
                    r.CodePointXCoords[0] = cursorX;
                    for (int i = codePoints.Length - 2; i >= 0; i--)
                    {
                        if (r.CodePointXCoords[i] == 0)
                        {
                            r.CodePointXCoords[i] = r.CodePointXCoords[i + 1];
                        }
                    }
                }
                else
                {
                    for (int i = 1; i < codePoints.Length; i++)
                    {
                        if (r.CodePointXCoords[i] == 0)
                        {
                            r.CodePointXCoords[i] = r.CodePointXCoords[i - 1];
                        }
                    }
                }

                // Also return the end cursor position
                r.EndXCoord = new SKPoint(cursorX, cursorY);

                // And some other useful metrics
                r.Ascent  = _fontMetrics.Ascent * style.FontSize / overScale;
                r.Descent = _fontMetrics.Descent * style.FontSize / overScale;
                r.XMin    = _fontMetrics.XMin * style.FontSize / overScale;

                // Done
                return(r);
            }
        }
Пример #9
0
 static private SKPaint MakeDefaultPaint(Color pColor, float pStrokeWidth, float pFontSize, SKTypeface pTypeface)
 {
     return(new SKPaint()
     {
         Color = pColor.ToSKColor(),
         StrokeWidth = pStrokeWidth,
         Typeface = pTypeface,
         TextSize = pFontSize,
         StrokeCap = SKStrokeCap.Round,
         BlendMode = SKBlendMode.Src,
         IsAntialias = true
     });
 }
Пример #10
0
 public TypefaceCollectionEntry(Typeface typeface, SKTypeface skTypeface)
 {
     Typeface   = typeface;
     SKTypeface = skTypeface;
 }
Пример #11
0
        /// <summary>
        /// Creates a bitmap of the graph.
        /// </summary>
        /// <param name="Settings">Graph settings.</param>
        /// <param name="States">State object(s) that contain graph-specific information about its inner states.
        /// These can be used in calls back to the graph object to make actions on the generated graph.</param>
        /// <returns>Bitmap</returns>
        public override SKImage CreateBitmap(GraphSettings Settings, out object[] States)
        {
            using (SKSurface Surface = SKSurface.Create(Settings.Width, Settings.Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul))
            {
                SKCanvas Canvas = Surface.Canvas;

                States = new object[0];

                Canvas.Clear(Settings.BackgroundColor);

                int x1, y1, x2, y2, x3, y3, w, h;

                x1 = Settings.MarginLeft;
                x2 = Settings.Width - Settings.MarginRight;
                y1 = Settings.MarginTop;
                y2 = Settings.Height - Settings.MarginBottom;

                if (!string.IsNullOrEmpty(this.labelY))
                {
                    x1 += (int)(Settings.LabelFontSize * 2 + 0.5);
                }

                if (!string.IsNullOrEmpty(this.labelX))
                {
                    y2 -= (int)(Settings.LabelFontSize * 2 + 0.5);
                }

                if (!string.IsNullOrEmpty(this.title))
                {
                    y1 += (int)(Settings.LabelFontSize * 2 + 0.5);
                }

                IVector YLabels = GetLabels(ref this.minY, ref this.maxY, this.y, Settings.ApproxNrLabelsY, out LabelType YLabelType);
                SKPaint Font    = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    HintingLevel  = SKPaintHinting.Full,
                    SubpixelText  = true,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Fill,
                    Color         = Settings.AxisColor,
                    Typeface      = SKTypeface.FromFamilyName(Settings.FontName, SKTypefaceStyle.Normal),
                    TextSize      = (float)Settings.LabelFontSize
                };
                float  Size;
                double MaxSize = 0;

                if (this.showYAxis)
                {
                    foreach (IElement Label in YLabels.ChildElements)
                    {
                        Size = Font.MeasureText(LabelString(Label, YLabelType));
                        if (Size > MaxSize)
                        {
                            MaxSize = Size;
                        }
                    }
                }

                x3 = (int)Math.Ceiling(x1 + MaxSize) + Settings.MarginLabel;

                IVector XLabels = GetLabels(ref this.minX, ref this.maxX, this.x, Settings.ApproxNrLabelsX, out LabelType XLabelType);
                MaxSize = 0;

                if (this.showXAxis)
                {
                    foreach (IElement Label in XLabels.ChildElements)
                    {
                        Size = Font.MeasureText(LabelString(Label, XLabelType));
                        if (Size > MaxSize)
                        {
                            MaxSize = Size;
                        }
                    }
                }

                y3 = (int)Math.Floor(y2 - MaxSize) - Settings.MarginLabel;
                w  = x2 - x3;
                h  = y3 - y1;

                SKPaint AxisBrush = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Fill,
                    Color         = Settings.AxisColor
                };
                SKPaint GridBrush = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Fill,
                    Color         = Settings.GridColor
                };
                SKPaint AxisPen = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Stroke,
                    Color         = Settings.AxisColor,
                    StrokeWidth   = Settings.AxisWidth
                };
                SKPaint GridPen = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Stroke,
                    Color         = Settings.GridColor,
                    StrokeWidth   = Settings.GridWidth
                };

                double OrigoX;
                double OrigoY;

                if (this.minX.AssociatedSet is IAbelianGroup AgX)
                {
                    OrigoX = Scale(new ObjectVector(AgX.AdditiveIdentity), this.minX, this.maxX, x3, w)[0];
                }
                else
                {
                    OrigoX = 0;
                }

                if (this.minY.AssociatedSet is IAbelianGroup AgY)
                {
                    OrigoY = Scale(new ObjectVector(AgY.AdditiveIdentity), this.minY, this.maxY, y3, -h)[0];
                }
                else
                {
                    OrigoY = 0;
                }

                DrawingArea DrawingArea = new DrawingArea(this.minX, this.maxX, this.minY, this.maxY, x3, y3, w, -h, (float)OrigoX, (float)OrigoY);
                double[]    LabelYY     = DrawingArea.ScaleY(YLabels);
                int         i           = 0;
                float       f;
                string      s;

                foreach (IElement Label in YLabels.ChildElements)
                {
                    Size = Font.MeasureText(s = LabelString(Label, YLabelType));
                    f    = (float)LabelYY[i++];

                    if (this.showGrid)
                    {
                        if (Label is DoubleNumber && ((DoubleNumber)Label).Value == 0)
                        {
                            Canvas.DrawLine(x3, f, x2, f, AxisPen);
                        }
                        else
                        {
                            Canvas.DrawLine(x3, f, x2, f, GridPen);
                        }
                    }

                    if (this.showYAxis)
                    {
                        f += (float)Settings.LabelFontSize * 0.5f;
                        Canvas.DrawText(s, x3 - Size - Settings.MarginLabel, f, Font);
                    }
                }

                double[] LabelXX = DrawingArea.ScaleX(XLabels);
                i = 0;

                foreach (IElement Label in XLabels.ChildElements)
                {
                    Size = Font.MeasureText(s = LabelString(Label, XLabelType));
                    f    = (float)LabelXX[i++];

                    if (this.showGrid)
                    {
                        if (Label is DoubleNumber && ((DoubleNumber)Label).Value == 0)
                        {
                            Canvas.DrawLine(f, y1, f, y3, AxisPen);
                        }
                        else
                        {
                            Canvas.DrawLine(f, y1, f, y3, GridPen);
                        }
                    }

                    if (this.showXAxis)
                    {
                        f -= Size * 0.5f;
                        if (f < x3)
                        {
                            f = x3;
                        }
                        else if (f + Size > x3 + w)
                        {
                            f = x3 + w - Size;
                        }

                        Canvas.DrawText(s, f, y3 + Settings.MarginLabel + (float)Settings.LabelFontSize, Font);
                    }
                }

                Font.Dispose();
                Font = null;

                Font = new SKPaint()
                {
                    FilterQuality = SKFilterQuality.High,
                    HintingLevel  = SKPaintHinting.Full,
                    SubpixelText  = true,
                    IsAntialias   = true,
                    Style         = SKPaintStyle.Fill,
                    Color         = Settings.AxisColor,
                    Typeface      = SKTypeface.FromFamilyName(Settings.FontName, SKTypefaceStyle.Bold),
                    TextSize      = (float)(Settings.LabelFontSize * 1.5)
                };

                if (!string.IsNullOrEmpty(this.title))
                {
                    Size = Font.MeasureText(this.title);

                    f = x3 + (x2 - x3 - Size) * 0.5f;

                    if (f < x3)
                    {
                        f = x3;
                    }
                    else if (f + Size > x3 + w)
                    {
                        f = x3 + w - Size;
                    }

                    Canvas.DrawText(this.title, f, (float)(Settings.MarginTop + 1.5 * Settings.LabelFontSize), Font);
                }

                if (!string.IsNullOrEmpty(this.labelX))
                {
                    Size = Font.MeasureText(this.labelX);

                    f = x3 + (x2 - x3 - Size) * 0.5f;

                    if (f < x3)
                    {
                        f = x3;
                    }
                    else if (f + Size > x3 + w)
                    {
                        f = x3 + w - Size;
                    }

                    Canvas.DrawText(this.labelX, f, (float)(y2 + 0.45 * Settings.LabelFontSize), Font);
                }

                if (!string.IsNullOrEmpty(this.labelY))
                {
                    Size = Font.MeasureText(this.labelY);

                    f = y3 - (y3 - y1 - Size) * 0.5f;

                    if (f - Size < y1)
                    {
                        f = y1 + Size;
                    }
                    else if (f > y3 + h)
                    {
                        f = y3 + h;
                    }

                    Canvas.Translate((float)(Settings.MarginLeft + 0.05 * Settings.LabelFontSize), f);
                    Canvas.RotateDegrees(-90);
                    Canvas.DrawText(this.labelY, 0, 0, Font);
                    Canvas.ResetMatrix();
                }

                IEnumerator <IVector>      ex          = this.x.GetEnumerator();
                IEnumerator <IVector>      ey          = this.y.GetEnumerator();
                IEnumerator <object[]>     eParameters = this.parameters.GetEnumerator();
                IEnumerator <DrawCallback> eCallbacks  = this.callbacks.GetEnumerator();
                SKPoint[]    Points;
                SKPoint[]    PrevPoints     = null;
                object[]     PrevParameters = null;
                DrawCallback PrevCallback   = null;

                while (ex.MoveNext() && ey.MoveNext() && eParameters.MoveNext() && eCallbacks.MoveNext())
                {
                    Points = DrawingArea.Scale(ex.Current, ey.Current);

                    if (PrevCallback != null && eCallbacks.Current.Target.GetType() == PrevCallback.Target.GetType())
                    {
                        eCallbacks.Current(Canvas, Points, eParameters.Current, PrevPoints, PrevParameters, DrawingArea);
                    }
                    else
                    {
                        eCallbacks.Current(Canvas, Points, eParameters.Current, null, null, DrawingArea);
                    }

                    PrevPoints     = Points;
                    PrevParameters = eParameters.Current;
                    PrevCallback   = eCallbacks.Current;
                }

                SKImage Result = Surface.Snapshot();

                if (Font != null)
                {
                    Font.Dispose();
                }

                AxisBrush.Dispose();
                GridBrush.Dispose();
                GridPen.Dispose();
                AxisPen.Dispose();

                States = new object[] { DrawingArea };

                return(Result);
            }
        }
Пример #12
0
 public SKFontInfo(SKTypeface face, float pFontSize)
 {
     TypeFace = face;
     FontSize = pFontSize;
 }
 public static void ClassInit(TestContext context)
 {
     Typeface = SKTypeface.FromFile(Path.Combine("simsun.ttf"));
 }
Пример #14
0
 private static int GetCacheKey(SKTypeface typeface, float fontSize)
 {
     return(typeface.GetHashCode() + (int)(fontSize * 100f));
 }
Пример #15
0
        /// <summary>
        /// Shape an array of utf-32 code points
        /// </summary>
        /// <param name="bufferSet">A re-usable text shaping buffer set that results will be allocated from</param>
        /// <param name="codePoints">The utf-32 code points to be shaped</param>
        /// <param name="style">The user style for the text</param>
        /// <param name="direction">LTR or RTL direction</param>
        /// <param name="clusterAdjustment">A value to add to all reported cluster numbers</param>
        /// <param name="asFallbackFor">The type face this font is a fallback for</param>
        /// <param name="textAlignment">The text alignment of the paragraph, used to control placement of glyphs within character cell when letter spacing used</param>
        /// <returns>A TextShaper.Result representing the shaped text</returns>
        public Result Shape(ResultBufferSet bufferSet, Slice <int> codePoints, IStyle style, TextDirection direction, int clusterAdjustment, SKTypeface asFallbackFor, TextAlignment textAlignment)
        {
            // Work out if we need to force this to a fixed pitch and if
            // so the unscale character width we need to use
            float forceFixedPitchWidth = 0;

            if (asFallbackFor != _typeface && asFallbackFor != null)
            {
                var originalTypefaceShaper = ForTypeface(asFallbackFor);
                if (originalTypefaceShaper._isFixedPitch)
                {
                    forceFixedPitchWidth = originalTypefaceShaper._fixedCharacterWidth;
                }
            }

            // Work out how much to shift glyphs in the character cell when using letter spacing
            // The idea here is to align the glyphs within the character cell the same way as the
            // text block alignment so that left/right aligned text still aligns with the margin
            // and centered text is still centered (and not shifted slightly due to the extra
            // space that would be at the right with normal letter spacing).
            float glyphLetterSpacingAdjustment = 0;

            switch (textAlignment)
            {
            case TextAlignment.Right:
                glyphLetterSpacingAdjustment = style.LetterSpacing;
                break;

            case TextAlignment.Center:
                glyphLetterSpacingAdjustment = style.LetterSpacing / 2;
                break;
            }


            using (var buffer = new HarfBuzzSharp.Buffer())
            {
                // Setup buffer
                buffer.AddUtf32(codePoints.AsSpan(), 0, -1);

                // Setup directionality (if supplied)
                switch (direction)
                {
                case TextDirection.LTR:
                    buffer.Direction = Direction.LeftToRight;
                    break;

                case TextDirection.RTL:
                    buffer.Direction = Direction.RightToLeft;
                    break;

                default:
                    throw new ArgumentException(nameof(direction));
                }

                // Guess other attributes
                buffer.GuessSegmentProperties();

                // Shape it
                _font.Shape(buffer);

                // RTL?
                bool rtl = buffer.Direction == Direction.RightToLeft;

                // Work out glyph scaling and offsetting for super/subscript
                float glyphScale   = style.FontSize / overScale;
                float glyphVOffset = 0;
                if (style.FontVariant == FontVariant.SuperScript)
                {
                    glyphScale   *= 0.65f;
                    glyphVOffset -= style.FontSize * 0.35f;
                }
                if (style.FontVariant == FontVariant.SubScript)
                {
                    glyphScale   *= 0.65f;
                    glyphVOffset += style.FontSize * 0.1f;
                }

                // Create results and get buffes
                var r = new Result();
                r.GlyphIndicies    = bufferSet.GlyphIndicies.Add((int)buffer.Length, false);
                r.GlyphPositions   = bufferSet.GlyphPositions.Add((int)buffer.Length, false);
                r.Clusters         = bufferSet.Clusters.Add((int)buffer.Length, false);
                r.CodePointXCoords = bufferSet.CodePointXCoords.Add(codePoints.Length, false);
                r.CodePointXCoords.Fill(0);

                // Convert points
                var   gp             = buffer.GlyphPositions;
                var   gi             = buffer.GlyphInfos;
                float cursorX        = 0;
                float cursorY        = 0;
                float cursorXCluster = 0;
                for (int i = 0; i < buffer.Length; i++)
                {
                    r.GlyphIndicies[i] = (ushort)gi[i].Codepoint;
                    r.Clusters[i]      = (int)gi[i].Cluster + clusterAdjustment;


                    // Update code point positions
                    if (!rtl)
                    {
                        // First cluster, different cluster, or same cluster with lower x-coord
                        if (i == 0 ||
                            (r.Clusters[i] != r.Clusters[i - 1]) ||
                            (cursorX < r.CodePointXCoords[r.Clusters[i] - clusterAdjustment]))
                        {
                            r.CodePointXCoords[r.Clusters[i] - clusterAdjustment] = cursorX;
                        }
                    }

                    // Get the position
                    var pos = gp[i];

                    // Update glyph position
                    r.GlyphPositions[i] = new SKPoint(
                        cursorX + pos.XOffset * glyphScale + glyphLetterSpacingAdjustment,
                        cursorY - pos.YOffset * glyphScale + glyphVOffset
                        );

                    // Update cursor position
                    cursorX += pos.XAdvance * glyphScale;
                    cursorY += pos.YAdvance * glyphScale;

                    // Ensure paragraph separator character (0x2029) has some
                    // width so it can be seen as part of the selection in the editor.
                    if (pos.XAdvance == 0 && codePoints[(int)gi[i].Cluster] == 0x2029)
                    {
                        cursorX += style.FontSize * 2 / 3;
                    }

                    if (i + 1 == gi.Length || gi[i].Cluster != gi[i + 1].Cluster)
                    {
                        cursorX += style.LetterSpacing;
                    }

                    // Are we falling back for a fixed pitch font and is the next character a
                    // new cluster?  If so advance by the width of the original font, not this
                    // fallback font
                    if (forceFixedPitchWidth != 0)
                    {
                        // New cluster?
                        if (i + 1 >= buffer.Length || gi[i].Cluster != gi[i + 1].Cluster)
                        {
                            // Work out fixed pitch position of next cluster
                            cursorXCluster += forceFixedPitchWidth * glyphScale;
                            if (cursorXCluster > cursorX)
                            {
                                // Nudge characters to center them in the fixed pitch width
                                if (i == 0 || gi[i - 1].Cluster != gi[i].Cluster)
                                {
                                    r.GlyphPositions[i].X += (cursorXCluster - cursorX) / 2;
                                }

                                // Use fixed width character position
                                cursorX = cursorXCluster;
                            }
                            else
                            {
                                // Character is wider (probably an emoji) so we
                                // allow it to exceed the fixed pitch character width
                                cursorXCluster = cursorX;
                            }
                        }
                    }

                    // Store RTL cursor position
                    if (rtl)
                    {
                        // First cluster, different cluster, or same cluster with lower x-coord
                        if (i == 0 ||
                            (r.Clusters[i] != r.Clusters[i - 1]) ||
                            (cursorX > r.CodePointXCoords[r.Clusters[i] - clusterAdjustment]))
                        {
                            r.CodePointXCoords[r.Clusters[i] - clusterAdjustment] = cursorX;
                        }
                    }
                }

                // Finalize cursor positions by filling in any that weren't
                // referenced by a cluster
                if (rtl)
                {
                    r.CodePointXCoords[0] = cursorX;
                    for (int i = codePoints.Length - 2; i >= 0; i--)
                    {
                        if (r.CodePointXCoords[i] == 0)
                        {
                            r.CodePointXCoords[i] = r.CodePointXCoords[i + 1];
                        }
                    }
                }
                else
                {
                    for (int i = 1; i < codePoints.Length; i++)
                    {
                        if (r.CodePointXCoords[i] == 0)
                        {
                            r.CodePointXCoords[i] = r.CodePointXCoords[i - 1];
                        }
                    }
                }

                // Also return the end cursor position
                r.EndXCoord = new SKPoint(cursorX, cursorY);

                // And some other useful metrics
                ApplyFontMetrics(ref r, style.FontSize);

                // Done
                return(r);
            }
        }
Пример #16
0
        public void Update(PageChatRender pageChatRender)
        {
            try
            {
                this.Width        = Int32.Parse(pageChatRender.textWidth.Text) + 10;
                this.Height       = Int32.Parse(pageChatRender.textHeight.Text) + 38;
                imgPreview.Height = Int32.Parse(pageChatRender.textHeight.Text);
                imgPreview.Width  = Int32.Parse(pageChatRender.textWidth.Text);
                PreviewData previewData = JsonConvert.DeserializeObject <PreviewData>(File.ReadAllText("preview_data.json"));
                BlockingCollection <TwitchCommentPreview> finalComments = new BlockingCollection <TwitchCommentPreview>();
                SKBitmap      previewBitmap   = new SKBitmap((int)this.Width, (int)imgPreview.Height);
                SKColor       backgroundColor = new SKColor(pageChatRender.colorBackground.SelectedColor.Value.R, pageChatRender.colorBackground.SelectedColor.Value.G, pageChatRender.colorBackground.SelectedColor.Value.B);
                SKColor       messageColor    = new SKColor(pageChatRender.colorFont.SelectedColor.Value.R, pageChatRender.colorFont.SelectedColor.Value.G, pageChatRender.colorFont.SelectedColor.Value.B);
                RenderOptions renderOptions   = new RenderOptions(pageChatRender.textJson.Text, "", backgroundColor, Int32.Parse(pageChatRender.textHeight.Text), Int32.Parse(pageChatRender.textWidth.Text), (bool)pageChatRender.checkBTTV.IsChecked, (bool)pageChatRender.checkFFZ.IsChecked, (bool)pageChatRender.checkOutline.IsChecked, (string)pageChatRender.comboFont.SelectedItem, Double.Parse(pageChatRender.textFontSize.Text), Double.Parse(pageChatRender.textUpdateTime.Text), (bool)pageChatRender.checkTimestamp.IsChecked, messageColor, Int32.Parse(pageChatRender.textFramerate.Text), Settings.Default.FfmpegInputArgs, Settings.Default.FfmpegOutputArgs);
                Size          canvasSize      = new Size(renderOptions.chat_width, renderOptions.text_height);
                SKPaint       nameFont        = new SKPaint()
                {
                    Typeface = SKTypeface.FromFamilyName(renderOptions.font, SKFontStyle.Bold), LcdRenderText = true, SubpixelText = true, TextSize = (float)renderOptions.font_size, IsAntialias = true, HintingLevel = SKPaintHinting.Full, FilterQuality = SKFilterQuality.High
                };
                SKPaint messageFont = new SKPaint()
                {
                    Typeface = SKTypeface.FromFamilyName(renderOptions.font, SKFontStyle.Normal), LcdRenderText = true, SubpixelText = true, TextSize = (float)renderOptions.font_size, IsAntialias = true, HintingLevel = SKPaintHinting.Full, FilterQuality = SKFilterQuality.High, Color = renderOptions.message_color
                };
                List <ThirdPartyEmote>        thirdPartyEmotes = new List <ThirdPartyEmote>();
                Dictionary <string, SKBitmap> chatEmotes       = new Dictionary <string, SKBitmap>();
                Dictionary <string, SKBitmap> emojiCache       = new Dictionary <string, SKBitmap>();
                string emojiRegex = "[#*0-9]\uFE0F\u20E3|[\u00A9\u00AE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618]|\u261D(?:\uD83C[\uDFFB-\uDFFF])?|[\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7\u26F8]|\u26F9(?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?|\uFE0F\u200D[\u2640\u2642]\uFE0F)?|[\u26FA\u26FD\u2702\u2705\u2708\u2709]|[\u270A-\u270D](?:\uD83C[\uDFFB-\uDFFF])?|[\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C(?:[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|[\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF84]|\uDF85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDF86-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFC1]|\uDFC2(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC3\uDFC4](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDFC5\uDFC6]|\uDFC7(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC8\uDFC9]|\uDFCA(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?|\uFE0F\u200D[\u2640\u2642]\uFE0F)?|[\uDFCD-\uDFF0]|\uDFF3(?:\uFE0F\u200D\uD83C\uDF08)?|\uDFF4(?:\u200D\u2620\uFE0F|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?|[\uDFF5\uDFF7-\uDFFF])|\uD83D(?:[\uDC00-\uDC14]|\uDC15(?:\u200D\uD83E\uDDBA)?|[\uDC16-\uDC40]|\uDC41(?:\uFE0F\u200D\uD83D\uDDE8\uFE0F)?|[\uDC42\uDC43](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC44\uDC45]|[\uDC46-\uDC50](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC51-\uDC65]|[\uDC66\uDC67](?:\uD83C[\uDFFB-\uDFFF])?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\u2764\uFE0F\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\u2764\uFE0F\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D(?:\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDC69\uD83C\uDFFB)|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D(?:\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDC69\uD83C[\uDFFB\uDFFC])|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D(?:\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDC69\uD83C[\uDFFB-\uDFFD])|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC6A|[\uDC6B-\uDC6D](?:\uD83C[\uDFFB-\uDFFF])?|\uDC6E(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F)?|\uDC70(?:\uD83C[\uDFFB-\uDFFF])?|\uDC71(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDC72(?:\uD83C[\uDFFB-\uDFFF])?|\uDC73(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDC74-\uDC76](?:\uD83C[\uDFFB-\uDFFF])?|\uDC77(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDC78(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC79-\uDC7B]|\uDC7C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC7D-\uDC80]|[\uDC81\uDC82](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDC83(?:\uD83C[\uDFFB-\uDFFF])?|\uDC84|\uDC85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC86\uDC87](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDC88-\uDCA9]|\uDCAA(?:\uD83C[\uDFFB-\uDFFF])?|[\uDCAB-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73]|\uDD74(?:\uD83C[\uDFFB-\uDFFF])?|\uDD75(?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?|\uFE0F\u200D[\u2640\u2642]\uFE0F)?|[\uDD76-\uDD79]|\uDD7A(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD87\uDD8A-\uDD8D]|[\uDD90\uDD95\uDD96](?:\uD83C[\uDFFB-\uDFFF])?|[\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE44]|[\uDE45-\uDE47](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDE48-\uDE4A]|\uDE4B(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDE4C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE4D\uDE4E](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDE4F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE80-\uDEA2]|\uDEA3(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDEA4-\uDEB3]|[\uDEB4-\uDEB6](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDEB7-\uDEBF]|\uDEC0(?:\uD83C[\uDFFB-\uDFFF])?|[\uDEC1-\uDEC5\uDECB]|\uDECC(?:\uD83C[\uDFFB-\uDFFF])?|[\uDECD-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB])|\uD83E(?:[\uDD0D\uDD0E]|\uDD0F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD10-\uDD17]|[\uDD18-\uDD1C](?:\uD83C[\uDFFB-\uDFFF])?|\uDD1D|[\uDD1E\uDD1F](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD20-\uDD25]|\uDD26(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDD27-\uDD2F]|[\uDD30-\uDD36](?:\uD83C[\uDFFB-\uDFFF])?|\uDD37(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDD38\uDD39](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDD3A|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F)?|[\uDD3D\uDD3E](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDD3F-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDB4]|[\uDDB5\uDDB6](?:\uD83C[\uDFFB-\uDFFF])?|\uDDB7|[\uDDB8\uDDB9](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDDBA|\uDDBB(?:\uD83C[\uDFFB-\uDFFF])?|[\uDDBC-\uDDCA]|[\uDDCD-\uDDCF](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|\uDDD0|\uDDD1(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C(?:\uDFFB(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\uD83C\uDFFB)?|\uDFFC(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC])?|\uDFFD(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD])?|\uDFFE(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])?|\uDFFF(?:\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])?))?|[\uDDD2-\uDDD5](?:\uD83C[\uDFFB-\uDFFF])?|\uDDD6(?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDDD7-\uDDDD](?:\u200D[\u2640\u2642]\uFE0F|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F)?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F)?|[\uDDE0-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])";

                using (SKCanvas previewCanvas = new SKCanvas(previewBitmap))
                {
                    previewCanvas.Clear(backgroundColor);

                    foreach (PreviewEmote previewDataEmote in previewData.emotes)
                    {
                        byte[]   imageBytes  = Convert.FromBase64String(previewDataEmote.image);
                        SKBitmap emoteBitmap = SKBitmap.Decode(imageBytes);
                        SKCodec  emoteCodec;
                        using (MemoryStream ms = new MemoryStream(imageBytes))
                            emoteCodec = SKCodec.Create(ms);

                        ThirdPartyEmote emote = new ThirdPartyEmote(new List <SKBitmap>()
                        {
                            emoteBitmap
                        }, emoteCodec, previewDataEmote.name, ".png", "0", 1);
                        thirdPartyEmotes.Add(emote);
                    }

                    foreach (PreviewComment previewComment in previewData.comments)
                    {
                        int               default_x         = 2;
                        Point             drawPos           = new Point(default_x, 0);
                        string            userName          = previewComment.name;
                        SKColor           userColor         = new SKColor(Convert.ToByte(previewComment.color.Substring(0, 2), 16), Convert.ToByte(previewComment.color.Substring(2, 2), 16), Convert.ToByte(previewComment.color.Substring(4, 2), 16));
                        List <SKBitmap>   imageList         = new List <SKBitmap>();
                        SKBitmap          sectionImage      = new SKBitmap((int)canvasSize.Width, (int)canvasSize.Height);
                        List <GifEmote>   currentGifEmotes  = new List <GifEmote>();
                        List <SKBitmap>   emoteList         = new List <SKBitmap>();
                        List <CheerEmote> cheerEmotes       = new List <CheerEmote>();
                        List <SKRect>     emotePositionList = new List <SKRect>();
                        new SKCanvas(sectionImage).Clear(renderOptions.background_color);
                        Comment comment = new Comment();
                        comment.message = new Message();
                        Fragment msg = new Fragment();
                        msg.text = previewComment.message;
                        comment.message.fragments = new List <Fragment>();
                        comment.message.fragments.Add(msg);
                        if (renderOptions.chat_timestamp)
                        {
                            sectionImage = pageChatRender.DrawTimestamp(sectionImage, imageList, messageFont, renderOptions, comment, canvasSize, ref drawPos, ref default_x);
                        }
                        if (previewComment.badges != null)
                        {
                            sectionImage = DrawBadges(sectionImage, imageList, renderOptions, canvasSize, ref drawPos, previewComment);
                        }
                        sectionImage = pageChatRender.DrawUsername(sectionImage, imageList, renderOptions, nameFont, userName, userColor, canvasSize, ref drawPos);
                        sectionImage = pageChatRender.DrawMessage(sectionImage, imageList, renderOptions, currentGifEmotes, messageFont, emojiCache, chatEmotes, thirdPartyEmotes, cheerEmotes, comment, canvasSize, ref drawPos, emojiRegex, ref default_x, emoteList, emotePositionList);


                        int finalHeight = 0;
                        foreach (var img in imageList)
                        {
                            finalHeight += img.Height;
                        }
                        SKBitmap finalImage       = new SKBitmap((int)canvasSize.Width, finalHeight);
                        SKCanvas finalImageCanvas = new SKCanvas(finalImage);
                        finalHeight = 0;
                        foreach (var img in imageList)
                        {
                            finalImageCanvas.DrawBitmap(img, 0, finalHeight);
                            finalHeight += img.Height;
                            img.Dispose();
                        }

                        finalComments.Add(new TwitchCommentPreview(finalImage, Double.Parse(comment.content_offset_seconds.ToString()), currentGifEmotes, emoteList, emotePositionList));
                    }

                    int y          = 0;
                    int tempHeight = 0;
                    foreach (TwitchCommentPreview twitchCommentPreview in finalComments)
                    {
                        tempHeight += twitchCommentPreview.section.Height;
                    }
                    SKBitmap tempBitmap = new SKBitmap((int)this.Width, tempHeight);

                    using (SKCanvas tempCanvas = new SKCanvas(tempBitmap))
                    {
                        foreach (TwitchCommentPreview twitchCommentPreview in finalComments)
                        {
                            tempCanvas.DrawBitmap(twitchCommentPreview.section, 0, y, imagePaint);

                            for (int i = 0; i < twitchCommentPreview.normalEmotes.Count; i++)
                            {
                                SKRect refrenceRect = twitchCommentPreview.normalEmotesPositions[i];
                                tempCanvas.DrawBitmap(twitchCommentPreview.normalEmotes[i], new SKRect(refrenceRect.Left, refrenceRect.Top + y, refrenceRect.Right, refrenceRect.Bottom + y), imagePaint);
                            }

                            y += twitchCommentPreview.section.Height;
                        }
                    }

                    previewCanvas.DrawBitmap(tempBitmap, 0, previewBitmap.Height - tempBitmap.Height);
                }

                using (var stream = new MemoryStream())
                {
                    SKImage.FromBitmap(previewBitmap).Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
                    var bitmap = new BitmapImage();
                    bitmap.BeginInit();
                    bitmap.StreamSource = stream;
                    bitmap.CacheOption  = BitmapCacheOption.OnLoad;
                    bitmap.EndInit();
                    bitmap.Freeze();
                    imgPreview.Source = bitmap;
                }
            }
            catch
            {
                try
                {
                    this.Width        = 500;
                    this.Height       = 338;
                    imgPreview.Width  = 500;
                    imgPreview.Height = 300;

                    SKBitmap errorBitmap = new SKBitmap(500, 300);
                    using (SKCanvas skCanvas = new SKCanvas(errorBitmap))
                    {
                        skCanvas.DrawText("ERROR, UNABLE TO RENDER CHAT", 40, 150,
                                          new SKPaint()
                        {
                            Typeface    = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold), TextSize = 18,
                            IsAntialias = true, FilterQuality = SKFilterQuality.High
                        });
                        SKBitmap peepo = SKBitmap.Decode(Application
                                                         .GetResourceStream(new Uri("pack://application:,,,/Images/peepoSad.png")).Stream);
                        skCanvas.DrawBitmap(peepo, 370, 132);
                    }

                    using (var stream = new MemoryStream())
                    {
                        SKImage.FromBitmap(errorBitmap).Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
                        var bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = stream;
                        bitmap.CacheOption  = BitmapCacheOption.OnLoad;
                        bitmap.EndInit();
                        bitmap.Freeze();
                        imgPreview.Source = bitmap;
                    }
                }
                catch
                {
                }
            }
        }
Пример #17
0
        }//end write JPEG

        public bool writeJpeg(CloudCoin cc, string tag, string filePath, string targetPath, string printMessage)
        {
            // Console.Out.WriteLine("Writing jpeg " + cc.sn);

            //  CoinUtils cu = new CoinUtils(cc);
            filePath = filePath.Replace("\\\\", "\\");
            bool fileSavedSuccessfully = true;

            /* BUILD THE CLOUDCOIN STRING */
            String cloudCoinStr = "01C34A46494600010101006000601D05"; //THUMBNAIL HEADER BYTES

            for (int i = 0; (i < 25); i++)
            {
                cloudCoinStr = cloudCoinStr + cc.an[i];
            } // end for each an

            //cloudCoinStr += "204f42455920474f4420262044454645415420545952414e545320";// Hex for " OBEY GOD & DEFEAT TYRANTS "
            //cloudCoinStr += "20466f756e6465727320372d352d3137";// Founders 7-5-17
            cloudCoinStr += "4c6976652046726565204f7220446965"; // Live Free or Die
            cloudCoinStr += "00000000000000000000000000";       //Set to unknown so program does not export user data
                                                                // for (int i =0; i < 25; i++) {
                                                                //     switch () { }//end switch pown char
                                                                // }//end for each pown
            cloudCoinStr += "00";                               // HC: Has comments. 00 = No
            cc.CalcExpirationDate();
            cloudCoinStr += cc.edHex;                           // 01;//Expiration date Sep 2016 (one month after zero month)
            cloudCoinStr += "01";                               //  cc.nn;//network number
            String hexSN     = cc.sn.ToString("X6");
            String fullHexSN = "";

            switch (hexSN.Length)
            {
            case 1: fullHexSN = ("00000" + hexSN); break;

            case 2: fullHexSN = ("0000" + hexSN); break;

            case 3: fullHexSN = ("000" + hexSN); break;

            case 4: fullHexSN = ("00" + hexSN); break;

            case 5: fullHexSN = ("0" + hexSN); break;

            case 6: fullHexSN = hexSN; break;
            }
            cloudCoinStr = (cloudCoinStr + fullHexSN);
            /* BYTES THAT WILL GO FROM 04 to 454 (Inclusive)*/
            byte[] ccArray = this.hexStringToByteArray(cloudCoinStr);


            /* READ JPEG TEMPLATE*/
            byte[] jpegBytes = null;

            //jpegBytes = readAllBytes(filePath);
            jpegBytes = File.ReadAllBytes(filePath);

            /* WRITE THE SERIAL NUMBER ON THE JPEG */

            //Bitmap bitmapimage;
            SKBitmap bitmapimage;
            //using (var ms = new MemoryStream(jpegBytes))
            {
                //bitmapimage = new Bitmap(ms);
                bitmapimage = SKBitmap.Decode(jpegBytes);
            }
            SKCanvas canvas = new SKCanvas(bitmapimage);
            //Graphics graphics = Graphics.FromImage(bitmapimage);
            //graphics.SmoothingMode = SmoothingMode.AntiAlias;
            //graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            SKPaint textPaint = new SKPaint()
            {
                IsAntialias = true,
                Color       = SKColors.White,
                TextSize    = 14,
                Typeface    = SKTypeface.FromFamilyName("Arial")
            };

            //PointF drawPointAddress = new PointF(30.0F, 25.0F);

            canvas.DrawText(printMessage, 30, 40, textPaint);
            //graphics.DrawString(String.Format("{0:N0}", cc.sn) + " of 16,777,216 on Network: 1", new Font("Arial", 10), Brushes.White, drawPointAddress);

            //ImageConverter converter = new ImageConverter();
            //byte[] snBytes = (byte[])converter.ConvertTo(bitmapimage, typeof(byte[]));
            SKImage image = SKImage.FromBitmap(bitmapimage);
            SKData  data  = image.Encode(SKEncodedImageFormat.Jpeg, 100);

            byte[] snBytes = data.ToArray();

            List <byte> b1 = new List <byte>(snBytes);
            List <byte> b2 = new List <byte>(ccArray);

            b1.InsertRange(4, b2);

            if (tag == "random")
            {
                Random r    = new Random();
                int    rInt = r.Next(100000, 1000000); //for ints
                tag = rInt.ToString();
            }

            string fileName = targetPath;

            File.WriteAllBytes(fileName, b1.ToArray());
            Console.Out.WriteLine("Writing to " + fileName);
            //CoreLogger.Log("Writing to " + fileName);
            return(fileSavedSuccessfully);
        }//end write JPEG
        public void Update(PageChatRender pageChatRender)
        {
            try
            {
                this.Width = Int32.Parse(pageChatRender.textWidth.Text) + 10;
                this.Height = Int32.Parse(pageChatRender.textHeight.Text) + 38;
                imgPreview.Height = Int32.Parse(pageChatRender.textHeight.Text);
                imgPreview.Width = Int32.Parse(pageChatRender.textWidth.Text);
                PreviewData previewData = JsonConvert.DeserializeObject<PreviewData>(File.ReadAllText("preview_data.json"));
                BlockingCollection<TwitchCommentPreview> finalComments = new BlockingCollection<TwitchCommentPreview>();
                SKBitmap previewBitmap = new SKBitmap((int)this.Width, (int)imgPreview.Height);
                SKColor backgroundColor = new SKColor(pageChatRender.colorBackground.SelectedColor.Value.R, pageChatRender.colorBackground.SelectedColor.Value.G, pageChatRender.colorBackground.SelectedColor.Value.B);
                SKColor messageColor = new SKColor(pageChatRender.colorFont.SelectedColor.Value.R, pageChatRender.colorFont.SelectedColor.Value.G, pageChatRender.colorFont.SelectedColor.Value.B);

                ChatRenderOptions renderOptions = new ChatRenderOptions()
                {
                    InputFile = pageChatRender.textJson.Text,
                    OutputFile = "",
                    BackgroundColor = backgroundColor,
                    ChatHeight = Int32.Parse(pageChatRender.textHeight.Text),
                    ChatWidth = Int32.Parse(pageChatRender.textWidth.Text),
                    BttvEmotes = (bool)pageChatRender.checkBTTV.IsChecked,
                    FfzEmotes = (bool)pageChatRender.checkFFZ.IsChecked,
                    Outline = (bool)pageChatRender.checkOutline.IsChecked,
                    Font = (string)pageChatRender.comboFont.SelectedItem,
                    FontSize = Double.Parse(pageChatRender.textFontSize.Text),
                    UpdateRate = Double.Parse(pageChatRender.textUpdateTime.Text),
                    Timestamp = (bool)pageChatRender.checkTimestamp.IsChecked,
                    MessageColor = messageColor,
                    Framerate = Int32.Parse(pageChatRender.textFramerate.Text),
                    InputArgs = Settings.Default.FfmpegInputArgs,
                    OutputArgs = Settings.Default.FfmpegOutputArgs,
                    MessageFontStyle = SKFontStyle.Normal,
                    UsernameFontStyle = SKFontStyle.Bold
                };
                System.Drawing.Size canvasSize = new System.Drawing.Size(renderOptions.ChatWidth, renderOptions.SectionHeight);
                SKPaint nameFont = new SKPaint() { Typeface = SKTypeface.FromFamilyName(renderOptions.Font, renderOptions.UsernameFontStyle), LcdRenderText = true, SubpixelText = true, TextSize = (float)renderOptions.FontSize, IsAntialias = true, HintingLevel = SKPaintHinting.Full, FilterQuality = SKFilterQuality.High };
                SKPaint messageFont = new SKPaint() { Typeface = SKTypeface.FromFamilyName(renderOptions.Font, renderOptions.MessageFontStyle), LcdRenderText = true, SubpixelText = true, TextSize = (float)renderOptions.FontSize, IsAntialias = true, HintingLevel = SKPaintHinting.Full, FilterQuality = SKFilterQuality.High, Color = renderOptions.MessageColor };
                List<TwitchEmote> thirdPartyEmotes = new List<TwitchEmote>();
                List<TwitchEmote> chatEmotes = new List<TwitchEmote>();
                Dictionary<string, SKBitmap> emojiCache = new Dictionary<string, SKBitmap>();

                using (SKCanvas previewCanvas = new SKCanvas(previewBitmap))
                {
                    previewCanvas.Clear(backgroundColor);

                    foreach (PreviewEmote previewDataEmote in previewData.emotes)
                    {
                        byte[] imageBytes = Convert.FromBase64String(previewDataEmote.image);
                        SKBitmap emoteBitmap = SKBitmap.Decode(imageBytes);
                        SKCodec emoteCodec;
                        using (MemoryStream ms = new MemoryStream(imageBytes))
                            emoteCodec = SKCodec.Create(ms);

                        TwitchEmote emote = new TwitchEmote(new List<SKBitmap>() { emoteBitmap }, emoteCodec, previewDataEmote.name, ".png", "0", 1, imageBytes);
                        thirdPartyEmotes.Add(emote);
                    }

                    foreach (PreviewComment previewComment in previewData.comments)
                    {
                        int default_x = 2;
                        System.Drawing.Point drawPos = new System.Drawing.Point(default_x, 0);
                        string userName = previewComment.name;
                        SKColor userColor = new SKColor(Convert.ToByte(previewComment.color.Substring(0, 2), 16), Convert.ToByte(previewComment.color.Substring(2, 2), 16), Convert.ToByte(previewComment.color.Substring(4, 2), 16));
                        List<SKBitmap> imageList = new List<SKBitmap>();
                        SKBitmap sectionImage = new SKBitmap(canvasSize.Width, canvasSize.Height);
                        List<GifEmote> currentGifEmotes = new List<GifEmote>();
                        List<SKBitmap> emoteList = new List<SKBitmap>();
                        List<CheerEmote> cheerEmotes = new List<CheerEmote>();
                        List<SKRect> emotePositionList = new List<SKRect>();
                        new SKCanvas(sectionImage).Clear(renderOptions.BackgroundColor);
                        Comment comment = new Comment();
                        comment.message = new Message();
                        Fragment msg = new Fragment();
                        msg.text = previewComment.message;
                        comment.message.fragments = new List<Fragment>();
                        comment.message.fragments.Add(msg);
                        if (renderOptions.Timestamp)
                            sectionImage = ChatRenderer.DrawTimestamp(sectionImage, imageList, messageFont, renderOptions, comment, canvasSize, ref drawPos, ref default_x);
                        if (previewComment.badges != null)
                            sectionImage = DrawBadges(sectionImage, imageList, renderOptions, canvasSize, ref drawPos, previewComment);
                        sectionImage = ChatRenderer.DrawUsername(sectionImage, imageList, renderOptions, nameFont, userName, userColor, canvasSize, ref drawPos);
                        sectionImage = ChatRenderer.DrawMessage(sectionImage, imageList, renderOptions, currentGifEmotes, messageFont, emojiCache, chatEmotes, thirdPartyEmotes, cheerEmotes, comment, canvasSize, ref drawPos, ref default_x, emoteList, emotePositionList);

                        int finalHeight = 0;
                        foreach (var img in imageList)
                            finalHeight += img.Height;
                        SKBitmap finalImage = new SKBitmap(canvasSize.Width, finalHeight);
                        SKCanvas finalImageCanvas = new SKCanvas(finalImage);
                        finalHeight = 0;
                        foreach (var img in imageList)
                        {
                            finalImageCanvas.DrawBitmap(img, 0, finalHeight);
                            finalHeight += img.Height;
                            img.Dispose();
                        }

                        finalComments.Add(new TwitchCommentPreview(finalImage, Double.Parse(comment.content_offset_seconds.ToString()), currentGifEmotes, emoteList, emotePositionList));
                    }

                    int y = 0;
                    int tempHeight = 0;
                    foreach (TwitchCommentPreview twitchCommentPreview in finalComments)
                        tempHeight += twitchCommentPreview.section.Height;
                    SKBitmap tempBitmap = new SKBitmap((int)this.Width, tempHeight);

                    using (SKCanvas tempCanvas = new SKCanvas(tempBitmap))
                    {
                        foreach (TwitchCommentPreview twitchCommentPreview in finalComments)
                        {
                            tempCanvas.DrawBitmap(twitchCommentPreview.section, 0, y, imagePaint);

                            for (int i = 0; i < twitchCommentPreview.normalEmotes.Count; i++)
                            {
                                SKRect refrenceRect = twitchCommentPreview.normalEmotesPositions[i];
                                tempCanvas.DrawBitmap(twitchCommentPreview.normalEmotes[i], new SKRect(refrenceRect.Left, refrenceRect.Top + y, refrenceRect.Right, refrenceRect.Bottom + y), imagePaint);
                            }

                            y += twitchCommentPreview.section.Height;
                        }
                    }

                    previewCanvas.DrawBitmap(tempBitmap, 0, previewBitmap.Height - tempBitmap.Height);
                }

                using (var stream = new MemoryStream())
                {
                    SKImage.FromBitmap(previewBitmap).Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
                    var bitmap = new BitmapImage();
                    bitmap.BeginInit();
                    bitmap.StreamSource = stream;
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    bitmap.EndInit();
                    bitmap.Freeze();
                    imgPreview.Source = bitmap;
                }
            }
            catch
            {
                try
                {
                    this.Width = 500;
                    this.Height = 338;
                    imgPreview.Width = 500;
                    imgPreview.Height = 300;

                    SKBitmap errorBitmap = new SKBitmap(500, 300);
                    using (SKCanvas skCanvas = new SKCanvas(errorBitmap))
                    {
                        skCanvas.DrawText("ERROR, UNABLE TO RENDER CHAT", 40, 150,
                            new SKPaint()
                            {
                                Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold), TextSize = 18,
                                IsAntialias = true, FilterQuality = SKFilterQuality.High
                            });
                        SKBitmap peepo = SKBitmap.Decode(Application
                            .GetResourceStream(new Uri("pack://application:,,,/Images/peepoSad.png")).Stream);
                        skCanvas.DrawBitmap(peepo, 370, 132);
                    }

                    using (var stream = new MemoryStream())
                    {
                        SKImage.FromBitmap(errorBitmap).Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
                        var bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = stream;
                        bitmap.CacheOption = BitmapCacheOption.OnLoad;
                        bitmap.EndInit();
                        bitmap.Freeze();
                        imgPreview.Source = bitmap;
                    }
                }
                catch
                {

                }
            }
        }
Пример #19
0
        public async Task drawGaugeAsync()
        {
            // Radial Gauge Constants
            int uPadding         = 150;
            int side             = 500;
            int radialGaugeWidth = 55;

            // Line TextSize inside Radial Gauge
            int lineSize1 = 220;
            int lineSize2 = 70;
            int lineSize3 = 80;
            int lineSize4 = 100;

            // Line Y Coordinate inside Radial Gauge
            int lineHeight1 = 70;
            int lineHeight2 = 170;
            int lineHeight3 = 270;
            int lineHeight4 = 370;
            int lineHeight5 = 530;

            // Start & End Angle for Radial Gauge
            float startAngle = -220;
            float sweepAngle = 260;

            try
            {
                // Getting Canvas Info
                SKImageInfo info    = args.Info;
                SKSurface   surface = args.Surface;
                SKCanvas    canvas  = surface.Canvas;
                progressUtils.setDevice(info.Height, info.Width);
                canvas.Clear();
                SKBlendMode blend = SKBlendMode.SrcIn;
                canvas.DrawColor(Color.White.ToSKColor(), blend);
                // Getting Device Specific Screen Values
                // -------------------------------------------------

                // Top Padding for Radial Gauge
                float upperPading = progressUtils.getFactoredHeight(uPadding);

                /* Coordinate Plotting for Radial Gauge
                 *
                 *    (X1,Y1) ------------
                 *           |   (XC,YC)  |
                 *           |      .     |
                 *         Y |            |
                 *           |            |
                 *            ------------ (X2,Y2))
                 *                  X
                 *
                 * To fit a perfect Circle inside --> X==Y
                 *       i.e It should be a Square
                 */

                // Xc & Yc are center of the Circle
                int   Xc = info.Width / 2;
                float Yc = progressUtils.getFactoredHeight(side);

                // X1 Y1 are lefttop cordiates of rectange
                int X1 = (int)(Xc - Yc);
                int Y1 = (int)(Yc - Yc + upperPading);

                // X2 Y2 are rightbottom cordiates of rectange
                int X2 = (int)(Xc + Yc);
                int Y2 = (int)(Yc + Yc + upperPading);

                //Loggig Screen Specific Calculated Values
                Debug.WriteLine("INFO " + info.Width + " - " + info.Height);
                Debug.WriteLine(" C : " + upperPading + "  " + info.Height);
                Debug.WriteLine(" C : " + Xc + "  " + Yc);
                Debug.WriteLine("XY : " + X1 + "  " + Y1);
                Debug.WriteLine("XY : " + X2 + "  " + Y2);

                //  Empty Gauge Styling
                SKPaint paint1 = new SKPaint
                {
                    Style       = SKPaintStyle.Stroke,
                    Color       = Color.FromHex("#e0dfdf").ToSKColor(),             // Colour of Radial Gauge
                    StrokeWidth = progressUtils.getFactoredWidth(radialGaugeWidth), // Width of Radial Gauge
                    StrokeCap   = SKStrokeCap.Round                                 // Round Corners for Radial Gauge
                };

                // Filled Gauge Styling
                SKPaint paint2 = new SKPaint
                {
                    Style       = SKPaintStyle.Stroke,
                    Color       = Color.FromHex("#05c782").ToSKColor(),             // Overlay Colour of Radial Gauge
                    StrokeWidth = progressUtils.getFactoredWidth(radialGaugeWidth), // Overlay Width of Radial Gauge
                    StrokeCap   = SKStrokeCap.Round                                 // Round Corners for Radial Gauge
                };

                // Defining boundaries for Gauge
                SKRect rect = new SKRect(X1, Y1, X2, Y2);


                //canvas.DrawRect(rect, paint1);
                //canvas.DrawOval(rect, paint1);

                // Rendering Empty Gauge
                SKPath path1 = new SKPath();
                path1.AddArc(rect, startAngle, sweepAngle);
                canvas.DrawPath(path1, paint1);

                // Rendering Filled Gauge
                SKPath path2 = new SKPath();
                path2.AddArc(rect, startAngle, (float)sweepAngleSlider.Value);
                canvas.DrawPath(path2, paint2);

                //---------------- Drawing Text Over Gauge ---------------------------

                // Achieved Minutes
                using (SKPaint skPaint = new SKPaint())
                {
                    skPaint.Style       = SKPaintStyle.Fill;
                    skPaint.IsAntialias = true;
                    skPaint.Color       = SKColor.Parse("#676a69");
                    skPaint.TextAlign   = SKTextAlign.Center;
                    skPaint.TextSize    = progressUtils.getFactoredHeight(lineSize1);
                    skPaint.Typeface    = SKTypeface.FromFamilyName(
                        "Arial",
                        SKFontStyleWeight.Bold,
                        SKFontStyleWidth.Normal,
                        SKFontStyleSlant.Upright);

                    // Drawing Achieved Minutes Over Radial Gauge
                    //  if (sw_listToggle.IsToggled)
                    //     canvas.DrawText(chartvalue + "", Xc, Yc + progressUtils.getFactoredHeight(lineHeight1), skPaint);
                    // else
                    //    canvas.DrawText(dailyWorkout + "", Xc, Yc + progressUtils.getFactoredHeight(lineHeight1), skPaint);
                }

                // Achieved Minutes Text Styling
                using (SKPaint skPaint = new SKPaint())
                {
                    skPaint.Style       = SKPaintStyle.Fill;
                    skPaint.IsAntialias = true;
                    skPaint.Color       = SKColor.Parse("#676a69");
                    skPaint.TextAlign   = SKTextAlign.Center;
                    skPaint.TextSize    = progressUtils.getFactoredHeight(lineSize2);
                    // canvas.DrawText("Seconds", Xc, Yc + progressUtils.getFactoredHeight(lineHeight2), skPaint);
                }

                // Goal Minutes Text Styling
                using (SKPaint skPaint = new SKPaint())
                {
                    skPaint.Style       = SKPaintStyle.Fill;
                    skPaint.IsAntialias = true;
                    skPaint.Color       = SKColor.Parse("#e2797a");
                    skPaint.TextAlign   = SKTextAlign.Center;
                    skPaint.TextSize    = progressUtils.getFactoredHeight(lineSize3);
                    skPaint.Typeface    = SKTypeface.FromFamilyName(
                        "Arial",
                        SKFontStyleWeight.Bold,
                        SKFontStyleWidth.Normal,
                        SKFontStyleSlant.Upright);

                    // Drawing Text Over Radial Gauge
                    // if (sw_listToggle.IsToggled)
                    // canvas.DrawText(DateTime.Now.ToString("dddd, dd'-'MM'-'yyyy"), Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint);
                    //else
                    {
                        //  canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint);
                    }
                }

                // Goal Minutes Text Styling
                using (SKPaint skPaint = new SKPaint())
                {
                    skPaint.Style       = SKPaintStyle.Fill;
                    skPaint.IsAntialias = true;
                    skPaint.Color       = SKColor.Parse("#e2797a");
                    skPaint.TextAlign   = SKTextAlign.Center;
                    skPaint.TextSize    = progressUtils.getFactoredHeight(lineSize3);
                    skPaint.Typeface    = SKTypeface.FromFamilyName(
                        "Arial",
                        SKFontStyleWeight.Bold,
                        SKFontStyleWidth.Normal,
                        SKFontStyleSlant.Upright);

                    // Drawing Text Over Radial Gauge
                    // if (sw_listToggle.IsToggled)
                    //  canvas.DrawText(DateTime.Now.ToString("HH:mm:ss"), Xc, Yc + progressUtils.getFactoredHeight(lineHeight4), skPaint);
                    //else
                    {
                        //  canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint);
                    }
                }
                // Goal Minutes Text Styling
                using (SKPaint skPaint = new SKPaint())
                {
                    skPaint.Style       = SKPaintStyle.Fill;
                    skPaint.IsAntialias = true;
                    skPaint.Color       = SKColor.Parse("#676a69");
                    skPaint.TextAlign   = SKTextAlign.Center;
                    skPaint.TextSize    = progressUtils.getFactoredHeight(lineSize4);
                    skPaint.Typeface    = SKTypeface.FromFamilyName(
                        "Arial",
                        SKFontStyleWeight.Bold,
                        SKFontStyleWidth.Normal,
                        SKFontStyleSlant.Upright);

                    // Drawing Text Over Radial Gauge
                    // if (sw_listToggle.IsToggled)
                    canvas.DrawText("Battery " + Chartvalue + "%", Xc, Yc + progressUtils.getFactoredHeight(lineHeight5), skPaint);
                    //else
                    {
                        //  canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
            }
        }
Пример #20
0
        public static void DrawCaptionLabels(this SKCanvas canvas, string label, SKColor labelColor, bool labelIsUnicode, char unicodeLang, string value, SKColor valueColor, float textSize, SKPoint point, SKTextAlign horizontalAlignment, SKTypeface typeface, out SKRect totalBounds)
        {
            var hasLabel      = !string.IsNullOrEmpty(label);
            var hasValueLabel = !string.IsNullOrEmpty(value);

            totalBounds = new SKRect();

            if (hasLabel || hasValueLabel)
            {
                var hasOffset     = hasLabel && hasValueLabel;
                var captionMargin = textSize * 0.60f;
                var space         = hasOffset ? captionMargin : 0;

                if (hasLabel)
                {
                    using (var paint = new SKPaint
                    {
                        TextSize = textSize,
                        IsAntialias = true,
                        Color = labelColor,
                        IsStroke = false,
                        TextAlign = horizontalAlignment,
                        Typeface = typeface
                    })
                    {
                        var bounds = new SKRect();
                        var text   = label;
                        paint.MeasureText(text, ref bounds);

                        var y = point.Y - ((bounds.Top + bounds.Bottom) / 2) - space;

                        if (labelIsUnicode)
                        {
                            using (var tf = SKFontManager.Default.MatchCharacter(unicodeLang))
                                using (var shaper = new SKShaper(tf))
                                {
                                    canvas.DrawShapedText(shaper, text, 0, 0, paint);
                                }
                        }
                        else
                        {
                            canvas.DrawText(text, point.X, y, paint);
                        }

                        var labelBounds = GetAbsolutePositionRect(point.X, y, bounds, horizontalAlignment);
                        totalBounds = labelBounds.Standardized;
                    }
                }

                if (hasValueLabel)
                {
                    using (var paint = new SKPaint()
                    {
                        TextSize = textSize,
                        IsAntialias = true,
                        FakeBoldText = true,
                        Color = valueColor,
                        IsStroke = false,
                        TextAlign = horizontalAlignment,
                        Typeface = typeface
                    })
                    {
                        var bounds = new SKRect();
                        var text   = value;
                        paint.MeasureText(text, ref bounds);

                        var y = point.Y - ((bounds.Top + bounds.Bottom) / 2) + space;

                        canvas.DrawText(text, point.X, y, paint);

                        var valueBounds = GetAbsolutePositionRect(point.X, y, bounds, horizontalAlignment);

                        if (totalBounds.IsEmpty)
                        {
                            totalBounds = valueBounds;
                        }
                        else
                        {
                            totalBounds.Union(valueBounds);
                        }
                    }
                }
            }
        }
Пример #21
0
 /// <summary>
 /// Load a font from a file
 /// </summary>
 /// <param name="fileName">The path to the input file</param>
 /// <returns>The loaded font</returns>
 public static SKTypeface LoadFont(string fileName)
 {
     using (var stream = File.OpenRead(fileName))
         using (var data = SKData.Create(stream))
             return(SKTypeface.FromData(data));
 }
Пример #22
0
        public static SKTypeface SFBold()
        {
            var customFontPath = NSBundle.MainBundle.PathForResource("SanFranciscoDisplay-Bold", ".otf", "Fonts");

            return(SKTypeface.FromFile(customFontPath));
        }
Пример #23
0
        internal static void DrawLabel(SKCanvas canvas, Orientation orientation, YPositionBehavior yPositionBehavior, SKSize itemSize, SKPoint point, SKColor color, SKRect bounds, string text, float textSize, SKTypeface typeface)
        {
            using (new SKAutoCanvasRestore(canvas))
            {
                using (var paint = new SKPaint())
                {
                    paint.TextSize    = textSize;
                    paint.IsAntialias = true;
                    paint.Color       = color;
                    paint.IsStroke    = false;
                    paint.Typeface    = typeface;

                    if (orientation == Orientation.Vertical)
                    {
                        var y = point.Y;

                        switch (yPositionBehavior)
                        {
                        case YPositionBehavior.UpToElementHeight:
                            y -= bounds.Width;
                            break;

                        case YPositionBehavior.UpToElementMiddle:
                            y -= bounds.Width / 2;
                            break;

                        case YPositionBehavior.DownToElementMiddle:
                            y += bounds.Width / 2;
                            break;

                        case YPositionBehavior.None:
                        default:
                            break;
                        }

                        canvas.RotateDegrees(90);
                        canvas.Translate(y, -point.X + (bounds.Height / 2));
                    }
                    else
                    {
                        if (bounds.Width > itemSize.Width)
                        {
                            text = text.Substring(0, Math.Min(3, text.Length));
                            paint.MeasureText(text, ref bounds);
                        }

                        if (bounds.Width > itemSize.Width)
                        {
                            text = text.Substring(0, Math.Min(1, text.Length));
                            paint.MeasureText(text, ref bounds);
                        }

                        var y = point.Y;

                        switch (yPositionBehavior)
                        {
                        case YPositionBehavior.UpToElementHeight:
                            y -= bounds.Height;
                            break;

                        case YPositionBehavior.UpToElementMiddle:
                            y -= bounds.Height / 2;
                            break;

                        case YPositionBehavior.DownToElementMiddle:
                            y += bounds.Height / 2;
                            break;

                        case YPositionBehavior.None:
                        default:
                            break;
                        }

                        canvas.Translate(point.X - (bounds.Width / 2), y);
                    }

                    canvas.DrawText(text, 0, 0, paint);
                }
            }
        }
Пример #24
0
        private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
        {
            var surface = e.Surface;
            var canvas  = surface.Canvas;

            canvas.Clear(SKColors.White);

            var fontAwesome         = "I {{fa-heart-o color=ff0000}} to {{fa-code}} on {{fa-windows color=1BA1E2}}!";
            var ionIcons            = "{{ion-ios-cloud-download-outline color=0000ff}} the SkiaSharp source from {{ion-social-github}}.";
            var materialDesignIcons = "SkiaSharp works on {{mdi-apple}}, {{mdi-android color=a4c639}}, {{mdi-windows}} and {{mdi-linux}}!";
            var materialIcons       = "SkiaSharp supports {{brush}} and {{photo color=006400}}!";
            var meteocons           = "We love the {{mc-sun color=f9d71c}} and some {{mc-cloud-double-o}} s.";
            var simple   = "We all {{icon-heart color=ff0000}} a {{icon-present}}!";
            var typicons = "SkiaSharp runs on {{typcn-device-desktop}}, {{typcn-device-laptop}}, {{typcn-device-phone}} and {{typcn-device-tablet}} devices!";
            var weather  = "An {{wi-solar-eclipse}} is when the {{wi-day-sunny color=f9d71c}} is hidden.";

            using (var lookup = new SKTextRunLookup())
                using (var textPaint = new SKPaint())
                {
                    // the lookup does not have to be re-created on each draw
                    // instead, it can be created and re-used
                    FontAwesome.AddTo(lookup);
                    IonIcons.AddTo(lookup);
                    MaterialDesignIcons.AddTo(lookup);
                    MaterialIcons.AddTo(lookup);
                    Meteocons.AddTo(lookup);
                    SimpleLineIcons.AddTo(lookup);
                    Typicons.AddTo(lookup);
                    WeatherIcons.AddTo(lookup);

                    textPaint.IsAntialias = true;
                    textPaint.TextSize    = 48;
                    textPaint.Typeface    = SKTypeface.FromFamilyName("Arial");

                    // the DrawIconifiedText method will re-calculate the text runs
                    // it may be better to cache this using the:
                    //     var runs = SKTextRun.Create(text, lookup);
                    // and then drawing it using the DrawText method.
                    var padding = 24;
                    var yOffset = padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(fontAwesome, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(ionIcons, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(materialDesignIcons, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(materialIcons, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(meteocons, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(simple, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(typicons, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;

                    canvas.DrawIconifiedText(weather, padding, yOffset, lookup, textPaint);
                    yOffset += padding + textPaint.TextSize;
                }
        }
Пример #25
0
        internal static void DrawLabel(SKCanvas canvas, Orientation orientation, bool isTop, SKSize itemSize, SKPoint point, SKColor color, SKRect bounds, string text, float textSize, SKTypeface typeface)
        {
            using (new SKAutoCanvasRestore(canvas))
            {
                using (var paint = new SKPaint())
                {
                    paint.TextSize    = textSize;
                    paint.IsAntialias = true;
                    paint.Color       = color;
                    paint.IsStroke    = false;
                    paint.Typeface    = typeface;

                    if (orientation == Orientation.Vertical)
                    {
                        var y = point.Y;

                        if (isTop)
                        {
                            y -= bounds.Width;
                        }

                        canvas.RotateDegrees(90);
                        canvas.Translate(y, -point.X + (bounds.Height / 2));
                    }
                    else
                    {
                        if (bounds.Width > itemSize.Width)
                        {
                            text = text.Substring(0, Math.Min(3, text.Length));
                            paint.MeasureText(text, ref bounds);
                        }

                        if (bounds.Width > itemSize.Width)
                        {
                            text = text.Substring(0, Math.Min(1, text.Length));
                            paint.MeasureText(text, ref bounds);
                        }

                        var y = point.Y;

                        if (isTop)
                        {
                            y -= bounds.Height;
                        }

                        canvas.Translate(point.X - (bounds.Width / 2), y);
                    }

                    canvas.DrawText(text, 0, 0, paint);
                }
            }
        }
 static CustomFontMapper()
 {
     typeface      = SKTypeface.FromFile("NotoSansCJKsc-Regular.otf");
     typefaceLight = SKTypeface.FromFile("NotoSansCJKsc-Light.otf");
 }
Пример #27
0
        private SKBitmap BuildThumbCollageBitmap(string[] paths, int width, int height, string?libraryName)
        {
            var bitmap = new SKBitmap(width, height);

            using var canvas = new SKCanvas(bitmap);
            canvas.Clear(SKColors.Black);

            using var backdrop = GetNextValidImage(paths, 0, out _);
            if (backdrop == null)
            {
                return(bitmap);
            }

            // resize to the same aspect as the original
            var backdropHeight = Math.Abs(width * backdrop.Height / backdrop.Width);

            using var residedBackdrop = SkiaEncoder.ResizeImage(backdrop, new SKImageInfo(width, backdropHeight, backdrop.ColorType, backdrop.AlphaType, backdrop.ColorSpace));
            // draw the backdrop
            canvas.DrawImage(residedBackdrop, 0, 0);

            // draw shadow rectangle
            var paintColor = new SKPaint
            {
                Color = SKColors.Black.WithAlpha(0x78),
                Style = SKPaintStyle.Fill
            };

            canvas.DrawRect(0, 0, width, height, paintColor);

            var typeFace = SKTypeface.FromFamilyName("sans-serif", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright) ?? SKTypeface.CreateDefault();

            // use the system fallback to find a typeface for the given CJK character
            var nonCjkPattern = @"[^\p{IsCJKUnifiedIdeographs}\p{IsCJKUnifiedIdeographsExtensionA}\p{IsKatakana}\p{IsHiragana}\p{IsHangulSyllables}\p{IsHangulJamo}]";
            var filteredName  = Regex.Replace(libraryName ?? string.Empty, nonCjkPattern, string.Empty);

            if (!string.IsNullOrEmpty(filteredName))
            {
                typeFace = SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, filteredName[0]);
            }

            // draw library name
            var textPaint = new SKPaint
            {
                Color       = SKColors.White,
                Style       = SKPaintStyle.Fill,
                TextSize    = 112,
                TextAlign   = SKTextAlign.Center,
                Typeface    = typeFace,
                IsAntialias = true
            };

            // scale down text to 90% of the width if text is larger than 95% of the width
            var textWidth = textPaint.MeasureText(libraryName);

            if (textWidth > width * 0.95)
            {
                textPaint.TextSize = 0.9f * width * textPaint.TextSize / textWidth;
            }

            canvas.DrawText(libraryName, width / 2f, (height / 2f) + (textPaint.FontMetrics.XHeight / 2), textPaint);

            return(bitmap);
        }
Пример #28
0
        public SKData DrawHistogram(string referenceName, int zoom, int chunk)
        {
            var refer = _service._references.FirstOrDefault(r => r.Name == referenceName);

            if (chunk == 0 && zoom == 10)
            {
                LoadReference(referenceName);
            }

            using var surface     = SKSurface.Create(new SKImageInfo(refer.Length * zoom, 220));
            using SKCanvas canvas = surface.Canvas;

            canvas.Clear();

            using SKPaint paint = new SKPaint
                  {
                      Style       = SKPaintStyle.StrokeAndFill,
                      Color       = SKColors.Blue,
                      StrokeWidth = 1
                  };

            using SKPaint linePaint = new SKPaint
                  {
                      Style       = SKPaintStyle.Stroke,
                      Color       = SKColors.Black,
                      StrokeWidth = 1
                  };

            using SKPaint dashPaint = new SKPaint
                  {
                      Style       = SKPaintStyle.Stroke,
                      Color       = SKColors.Black,
                      StrokeWidth = 1,
                      PathEffect  = SKPathEffect.CreateDash(new[] { 20f, 5f }, 0)
                  };

            var histData = _service._histograms[refer.Name];

            var scale = (float)(100 / histData.Average());

            for (int i = 0; i < refer.Length; i++)
            {
                canvas.DrawRect(i * zoom + 5, 200 - (histData[i] * scale), zoom, histData[i] * scale, paint);
            }

            canvas.DrawLine(5, 0, 5, 200, linePaint);
            canvas.DrawLine(5, 199, refer.Length * zoom, 199, linePaint);

            var average = (int)(Math.Round(histData.Average()));

            canvas.DrawLine(5, average * scale, refer.Length * zoom, average * scale, dashPaint);

            using SKPaint textPaint = new SKPaint
                  {
                      Style        = SKPaintStyle.StrokeAndFill,
                      Color        = SKColors.Black,
                      StrokeWidth  = 1,
                      TextSize     = 20,
                      Typeface     = SKTypeface.FromFamilyName("Courier New"),
                      SubpixelText = true
                  };
            canvas.DrawText(average.ToString(), 6, average * scale - 2, textPaint);

            var cnt = textPaint.MeasureText("ACGT");

            if (zoom == 10)
            {
                textPaint.TextSize = textPaint.TextSize * 40 / cnt;
                var shaper = new SKShaper(SKTypeface.FromFamilyName("Courier New"));

                canvas.DrawShapedText(shaper, reference, 5, 215, textPaint);
            }

            var      width  = (chunk + 1) * WIDTH * zoom > refer.Length * zoom ? refer.Length * zoom % WIDTH : WIDTH;
            SKPixmap pixmap = surface.Snapshot().Subset(SKRectI.Create(chunk * WIDTH, 0, width, canvas.DeviceClipBounds.Height)).PeekPixels();

            var options = new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossless, 100);

            return(pixmap.Encode(options));
        }
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.DrawColor(SKColors.White);

            var basePaint = new SKPaint();

            basePaint.IsAntialias = true;
            basePaint.TextSize    = 60;

            // first, we can just use a font (system default if not exists)
            using (var paint = basePaint.Clone())
                using (var courier = SKTypeface.FromFamilyName("Courier New"))
                {
                    paint.Typeface = courier;
                    canvas.DrawText("'A', 'ݐ', '年'", 40, 100, paint);
                }

            // the font manager finds fonts
            var fontManager = SKFontManager.Default;

            // or, we can try and make sure that we have the character, and hope it has the others
            using (var paint = basePaint.Clone())
                using (var courier = fontManager.MatchCharacter("Courier New", 'ݐ'))
                {
                    paint.Typeface = courier;
                    canvas.DrawText("'A', 'ݐ', '年'", 40, 200, paint);
                }

            // if we know the font doesn't have the character, or don't want to fall back
            using (var paint = basePaint.Clone())
                using (var courier = SKTypeface.FromFamilyName("Courier New"))
                    using (var arabic = fontManager.MatchCharacter("Courier New", 'ݐ'))
                        using (var japanese = fontManager.MatchCharacter("Courier New", '年'))
                        {
                            var first    = "'A', '";
                            var arabChar = "ݐ";
                            var mid      = "', '";
                            var japChar  = "年";
                            var last     = "'";

                            float x = 40;

                            // draw the first bit
                            paint.Typeface = courier;
                            canvas.DrawText(first, x, 300, paint);
                            x += paint.MeasureText(first);

                            // the arab character
                            paint.Typeface = arabic;
                            canvas.DrawText(arabChar, x, 300, paint);
                            x += paint.MeasureText(arabChar);

                            // draw the next bit
                            paint.Typeface = courier;
                            canvas.DrawText(mid, x, 300, paint);
                            x += paint.MeasureText(mid);

                            // the japanese character
                            paint.Typeface = japanese;
                            canvas.DrawText(japChar, x, 300, paint);
                            x += paint.MeasureText(japChar);

                            // the end
                            paint.Typeface = courier;
                            canvas.DrawText(last, x, 300, paint);
                        }

            // let's draw some emojis (UTF-32 characters)
            var emojiChar = StringUtilities.GetUnicodeCharacterCode("🚀", SKTextEncoding.Utf32);

            using (var paint = basePaint.Clone())
                using (var emoji = fontManager.MatchCharacter(emojiChar))
                {
                    paint.Typeface = emoji;
                    canvas.DrawText("🌐 🍪 🍕 🚀", 40, 400, paint);
                }
        }
Пример #30
0
        public async Task <Stream> DrawProfile(User user)
        {
            // get bitmaps
            background = await Utils.GetBitmapFromUrl(user.BackgroundUrl);

            avatar = await Utils.GetBitmapFromUrl(user.AvatarUrl);

            // clear the canvas
            canvas.Clear(clearColor);

            // draw background
            {
                using (SKPaint paint = new SKPaint())
                {
                    // setup paint
                    paint.FilterQuality = SKFilterQuality.High;

                    // resize, crop and covert to image background
                    SKImage BackgroundImage = PrepareBackground(background);

                    // draw background
                    canvas.DrawImage(BackgroundImage, SKRect.Create(0, 0, profileWidth, profileHeight), paint);
                }
            }

            // draw panels
            {
                // setups paint and canvas
                panel.Open();

                // main panel
                {
                    var position  = new SKPoint(20 * scale, 150 * scale);
                    var size      = new SKSize(472 * scale, 342 * scale);
                    var roundRect = new SKRoundRect(SKRect.Create(position, size), 32 * scale);
                    panel.DrawRounRect(roundRect);
                }

                // avatar border
                {
                    var position = new SKPoint(x: 192 * scale, y: 82 * scale);
                    var radius   = 64 * scale;
                    var border   = 16;

                    panel.DrawCircle(position.X - border, position.Y - border, radius + border);
                }

                // draw panels
                panel.Close();
            }

            // draw avatar
            {
                // avatar information
                var position = new SKPoint(x: 192 * scale, y: 82 * scale);
                var size     = new SKSize(width: 128 * scale, height: 128 * scale);
                var radius   = 64 * scale;

                using (var paint = new SKPaint())
                {
                    // setup paint
                    paint.IsAntialias   = true;
                    paint.FilterQuality = SKFilterQuality.High;

                    // save canvas
                    canvas.Save();

                    // create clip and aplay it to canvas
                    using (SKPath clip = new SKPath())
                    {
                        clip.AddCircle(radius + position.X, radius + position.Y, radius);
                        canvas.ClipPath(clip, SKClipOperation.Intersect, true);
                    }

                    // draw avatar
                    canvas.DrawBitmap(avatar, SKRect.Create(position, size), paint);

                    // restore canvas
                    canvas.Restore();
                }
            }

            // draw username
            {
                using (var paint = new SKPaint())
                {
                    // setup paint
                    paint.TextSize    = (int)(48 * scale);
                    paint.Color       = SKColors.White;
                    paint.IsAntialias = true;

                    // calculate position
                    float UsernameLength = paint.MeasureText($"{ user.Username }#{ user.Discriminator }");
                    float x = ((profileWidth - UsernameLength) / 2);
                    float y = 250 * scale;

                    // draw username
                    paint.Typeface = SKTypeface.FromFile("Common/Assets/Fonts/Roboto-Regular.ttf");
                    canvas.DrawText(user.Username, x, y, paint);

                    // recalculate position for discriminator
                    float offset = paint.MeasureText($"{ user.Username }");
                    x += offset;

                    // draw discriminator
                    paint.Typeface = SKTypeface.FromFile("Common/Assets/Fonts/Roboto-Thin.ttf");
                    canvas.DrawText($"#{ user.Discriminator }", x, y, paint);
                }
            }


            // return surface as stream
            return(surface.Snapshot().Encode().AsStream());
        }