Как заполнить текст двумя разными цветами/текстурами

Я рисую текст поверх изображения с помощью Path.Addstring и заливаю его цветом, и он отлично работает. Теперь я хотел бы разделить (разделить) текст по вертикали и иметь 2 разных цвета или текстуры. Например. верхнюю половину текста сплошной кистью, а нижнюю половину штриховой кистью. Я хотел бы знать, возможно ли это и каким образом я должен это реализовать.

Эталонное изображение, созданное с помощью программы Paint.net. Я нарисовал линию, чтобы разделить текст, и заполнил нижнюю часть другой текстурой.

Как заполнить текст двумя разными цветами/текстурами

* Я не хочу, чтобы линия была видна в конечном выводе.

🤔 А знаете ли вы, что...
C# обеспечивает возможность создания многопоточных приложений с помощью пространства имен System.Threading.


1
37
1

Ответ:

Решено

Возможно.

  1. Заполните контур сплошной кистью.
  2. Получите прямоугольник, ограничивающий путь, с помощью метода GraphicsPath.GetBounds.
  3. Вызовите метод Graphics.SetClip, чтобы исключить верхнюю половину прямоугольника.
  4. Заполните путь знаком TextureBrush или HatchBrush.

Пример, в котором используется ЛюкКисть для заполнения второй половины пути по вертикали.

private void SomeControl_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    var r = (sender as Control).ClientRectangle;
            
    using (var gp = new GraphicsPath())
    using (var sf = new StringFormat())
    using (var fnt = new Font("Blackoak Std", 72))
    using (var hbr = new HatchBrush(HatchStyle.Percent25, Color.White, Color.Red))
    {
        sf.Alignment = sf.LineAlignment = StringAlignment.Center;

        gp.AddString("RED", fnt.FontFamily, (int)fnt.Style, GetEmFontSize(fnt), r, sf);

        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.FillPath(Brushes.Red, gp);

        var rf = gp.GetBounds();
        rf.Height /= 2f;

        g.SetClip(rf, CombineMode.Exclude);
        g.FillPath(hbr, gp);
        g.ResetClip();
        g.SmoothingMode = SmoothingMode.None;
    }
}

private float GetEmFontSize(Font fnt) =>
    fnt.SizeInPoints * (fnt.FontFamily.GetCellAscent(fnt.Style) + 
    fnt.FontFamily.GetCellDescent(fnt.Style)) / fnt.FontFamily.GetEmHeight(fnt.Style);

См. также другие значения Стиль люка.

SOQ72225088A

SOQ72225088B