internal unsafe static void DrawLine(this Gdi32.HDC hdc, Gdi32.HPEN pen, int x1, int y1, int x2, int y2)
        {
            using var ropScope  = new Gdi32.SetRop2Scope(hdc, Gdi32.R2.COPYPEN);
            using var bkScope   = new Gdi32.SetBkModeScope(hdc, Gdi32.BKMODE.TRANSPARENT);
            using var selection = new Gdi32.SelectObjectScope(hdc, pen);

            Point oldPoint = new Point();

            Gdi32.MoveToEx(hdc, x1, y1, &oldPoint);
            Gdi32.LineTo(hdc, x2, y2);
            Gdi32.MoveToEx(hdc, oldPoint.X, oldPoint.Y, &oldPoint);
        }
Example #2
0
        /// <summary>
        ///  Draws the text in the given bounds, using the given Font, foreColor and backColor, and according to the specified
        ///  TextFormatFlags flags.
        ///
        ///  If font is null, the font currently selected in the hdc is used.
        ///
        ///  If foreColor and/or backColor are Color.Empty, the hdc current text and/or background color are used.
        /// </summary>
        public static void DrawText(
            this Gdi32.HDC hdc,
            ReadOnlySpan <char> text,
            FontCache.Scope font,
            Rectangle bounds,
            Color foreColor,
            User32.DT flags,
            Color backColor            = default,
            TextPaddingOptions padding = default)
        {
            if (text.IsEmpty || foreColor == Color.Transparent)
            {
                return;
            }

            ValidateFlags(flags);

            // DrawText requires default text alignment.
            using var alignment = new Gdi32.SetTextAlignmentScope(hdc, default);

            // Color empty means use the one currently selected in the dc.
            using var textColor = foreColor.IsEmpty ? default : new Gdi32.SetTextColorScope(hdc, foreColor);
                                  using var fontSelection = new Gdi32.SelectObjectScope(hdc, (Gdi32.HFONT)font);

                                  Gdi32.BKMODE newBackGroundMode = (backColor.IsEmpty || backColor == Color.Transparent) ?
                                                                   Gdi32.BKMODE.TRANSPARENT :
                                                                   Gdi32.BKMODE.OPAQUE;

                                  using var backgroundMode  = new Gdi32.SetBkModeScope(hdc, newBackGroundMode);
                                  using var backgroundColor = newBackGroundMode != Gdi32.BKMODE.TRANSPARENT
                ? new Gdi32.SetBackgroundColorScope(hdc, backColor)
                : default;

                                  User32.DRAWTEXTPARAMS dtparams = GetTextMargins(font, padding);

                                  bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, ref dtparams);

                                  // Adjust unbounded rect to avoid overflow since Rectangle ctr does not do param validation.
                                  if (bounds.Width == TextRenderer.MaxSize.Width)
                                  {
                                      bounds.Width -= bounds.X;
                                  }

                                  if (bounds.Height == TextRenderer.MaxSize.Height)
                                  {
                                      bounds.Height -= bounds.Y;
                                  }

                                  RECT rect = bounds;

                                  User32.DrawTextExW(hdc, text, ref rect, flags, ref dtparams);
        }
        /// <summary>
        ///  Draws lines with the <paramref name="hpen"/> using points defined in <paramref name="lines"/>.
        /// </summary>
        /// <param name="lines">
        ///  MUST be a mulitple of 4. Each group of 4 represents x1, y1, x2, y2.
        /// </param>
        internal unsafe static void DrawLines(this Gdi32.HDC hdc, Gdi32.HPEN hpen, ReadOnlySpan <int> lines)
        {
            Debug.Assert((lines.Length % 4) == 0);

            using var ropScope  = new Gdi32.SetRop2Scope(hdc, Gdi32.R2.COPYPEN);
            using var bkScope   = new Gdi32.SetBkModeScope(hdc, Gdi32.BKMODE.TRANSPARENT);
            using var selection = new Gdi32.SelectObjectScope(hdc, hpen);

            Point oldPoint = new Point();

            for (int i = 0; i < lines.Length; i += 4)
            {
                Gdi32.MoveToEx(hdc, lines[i], lines[i + 1], &oldPoint);
                Gdi32.LineTo(hdc, lines[i + 2], lines[i + 3]);
                Gdi32.MoveToEx(hdc, oldPoint.X, oldPoint.Y, null);
            }
        }