public unsafe void TextRenderer_DrawText_DefaultBackground_RendersTransparent(Func <IDeviceContext, Action> func)
        {
            using var emf = EmfScope.Create();
            DeviceContextState state = new DeviceContextState(emf);

            func(new HdcDeviceContextAdapter(emf)).Invoke();

            bool success = false;

            emf.EnumerateWithState((ref EmfRecord record, DeviceContextState state) =>
            {
                switch (record.Type)
                {
                case Gdi32.EMR.EXTTEXTOUTW:
                    var textOut = record.ExtTextOutWRecord;
                    Assert.Equal("Acrylic", textOut->emrtext.GetString().ToString());
                    Assert.Equal(Gdi32.MM.TEXT, state.MapMode);
                    Assert.Equal(Gdi32.BKMODE.TRANSPARENT, state.BackgroundMode);
                    Assert.Equal((COLORREF)Color.Blue, state.TextColor);
                    Assert.Equal(SystemFonts.DefaultFont.Name, state.SelectedFont);
                    success = true;
                    return(false);
                }
                return(true);
            },
                                   state);

            Assert.True(success, "Did not find the text out record.");
        }
        public unsafe void Button_FlatStyle_WithText_Rectangle()
        {
            using Button button = new Button
                  {
                      Text      = "Flat Style",
                      FlatStyle = FlatStyle.Flat,
                  };

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            emf.Validate(
                state,
                Validate.SkipType(Gdi32.EMR.BITBLT),
                Validate.TextOut("Flat Style"),
                Validate.Rectangle(
                    new Rectangle(0, 0, button.Width - 1, button.Height - 1),
                    State.PenColor(Color.Black),
                    State.PenStyle(Gdi32.PS.ENDCAP_ROUND),
                    State.BrushStyle(Gdi32.BS.NULL),       // Regressed in https://github.com/dotnet/winforms/pull/3667
                    State.Rop2(Gdi32.R2.COPYPEN)));
        }
        public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            complete = true;

            _processor?.Invoke(ref record);
            _processorWithState?.Invoke(ref record, state);
        }
        public void ControlPaint_DrawBorder_Inset_Rendering()
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            using Graphics graphics = Graphics.FromHdc((IntPtr)emf.HDC);

            Rectangle bounds = new Rectangle(10, 10, 10, 10);

            ControlPaint.DrawBorder(graphics, bounds, Color.Gray, ButtonBorderStyle.Inset);

            // For whatever reason GDI+ renders as polylines scaled 16x with a 1/16th world transform applied.
            // For test readability we'll transform the points from our coordinates to the logical coordinates.
            Matrix3x2 oneSixteenth = Matrix3x2.CreateScale(0.0625f);
            Matrix3x2 times16      = Matrix3x2.CreateScale(16.0f);

            // This is the default pen style GDI+ renders polylines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT
                                | Gdi32.PS.JOIN_MITER | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                // Top
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 10, 19, 10),
                    State.Pen(16, ControlPaint.DarkDark(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Left
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 10, 10, 19),
                    State.Pen(16, ControlPaint.DarkDark(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Bottom
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 10, 19, 19, 19),
                    State.Pen(16, ControlPaint.LightLight(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Right
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 19, 10, 19, 19),
                    State.Pen(16, ControlPaint.LightLight(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Top inset
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 11, 11, 18, 11),
                    State.Pen(16, ControlPaint.Light(Color.Gray), penStyle),
                    State.Transform(oneSixteenth)),
                // Left inset
                Validate.Polyline16(
                    bounds: null,
                    PointArray(times16, 11, 11, 11, 18),
                    State.Pen(16, ControlPaint.Light(Color.Gray), penStyle),
                    State.Transform(oneSixteenth))
                );
        }
        public unsafe void Button_FlatStyle_WithText_Rectangle()
        {
            using Button button = new Button
                  {
                      Text      = "Flat Style",
                      FlatStyle = FlatStyle.Flat,
                  };

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            emf.Validate(
                state,
                Validate.SkipType(Gdi32.EMR.BITBLT),
                Validate.TextOut("Flat Style"),
                Validate.Rectangle(
                    new Rectangle(0, 0, button.Width - 1, button.Height - 1),
                    penColor: Color.Black,
                    penStyle: Gdi32.PS.ENDCAP_ROUND,
                    brushColor: Color.Empty,        // Color doesn't really matter as we're using a null brush
                    brushStyle: Gdi32.BS.NULL,      // Regressed in https://github.com/dotnet/winforms/pull/3667
                    rop2: Gdi32.R2.COPYPEN));
        }
Beispiel #6
0
        public unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            // We're only checking one TextOut record, so this call completes our work.
            complete = true;

            EMREXTTEXTOUTW *textOut = record.ExtTextOutWRecord;

            if (_validate.HasFlag(Flags.Text))
            {
                Assert.Equal(_text, textOut->emrtext.GetString().ToString());
            }

            if (_validate.HasFlag(Flags.MapMode))
            {
                Assert.Equal(_mapMode, state.MapMode);
            }

            if (_validate.HasFlag(Flags.BackgroundMode))
            {
                Assert.Equal(_backgroundMode, state.BackgroundMode);
            }

            if (_validate.HasFlag(Flags.TextColor))
            {
                Assert.Equal((COLORREF)_textColor, state.TextColor);
            }

            if (_validate.HasFlag(Flags.FontFace))
            {
                Assert.Equal(_fontFace, state.SelectedFont.FaceName.ToString());
            }
        }
