Пример #1
0
        public Form1()
        {
            InitializeComponent();
            ResizeRedraw = true;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

            /*
             * _richString = new RichString()
             *          .FontSize(18).FontFamily("Open Sans")
             *          .Alignment(TextAlignment.Center).MarginBottom(20)
             *          .Add("CHARACTER SPACING!!", letterSpacing: 10, fontSize: 28)
             *          .Paragraph()
             *          .Alignment(TextAlignment.Left)
             *          .Add("Para2a\nParam2b")
             *          ;
             * var rs = new RichString()
             *  .Alignment(TextAlignment.Center)
             *  .FontFamily("Segoe UI")
             *  .MarginBottom(20)
             *  .Add("Welcome To RichTextKit", fontSize:24, fontWeight: 700, fontItalic: true)
             *  .Paragraph().Alignment(TextAlignment.Left)
             *  .FontSize(18)
             *  .Add("This is a test string");
             */

            var rs = new RichString()
                     .Add("Big text", fontSize: 40, letterSpacing: 0, backgroundColor: new SKColor(0xFFFF0000))
                     .Add("Little text", fontSize: 12, letterSpacing: 0);


            _richString = rs;
        }
Пример #2
0
        public static string FromStyle(this string text, RichString rs)
        {
            string output = "";

            if (rs.bold)
            {
                output += "<b>";
            }
            if (rs.italic)
            {
                output += "<i>";
            }
            if (rs.colored)
            {
                output += "<color=" + rs.Color + ">";
            }

            output += text;

            if (rs.colored)
            {
                output += "</color>";
            }
            if (rs.italic)
            {
                output += "</i>";
            }
            if (rs.bold)
            {
                output += "</b>";
            }
            return(output);
        }
Пример #3
0
        public static SKImage SensorTitle(List <SensorReading> readings, SKColor readingColor)
        {
            var latestReading = readings.OrderByDescending(x => x.ReadingDateTime).First();

            var fitSize =
                TextHelpers.AutoFitRichStringWidth(
                    $"{latestReading.ReadingValue:0.0} - {latestReading.ReadingDateTime:M/dd HH}",
                    "Arial", 360, 40);

            var titleRichString = new RichString()
                                  .FontFamily("Arial")
                                  .TextColor(SKColors.White)
                                  .FontSize(fitSize)
                                  .TextColor(readingColor)
                                  .Add($"{latestReading.ReadingValue:0.0}")
                                  .TextColor(SKColors.Gray)
                                  .Add(" - ")
                                  .TextColor(SKColors.White)
                                  .Add($"{latestReading.ReadingTag}");

            var titleChartImage   = new SKImageInfo(400, 50);
            var titleChartSurface = SKSurface.Create(titleChartImage);
            var titleChartCanvas  = titleChartSurface.Canvas;

            var titleLeftStart = (400 - titleRichString.MeasuredWidth) / 2;

            titleRichString.Paint(titleChartCanvas, new SKPoint(titleLeftStart, 10));

            titleChartCanvas.Save();

            return(titleChartSurface.Snapshot());
        }
Пример #4
0
        public RichTextKitPage()
        {
            InitializeComponent();

            richString = new RichString()
                         .MarginLeft(12)
                         .MarginTop(12)
                         .MarginRight(12)
                         .MarginBottom(12)
                         .FontSize(18)
                         .FontFamily("Segoe UI")
                         .Add("Welcome to RichTextKit!\n", fontSize: 24, fontWeight: 700)
                         .Add("\nRichTextKit is a rich text layout, rendering and measurement library for SkiaSharp.\n\nIt supports normal, ")
                         .Add("bold", fontWeight: 700)
                         .Add(", ")
                         .Add("italic", fontItalic: true)
                         .Add(", ")
                         .Add("underline", underline: UnderlineStyle.Gapped)
                         .Add(" (including ")
                         .Add("gaps over descenders", underline: UnderlineStyle.Gapped)
                         .Add("), ")
                         .Add("strikethrough", strikeThrough: StrikeThroughStyle.Solid)
                         .Add(", superscript (E=mc")
                         .Add("2", fontVariant: FontVariant.SuperScript)
                         .Add("), subscript (H")
                         .Add("2", fontVariant: FontVariant.SubScript)
                         .Add("O), ")
                         .Add("colored ", textColor: SKColors.Red)
                         .Add("text", textColor: SKColors.Blue)
                         .Add(" and ")
                         .Add("mixed ")
                         .Add("sizes, ", fontSize: 12)
                         .Add("widths", fontFamily: "Consolas")
                         .Add(" and ")
                         .Add("fonts", fontFamily: "Segoe Script")
                         .Add(".\n\n")
                         .Add("Font fallback means emojis work: 🌐 🍪 🍕 🚀 and ")
                         .Add("text shaping and bi-directional text support means complex scripts and languages like Arabic: مرحبا بالعالم, Japanese: ハローワールド, Chinese: 世界您好 and Hindi: हैलो वर्ल्ड are rendered correctly!\n\n")
                         .Add("RichTextKit also supports left/center/right text alignment, word wrapping, truncation with ellipsis place-holder, text measurement, hit testing, painting a selection range, caret position & shape helpers.")
                         .Paragraph()
                         .Add(LipsumGenerator.Generate(1));
        }
