public PaintRecord(TextStyle style, SkTextBlob text, SKFontMetrics metrics, int line, double run_width)
 {
     this.style_   = style;
     this.text_    = text;
     this.metrics_ = metrics;
     //C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
     //ORIGINAL LINE: this.line_ = line;
     this.line_      = line;
     this.run_width_ = run_width;
 }
Beispiel #2
0
 private void InitializeRendering()
 {
     paint.Color         = SKColors.Black;
     paint.TextSize      = FontSize;
     paint.Typeface      = this.Typeface;
     paint.SubpixelText  = true;
     paint.LcdRenderText = true;
     paint.IsAntialias   = true;
     typeMetrics         = paint.FontMetrics;
     TextViewModel.VisualBuffer.Changed += VisualBuffer_Changed;
 }
Beispiel #3
0
        private SKPaint getTextBlock(double fontSize)
        {
            if (!this.textBlocks.ContainsKey(fontSize))
            {
                SKPaint textBlock = new SKPaint();
                Label   label     = new Label();
                textBlock.TextSize = (float)fontSize;
                textBlock.Typeface = SKTypeface.FromFamilyName(label.FontFamily);

                // leave enough height for the characters for the highest ("M") and lowest ("g") characters
                SKFontMetrics metrics = new SKFontMetrics();
                textBlock.GetFontMetrics(out metrics);
                this.fontLineHeight = metrics.Descent - metrics.Ascent;
                SKRect bounds = new SKRect();
                textBlock.MeasureText("M", ref bounds);
                this.leftMargin           = bounds.Left;
                this.textBlocks[fontSize] = textBlock;
            }
            return(this.textBlocks[fontSize]);
        }
Beispiel #4
0
        /// <summary>
        /// Generates a bitmap using the provided textData and font info. Note that
        /// you are responsible for calling <code>Dispose</code> on the returned bitmap.
        /// </summary>
        /// <param name="textData">The <code>ITextData</code> to read from</param>
        /// <returns>The generated <code>SKBitmap</code></returns>
        public SKBitmap GenerateBitmap(ITextData textData)
        {
            using (var paint = new SKPaint())
            {
                paint.IsAntialias  = this.ShouldAntialias;
                paint.IsDither     = this.ShouldDither;
                paint.IsAutohinted = this.ShouldHint;

                var font = this.Font;
                paint.Typeface             = font.Typeface.SkiaTypeface;
                paint.TextSize             = font.TextSize;
                paint.TextEncoding         = SKTextEncoding.Utf8;
                paint.SubpixelText         = true;
                paint.DeviceKerningEnabled = false;

                paint.Color = font.Color.SkiaColor;
                var backgroundColor = this.BackgroundColor;

                int textWidth  = textData.Width;
                int textHeight = textData.Height;

                // spacing reserved for a single character
                SKFontMetrics fontMetrics      = paint.FontMetrics;
                int           characterSpacing = font.CharacterSpacing;

                Debug.Assert(characterSpacing > 0);

                // bitmap may not be big enough for all text if using
                // non-monospace characters and/or characterSize/ is not
                // sufficient. Too bad.
                int bitmapWidth  = characterSpacing * textWidth;
                int bitmapHeight = characterSpacing * textHeight;

                Debug.Assert(bitmapWidth > 0);
                Debug.Assert(bitmapHeight > 0);

                // NOTE: this will need to be disposed by the caller.
                var bitmap = new SKBitmap(
                    bitmapWidth, bitmapHeight,
                    SKImageInfo.PlatformColorType, SKAlphaType.Premul
                    );
                using (var canvas = new SKCanvas(bitmap))
                {
                    bitmap.Erase(backgroundColor);
                    var parallelOptions = new ParallelOptions {
                        MaxDegreeOfParallelism = 1
                    };
                    Parallel.For(0, textHeight, parallelOptions, y =>
                    {
                        Parallel.For(0, textWidth, x =>
                        {
                            string charAsString = textData[x, y].ToString();

                            // dimensions of actual printed chars
                            float charWidth  = paint.MeasureText(charAsString);
                            float charHeight = -fontMetrics.Ascent;
                            Debug.Assert(charWidth > 0);
                            Debug.Assert(charHeight > 0);

                            // the actual position to render them.
                            // they should be centered in the space allocated to them.
                            float textX = (x * characterSpacing) + (characterSpacing - charWidth) * 0.5f;
                            float textY = (y * characterSpacing) + (characterSpacing * 0.75f);

                            canvas.DrawText(
                                text: textData[x, y].ToString(),
                                x: textX,
                                y: textY,
                                paint: paint
                                );
                        });
                    });
                }
                return(bitmap);
            }
        }
