diff --git a/build/ApiDiff.props b/build/ApiDiff.props
index da82fbcc51..3d322f56d5 100644
--- a/build/ApiDiff.props
+++ b/build/ApiDiff.props
@@ -7,6 +7,6 @@
-
+
diff --git a/src/Avalonia.OpenGL/Egl/EglContext.cs b/src/Avalonia.OpenGL/Egl/EglContext.cs
index 5365354418..249b4d547f 100644
--- a/src/Avalonia.OpenGL/Egl/EglContext.cs
+++ b/src/Avalonia.OpenGL/Egl/EglContext.cs
@@ -73,7 +73,8 @@ namespace Avalonia.OpenGL.Egl
var old = new RestoreContext(_egl, _disp.Handle, _lock);
var surf = surface ?? OffscreenSurface;
_egl.MakeCurrent(_disp.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
- if (!_egl.MakeCurrent(_disp.Handle, surf.DangerousGetHandle(), surf.DangerousGetHandle(), Context))
+ if (!_egl.MakeCurrent(_disp.Handle, surf?.DangerousGetHandle() ?? IntPtr.Zero,
+ surf?.DangerousGetHandle() ?? IntPtr.Zero, Context))
throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl);
success = true;
return old;
diff --git a/src/Avalonia.OpenGL/Egl/EglDisplay.cs b/src/Avalonia.OpenGL/Egl/EglDisplay.cs
index fd3de854f5..623364866b 100644
--- a/src/Avalonia.OpenGL/Egl/EglDisplay.cs
+++ b/src/Avalonia.OpenGL/Egl/EglDisplay.cs
@@ -158,15 +158,21 @@ namespace Avalonia.OpenGL.Egl
var ctx = _egl.CreateContext(_display, _config, shareCtx?.Context ?? IntPtr.Zero, _contextAttributes);
if (ctx == IntPtr.Zero)
throw OpenGlException.GetFormattedException("eglCreateContext", _egl);
- var surf = _egl.CreatePBufferSurface(_display, _config, new[]
+
+ var extensions = _egl.QueryString(Handle, EGL_EXTENSIONS);
+
+ IntPtr surf = IntPtr.Zero;
+ if (extensions?.Contains("EGL_KHR_surfaceless_context") != true)
{
- EGL_WIDTH, 1,
- EGL_HEIGHT, 1,
- EGL_NONE
- });
- if (surf == IntPtr.Zero)
- throw OpenGlException.GetFormattedException("eglCreatePBufferSurface", _egl);
- var rv = new EglContext(this, _egl, shareCtx, ctx, context => new EglSurface(this, context, surf),
+ surf = _egl.CreatePBufferSurface(_display, _config,
+ new[] { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE });
+ if (surf == IntPtr.Zero)
+ throw OpenGlException.GetFormattedException("eglCreatePBufferSurface", _egl);
+ }
+
+ var rv = new EglContext(this, _egl, shareCtx, ctx,
+ context =>
+ surf == IntPtr.Zero ? null : new EglSurface(this, context, surf),
_version, _sampleCount, _stencilSize);
return rv;
}
diff --git a/src/Avalonia.Visuals/Media/GlyphRun.cs b/src/Avalonia.Visuals/Media/GlyphRun.cs
index 155339b985..66a8c1dd0c 100644
--- a/src/Avalonia.Visuals/Media/GlyphRun.cs
+++ b/src/Avalonia.Visuals/Media/GlyphRun.cs
@@ -18,7 +18,7 @@ namespace Avalonia.Media
private double _fontRenderingEmSize;
private Size? _size;
private int _biDiLevel;
- private Point _baselineOrigin;
+ private Point? _baselineOrigin;
private ReadOnlySlice _glyphIndices;
private ReadOnlySlice _glyphAdvances;
@@ -97,7 +97,9 @@ namespace Avalonia.Media
{
get
{
- return _baselineOrigin;
+ _baselineOrigin ??= CalculateBaselineOrigin();
+
+ return _baselineOrigin.Value;
}
set => Set(ref _baselineOrigin, value);
}
@@ -538,6 +540,15 @@ namespace Avalonia.Media
return GlyphAdvances[index];
}
+ ///
+ /// Calculates the default baseline origin of the .
+ ///
+ /// The baseline origin.
+ private Point CalculateBaselineOrigin()
+ {
+ return new Point(0, -GlyphTypeface.Ascent * Scale);
+ }
+
///
/// Calculates the size of the .
///
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
index d13b4836ea..fc98e9f6f8 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
@@ -39,7 +39,7 @@ namespace Avalonia.Media.TextFormatting
foreach (var textRun in _textRuns)
{
- var offsetY = LineMetrics.TextBaseline;
+ var offsetY = LineMetrics.TextBaseline - textRun.GlyphRun.BaselineOrigin.Y;
using (drawingContext.PushPostTransform(Matrix.CreateTranslation(currentX, offsetY)))
{
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
index 72eed9e543..dc44d2d55f 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
+++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
@@ -141,17 +141,7 @@ namespace Avalonia.LinuxFramebuffer.Output
_platformGl = new EglPlatformOpenGlInterface(_eglDisplay);
_eglSurface = _platformGl.CreateWindowSurface(_gbmTargetSurface);
-
- EglContext CreateContext(EglContext share)
- {
- var offSurf = gbm_surface_create(device, 1, 1, GbmColorFormats.GBM_FORMAT_XRGB8888,
- GbmBoFlags.GBM_BO_USE_RENDERING);
- if (offSurf == null)
- throw new InvalidOperationException("Unable to create 1x1 sized GBM surface");
- return _eglDisplay.CreateContext(share, _platformGl.CreateWindowSurface(offSurf));
- }
-
- _deferredContext = CreateContext(null);
+ _deferredContext = _platformGl.PrimaryEglContext;
using (_deferredContext.MakeCurrent(_eglSurface))
{
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index 9a486b60aa..cbc896813f 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -42,6 +42,11 @@ namespace Avalonia.Skia
///
public struct CreateInfo
{
+ ///
+ /// Canvas to draw to.
+ ///
+ public SKCanvas Canvas;
+
///
/// Surface to draw to.
///
@@ -89,7 +94,7 @@ namespace Avalonia.Skia
if (_grContext != null)
Monitor.Enter(_grContext);
Surface = createInfo.Surface;
- Canvas = createInfo.Surface.Canvas;
+ Canvas = createInfo.Canvas ?? createInfo.Surface?.Canvas;
if (Canvas == null)
{
diff --git a/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs b/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
new file mode 100644
index 0000000000..72438609d5
--- /dev/null
+++ b/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
@@ -0,0 +1,31 @@
+using Avalonia.Platform;
+using Avalonia.Rendering;
+using SkiaSharp;
+
+namespace Avalonia.Skia.Helpers
+{
+ public class DrawingContextHelper
+ {
+ ///
+ /// Wrap Skia canvas in drawing context so we can use Avalonia api to render to external skia canvas
+ /// this is useful in scenarios where canvas is not controlled by application, but received from another non avalonia api
+ /// like: SKCanvas canvas = SKDocument.BeginPage(...);
+ ///
+ ///
+ ///
+ ///
+ /// DrawingContext
+ public static IDrawingContextImpl WrapSkiaCanvas(SKCanvas canvas, Vector dpi, IVisualBrushRenderer visualBrushRenderer = null)
+ {
+ var createInfo = new DrawingContextImpl.CreateInfo
+ {
+ Canvas = canvas,
+ Dpi = dpi,
+ VisualBrushRenderer = visualBrushRenderer,
+ DisableTextLcdRendering = true,
+ };
+
+ return new DrawingContextImpl(createInfo);
+ }
+ }
+}