Пример #5
0
        public static float AutoFitRichStringWidth(string stringContents, string fontFamily, int maxWidth,
                                                   int maxHeight)
        {
            var fontSize = 1;

            var testString = new RichString()
                             .FontFamily(fontFamily)
                             .FontSize(fontSize)
                             .Add(stringContents);

            while (testString.MeasuredWidth < maxWidth && testString.MeasuredHeight < maxHeight)
            {
                testString = new RichString()
                             .FontFamily(fontFamily)
                             .FontSize(++fontSize)
                             .Add(stringContents);
            }

            return(fontSize);
        }
Пример #6
0
        public static void DrawItem(SKCanvas canvas, Item item, Lang lang, SKRect rect)
        {
            Console.Out.WriteLine($"[{lang}] {item.name.GetText(lang)}".AsSpan());
            DrawItemBackground(canvas, rect);
            SKRect padded      = new(rect.Left + itemPadding, rect.Top + itemPadding, rect.Right - itemPadding, rect.Bottom);
            float  imageHeight = padded.Height * 0.4f;
            float  nameHeight  = padded.Height * 0.2f;
            float  descHeight  = padded.Height * 0.4f;
            SKRect imageRect   = crect(padded.Left, padded.Top, padded.Width, imageHeight);
            SKRect nameRect    = crect(padded.Left + 3, padded.Top + imageHeight, padded.Width - 5, nameHeight);
            SKRect descRect    = crect(padded.Left + 3, padded.Top + imageHeight + nameHeight, padded.Width - 5, descHeight);
            var    scaled      = item.GetScaledBitmap(imageRect);

            if (scaled != null)
            {
                var imageDestRect = CalculateDisplayRect(imageRect, scaled, BitmapAlignment.Start, BitmapAlignment.Center);
                canvas.DrawBitmap(scaled, imageDestRect.Left + 5, imageDestRect.Top);
            }

            #region Draw Name

            RichString name = new RichString()
            {
                MaxWidth     = nameRect.Width,
                DefaultStyle = nameStyle,
            }.Add(item.name.GetText(lang));
            name.MaxLines = 1;
            name.Paint(canvas, new SKPoint(nameRect.Left, nameRect.Top + 4), paintOptions);

            #endregion Draw Name

            RichString desc = new RichString()
            {
                MaxWidth     = nameRect.Width,
                MaxHeight    = null,
                DefaultStyle = descStyle,
            }.Add(item.description.GetText(lang));
            desc.MaxLines = 20;
            desc.Paint(canvas, new SKPoint(descRect.Left, descRect.Top + 1), paintOptions);
        }
Пример #7
0
        public static void DrawLabel(SKCanvas canvas, MetaType metaType, Lang lang, SKRect rect)
        {
            var lineR = rect;

            lineR.Inflate(-(canvasMaxWidth * 0.8f), -(itemMargin * 2.4f));
            //top
            //canvas.DrawLine(new SKPoint(lineR.Left, lineR.Top), new SKPoint(lineR.Right, lineR.Top), labelLine);
            //bottom
            canvas.DrawLine(new SKPoint(lineR.Left, lineR.Bottom), new SKPoint(lineR.Right, lineR.Bottom), labelLine);

            string     labelName = "- " + GetMetaTypeLabel(lang, metaType) + " -";
            RichString desc      = new RichString()
            {
                DefaultStyle = labelStyle,
                MaxLines     = 1,
            }.Add(labelName);
            const int offsetY = 3;
            int       ori     = canvas.SaveLayer(labelPaint);

            desc.Paint(canvas, new SKPoint(rect.MidX - desc.MeasuredWidth / 2, rect.MidY - desc.MeasuredHeight / 2 - offsetY), paintOptions);
            canvas.RestoreToCount(ori);
        }
