Свойство DrawString в прямоугольнике с несколькими шрифтами c # - PullRequest
2 голосов
/ 06 июля 2011

Я использую C # WinForms и GDI +, чтобы сделать что-то, я надеюсь, это не будет большой проблемой, но ...

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

Используемый алгоритм выглядит следующим образом: -

Разделить строкив коллекцию выделения, а не выделения.

Do

  If Highlightedtext Then

    DrawString(HighLightedText);
    Move X position forward to next character space

  Else

    DrawString(NormalText);
    Move X position forward to next character space

  End If

Loop

Я бы вставил код, но он грязный и длинный (я его поддерживаю).Он выведет find, является ли текст одной строкой с подсветкой или нет, так как он обернет его в пределах прямоугольника без проблем, если он слишком длинный.Если это многократное выделение, а строка больше прямоугольника, она будет писать за ее пределами ... это потому, что "переместить позицию X вперед ..." просто перемещает прямоугольник, в котором возникает проблема!

Я хочу по существу переместить точку, в которой текст печатается внутри исходного прямоугольника, и напечатать ее на следующей строке, если требуется перенос.Кто-нибудь может помочь с этим?Это настоящая боль!

1 Ответ

1 голос
/ 11 июля 2011

Мне удалось отсортировать это, заставив мою функцию выполнять по одному символу за раз.

Для этого я сделал функцию для получения массива (который является длиной самой строки) логических значений, которые установили для любых выделенных символов значение true.

private bool[] Get_CharacterArray(string text)
    {
        // Declare the length of the array, all set to false
        bool[] characters = new bool[text.Length];

        // Get the matching points
        List<Point> wordLocs = FindMatchingTerms(text);
        wordLocs.Sort(PointComparison);

        int position = 0;
        foreach (Point loc in wordLocs)
        {
            // We're only setting the array for matched points
            for (position = loc.X; position <= loc.Y; position++)
            {
                characters[position] = true;
            }
        }

        // Return the array
        return characters;
    }

(FindMatchingTerms () - это функция, которая будет искать в строке и возвращать совпадения, найденные в коллекции).

Затем я зацикливаю этот массив, чтобы вывести его на экран, но отслеживая ширину моей прямоугольной границы.Когда он уменьшается до соответствующего размера, я сбрасываю позицию рисования обратно в начало, а затем немного сдвигаю начальную позицию Y.

private void RenderFormattedText(Graphics g, RectangleF bounds, string text, string matchText, Font font, Color colour, bool alignTextToTop)
            {
                const string spaceCharacter = " ";
                const string hyphenCharacter = "-";
                Font fr = null;
                Font fi = null;
                try
                {
                    // Get teh matching characters.
                    bool[] charactersMatched = Get_CharacterArray(text);

                    // Setup the fonts and bounds.
                    fr = new Font(font.FontFamily, font.Size, FontStyle.Regular);
                    fi = new Font(font.FontFamily, font.Size, FontStyle.Bold | FontStyle.Underline);
                    SizeF fontSize = g.MeasureString(text, fi, 0, StringFormat.GenericTypographic);
                    RectangleF area = bounds;

                    // Loop all the characters of the phrase
                    for (int pos = 0; pos < charactersMatched.Length; pos++)
                    {
                        // Draw the character in the appropriate style.
                        string output = text.Substring(pos, 1);
                        if (charactersMatched[pos])
                        {
                            area.X += DrawFormattedText(g, area, output, fi, colour);
                        }
                        else
                        {
                            area.X += DrawFormattedText(g, area, output, fr, colour);
                        }

                        // Are we towards the end of the line?
                        if (area.X > (bounds.X + bounds.Width - 1))
                        {
                            // are we in the middle of a word?
                            string preOutput = spaceCharacter;
                            string postOutput = spaceCharacter;

                            // Get at the previous character and after character
                            preOutput = text.Substring(pos - 1, 1);
                            if ((pos + 1) <= text.Length)
                            {
                                postOutput = text.Substring(pos + 1, 1);
                            }

                            // Are we in the middle of a word? if so, hyphen it!
                            if (!preOutput.Equals(spaceCharacter) && !postOutput.Equals(spaceCharacter))
                            {
                                if (charactersMatched[pos])
                                {
                                    area.X += DrawFormattedText(g, area, hyphenCharacter, fi, colour);
                                }
                                else
                                {
                                    area.X += DrawFormattedText(g, area, hyphenCharacter, fr, colour);
                                }
                            }
                        }

                        // Are we at the end of the line?
                        if (area.X > (bounds.X + bounds.Width))
                        {
                            area.X = bounds.X;
                            area.Y += fontSize.Height + 2;
                        }
                    }
                }
                finally
                {
                    fr.Dispose();
                    fi.Dispose();
                }
            }

Надеюсь, кто-то найдет это полезным :)там есть некоторые константы для spaceCharacter и hypenCharacter, которые должны быть понятны!Существуют пользовательские функции для рисования строки, но, тем не менее, это должно иметь смысл, надеюсь, это поможет кому-то еще.

...