示例#1
0
        public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
        {
            // For now silently ignore
            if (context.GrContext == null)
            {
                return;
            }

            using (Lock())
            {
                if (_textureId == 0)
                {
                    return;
                }
                using (var backendTexture = new GRBackendTexture(PixelSize.Width, PixelSize.Height, false,
                                                                 new GRGlTextureInfo(
                                                                     GlConsts.GL_TEXTURE_2D, (uint)_textureId,
                                                                     (uint)_internalFormat)))
                    using (var surface = SKSurface.Create(context.GrContext, backendTexture, GRSurfaceOrigin.TopLeft,
                                                          SKColorType.Rgba8888))
                    {
                        // Again, silently ignore, if something went wrong it's not our fault
                        if (surface == null)
                        {
                            return;
                        }

                        using (var snapshot = surface.Snapshot())
                            context.Canvas.DrawImage(snapshot, sourceRect, destRect, paint);
                    }
            }
        }
 /// <inheritdoc />
 public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
 {
     using (var image = SnapshotImage())
     {
         context.Canvas.DrawImage(image, sourceRect, destRect, paint);
     }
 }
示例#3
0
 /// <inheritdoc />
 public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
 {
     if (sourceRect.Left == 0 && sourceRect.Top == 0 && sourceRect.Size == destRect.Size)
     {
         _surface.Canvas.Flush();
         _surface.Draw(context.Canvas, destRect.Left, destRect.Top, paint);
     }
     else
     {
         using (var image = SnapshotImage())
         {
             context.Canvas.DrawImage(image, sourceRect, destRect, paint);
         }
     }
 }
 /// <inheritdoc />
 public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
 {
     lock (_lock)
         context.Canvas.DrawBitmap(_bitmap, sourceRect, destRect, paint);
 }
