public void DrawGlyphRun(float baselineOriginX, float baselineOriginY, Graphics.Direct2D.MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ClientDrawingEffect clientDrawingEffect)
        {
            using (PathGeometry pathGeometry = _factory.CreatePathGeometry())
            {

                using (GeometrySink sink = pathGeometry.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(
                        glyphRun.EmSize,
                        glyphRun.GlyphIndices,
                        glyphRun.GlyphAdvances,
                        glyphRun.GlyphOffsets,
                        glyphRun.IsSideways,
                        glyphRun.BidiLevel != 0,
                        sink);
                    sink.Close();
                }

                CustomGeometrySink customSink = new CustomGeometrySink();
                pathGeometry.Stream(customSink);
                customSink.Close();
                System.Diagnostics.Debug.WriteLine(customSink.ToString());

                Matrix3x2 matrix = new Matrix3x2(1, 0, 0, 1, baselineOriginX, baselineOriginY);
                using (TransformedGeometry transformedGeometry = _factory.CreateTransformedGeometry(pathGeometry, matrix))
                {
                    _renderTarget.DrawGeometry(_outlineBrush, 5, transformedGeometry);
                    _renderTarget.FillGeometry(_fillBrush, transformedGeometry);
                }
            }
        }
Example #2
0
        public Result DrawGlyphRun(
            object clientDrawingContext,
            float baselineOriginX,
            float baselineOriginY,
            MeasuringMode measuringMode,
            GlyphRun glyphRun,
            GlyphRunDescription glyphRunDescription,
            ComObject clientDrawingEffect)
        {
            var wrapper = clientDrawingEffect as BrushWrapper;
            var brush   = (wrapper == null) ?
                          this.foreground :
                          wrapper.Brush.ToDirect2D(this.renderTarget);

            this.renderTarget.DrawGlyphRun(
                new Vector2(baselineOriginX, baselineOriginY),
                glyphRun,
                brush,
                measuringMode);

            if (wrapper != null)
            {
                brush.Dispose();
            }

            return(Result.Ok);
        }