Beispiel #7
0
        public void NumericUpDown_VisualStyles_off_BasicRendering_ControlDisabled()
        {
            if (Application.RenderWithVisualStyles)
            {
                return;
            }

            using var form   = new Form();
            using var upDown = new NumericUpDown();

            form.Controls.Add(upDown);

            // Check the disabled state
            upDown.Enabled = false;

            using var emfDisabled = new EmfScope();
            DeviceContextState state = new DeviceContextState(emfDisabled);

            upDown.PrintToMetafile(emfDisabled);

            emfDisabled.Validate(
                state,
                Validate.Rectangle(
                    new Rectangle(0, 0, 99, 18),
                    State.Pen(1, upDown.BackColor, Gdi32.PS.SOLID)),
                Validate.Rectangle(
                    new Rectangle(1, 1, 97, 16),
                    State.Pen(1, SystemColors.Control, Gdi32.PS.SOLID)),
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.LineTo(
                    (0, 18), (16, 18),
                    State.Pen(1, upDown.BackColor, Gdi32.PS.SOLID)));
        }
Beispiel #8
0
        public void TextBox_Disabled_PlaceholderText_RendersBackgroundCorrectly()
        {
            // Regression test for https://github.com/dotnet/winforms/issues/3706

            using Form form       = new Form();
            using TextBox textBox = new TextBox
                  {
                      Size            = new Size(80, 23),
                      PlaceholderText = "abc",
                      Enabled         = false
                  };
            form.Controls.Add(textBox);

            // Force the handle creation
            Assert.NotEqual(IntPtr.Zero, form.Handle);
            Assert.NotEqual(IntPtr.Zero, textBox.Handle);

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            textBox.TestAccessor().Dynamic.DrawPlaceholderText(emf.HDC);

            emf.Validate(
                state,
                Validate.TextOut(
                    "abc",
                    bounds: null,                                   // Don't care about the bounds for this test
                    State.BackgroundMode(Gdi32.BKMODE.TRANSPARENT)));
        }
        public void ControlPaint_DrawBorder_Dashed_Rendering()
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            using Graphics graphics = Graphics.FromHdc((IntPtr)emf.HDC);

            Rectangle bounds = new Rectangle(10, 10, 10, 10);

            ControlPaint.DrawBorder(graphics, bounds, Color.Pink, ButtonBorderStyle.Dashed);

            // For whatever reason GDI+ renders as polygons scaled 16x with a 1/16th world transform applied.
            Matrix3x2 oneSixteenth = Matrix3x2.CreateScale(0.0625f);

            // This is the default pen style GDI+ renders dotted lines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT
                                | Gdi32.PS.JOIN_BEVEL | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                Validate.PolyPolygon16(
                    new Rectangle(8, 8, 13, 13),
                    polyCount: 9,
                    State.Transform(oneSixteenth),
                    State.Pen(16, Color.Pink, penStyle),
                    State.Brush(Color.Pink, Gdi32.BS.SOLID)));
        }