示例#5
0
        internal void Draw(DrawingContextImpl context,
                           SKCanvas canvas,
                           SKPoint origin,
                           DrawingContextImpl.PaintWrapper foreground,
                           bool canUseLcdRendering)
        {
            /* TODO: This originated from Native code, it might be useful for debugging character positions as
             * we improve the FormattedText support. Will need to port this to C# obviously. Rmove when
             * not needed anymore.
             *
             *  SkPaint dpaint;
             *  ctx->Canvas->save();
             *  ctx->Canvas->translate(origin.fX, origin.fY);
             *  for (int c = 0; c < Lines.size(); c++)
             *  {
             *      dpaint.setARGB(255, 0, 0, 0);
             *      SkRect rc;
             *      rc.fLeft = 0;
             *      rc.fTop = Lines[c].Top;
             *      rc.fRight = Lines[c].Width;
             *      rc.fBottom = rc.fTop + LineOffset;
             *      ctx->Canvas->drawRect(rc, dpaint);
             *  }
             *  for (int c = 0; c < Length; c++)
             *  {
             *      dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10);
             *      dpaint.setStyle(SkPaint::kFill_Style);
             *      ctx->Canvas->drawRect(Rects[c], dpaint);
             *  }
             *  ctx->Canvas->restore();
             */
            using (var paint = _paint.Clone())
            {
                IDisposable currd          = null;
                var         currentWrapper = foreground;
                SKPaint     currentPaint   = null;
                try
                {
                    ApplyWrapperTo(ref currentPaint, foreground, ref currd, paint, canUseLcdRendering);
                    bool hasCusomFGBrushes = _foregroundBrushes.Any();

                    for (int c = 0; c < _skiaLines.Count; c++)
                    {
                        AvaloniaFormattedTextLine line = _skiaLines[c];

                        float x = TransformX(origin.X, 0, paint.TextAlign);

                        if (!hasCusomFGBrushes)
                        {
                            var subString = Text.Substring(line.Start, line.Length);
                            canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint);
                        }
                        else
                        {
                            float  currX = x;
                            string subStr;
                            float  measure;
                            int    len;
                            float  factor;
                            switch (paint.TextAlign)
                            {
                            case SKTextAlign.Left:
                                factor = 0;
                                break;

                            case SKTextAlign.Center:
                                factor = 0.5f;
                                break;

                            case SKTextAlign.Right:
                                factor = 1;
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }

                            var textLine = Text.Substring(line.Start, line.Length);
                            currX -= textLine.Length == 0 ? 0 : paint.MeasureText(textLine) * factor;

                            for (int i = line.Start; i < line.Start + line.Length;)
                            {
                                var fb = GetNextForegroundBrush(ref line, i, out len);

                                if (fb != null)
                                {
                                    //TODO: figure out how to get the brush size
                                    currentWrapper = context.CreatePaint(new SKPaint {
                                        IsAntialias = true
                                    }, fb,
                                                                         new Size());
                                }
                                else
                                {
                                    if (!currentWrapper.Equals(foreground))
                                    {
                                        currentWrapper.Dispose();
                                    }
                                    currentWrapper = foreground;
                                }

                                subStr  = Text.Substring(i, len);
                                measure = paint.MeasureText(subStr);
                                currX  += measure * factor;

                                ApplyWrapperTo(ref currentPaint, currentWrapper, ref currd, paint, canUseLcdRendering);

                                canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint);

                                i     += len;
                                currX += measure * (1 - factor);
                            }
                        }
                    }
                }
                finally
                {
                    if (!currentWrapper.Equals(foreground))
                    {
                        currentWrapper.Dispose();
                    }
                    currd?.Dispose();
                }
            }
        }
 private static SKPaint ApplyWrapperTo(ref DrawingContextImpl.PaintWrapper wrapper,
                                         ref IDisposable curr, SKPaint paint)
 {
     curr?.Dispose();
     curr = wrapper.ApplyTo(paint);
     return wrapper.Paint;
 }
        internal void Draw(DrawingContextImpl context,
                           SKCanvas canvas, SKPoint origin,
                           DrawingContextImpl.PaintWrapper foreground)
        {
            /* TODO: This originated from Native code, it might be useful for debugging character positions as
             * we improve the FormattedText support. Will need to port this to C# obviously. Rmove when
             * not needed anymore.

                SkPaint dpaint;
                ctx->Canvas->save();
                ctx->Canvas->translate(origin.fX, origin.fY);
                for (int c = 0; c < Lines.size(); c++)
                {
                    dpaint.setARGB(255, 0, 0, 0);
                    SkRect rc;
                    rc.fLeft = 0;
                    rc.fTop = Lines[c].Top;
                    rc.fRight = Lines[c].Width;
                    rc.fBottom = rc.fTop + LineOffset;
                    ctx->Canvas->drawRect(rc, dpaint);
                }
                for (int c = 0; c < Length; c++)
                {
                    dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10);
                    dpaint.setStyle(SkPaint::kFill_Style);
                    ctx->Canvas->drawRect(Rects[c], dpaint);
                }
                ctx->Canvas->restore();
            */
            SKPaint paint = _paint;
            IDisposable currd = null;
            var currentWrapper = foreground;

            try
            {
                SKPaint currFGPaint = ApplyWrapperTo(ref foreground, ref currd, paint);
                bool hasCusomFGBrushes = _foregroundBrushes.Any();

                for (int c = 0; c < _skiaLines.Count; c++)
                {
                    AvaloniaFormattedTextLine line = _skiaLines[c];

                    float x = TransformX(origin.X, 0, paint.TextAlign);

                    if (!hasCusomFGBrushes)
                    {
                        var subString = _text.Substring(line.Start, line.Length);
                        canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint);
                    }
                    else
                    {
                        float currX = x;
                        string subStr;
                        int len;

                        for (int i = line.Start; i < line.Start + line.Length;)
                        {
                            var fb = GetNextForegroundBrush(ref line, i, out len);

                            if (fb != null)
                            {
                                //TODO: figure out how to get the brush size
                                currentWrapper = context.CreatePaint(fb, new Size());
                            }
                            else
                            {
                                if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
                                currentWrapper = foreground;
                            }

                            subStr = _text.Substring(i, len);

                            if (currFGPaint != currentWrapper.Paint)
                            {
                                currFGPaint = ApplyWrapperTo(ref currentWrapper, ref currd, paint);
                            }

                            canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint);

                            i += len;
                            currX += paint.MeasureText(subStr);
                        }
                    }
                }
            }
            finally
            {
                if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
                currd?.Dispose();
            }
        }