Example #3
0
        public Result DrawGlyphRun(
            object clientDrawingContext,
            float baselineOriginX,
            float baselineOriginY,
            MeasuringMode measuringMode,
            GlyphRun glyphRun,
            GlyphRunDescription glyphRunDescription,
            ComObject clientDrawingEffect)
        {
            var wrapper = clientDrawingEffect as BrushWrapper;

            // TODO: Work out how to get the size below rather than passing new Size().
            var brush = (wrapper == null) ?
                        _foreground :
                        _context.CreateBrush(wrapper.Brush, new Size()).PlatformBrush;

            _renderTarget.DrawGlyphRun(
                new Vector2(baselineOriginX, baselineOriginY),
                glyphRun,
                brush,
                measuringMode);

            if (wrapper != null)
            {
                brush.Dispose();
            }

            return(Result.Ok);
        }
        public override Result DrawGlyphRun(
            object clientDrawingContext,
            float baselineOriginX,
            float baselineOriginY,
            D2D1.MeasuringMode measuringMode,
            GlyphRun glyphRun,
            GlyphRunDescription glyphRunDescription,
            ComObject clientDrawingEffect
            )
        {
            var fHash     = FontHash(glyphRun.FontFace, glyphRun.FontSize);
            var positionX = (float)Math.Floor(baselineOriginX + 0.5f);
            var positionY = (float)Math.Floor(baselineOriginY + 0.5f);

            Color4     brushColor = Color4.White;
            TextShadow shadow     = new TextShadow();

            if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect colorFx)
            {
                brushColor = colorFx.Color;
                shadow     = colorFx.Shadow;
            }

            for (int i = 0; i < glyphRun.Indices.Length; i++)
            {
                var glyph = GetGlyph(fHash, glyphRun.FontFace, glyphRun.Indices[i], glyphRun.FontSize);
                if (shadow.Enabled)
                {
                    Quads.Add(new DrawQuad()
                    {
                        Texture     = glyph.Texture,
                        Source      = glyph.Rectangle,
                        Destination = new Rectangle(
                            (int)(glyph.OffsetX + positionX + 2),
                            (int)(glyph.OffsetY + positionY + 2),
                            glyph.Rectangle.Width,
                            glyph.Rectangle.Height
                            ),
                        Color = shadow.Color
                    });
                }
                var q = new DrawQuad()
                {
                    Texture     = glyph.Texture,
                    Source      = glyph.Rectangle,
                    Destination = new Rectangle(
                        (int)(glyph.OffsetX + positionX),
                        (int)(glyph.OffsetY + positionY),
                        glyph.Rectangle.Width,
                        glyph.Rectangle.Height
                        ),
                    Color = brushColor
                };
                Quads.Add(q);
                positionX += glyphRun.Advances[i];
            }
            return(Result.Ok);
        }
 public CanvasGlyphRun(Vector2 baselineOrigin, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription,
                       Brush foregroundBrush, MeasuringMode measuringMode)
 {
     BaselineOrigin      = baselineOrigin;
     GlyphRun            = glyphRun;
     GlyphRunDescription = glyphRunDescription;
     ForegroundBrush     = foregroundBrush;
     MeasuringMode       = measuringMode;
 }
        public override Result DrawGlyphRun(
            object clientDrawingContext,
            float baselineOriginX,
            float baselineOriginY,
            MeasuringMode measuringMode,
            GlyphRun glyphRun,
            GlyphRunDescription glyphRunDescription,
            ComObject clientDrawingEffect)
        {
            var brush = clientDrawingEffect as Brush ?? _defaultBrush;

            if (brush == null)
            {
                throw new NullReferenceException("No brush is set as a drawing effect for this glyph run and no default brush was given.");
            }

            var             textBrush       = brush as TextBrush;
            SolidColorBrush backgroundBrush = textBrush?.Background;

            if (backgroundBrush != null)
            {
                // Get width of text
                float totalWidth = 0;

                foreach (float advance in glyphRun.Advances)
                {
                    totalWidth += advance;
                }

                // Get height of text
                var fontMetrics = glyphRun.FontFace.Metrics;
                var adjust      = glyphRun.FontSize / fontMetrics.DesignUnitsPerEm;
                var ascent      = adjust * fontMetrics.Ascent;
                var descent     = adjust * fontMetrics.Descent;
                var rect        = new RawRectangleF(baselineOriginX,
                                                    baselineOriginY - ascent,
                                                    baselineOriginX + totalWidth,
                                                    baselineOriginY + descent);

                // Fill Rectangle
                _renderTarget.FillRectangle(rect, backgroundBrush);
            }

            _renderTarget.DrawGlyphRun(new Vector2(baselineOriginX, baselineOriginY), glyphRun, brush, measuringMode);
            return(Result.Ok);
        }
        public void DrawGlyphRun(float baselineOriginX, float baselineOriginY, Graphics.Direct2D.MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ClientDrawingEffect clientDrawingEffect)
        {
            using (PathGeometry pathGeometry = _factory.CreatePathGeometry())
            {

                using (GeometrySink sink = pathGeometry.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(
                        glyphRun.EmSize,
                        glyphRun.GlyphIndices,
                        glyphRun.GlyphAdvances,
                        glyphRun.GlyphOffsets,
                        glyphRun.IsSideways,
                        glyphRun.BidiLevel != 0,
                        sink);
                    sink.Close();
                }

                CustomGeometrySink customSink = new CustomGeometrySink();
                pathGeometry.Stream(customSink);
                customSink.Close();
                System.Diagnostics.Debug.WriteLine(customSink.ToString());

                SolidColorBrush brush = null;
                if (clientDrawingEffect != null)
                {
                    ColorDrawingEffect drawingEffect = clientDrawingEffect as ColorDrawingEffect;
                    if (drawingEffect != null)
                    {
                        brush = _renderTarget.CreateSolidColorBrush(drawingEffect.Color);
                    }
                }

                Matrix3x2 matrix = new Matrix3x2(1, 0, 0, 1, baselineOriginX, baselineOriginY);
                using (TransformedGeometry transformedGeometry = _factory.CreateTransformedGeometry(pathGeometry, matrix))
                {
                    _renderTarget.FillGeometry(brush == null ? _defaultBrush : brush, transformedGeometry);
                }
                if (brush != null)
                    brush.Dispose();
            }
        }
        public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY,
                                   MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription,
                                   ComObject clientDrawingEffect)
        {
            using (var path = new PathGeometry(_factory))
                using (var sink = path.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances,
                                                         glyphRun.Offsets, glyphRun.IsSideways, (glyphRun.BidiLevel % 2) > 0, sink);
                    sink.Close();

                    var matrix = new Matrix3x2(1.0f, 0.0f, 0.0f, 1.0f, Location.X + baselineOriginX, Location.Y + baselineOriginY);
                    using (var transformedGeometry = new TransformedGeometry(_factory, path, matrix))
                    {
                        Renderer.Context2D.AntialiasMode = AntialiasMode.Aliased;
                        Renderer.Context2D.DrawGeometry(transformedGeometry, OutlineBrush, StrokeWidth);
                        Renderer.Context2D.AntialiasMode = AntialiasMode.PerPrimitive;
                        Renderer.Context2D.FillGeometry(transformedGeometry, FillBrush);
                    }
                }
            return(Result.Ok);
        }