Beispiel #10
0
        public void NumericUpDown_BasicRendering()
        {
            using var form   = new Form();
            using var upDown = new NumericUpDown();

            form.Controls.Add(upDown);

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Assert.Equal(new Rectangle(0, 0, 120, 23), upDown.Bounds);

            // The rendering here is the "fill" for the background around the child edit control, which
            // doesn't match up to the main control's bounds.
            upDown.PrintToMetafile(emf);
            emf.Validate(
                state,
                Validate.Rectangle(
                    new Rectangle(1, 1, 98, 17),
                    State.Pen(2, upDown.BackColor, Gdi32.PS.SOLID)));

            // Printing the main control doesn't get the redraw for the child controls on the first render,
            // directly hitting the up/down button subcontrol.

            using var emfButtons = new EmfScope();
            state = new DeviceContextState(emfButtons);
            upDown.Controls[0].PrintToMetafile(emfButtons);

            // This is the "fill" line under the up/down arrows
            emfButtons.Validate(
                state,
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.LineTo(
                    (0, 18), (16, 18),
                    State.Pen(1, upDown.BackColor, Gdi32.PS.SOLID)));

            // Now check the disabled state

            upDown.Enabled = false;

            using var emfDisabled = new EmfScope();
            state = new DeviceContextState(emfDisabled);
            upDown.PrintToMetafile(emfDisabled);

            emfDisabled.Validate(
                state,
                Validate.Rectangle(
                    new Rectangle(0, 0, 99, 18),
                    State.Pen(1, upDown.BackColor, Gdi32.PS.SOLID)),
                Validate.Rectangle(
                    new Rectangle(1, 1, 97, 16),
                    State.Pen(1, SystemColors.Control, Gdi32.PS.SOLID)),
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.SkipType(Gdi32.EMR.STRETCHDIBITS),
                Validate.LineTo(
                    (0, 18), (16, 18),
                    State.Pen(1, upDown.BackColor, Gdi32.PS.SOLID)));
        }
Beispiel #11
0
        internal static void Validate(
            this EmfScope emf,
            DeviceContextState state,
            params IEmfValidator[] validationSteps)
        {
            if (state is null)
            {
                throw new ArgumentNullException(nameof(state));
            }
            if (validationSteps is null)
            {
                throw new ArgumentNullException(nameof(validationSteps));
            }

            int           currentIndex     = 0;
            IEmfValidator?currentValidator = validationSteps[currentIndex];

            emf.EnumerateWithState((ref EmfRecord record, DeviceContextState state) =>
            {
                if (currentValidator?.ShouldValidate(record.Type) ?? false)
                {
                    try
                    {
                        currentValidator.Validate(ref record, state, out bool complete);

                        if (complete)
                        {
                            // Current validator doesn't want to look at any more records.
                            currentIndex++;
                            currentValidator = currentIndex < validationSteps.Length
                                    ? validationSteps[currentIndex]
                                    : null;
                        }
                    }
                    catch (XunitException e)
                    {
                        throw new WrappedXunitException(
                            $"\nValidator index {currentIndex}: {currentValidator!.GetType().Name} failed",
                            e);
                    }
                }
                else
                {
                    Assert.False(IsRenderingRecord(record.Type), $"Got unexpected {record.Type}");
                }

                return(true);
            },
                                   state);

            if (currentValidator != null)
            {
                Assert.False(
                    currentValidator.FailIfIncomplete,
                    $"{currentValidator.GetType().Name} did not receive expected records");
            }
        }