示例#8
0
        internal void Draw(DrawingContextImpl context,
                           SKCanvas canvas, SKPoint origin,
                           DrawingContextImpl.PaintWrapper foreground)
        {
            /* TODO: This originated from Native code, it might be useful for debugging character positions as
             * we improve the FormattedText support. Will need to port this to C# obviously. Rmove when
             * not needed anymore.
             *
             *  SkPaint dpaint;
             *  ctx->Canvas->save();
             *  ctx->Canvas->translate(origin.fX, origin.fY);
             *  for (int c = 0; c < Lines.size(); c++)
             *  {
             *      dpaint.setARGB(255, 0, 0, 0);
             *      SkRect rc;
             *      rc.fLeft = 0;
             *      rc.fTop = Lines[c].Top;
             *      rc.fRight = Lines[c].Width;
             *      rc.fBottom = rc.fTop + LineOffset;
             *      ctx->Canvas->drawRect(rc, dpaint);
             *  }
             *  for (int c = 0; c < Length; c++)
             *  {
             *      dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10);
             *      dpaint.setStyle(SkPaint::kFill_Style);
             *      ctx->Canvas->drawRect(Rects[c], dpaint);
             *  }
             *  ctx->Canvas->restore();
             */
            SKPaint     paint          = _paint;
            IDisposable currd          = null;
            var         currentWrapper = foreground;

            try
            {
                SKPaint currFGPaint       = ApplyWrapperTo(ref foreground, ref currd, paint);
                bool    hasCusomFGBrushes = _foregroundBrushes.Any();

                for (int c = 0; c < _skiaLines.Count; c++)
                {
                    AvaloniaFormattedTextLine line = _skiaLines[c];

                    float x = TransformX(origin.X, 0, paint.TextAlign);

                    if (!hasCusomFGBrushes)
                    {
                        var subString = _text.Substring(line.Start, line.Length);
                        canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint);
                    }
                    else
                    {
                        float  currX = x;
                        string subStr;
                        int    len;

                        for (int i = line.Start; i < line.Start + line.Length;)
                        {
                            var fb = GetNextForegroundBrush(ref line, i, out len);

                            if (fb != null)
                            {
                                //TODO: figure out how to get the brush size
                                currentWrapper = context.CreatePaint(fb, new Size());
                            }
                            else
                            {
                                if (!currentWrapper.Equals(foreground))
                                {
                                    currentWrapper.Dispose();
                                }
                                currentWrapper = foreground;
                            }

                            subStr = _text.Substring(i, len);

                            if (currFGPaint != currentWrapper.Paint)
                            {
                                currFGPaint = ApplyWrapperTo(ref currentWrapper, ref currd, paint);
                            }

                            canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint);

                            i     += len;
                            currX += paint.MeasureText(subStr);
                        }
                    }
                }
            }
            finally
            {
                if (!currentWrapper.Equals(foreground))
                {
                    currentWrapper.Dispose();
                }
                currd?.Dispose();
            }
        }
示例#9
0
 /// <inheritdoc />
 public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
 {
     context.Canvas.DrawImage(_image, sourceRect, destRect, paint);
 }
        public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
        {
            var  session = _surface.BeginDraw();
            bool success = false;

            try
            {
                var disp = session.Display;
                var gl   = disp.GlInterface;
                gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var fb);

                var size    = session.Size;
                var scaling = session.Scaling;
                if (size.Width <= 0 || size.Height <= 0 || scaling < 0)
                {
                    session.Dispose();
                    throw new InvalidOperationException(
                              $"Can't create drawing context for surface with {size} size and {scaling} scaling");
                }

                gl.Viewport(0, 0, size.Width, size.Height);
                gl.ClearStencil(0);
                gl.ClearColor(0, 0, 0, 0);
                gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                lock (_grContext)
                {
                    _grContext.ResetContext();

                    GRBackendRenderTarget renderTarget =
                        new GRBackendRenderTarget(size.Width, size.Height, disp.SampleCount, disp.StencilSize,
                                                  new GRGlFramebufferInfo((uint)fb, GRPixelConfig.Rgba8888.ToGlSizedFormat()));
                    var surface = SKSurface.Create(_grContext, renderTarget,
                                                   GRSurfaceOrigin.BottomLeft,
                                                   GRPixelConfig.Rgba8888.ToColorType());

                    var nfo = new DrawingContextImpl.CreateInfo
                    {
                        GrContext               = _grContext,
                        Canvas                  = surface.Canvas,
                        Dpi                     = SkiaPlatform.DefaultDpi * scaling,
                        VisualBrushRenderer     = visualBrushRenderer,
                        DisableTextLcdRendering = true
                    };


                    var ctx = new DrawingContextImpl(nfo, Disposable.Create(() =>
                    {
                        surface.Canvas.Flush();
                        surface.Dispose();
                        renderTarget.Dispose();
                        _grContext.Flush();
                        session.Dispose();
                    }));
                    success = true;
                    return(ctx);
                }
            }
            finally
            {
                if (!success)
                {
                    session.Dispose();
                }
            }
        }
示例#11
0
 public SkiaLeaseFeature(DrawingContextImpl context)
 {
     _context = context;
 }
示例#12
0
 public void Dispose()
 {
     _context.Canvas.SetMatrix(_revertTransform);
     _context._leased = false;
     _context         = null;
 }
示例#13
0
 public ApiLease(DrawingContextImpl context)
 {
     _revertTransform = context.Canvas.TotalMatrix;
     _context         = context;
     _context._leased = true;
 }