Example #9
0
        public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            var pathGeometry = new PathGeometry(_d2DFactory);
            var geometrySink = pathGeometry.Open();

            var fontFace = glyphRun.FontFace;

            if (glyphRun.Indices.Length > 0)
            {
                fontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 != 0, geometrySink);
            }
            geometrySink.Close();
            geometrySink.Dispose();
            fontFace.Dispose();

            var matrix = new Matrix3x2()
            {
                M11 = 1,
                M12 = 0,
                M21 = 0,
                M22 = 1,
                M31 = baselineOriginX,
                M32 = baselineOriginY
            };

            var transformedGeometry = new TransformedGeometry(_d2DFactory, pathGeometry, matrix);

            var brushColor = (Color4)Color.Black;

            if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect)
            {
                brushColor = (clientDrawingEffect as ColorDrawingEffect).Color;
            }

            var brush = new SolidColorBrush(_renderTarget, brushColor);

            _renderTarget.DrawGeometry(transformedGeometry, brush);
            _renderTarget.FillGeometry(transformedGeometry, brush);

            pathGeometry.Dispose();
            transformedGeometry.Dispose();
            brush.Dispose();

            return(SharpDX.Result.Ok);
        }
Example #10
0
            public override Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
            {
                using (PathGeometry path = new PathGeometry(renderer.factory2d))
                {
                    using (GeometrySink sink = path.Open())
                    {
                        glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.Advances.Length, glyphRun.IsSideways, (glyphRun.BidiLevel % 2) > 0, sink);
                        sink.Close();
                    }

                    var matrix = new Matrix3x2()
                    {
                        M11 = 1,
                        M12 = 0,
                        M21 = 0,
                        M22 = 1,
                        M31 = baselineOriginX,
                        M32 = baselineOriginY
                    };

                    TransformedGeometry transformedGeometry = new TransformedGeometry(renderer.factory2d, path, matrix);
                    renderer.rtv2d.DrawGeometry(transformedGeometry, renderer.brush2dOutline);
                    Utilities.Dispose(ref transformedGeometry);
                }

                return(new Result());
            }
 /// <summary>
 /// <see cref="IDWriteTextLayout.Draw(IntPtr, IDWriteTextRenderer, float, float)"/> calls this function to instruct the client to render a run of glyphs.
 /// </summary>
 /// <param name="clientDrawingContext">The drawing context passed to <see cref="IDWriteTextLayout.Draw(IntPtr, IDWriteTextRenderer, float, float)"/>.</param>
 /// <param name="baselineOriginX">The pixel location (X-coordinate) at the baseline origin of the glyph run.</param>
 /// <param name="baselineOriginY">The pixel location (Y-coordinate) at the baseline origin of the glyph run.</param>
 /// <param name="measuringMode">The measuring method for glyphs in the run, used with the other properties to determine the rendering mode.</param>
 /// <param name="glyphRun">The <see cref="GlyphRun"/> instance to render.</param>
 /// <param name="glyphRunDescription">The <see cref="GlyphRunDescription"/> instance which contains properties of the characters associated with this run.</param>
 /// <param name="clientDrawingEffect">Application-defined drawing effects for the glyphs to render. Usually this argument represents effects such as the foreground brush filling the interior of text.</param>
 public virtual void DrawGlyphRun(IntPtr clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, IUnknown clientDrawingEffect)
 {
 }
        public override Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            using (PathGeometry path = new PathGeometry(_factory))
                using (GeometrySink sink = path.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, false, sink);
                    sink.Close();

                    var translation = Matrix3x2.Translation(baselineOriginX, baselineOriginY);
                    var outline     = new TransformedGeometry(_factory, path, translation);
                    using (var strokeStyle = new StrokeStyle(_factory, new StrokeStyleProperties {
                        LineJoin = LineJoin.Round
                    }))
                    {
                        for (int i = 1; i < 8; i++)
                        {
                            var color = Color.White;
                            color.A /= (byte)Math.Ceiling(i / 1.5);
                            using (var brush = new SolidColorBrush(_surface, color))
                            {
                                _surface.DrawGeometry(outline, brush, i, strokeStyle);
                            }
                        }
                    }
                }

            return(new Result());
        }
Example #13
0
        public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            using (var pathGeometry = new PathGeometry(_d2DFactory))
            {
                using (var geometrySink = pathGeometry.Open())
                {
                    using (var fontFace = glyphRun.FontFace)
                    {
                        if (glyphRun.Indices.Length > 0)
                        {
                            fontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets,
                                                        glyphRun.Indices.Length, glyphRun.IsSideways, glyphRun.BidiLevel % 2 != 0, geometrySink);
                        }
                    }
                    geometrySink.Close();
                }


                var matrix = new Matrix3x2()
                {
                    M11 = 1,
                    M12 = 0,
                    M21 = 0,
                    M22 = 1,
                    M31 = baselineOriginX,
                    M32 = baselineOriginY
                };

                using (var transformedGeometry = new TransformedGeometry(_d2DFactory, pathGeometry, matrix))
                {
                    _dc.DrawGeometry(transformedGeometry, _outlineBrush);
                    _dc.FillGeometry(transformedGeometry, _fillBrush);
                }
            }
            return(SharpDX.Result.Ok);
        }