Beispiel #12
0
        public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            base.Validate(ref record, state, out _);

            // We're only checking one PolyPolyline16 record, so this call completes our work.
            complete = true;

            Validate(record.PolyPolyline16Record);
        }
        public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            if (_count <= 0)
            {
                throw new InvalidOperationException();
            }

            _validator.Validate(ref record, state, out _);
            _count--;
            complete = _count == 0;
        }
        public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            base.Validate(ref record, state, out _);

            // We're only checking one BitBlt record, so this call completes our work.
            complete = true;

            if (_bounds.HasValue)
            {
                EMRBITBLT *bitBlt = record.BitBltRecord;
                Assert.Equal(_bounds.Value, (Rectangle)bitBlt->rclBounds);
            }
        }
        public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            base.Validate(ref record, state, out _);

            // We're only checking one Rectangle record, so this call completes our work.
            complete = true;

            if (_bounds.HasValue)
            {
                EMRRECTRECORD *rectangle = record.RectangleRecord;
                Assert.Equal(_bounds.Value, (Rectangle)rectangle->rect);
            }
        }
        public unsafe void Button_VisualStyles_on_Default_WithText_LineDrawing()
        {
            if (!Application.RenderWithVisualStyles)
            {
                return;
            }

            using Button button = new Button { Text = "Hello" };
            using var emf       = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            /*
             *
             * [ENHMETAHEADER] Bounds: {0, 0, 74, 22 (LTRB)} Device Size: {Width=3840, Height=2160} Header Size: 108
             * [EMRINTERSECTCLIPRECT] RECT: {0, 0, 75, 23 (LTRB)}
             * [EMRSETVIEWPORTORGEX] Point: {X=0,Y=0}
             * [EMRCREATEBRUSHINDIRECT] Index: 1 Style: SOLID Color: [R=240, G=240, B=240] (COLOR_MENU, COLOR_BTNFACE, COLOR_MENUBAR)
             * [EMRSELECTOBJECT] Index: 1
             * [EMRBITBLT] Bounds: {0, 0, -1, -1 (LTRB)} Destination: {0, 0, 120, 0 (LTRB)} Rop: PATCOPY Source DC Color: [R=0, G=0, B=0] (COLOR_BACKGROUND, COLOR_MENUTEXT, COLOR_WINDOWTEXT, COLOR_CAPTIONTEXT, COLOR_BTNTEXT, COLOR_INACTIVECAPTIONTEXT, COLOR_INFOTEXT)
             * [EMRSELECTOBJECT] StockObject: WHITE_BRUSH
             * [EMRDELETEOBJECT] Index: 1
             * [EMRCREATEBRUSHINDIRECT] Index: 1 Style: SOLID Color: [R=240, G=240, B=240] (COLOR_MENU, COLOR_BTNFACE, COLOR_MENUBAR)
             * [EMRSELECTOBJECT] Index: 1
             * [EMRBITBLT] Bounds: {0, 0, -1, -1 (LTRB)} Destination: {0, 0, 120, 0 (LTRB)} Rop: PATCOPY Source DC Color: [R=0, G=0, B=0] (COLOR_BACKGROUND, COLOR_MENUTEXT, COLOR_WINDOWTEXT, COLOR_CAPTIONTEXT, COLOR_BTNTEXT, COLOR_INACTIVECAPTIONTEXT, COLOR_INFOTEXT)
             * [EMRSELECTOBJECT] StockObject: WHITE_BRUSH
             * [EMRDELETEOBJECT] Index: 1
             * [EMRSETVIEWPORTORGEX] Point: {X=0,Y=0}
             * [EMREXTSELECTCLIPRGN] Mode: COPY Bounds: {0, 0, 75, 23 (LTRB)} Rects: 1 Rect index 0: {0, 0, 75, 23 (LTRB)}
             * [EMRINTERSECTCLIPRECT] RECT: {0, 0, 75, 23 (LTRB)}
             * [EMRALPHABLEND]
             * [EMREXTSELECTCLIPRGN] Mode: COPY Bounds: {0, 0, 75, 23 (LTRB)} Rects: 1 Rect index 0: {0, 0, 75, 23 (LTRB)}
             * [EMRSAVEDC]
             * [EMRSETICMMODE] Mode: ICM_OFF
             * [EMREXTSELECTCLIPRGN] Mode: Set Default
             * [EMRSETBKMODE] Mode: BKMODE_TRANSPARENT
             * [EMRSETTEXTCOLOR] Color: [R=0, G=0, B=0] (COLOR_BACKGROUND, COLOR_MENUTEXT, COLOR_WINDOWTEXT, COLOR_CAPTIONTEXT, COLOR_BTNTEXT, COLOR_INACTIVECAPTIONTEXT, COLOR_INFOTEXT)
             * [EMRSETTEXTALIGN] Mode: TA_BASELINE
             * [EMREXTCREATEFONTINDIRECTW] Index: 1 FaceName: 'Segoe UI' Height: -12 Weight: FW_NORMAL
             * [EMRSELECTOBJECT] Index: 1
             * [EMREXTTEXTOUTW] Bounds: {24, 4, 51, 18 (LTRB)} Text: 'Hello'
             * [EMRSELECTOBJECT] StockObject: SYSTEM_FONT
             * [EMRRESTOREDC] Index: -1
             * [EMRDELETEOBJECT] Index: 1
             * [EMREOF]
             *
             */
        }