Beispiel #5
0
        public override RSize MeasureString(string str, RFont font)
        {
            var f        = ((FontAdapter)font).Font;
            var textSize = SkRenderer.GetTextBound(str, f);
            var size     = new Size((int)textSize.Width, (int)textSize.Height);

            var p = SkRenderer.PaintFromFont(f);

            // if (!GloablRenderSettings.UseGdiMeasureFont)
            // {
            //
            // p.Typeface = SKTypeface.FromFamilyName(f.OriginalFontName);
            // p.TextSize = f.Size;
            // p.TextAlign = SKTextAlign.Left;
            //
            // var r = new SKRect();
            // var d = p.MeasureText(str, ref r);
            // float whiteSpaceWidth = d - r.Width;
            // r.Left -= whiteSpaceWidth / 2;
            // r.Right += whiteSpaceWidth / 2;

            // r.Top -= whiteSpaceWidth * 2;
            // r.Bottom += whiteSpaceWidth * 2;


            // size = new Size((int) r.Width + (int) (r.Width / 2), (int) f.Height);

            // var winSize = new Size();
            // SkRendererAdapter.GetTextExtentPoint32(_hdc, str, str.Length, ref winSize);

            // Console.WriteLine("123");
            // }
            // else
            // {
            // SkRendererAdapter.GetTextExtentPoint32(_hdc, str, str.Length, ref size);
            // }

            if (font.Height < 0)
            {
                // if (!GloablRenderSettings.UseGdiMeasureFont)
                // {

                var metrics         = new SKFontMetrics();
                var m               = p.GetFontMetrics(out metrics);
                var underlineOffset = (int)
                                      (metrics.XHeight - metrics.Descent + (metrics.UnderlinePosition ?? 0) + 1);
                ((FontAdapter)font).SetMetrics(size.Height, underlineOffset);
                Console.WriteLine();

                // }
                // else
                // {
                // TextMetric lptm;
                // SkRendererAdapter.GetTextMetrics(_hdc, out lptm);
                // var underlineOffset = lptm.tmHeight - lptm.tmDescent + lptm.tmUnderlined + 1;
                // ((FontAdapter) font).SetMetrics(size.Height, underlineOffset);
                // }
            }

            return(Utils.Convert(size));
        }
Beispiel #6
0
 public static float GetHeight(this SKFontMetrics me) => me.Descent - me.Ascent;
Beispiel #7
0
        internal unsafe void Run()
        {
            if (!needRun)
            {
                return;
            }

            lines.Clear();

            //设置paint参数
            var paint = new SKPaint();

            paint.TextEncoding = SKTextEncoding.Utf16;
            font.ApplyToSKPaint(paint, GraphicsUnit.Pixel, dpi); //注意目标类型为像素
            //测量FontMetric
            SKFontMetrics metrics = font.FontMetrics;

            //根据文字排版方向确认限宽及限高
            float maxWidth  = Math.Min(32767, IsVertical ? height : width); //TODO:
            float maxHeight = IsVertical ? width : height;

            //TODO:计算高度不满足一行的情况

            fixed(char *ptr = Text)
            {
                byte *textPtr      = (byte *)ptr;
                byte *startTextPtr = (byte *)ptr;

                int   totalBytes = text.Length * 2;
                int   leftBytes  = totalBytes;
                float y          = 0;

                while (true)
                {
                    //根据是否允许换行,调用不同的breakText方法
                    var measuredWidth = 0f;
                    var lineBytes     = (int)paint.BreakText(new IntPtr(startTextPtr), new IntPtr(leftBytes), maxWidth, out measuredWidth);
                    //var lineBytes = SkiaApi.sk_paint_break_text_icu(paint, new IntPtr(startTextPtr), leftBytes, maxWidth, null); //TODO:***** fix maxWidth

                    var newLine = new TextLayoutLine(this);
                    newLine.startByteIndex = (int)(startTextPtr - textPtr);
                    newLine.byteLength     = lineBytes;
                    newLine.widths         = paint.GetGlyphWidths(new IntPtr(startTextPtr), lineBytes);
                    //newLine.startCharIndex = 0; //TODO:

                    //根据对齐方式计算Line的offsetX值
                    if (stringFormat != null && stringFormat.Alignment != StringAlignment.Near)
                    {
                        //计算当前行Ink总宽度
                        float lineInkWidth = 0f;
                        for (int i = 0; i < newLine.widths.Length; i++)
                        {
                            lineInkWidth += newLine.widths[i];
                        }
                        float lineSpace = width - lineInkWidth;
                        if (lineSpace > 0f)
                        {
                            if (stringFormat.Alignment == StringAlignment.Center)
                            {
                                newLine.offsetX = lineSpace / 2f;
                            }
                            else if (stringFormat.Alignment == StringAlignment.Far)
                            {
                                newLine.offsetX = lineSpace;
                            }
                        }
                    }
                    //添加新行
                    lines.Add(newLine);

                    //判断是否允许换行,不允许直接退出循环
                    if (IsNoWrap)
                    {
                        break;
                    }

                    //计算下一行高度是否超出限高
                    y = y - metrics.Ascent + metrics.Descent + metrics.Leading;
                    if ((y - metrics.Ascent + metrics.Descent) > maxHeight)
                    {
                        break;
                    }

                    //偏移剩余部分,并判断是否全部计算完毕
                    startTextPtr += lineBytes;
                    if ((int)(startTextPtr - textPtr) >= totalBytes)
                    {
                        break;
                    }
                    leftBytes -= lineBytes;
                }
            }

            //根据对齐方式计算offsetY的值
            CalcOffsetY();

            needRun = false;
        }