Example #14
0
        public override SharpDXLib.Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, SharpDXLib.ComObject clientDrawingEffect)
        {
            var cce  = (ClientTextEffect)clientDrawingEffect;
            var args = (Object[])clientDrawingContext;
            var ofs  = (Point)args[0];
            var ut   = (UText)args[1];

            Point origin = new Point(baselineOriginX, baselineOriginY);

            var fgb = cce == null ? defaultEffect.fgBrush : cce.fgBrush;

            rt.DrawGlyphRun(D2DTr.tr(origin), glyphRun, fgb, MeasuringMode.Natural);

            return(SharpDXLib.Result.Ok);
        }
        public override SharpDX.Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, SharpDX.ComObject clientDrawingEffect)
        {
            PathGeometry pg = new PathGeometry(this.factory);

            GeometrySink sink = pg.Open();

            glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 == 1, sink as SimplifiedGeometrySink);

            sink.Close();

            TransformedGeometry tg = new TransformedGeometry(this.factory, pg, Matrix3x2.Translation(baselineOriginX, baselineOriginY));

            pg.Dispose();

            //Transform from baseline

            this.AddGeometry(tg);

            return(SharpDX.Result.Ok);
        }
Example #16
0
        public override Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            SolidColorBrush sb = defaultBrush;

            if (clientDrawingEffect != null && clientDrawingEffect is SolidColorBrush)
            {
                sb = (SolidColorBrush)clientDrawingEffect;
            }

            try
            {
                this.renderTarget.DrawGlyphRun(new Vector2(baselineOriginX, baselineOriginY), glyphRun, sb, measuringMode);
                return(Result.Ok);
            }
            catch
            {
                return(Result.Fail);
            }
        }
        public void DrawGlyphRun(float baselineOriginX, float baselineOriginY, Graphics.Direct2D.MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ClientDrawingEffect clientDrawingEffect)
        {
            using (PathGeometry pathGeometry = _factory.CreatePathGeometry())
            {
                using (GeometrySink sink = pathGeometry.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(
                        glyphRun.EmSize,
                        glyphRun.GlyphIndices,
                        glyphRun.GlyphAdvances,
                        glyphRun.GlyphOffsets,
                        glyphRun.IsSideways,
                        glyphRun.BidiLevel != 0,
                        sink);
                    sink.Close();
                }

                CustomGeometrySink customSink = new CustomGeometrySink();
                pathGeometry.Stream(customSink);
                customSink.Close();
                System.Diagnostics.Debug.WriteLine(customSink.ToString());

                SolidColorBrush brush = null;
                if (clientDrawingEffect != null)
                {
                    ColorDrawingEffect drawingEffect = clientDrawingEffect as ColorDrawingEffect;
                    if (drawingEffect != null)
                    {
                        brush = _renderTarget.CreateSolidColorBrush(drawingEffect.Color);
                    }
                }

                Matrix3x2 matrix = new Matrix3x2(1, 0, 0, 1, baselineOriginX, baselineOriginY);
                using (TransformedGeometry transformedGeometry = _factory.CreateTransformedGeometry(pathGeometry, matrix))
                {
                    _renderTarget.FillGeometry(brush == null ? _defaultBrush : brush, transformedGeometry);
                }
                if (brush != null)
                {
                    brush.Dispose();
                }
            }
        }
        public void DrawGlyphRun(float baselineOriginX, float baselineOriginY, Graphics.Direct2D.MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ClientDrawingEffect clientDrawingEffect)
        {
            using (PathGeometry pathGeometry = _factory.CreatePathGeometry())
            {
                using (GeometrySink sink = pathGeometry.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(
                        glyphRun.EmSize,
                        glyphRun.GlyphIndices,
                        glyphRun.GlyphAdvances,
                        glyphRun.GlyphOffsets,
                        glyphRun.IsSideways,
                        glyphRun.BidiLevel != 0,
                        sink);
                    sink.Close();
                }

                CustomGeometrySink customSink = new CustomGeometrySink();
                pathGeometry.Stream(customSink);
                customSink.Close();
                System.Diagnostics.Debug.WriteLine(customSink.ToString());

                Matrix3x2 matrix = new Matrix3x2(1, 0, 0, 1, baselineOriginX, baselineOriginY);
                using (TransformedGeometry transformedGeometry = _factory.CreateTransformedGeometry(pathGeometry, matrix))
                {
                    _renderTarget.DrawGeometry(_outlineBrush, 5, transformedGeometry);
                    _renderTarget.FillGeometry(_fillBrush, transformedGeometry);
                }
            }
        }