Beispiel #17
0
        public unsafe void TextRenderer_DrawText_DefaultBackground_RendersTransparent(Func <IDeviceContext, Action> func)
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            func(new HdcDeviceContextAdapter(emf)).Invoke();

            emf.Validate(
                state,
                Validate.TextOut(
                    "Acrylic",
                    Color.Blue,
                    fontFace: SystemFonts.DefaultFont.Name));
        }
Beispiel #18
0
        public unsafe void TextRenderer_DrawText_DefaultBackground_RendersTransparent(Func <IDeviceContext, Action> func)
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            func(new HdcDeviceContextAdapter(emf)).Invoke();

            emf.Validate(
                state,
                Validate.TextOut(
                    "Acrylic",
                    bounds: null,                                   // Don't care about the bounds for this test
                    State.FontFace(SystemFonts.DefaultFont.Name),
                    State.TextColor(Color.Blue)));
        }
Beispiel #19
0
        public void ToolStrip_RendersBackgroundCorrectly()
        {
            using Form form           = new Form();
            using ToolStrip toolStrip = new ToolStrip
                  {
                      BackColor = Color.Blue,
                      Size      = new Size(200, 38)
                  };
            form.Controls.Add(toolStrip);

            // Force the handle creation
            _ = form.Handle;
            _ = toolStrip.Handle;
            form.PerformLayout();

            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle      bounds = toolStrip.Bounds;
            PaintEventArgs e      = new PaintEventArgs(emf, bounds);

            toolStrip.TestAccessor().Dynamic.OnPaintBackground(e);

            Rectangle bitBltBounds = new Rectangle(bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);

            RECT[] expectedRects = new RECT[]
            {
                new RECT(0, 0, 1, 1),
                new RECT(bounds.Width - 3, 0, bounds.Width, 1),
                new RECT(bounds.Width - 1, 1, bounds.Width, 3),
                new RECT(0, bounds.Height - 2, 1, bounds.Height - 1),
                new RECT(bounds.Width - 1, bounds.Height - 2, bounds.Width, bounds.Height - 1),
                new RECT(0, bounds.Height - 1, 2, bounds.Height),
                new RECT(bounds.Width - 2, bounds.Height - 1, bounds.Width, bounds.Height)
            };

            emf.Validate(
                state,
                Validate.BitBltValidator(
                    bitBltBounds,
                    State.BrushColor(Color.Blue)),
                Validate.BitBltValidator(
                    bitBltBounds,
                    State.BrushColor(form.BackColor),
                    State.Clipping(expectedRects)));

            var details = emf.RecordsToString();
        }