Пример #8
0
        public static void DrawCaptionLabels(this SKCanvas canvas, string label, SKColor labelColor, TextDirection textDirection, float labelTextSpacing, 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;

                        RichString rs;

                        if (typeface != null)
                        {
                            rs = new RichString()
                                 .FontFamily(typeface.FamilyName)
                                 .FontSize(textSize)
                                 .LetterSpacing(labelTextSpacing)
                                 .TextColor(labelColor)
                                 .TextDirection(textDirection)
                                 .Add(text);
                        }
                        else
                        {
                            rs = new RichString()
                                 .FontSize(textSize)
                                 .LetterSpacing(labelTextSpacing)
                                 .TextColor(labelColor)
                                 .TextDirection(textDirection)
                                 .Add(text);
                        }

                        rs.Paint(canvas, new SKPoint(point.X, y), new TextPaintOptions
                        {
                            IsAntialias   = true,
                            LcdRenderText = true
                        });

                        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);
                        }
                    }
                }
            }
        }
Пример #9
0
 public void DrawString(RichString richString, Point position)
 {
     this.DrawString(position, richString.Font, richString.Text, richString.TextSize, richString.Color,
         richString.Bold, richString.Italic, richString.Underline);
 }
Пример #10
0
 public Size MeasureTextSize(RichString richString)
 {
     return this.MeasureTextSize(richString.Text, richString.TextSize, richString.Bold);
 }
Пример #11
0
        public RichString CreateRichString(string fragment)
        {
            RichString richString = new RichString(fragment);
            richString.Font = activeFont;
            richString.TextSize = activeTextSize;
            richString.Color = activeColor;
            richString.Bold = activeBold;
            richString.Italic = activeItalic;
            richString.Underline = activeUnderline;
            richString.NewLine = activeNewLine;
            richString.Modified = false;

            activeNewLine = false;

            return richString;
        }
Пример #12
0
        public void Append(RichString richString)
        {
            if(richString.NewLine) {
                nextStringPoint.X = 0;
                nextStringPoint.Y += lineSize;
                lineSize = 0;
            }
            lineSize = Math.Max(lineSize, richString.Size.Height);

            RichLabelString richLabelString = new RichLabelString(richString);

            if(nextStringPoint.X + richLabelString.RichString.Size.Width > Bounds.Width) { // if the text will not fit on this line
                string str = richLabelString.RichString.Text;
                if(str.Contains(" ")) { // if there are multiple words

                    List<string> fragments = new List<string>();
                    List<Point> points = new List<Point>();

                    while(nextStringPoint.X + richLabelString.RichString.Font.MeasureTextSize(str, richLabelString.RichString.TextSize,
                        richLabelString.RichString.Bold).Width > Bounds.Width) { // while there's remaining text that can't fit
                        int bestMatch = 0;
                        while(true) { // it matches for the best point of splitting
                            int nextMatch = str.IndexOf(' ', bestMatch + 1);
                            if(nextMatch != -1) { // if there is another space after the best match
                                if(nextStringPoint.X + richLabelString.RichString.Font.MeasureTextSize(
                                    str.Substring(0, nextMatch), richLabelString.RichString.TextSize, richLabelString.RichString.Bold
                                    ).Width > Bounds.Width)
                                    break; // if it doesn't fit, abort
                                else bestMatch = nextMatch; // otherwise the line can hold this much
                            } else break;
                        }
                        if(bestMatch == 0) bestMatch = str.IndexOf(" ");
                        if(bestMatch == -1) bestMatch = str.Length - 1;
                        fragments.Add(str.Substring(0, bestMatch));
                        points.Add(nextStringPoint);
                        nextStringPoint.X = 0;
                        nextStringPoint.Y += lineSize;
                        str = str.Substring(bestMatch + 1);
                    }
                    if(str.Length > 0) { // put the remnants
                        fragments.Add(str);
                        points.Add(nextStringPoint);
                        nextStringPoint.X += richLabelString.RichString.Font.MeasureTextSize(str, richLabelString.RichString.TextSize,
                            richLabelString.RichString.Bold).Width;
                    }
                    richLabelString.StringPoints = points.ToArray();
                    richLabelString.StringFragments = fragments.ToArray();
                } else { // there is only one word, put it on the next line
                    nextStringPoint.X = 0;
                    nextStringPoint.Y += lineSize;

                    richLabelString.StringPoints = new Point[]{ nextStringPoint };

                    nextStringPoint.X += richLabelString.RichString.Size.Width;
                    lineSize = richLabelString.RichString.Size.Height;
                }
            } else {
                richLabelString.StringPoints = new Point[]{ nextStringPoint };
                nextStringPoint.X += richLabelString.RichString.Size.Width;
            }
            this.MaxSize = new Size(this.Bounds.Width,
                richLabelString.StringPoints.Last().Y + richLabelString.RichString.Size.Height);
            text.Add(richLabelString);
        }
Пример #13
0
 internal RichLabelString(RichString richString)
     : this()
 {
     RichString = richString;
 }