Example #19
0
    public override void DrawGlyphRun(IntPtr clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, IUnknown clientDrawingEffect)
    {
        ID2D1SolidColorBrush brush = _defaultBrush;

        if (clientDrawingEffect is ComObject comObject)
        {
            brush = comObject.QueryInterfaceOrNull <ID2D1SolidColorBrush>();
        }

        try
        {
            _renderTarget.DrawGlyphRun(
                new System.Drawing.PointF(baselineOriginX, baselineOriginY),
                glyphRun,
                brush,
                measuringMode);
        }
        catch
        {
        }
    }
        /// <summary>
        /// IDWriteTextLayout::Draw calls this function to instruct the client to render a run of glyphs.
        /// </summary>
        /// <param name="clientDrawingContext">The application-defined drawing context passed to  <see cref="M:SharpDX.DirectWrite.TextLayout.Draw_(System.IntPtr,System.IntPtr,System.Single,System.Single)" />.</param>
        /// <param name="baselineOriginX">The pixel location (X-coordinate) at the baseline origin of the glyph run.</param>
        /// <param name="baselineOriginY">The pixel location (Y-coordinate) at the baseline origin of the glyph run.</param>
        /// <param name="measuringMode">The measuring method for glyphs in the run, used with the other properties to determine the rendering mode.</param>
        /// <param name="glyphRun">Pointer to the glyph run instance to render.</param>
        /// <param name="glyphRunDescription">A pointer to the optional glyph run description instance which contains properties of the characters  associated with this run.</param>
        /// <param name="clientDrawingEffect">Application-defined drawing effects for the glyphs to render. Usually this argument represents effects such as the foreground brush filling the interior of text.</param>
        /// <returns>
        /// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
        /// </returns>
        /// <unmanaged>HRESULT DrawGlyphRun([None] void* clientDrawingContext,[None] FLOAT baselineOriginX,[None] FLOAT baselineOriginY,[None] DWRITE_MEASURING_MODE measuringMode,[In] const DWRITE_GLYPH_RUN* glyphRun,[In] const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,[None] IUnknown* clientDrawingEffect)</unmanaged>
        /// <remarks>
        /// The <see cref="M:SharpDX.DirectWrite.TextLayout.Draw_(System.IntPtr,System.IntPtr,System.Single,System.Single)" /> function calls this callback function with all the information about glyphs to render. The application implements this callback by mostly delegating the call to the underlying platform's graphics API such as {{Direct2D}} to draw glyphs on the drawing context. An application that uses GDI can implement this callback in terms of the <see cref="M:SharpDX.DirectWrite.BitmapRenderTarget.DrawGlyphRun(System.Single,System.Single,SharpDX.Direct2D1.MeasuringMode,SharpDX.DirectWrite.GlyphRun,SharpDX.DirectWrite.RenderingParams,SharpDX.Color4)" /> method.
        /// </remarks>
        public override SDX.Result DrawGlyphRun(
            object clientDrawingContext, float baselineOriginX, float baselineOriginY,
            MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, SDX.ComObject clientDrawingEffect)
        {
            if ((glyphRun.Indices == null) ||
                (glyphRun.Indices.Length == 0))
            {
                return(SDX.Result.Ok);;
            }

            SharpDX.DirectWrite.Factory dWriteFactory = GraphicsCore.Current.FactoryDWrite;
            SharpDX.Direct2D1.Factory   d2DFactory    = GraphicsCore.Current.FactoryD2D;

            // Extrude geometry data out of given glyph run
            SimplePolygon2DGeometrySink geometryExtruder = new SimplePolygon2DGeometrySink(new Vector2(baselineOriginX, baselineOriginY));

            using (PathGeometry pathGeometry = new PathGeometry(d2DFactory))
            {
                // Write all geometry data into a standard PathGeometry object
                using (GeometrySink geoSink = pathGeometry.Open())
                {
                    glyphRun.FontFace.GetGlyphRunOutline(
                        glyphRun.FontSize,
                        glyphRun.Indices,
                        glyphRun.Advances,
                        glyphRun.Offsets,
                        glyphRun.IsSideways,
                        glyphRun.BidiLevel % 2 == 1,
                        geoSink);
                    geoSink.Close();
                }

                // Simplify written geometry and write it into own structure
                pathGeometry.Simplify(GeometrySimplificationOption.Lines, m_geometryOptions.SimplificationFlatternTolerance, geometryExtruder);
            }

            // Structure for caching the result
            VertexStructure        tempStructure = new VertexStructure();
            VertexStructureSurface tempSurface   = tempStructure.CreateSurface();

            // Create the text surface
            if (m_geometryOptions.MakeSurface)
            {
                // Separate polygons by clock direction
                // Order polygons as needed for further hole finding algorithm
                IEnumerable <Polygon2D> fillingPolygons = geometryExtruder.GeneratedPolygons
                                                          .Where(actPolygon => actPolygon.EdgeOrder == EdgeOrder.CounterClockwise)
                                                          .OrderBy(actPolygon => actPolygon.BoundingBox.Size.X * actPolygon.BoundingBox.Size.Y);
                List <Polygon2D> holePolygons = geometryExtruder.GeneratedPolygons
                                                .Where(actPolygon => actPolygon.EdgeOrder == EdgeOrder.Clockwise)
                                                .OrderByDescending(actPolygon => actPolygon.BoundingBox.Size.X * actPolygon.BoundingBox.Size.Y)
                                                .ToList();

                // Build geometry for all polygons
                int loopPolygon = 0;
                foreach (Polygon2D actFillingPolygon in fillingPolygons)
                {
                    // Find all corresponding holes
                    BoundingBox2D           actFillingPolygonBounds = actFillingPolygon.BoundingBox;
                    IEnumerable <Polygon2D> correspondingHoles      = holePolygons
                                                                      .Where(actHolePolygon => actHolePolygon.BoundingBox.IsContainedBy(actFillingPolygonBounds))
                                                                      .ToList();

                    // Two steps here:
                    // - Merge current filling polygon and all its holes.
                    // - Remove found holes from current hole list
                    Polygon2D      polygonForRendering     = actFillingPolygon;
                    Polygon2D      polygonForTriangulation = actFillingPolygon.Clone();
                    List <Vector2> cutPoints = new List <Vector2>();
                    foreach (Polygon2D actHole in correspondingHoles)
                    {
                        holePolygons.Remove(actHole);
                        polygonForRendering     = polygonForRendering.MergeWithHole(actHole, Polygon2DMergeOptions.Default, cutPoints);
                        polygonForTriangulation = polygonForTriangulation.MergeWithHole(actHole, new Polygon2DMergeOptions()
                        {
                            MakeMergepointSpaceForTriangulation = true
                        });
                    }

                    loopPolygon++;
                    int actBaseIndex = (int)tempStructure.CountVertices;

                    EdgeOrder edgeOrder = polygonForRendering.EdgeOrder;
                    float     edgeSize  = edgeOrder == EdgeOrder.CounterClockwise ? 0.1f : 0.4f;

                    // Append all vertices to temporary VertexStructure
                    for (int loop = 0; loop < polygonForRendering.Vertices.Count; loop++)
                    {
                        // Calculate 3d location and texture coordinate
                        Vector3 actVertexLocation = new Vector3(
                            polygonForRendering.Vertices[loop].X,
                            0f,
                            polygonForRendering.Vertices[loop].Y);
                        Vector2 actTexCoord = new Vector2(
                            (polygonForRendering.Vertices[loop].X - polygonForRendering.BoundingBox.Location.X) / polygonForRendering.BoundingBox.Size.X,
                            (polygonForRendering.Vertices[loop].Y - polygonForRendering.BoundingBox.Location.Y) / polygonForRendering.BoundingBox.Size.Y);
                        if (float.IsInfinity(actTexCoord.X) || float.IsNaN(actTexCoord.X))
                        {
                            actTexCoord.X = 0f;
                        }
                        if (float.IsInfinity(actTexCoord.Y) || float.IsNaN(actTexCoord.Y))
                        {
                            actTexCoord.Y = 0f;
                        }

                        // Append the vertex to the result
                        tempStructure.AddVertex(
                            new Vertex(
                                actVertexLocation,
                                m_geometryOptions.SurfaceVertexColor,
                                actTexCoord,
                                new Vector3(0f, 1f, 0f)));
                    }

                    // Generate cubes on each vertex if requested
                    if (m_geometryOptions.GenerateCubesOnVertices)
                    {
                        for (int loop = 0; loop < polygonForRendering.Vertices.Count; loop++)
                        {
                            Color4 colorToUse      = Color4.GreenColor;
                            float  pointRenderSize = 0.1f;
                            if (cutPoints.Contains(polygonForRendering.Vertices[loop]))
                            {
                                colorToUse      = Color4.RedColor;
                                pointRenderSize = 0.15f;
                            }

                            Vector3 actVertexLocation = new Vector3(
                                polygonForRendering.Vertices[loop].X,
                                0f,
                                polygonForRendering.Vertices[loop].Y);
                            tempSurface.BuildCube24V(actVertexLocation, pointRenderSize, colorToUse);
                        }
                    }

                    // Triangulate the polygon
                    IEnumerable <int> triangleIndices = polygonForTriangulation.TriangulateUsingCuttingEars();
                    if (triangleIndices == null)
                    {
                        continue;
                    }
                    if (triangleIndices == null)
                    {
                        throw new SeeingSharpGraphicsException("Unable to triangulate given PathGeometry object!");
                    }

                    // Append all triangles to the temporary structure
                    using (IEnumerator <int> indexEnumerator = triangleIndices.GetEnumerator())
                    {
                        while (indexEnumerator.MoveNext())
                        {
                            int index1 = indexEnumerator.Current;
                            int index2 = 0;
                            int index3 = 0;

                            if (indexEnumerator.MoveNext())
                            {
                                index2 = indexEnumerator.Current;
                            }
                            else
                            {
                                break;
                            }
                            if (indexEnumerator.MoveNext())
                            {
                                index3 = indexEnumerator.Current;
                            }
                            else
                            {
                                break;
                            }

                            tempSurface.AddTriangle(
                                (int)(actBaseIndex + index3),
                                (int)(actBaseIndex + index2),
                                (int)(actBaseIndex + index1));
                        }
                    }
                }
            }

            // Make volumetric outlines
            int triangleCountWithoutSide = tempSurface.CountTriangles;

            if (m_geometryOptions.MakeVolumetricText)
            {
                float volumetricTextDepth = m_geometryOptions.VolumetricTextDepth;
                if (m_geometryOptions.VerticesScaleFactor > 0f)
                {
                    volumetricTextDepth = volumetricTextDepth / m_geometryOptions.VerticesScaleFactor;
                }

                // Add all side surfaces
                foreach (Polygon2D actPolygon in geometryExtruder.GeneratedPolygons)
                {
                    foreach (Line2D actLine in actPolygon.Lines)
                    {
                        tempSurface.BuildRect4V(
                            new Vector3(actLine.StartPosition.X, -volumetricTextDepth, actLine.StartPosition.Y),
                            new Vector3(actLine.EndPosition.X, -volumetricTextDepth, actLine.EndPosition.Y),
                            new Vector3(actLine.EndPosition.X, 0f, actLine.EndPosition.Y),
                            new Vector3(actLine.StartPosition.X, 0f, actLine.StartPosition.Y),
                            m_geometryOptions.VolumetricSideSurfaceVertexColor);
                    }
                }
            }

            // Do also make back surface?
            if (m_geometryOptions.MakeBackSurface)
            {
                for (int loop = 0; loop < triangleCountWithoutSide; loop++)
                {
                    Triangle triangle     = tempSurface.Triangles[loop];
                    Vertex   vertex0      = tempStructure.Vertices[triangle.Index1];
                    Vertex   vertex1      = tempStructure.Vertices[triangle.Index2];
                    Vertex   vertex2      = tempStructure.Vertices[triangle.Index3];
                    Vector3  changeVector = new Vector3(0f, -m_geometryOptions.VolumetricTextDepth, 0f);

                    tempSurface.AddTriangle(
                        vertex2.Copy(vertex2.Position - changeVector, Vector3.Negate(vertex2.Normal)),
                        vertex1.Copy(vertex1.Position - changeVector, Vector3.Negate(vertex1.Normal)),
                        vertex0.Copy(vertex0.Position - changeVector, Vector3.Negate(vertex0.Normal)));
                }
            }

            // TODO: Make this configurable
            tempStructure.ToggleCoordinateSystem();

            // Scale the text using given scale factor
            if (m_geometryOptions.VerticesScaleFactor > 0f)
            {
                Matrix4x4 scaleMatrix = Matrix4x4.CreateScale(
                    m_geometryOptions.VerticesScaleFactor,
                    m_geometryOptions.VerticesScaleFactor,
                    m_geometryOptions.VerticesScaleFactor);

                Matrix4Stack transformMatrix = new Matrix4Stack(scaleMatrix);
                transformMatrix.TransformLocal(m_geometryOptions.VertexTransform);

                tempStructure.UpdateVerticesUsingRelocationFunc((actVector) => Vector3.Transform(actVector, transformMatrix.Top));
            }

            // Calculate all normals before adding to target structure
            if (m_geometryOptions.CalculateNormals)
            {
                tempStructure.CalculateNormalsFlat();
            }

            // Merge temporary structure to target structure
            m_targetSurface.AddStructure(tempStructure);

            return(SDX.Result.Ok);
        }