Beispiel #20
0
        public unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            // We're only checking one TextOut record, so this call completes our work.
            complete = true;

            EMRRECTRECORD *rectangle = record.RectangleRecord;

            if (_validate.HasFlag(Flags.Bounds))
            {
                Assert.Equal(_bounds, (Rectangle)rectangle->rect);
            }

            if (_validate.HasFlag(Flags.BrushColor))
            {
                Assert.Equal((COLORREF)_brushColor, state.SelectedBrush.lbColor);
            }

            if (_validate.HasFlag(Flags.BrushStyle))
            {
                Assert.Equal(_brushStyle, state.SelectedBrush.lbStyle);
            }

            if (_validate.HasFlag(Flags.PenColor))
            {
                Assert.Equal((COLORREF)_penColor, state.SelectedPen.lopnColor);
            }

            if (_validate.HasFlag(Flags.PenWidth))
            {
                Assert.Equal(_penWidth, state.SelectedPen.lopnWidth.X);
            }

            if (_validate.HasFlag(Flags.PenStyle))
            {
                Assert.Equal(_penStyle, state.SelectedPen.lopnStyle);
            }

            if (_validate.HasFlag(Flags.BackgroundMode))
            {
                Assert.Equal(_backgroundMode, state.BackgroundMode);
            }

            if (_validate.HasFlag(Flags.RopMode))
            {
                Assert.Equal(_rop2, state.Rop2Mode);
            }
        }
        public void ControlPaint_DrawBorder_Solid_Rendering()
        {
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            using Graphics graphics = Graphics.FromHdc((IntPtr)emf.HDC);

            Rectangle bounds = new Rectangle(10, 10, 10, 10);

            ControlPaint.DrawBorder(graphics, bounds, Color.Blue, ButtonBorderStyle.Solid);

            emf.Validate(
                state,
                Validate.Rectangle(
                    // We match the legacy GDI+ rendering, where the right and bottom are drawn inside the bounds
                    new Rectangle(10, 10, 9, 9),
                    State.Pen(1, Color.Blue, Gdi32.PS.SOLID)));
        }
        public unsafe void Button_VisualStyles_off_Default_WithText_LineDrawing()
        {
            if (Application.RenderWithVisualStyles)
            {
                return;
            }

            using Button button = new Button { Text = "Hello" };
            using var emf       = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            emf.Validate(
                state,
                Validate.SkipType(Gdi32.EMR.BITBLT),
                Validate.TextOut("Hello"),
                Validate.LineTo(
                    (bounds.Right - 1, 0), (0, 0),
                    State.PenColor(SystemColors.ControlLightLight)),
                Validate.LineTo(
                    (0, 0), (0, bounds.Bottom - 1),
                    State.PenColor(SystemColors.ControlLightLight)),
                Validate.LineTo(
                    (0, bounds.Bottom - 1), (bounds.Right - 1, bounds.Bottom - 1),
                    State.PenColor(SystemColors.ControlDarkDark)),
                Validate.LineTo(
                    (bounds.Right - 1, bounds.Bottom - 1), (bounds.Right - 1, -1),
                    State.PenColor(SystemColors.ControlDarkDark)),
                Validate.LineTo(
                    (bounds.Right - 2, 1), (1, 1),
                    State.PenColor(SystemColors.Control)),
                Validate.LineTo(
                    (1, 1), (1, bounds.Bottom - 2),
                    State.PenColor(SystemColors.Control)),
                Validate.LineTo(
                    (1, bounds.Bottom - 2), (bounds.Right - 2, bounds.Bottom - 2),
                    State.PenColor(SystemColors.ControlDark)),
                Validate.LineTo(
                    (bounds.Right - 2, bounds.Bottom - 2), (bounds.Right - 2, 0),
                    State.PenColor(SystemColors.ControlDark)));
        }
Beispiel #23
0
        public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            base.Validate(ref record, state, out _);

            // We're only checking one TextOut record, so this call completes our work.
            complete = true;

            EMREXTTEXTOUTW *textOut = record.ExtTextOutWRecord;

            if (_text != null)
            {
                Assert.Equal(_text, textOut->emrtext.GetText().ToString());
            }

            if (_bounds.HasValue)
            {
                Assert.Equal(_bounds.Value, (Rectangle)textOut->rclBounds);
            }
        }
        public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            base.Validate(ref record, state, out _);

            // We're only checking one LineTo record, so this call completes our work.
            complete = true;

            EMRPOINTRECORD *lineTo = record.LineToRecord;

            if (_from.HasValue)
            {
                Assert.Equal(_from.Value, state.BrushOrigin);
            }

            if (_to.HasValue)
            {
                Assert.Equal(_to.Value, lineTo->point);
            }
        }
