WPF: разрешение DrawingContext - PullRequest
       21

WPF: разрешение DrawingContext

1 голос
/ 15 января 2020

Я использую класс DrawingContext для рисования гистограммы, но метки и метки получаются размытыми:

enter image description here

В коде Я использую класс BarRenderer, полученный из FrameworkElement. Каждый столбец представлен экземпляром BarRenderer, и я рисую, переопределяя метод OnRender. У каждого "бара" есть label и value, где label - текст ниже, а value определяет высоту бара. Логика c, отвечающая за рисование меток и меток, выглядит следующим образом:

private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
{
    drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));

    y += 6;
    if (LabelRotationDegree != 0)
    {
        RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
        TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);

        drawingContext.PushTransform(translateTransform);
        drawingContext.PushTransform(rotateTransform);
    }

    drawingContext.DrawText(text, new Point(x, y));

    if (LabelRotationDegree != 0)
    {
        drawingContext.Pop();
        drawingContext.Pop();
    }
}

Я сомневаюсь, что проблема связана с преобразованием вращения, поскольку, когда метки не преобразованы, они больше не размыты как до:

enter image description here

Но, как видно, некоторые клещи темнее других. Так что я делаю не так?

РЕДАКТИРОВАТЬ:

Я уже установил SnapsToDevicePixels на true, и когда я установил RenderOptions.SetEdgeMode на Aliased, некоторые галочки исчезают и текст все еще размыто:

enter image description here

Редактировать 2: Дополнительный код

public class GraphUnitRenderer : FrameworkElement
{
    private const double TEXT_SIZE = 12;
    private const double KEY_LABELS_HEIGHT = 50;

    private readonly Typeface _typeface;
    private readonly CultureInfo _cultureInfo;
    private readonly Pen _blackPen;
    private readonly Pen _bluePen;
    private readonly Pen _tickBlackPen;
    private readonly Pen _whitePen;



    public BarData Data { get; set; }

    //Some properties

    public GraphUnitRenderer()
    {
        _typeface = new Typeface("Segoe UI");
        _cultureInfo = CultureInfo.CurrentCulture;

        _blackPen = new Pen(Brushes.Black, 1);
        _bluePen = new Pen(Brushes.Blue, 1);
        _tickBlackPen = new Pen(Brushes.Black, 2);
        _whitePen = new Pen(Brushes.White, 1);

        /*
        _blackPen.Freeze();
        _bluePen.Freeze();
        _tickBlackPen.Freeze();
        _whitePen.Freeze();
        */

        RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
        SnapsToDevicePixels = true;

    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);


        FormattedText keyText = GetText(Data.Key);

        //Bar drawing logic 

        if (LabelDisplayIsForced || (LabelRotationDegree == 0 && keyText.WidthIncludingTrailingWhitespace < Width) || (LabelRotationDegree != 0 && keyText.Height < Width))
            DrawLabel(drawingContext, keyText, 0.5 * (Width - keyText.WidthIncludingTrailingWhitespace), GetYPosition(1) + 1, 1);

    }


    private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
    {
        drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));

        y += 6;
        if (LabelRotationDegree != 0)
        {
            RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
            TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);

            drawingContext.PushTransform(translateTransform);
            drawingContext.PushTransform(rotateTransform);
        }

        drawingContext.DrawText(text, new Point(x, y));

        if (LabelRotationDegree != 0)
        {
            drawingContext.Pop();
            drawingContext.Pop();
        }
    }


    private double GetYPosition(double position) => Height - position - KEY_LABELS_HEIGHT;
    private FormattedText GetText(string text) => new FormattedText(text, _cultureInfo, FlowDirection.LeftToRight, _typeface, TEXT_SIZE, Brushes.Black, VisualTreeHelper.GetDpi(this).PixelsPerDip);
}
...