Example #21
0
        private void TextByGlyph(RectangleF rect, string text, TextInfo info, SolidColorBrush brush)
        {
            FontFace fontFace;

            if (!m_faceMap.TryGetValue(info.Font, out fontFace))
            {
                using (var f = new SharpDX.DirectWrite.Factory())
                    using (var collection = f.GetSystemFontCollection(false))
                    {
                        int familyIndex;
                        if (!collection.FindFamilyName(info.Font.FamilylName, out familyIndex))
                        {
                            return;
                        }

                        using (var family = collection.GetFontFamily(familyIndex))
                            using (var font = family.GetFont(0))
                            {
                                fontFace = new FontFace(font);
                                m_faceMap.Add(info.Font, fontFace);
                            }
                    }
            }

            var codePoints = EnumCodePoints(text).ToArray();
            var indices    = fontFace.GetGlyphIndices(codePoints);

            // Get glyph
            var metrices = fontFace.GetDesignGlyphMetrics(indices, false);

            // draw
            var glyphRun = new GlyphRun
            {
                FontFace = fontFace,
                Indices  = indices,
                FontSize = info.Font.Size,
            };

            bool done = false;

            using (var f = new SharpDX.DirectWrite.Factory())
                using (var ff = f.QueryInterface <SharpDX.DirectWrite.Factory4>())
                {
                    var desc = new GlyphRunDescription
                    {
                    };
                    ColorGlyphRunEnumerator it;
                    var result = ff.TryTranslateColorGlyphRun(0, 0, glyphRun,
                                                              null, MeasuringMode.Natural, null, 0, out it);
                    if (result.Code == DWRITE_E_NOCOLORLOR)
                    {
                        m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size), glyphRun, brush, MeasuringMode.Natural);
                    }
                    else
                    {
                        while (true)
                        {
                            var colorBrush = GetOrCreateBrush(new Color4(
                                                                  it.CurrentRun.RunColor.R,
                                                                  it.CurrentRun.RunColor.G,
                                                                  it.CurrentRun.RunColor.B,
                                                                  it.CurrentRun.RunColor.A));
                            m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size),
                                                                   it.CurrentRun.GlyphRun, colorBrush, MeasuringMode.Natural);
                            done = true;

                            SharpDX.Mathematics.Interop.RawBool hasNext;
                            it.MoveNext(out hasNext);
                            if (!hasNext)
                            {
                                break;;
                            }
                        }
                    }
                }
        }