Beispiel #25
0
        public unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete)
        {
            // We're only checking one TextOut record, so this call completes our work.
            complete = true;

            EMRPOINTRECORD *lineTo = record.LineToRecord;

            if (_validate.HasFlag(Flags.From))
            {
                Assert.Equal(_from, state.BrushOrigin);
            }

            if (_validate.HasFlag(Flags.To))
            {
                Assert.Equal(_to, lineTo->point);
            }

            if (_validate.HasFlag(Flags.PenColor))
            {
                Assert.Equal((COLORREF)_penColor, state.SelectedPen.lopnColor);
            }

            if (_validate.HasFlag(Flags.PenWidth))
            {
                Assert.Equal(_penWidth, state.SelectedPen.lopnWidth.X);
            }

            if (_validate.HasFlag(Flags.PenStyle))
            {
                Assert.Equal(_penStyle, state.SelectedPen.lopnStyle);
            }

            if (_validate.HasFlag(Flags.BackgroundMode))
            {
                Assert.Equal(_backgroundMode, state.BackgroundMode);
            }

            if (_validate.HasFlag(Flags.RopMode))
            {
                Assert.Equal(_rop2, state.Rop2Mode);
            }
        }
Beispiel #26
0
        public unsafe void Button_Default_LineDrawing()
        {
            using Button button = new Button();
            using var emf       = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            emf.Validate(
                state,
                Validate.Repeat(Validate.SkipType(Gdi32.EMR.BITBLT), 2),
                Validate.LineTo((bounds.Right - 1, 0), (0, 0), SystemColors.ControlLightLight),
                Validate.LineTo((0, 0), (0, bounds.Bottom - 1), SystemColors.ControlLightLight),
                Validate.LineTo((0, bounds.Bottom - 1), (bounds.Right - 1, bounds.Bottom - 1), SystemColors.ControlDarkDark),
                Validate.LineTo((bounds.Right - 1, bounds.Bottom - 1), (bounds.Right - 1, -1), SystemColors.ControlDarkDark),
                Validate.LineTo((bounds.Right - 2, 1), (1, 1), SystemColors.Control),
                Validate.LineTo((1, 1), (1, bounds.Bottom - 2), SystemColors.Control),
                Validate.LineTo((1, bounds.Bottom - 2), (bounds.Right - 2, bounds.Bottom - 2), SystemColors.ControlDark),
                Validate.LineTo((bounds.Right - 2, bounds.Bottom - 2), (bounds.Right - 2, 0), SystemColors.ControlDark));
        }
        public unsafe void Button_VisualStyles_on_Default_LineDrawing()
        {
            if (!Application.RenderWithVisualStyles)
            {
                return;
            }

            using Button button = new Button();
            using var emf       = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            Rectangle bounds = button.Bounds;

            button.PrintToMetafile(emf);

            /*
             *
             * [ENHMETAHEADER] Bounds: {0, 0, 74, 22 (LTRB)} Device Size: {Width=1024, Height=768} Header Size: 108
             * [EMRINTERSECTCLIPRECT] RECT: {0, 0, 75, 23 (LTRB)}
             * [EMRSETVIEWPORTORGEX] Point: {X=0,Y=0}
             * [EMRCREATEBRUSHINDIRECT] Index: 1 Style: SOLID Color: [R=240, G=240, B=240] (COLOR_MENU, COLOR_BTNFACE, COLOR_MENUBAR)
             * [EMRSELECTOBJECT] Index: 1
             * [EMRBITBLT] Bounds: {0, 0, -1, -1 (LTRB)} Destination: {0, 0, 120, 0 (LTRB)} Rop: PATCOPY Source DC Color: [R=0, G=0, B=0] (COLOR_BACKGROUND, COLOR_MENUTEXT, COLOR_WINDOWTEXT, COLOR_CAPTIONTEXT, COLOR_BTNTEXT, COLOR_INACTIVECAPTIONTEXT, COLOR_INFOTEXT)
             * [EMRSELECTOBJECT] StockObject: WHITE_BRUSH
             * [EMRDELETEOBJECT] Index: 1
             * [EMRCREATEBRUSHINDIRECT] Index: 1 Style: SOLID Color: [R=240, G=240, B=240] (COLOR_MENU, COLOR_BTNFACE, COLOR_MENUBAR)
             * [EMRSELECTOBJECT] Index: 1
             * [EMRBITBLT] Bounds: {0, 0, -1, -1 (LTRB)} Destination: {0, 0, 120, 0 (LTRB)} Rop: PATCOPY Source DC Color: [R=0, G=0, B=0] (COLOR_BACKGROUND, COLOR_MENUTEXT, COLOR_WINDOWTEXT, COLOR_CAPTIONTEXT, COLOR_BTNTEXT, COLOR_INACTIVECAPTIONTEXT, COLOR_INFOTEXT)
             * [EMRSELECTOBJECT] StockObject: WHITE_BRUSH
             * [EMRDELETEOBJECT] Index: 1
             * [EMRSETVIEWPORTORGEX] Point: {X=0,Y=0}
             * [EMREXTSELECTCLIPRGN] Mode: COPY Bounds: {0, 0, 75, 23 (LTRB)} Rects: 1 Rect index 0: {0, 0, 75, 23 (LTRB)}
             * [EMRINTERSECTCLIPRECT] RECT: {0, 0, 75, 23 (LTRB)}
             * [EMRALPHABLEND]
             * [EMREXTSELECTCLIPRGN] Mode: COPY Bounds: {0, 0, 75, 23 (LTRB)} Rects: 1 Rect index 0: {0, 0, 75, 23 (LTRB)}
             * [EMREOF]
             *
             */
        }
        public void StatusStrip_RendersBorderCorrectly()
        {
            using Form form = new Form();
            using StatusStrip statusStrip = new StatusStrip
                  {
                      BackColor  = Color.Blue,
                      SizingGrip = false,
                      Renderer   = new ToolStripProfessionalRenderer(new CustomColorTable()),
                      Size       = new Size(200, 38)
                  };
            form.Controls.Add(statusStrip);

            // Force the handle creation
            Assert.NotEqual(IntPtr.Zero, form.Handle);
            Assert.NotEqual(IntPtr.Zero, statusStrip.Handle);

            // Create an Enhance Metafile into which we will render the control
            using var emf = new EmfScope();
            DeviceContextState state = new DeviceContextState(emf);

            // Render the control
            statusStrip.PrintToMetafile(emf);

            Rectangle bounds         = statusStrip.Bounds;
            Rectangle bitBltBounds   = new Rectangle(bounds.X, 0, bounds.Width - 1, bounds.Height - 1);
            Rectangle polylineBounds = new Rectangle(bounds.X, 0, bounds.Width - 1, 15);

            // This is the default pen style GDI+ renders polylines with
            Gdi32.PS penStyle = Gdi32.PS.SOLID | Gdi32.PS.JOIN_ROUND | Gdi32.PS.COSMETIC | Gdi32.PS.ENDCAP_FLAT | Gdi32.PS.JOIN_MITER | Gdi32.PS.GEOMETRIC;

            emf.Validate(
                state,
                Validate.BitBltValidator(bitBltBounds, State.BrushColor(Color.Blue)),
                Validate.Polyline16(polylineBounds, null, State.Pen(16, Color.Green, penStyle))
                );

            var details = emf.RecordsToString();
        }
 public void Validate(DeviceContextState state)
 {
     Assert.Equal((COLORREF)_brushColor, state.SelectedBrush.lbColor);
     Assert.Equal(_brushStyle, state.SelectedBrush.lbStyle);
 }
Beispiel #30
0
 public string ToString(DeviceContextState state)
 {
     Point[] transformedPoints = points.Transform(point => state.TransformPoint(point));
     return($"[EMR{emr.iType}] Bounds: {rclBounds} Points: {string.Join(' ', transformedPoints)}");
 }