System.Drawing.Font - изменить интервал между буквами? - PullRequest
3 голосов
/ 20 октября 2011

Используя System.Drawing.Font, есть ли способ изменить интервал букв, как вы можете изменить размер шрифта?

Я хочу увеличить интервал между буквами, чтобы он соответствовал определенной ширине.

Если это невозможно, есть ли альтернативы для получения желаемого эффекта? Например, есть ли простой способ иметь несколько графических изображений, которые будут соответствовать моей конкретной ширине?

Ответы [ 2 ]

4 голосов
/ 20 октября 2011

Я не думаю, что DrawString позволит вам указать что-либо столь же подробное, как интервал между символами, но я бы создал вспомогательную функцию, которая вычисляет интервал на основе желаемой ширины, а затем нарисует каждый символ, чтобы он соответствовал.

Попробуйте и посмотрите, как вы попадаете ...

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        foreach (char c in text)
        {
            widthNeeded += g.MeasureString(c.ToString(), font).Width;
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += g.MeasureString(c.ToString(), font).Width + spacing;
        }
    }

Возможно, вы могли бы оптимизировать это, чтобы сделать только один вызов MeasureString на символ.Или даже используйте MeasureCharacterRanges, чтобы получить массив (который я считаю более точным в любом случае)

Редактировать : здесь приведен пример использования MeasureCharacterRanges ...

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        Region[] regions = g.MeasureCharacterRanges(text, font, new RectangleF(point, new SizeF(desiredWidth, font.Height + 10)), StringFormat.GenericDefault);
        float[] widths = new float[regions.Length];
        for(int i = 0; i < widths.Length; i++)
        {
            widths[i] = regions[i].GetBounds(g).Width;
            widthNeeded += widths[i];
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        int index = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += widths[index] + spacing;
            index++;
        }
    }
0 голосов
/ 25 января 2017

Этот код поддерживает новую строку в тексте и возвращает объект Image.

public static Image ConvertTextToImage(String text, Font font, Color textColor, int spacing = 0)
{
    var textParts = SplitOnBreakLines(text);
    // dummy image, just create drawing
    var img = new Bitmap(1, 1);
    var drawing = Graphics.FromImage(img);
    // calculate width, height
    var width = 0.0F;
    foreach (char c in text)
    {
        width += drawing.MeasureString(c.ToString(), font).Width;
    }           
    width = (width + spacing * (ClearBreakLines(text).Length - 1))  / textParts.Length;
    if (width <= 0)
        width = 1;
    var height = font.Height * textParts.Length;
    // clear and create new objects
    img.Dispose();
    drawing.Dispose();

    img = new Bitmap((int)width, (int)height);
    drawing = Graphics.FromImage(img);

    //Adjust for high quality
    drawing.CompositingQuality = CompositingQuality.HighQuality;
    drawing.InterpolationMode = InterpolationMode.HighQualityBilinear;
    drawing.PixelOffsetMode = PixelOffsetMode.HighQuality;
    drawing.SmoothingMode = SmoothingMode.HighQuality;
    drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

    //paint the background
    drawing.Clear(Color.Transparent);

    //create a brush for the text
    var textBrush = new SolidBrush(textColor);
    //write text
    var indent = 0.0F;
    var point = new Point();            
    foreach (var textPart in textParts)
    {
        foreach (char c in textPart)
        {
            drawing.DrawString(c.ToString(), font, textBrush, new PointF(point.X + indent, point.Y));
            indent += drawing.MeasureString(c.ToString(), font).Width + spacing;
        }
        indent = 0.0F;
        point.Y += font.Height;
    }
    drawing.Save();
    textBrush.Dispose();
    drawing.Dispose();
    return img;           
}

public static string ClearBreakLines(string s)
{
    return Regex.Replace(s, @"\r\n?|\n", string.Empty);
}

public static string[] SplitOnBreakLines(string s)
{
    return Regex.Split(s, @"\r\n?|\n");           
}
...