Example #22
0
        public override Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            SharpDX.Direct2D1.Brush brush = defaultBrush;
            if (clientDrawingEffect != null && clientDrawingEffect is SharpDX.Direct2D1.Brush)
            {
                brush = (SharpDX.Direct2D1.Brush)clientDrawingEffect;
            }

            try
            {
                renderTarget.DrawGlyphRun(new Vector2(baselineOriginX, baselineOriginY), glyphRun, brush, measuringMode);
                return(Result.Ok);
            }
            catch
            {
                return(Result.Fail);
            }
        }
Example #23
0
        public override SharpDX.Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, SharpDX.ComObject clientDrawingEffect)
        {
            Color4 c = Color4.White;

            if (clientDrawingEffect != null)
            {
                if (clientDrawingEffect is SharpDX.Direct2D1.SolidColorBrush)
                {
                    var sb = (SharpDX.Direct2D1.SolidColorBrush)clientDrawingEffect;
                    c = sb.Color;
                }
            }

            if (glyphRun.Indices.Length > 0)
            {
                PathGeometry pg = new PathGeometry(this.factory);

                GeometrySink sink = pg.Open();

                glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 == 1, sink as SimplifiedGeometrySink);
                sink.Close();

                TransformedGeometry tg = new TransformedGeometry(this.factory, pg, Matrix3x2.Translation(baselineOriginX, baselineOriginY) * Matrix3x2.Scaling(1.0f, -1.0f));

                pg.Dispose();
                sink.Dispose();
                //Transform from baseline

                this.AddGeometry(tg);

                return(SharpDX.Result.Ok);
            }
            else
            {
                return(SharpDX.Result.Ok);
            }
        }
Example #24
0
        public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
        {
            var pathGeometry = new PathGeometry(_d2DFactory);
            var geometrySink = pathGeometry.Open();

            float[]       advances;
            GlyphOffset[] offsets;
            var           indecies = glyphRun.ToArrays(out advances, out offsets);

            var result = glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, indecies, advances, offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 != 0, geometrySink);

            geometrySink.Close();
            var matrix = new Matrix3x2()
            {
                M11 = 1,
                M12 = 0,
                M21 = 0,
                M22 = 1,
                M31 = baselineOriginX,
                M32 = baselineOriginY
            };

            var transformedGeometry = new TransformedGeometry(_d2DFactory, pathGeometry, matrix);

            var brushColor = new Color4(1, 0, 0, 0);

            if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect)
            {
                brushColor = (clientDrawingEffect as ColorDrawingEffect).Color;
            }

            var brush = new SolidColorBrush(_renderTarget, brushColor);

            _renderTarget.DrawGeometry(transformedGeometry, brush);
            _renderTarget.FillGeometry(transformedGeometry, brush);

            pathGeometry.Dispose();
            transformedGeometry.Dispose();
            brush.Dispose();

            return(SharpDX.Result.Ok);
        }