3

I am trying to achieve highlighting a wrapped text in the given bounds. I can achieve the expected behavior. If the search text is in single line and i am facing issue if the search text is rendered in two lines (wrapped) like below,

Empty area also highlighted along with search text

I have used character range and MeasureCharacterRanges method to find the regions of the text area and exlcuded the text regions that doesn't match the given search text, but i couldn't find the region of the empty area that doesn't have text rendered, so empty area also highlighted along with given search text.

StringFormat stringFormat = new StringFormat(StringFormat.GenericDefault);
Font font = new Font("Segoe UI", 9F, FontStyle.Regular);

var searchText = string.IsNullOrEmpty(SearchText) ? string.Empty : SearchText;
int matchIndex = Text.IndexOf(searchText);
if (matchIndex != -1 && searchText.Length > 0)
{
    CharacterRange[] characterRange = new CharacterRange[]
    {
            new CharacterRange(0, matchIndex),
            new CharacterRange(matchIndex, searchText.Length),
            new CharacterRange(matchIndex + searchText.Length , Text.Length - matchIndex - searchText.Length),
    };


    //Set the range of characters to be measured.
    stringFormat.SetMeasurableCharacterRanges(characterRange);

    //Gets the regions of the measurable characters applied to the string format for the given text with in the text bounds.
    Region[] regions = e.Graphics.MeasureCharacterRanges(Text, font, e.ClipRectangle, stringFormat);

    var clipBounds = e.Graphics.ClipBounds;

    for (int i = 0; i < regions.Length; i++)
    {
        RectangleF bound = regions[i].GetBounds(e.Graphics);
        e.Graphics.SetClip(Rectangle.Ceiling(bound));
        for (int j = 0; j < regions.Length; j++)
        {
            if (j != i)
                e.Graphics.ExcludeClip(regions[j]);
        }

        Rectangle rbound = new Rectangle((int)bound.X, (int)bound.Y, (int)bound.Width, (int)bound.Height);
        Brush brush = new SolidBrush(Color.Yellow);
        if (i == 1)
            e.Graphics.FillRectangle(brush, rbound);
     }

    e.Graphics.SetClip(clipBounds);
}


// Paints the text.
e.Graphics.DrawString(Text, font, Brushes.Black, e.ClipRectangle);

Above is the code used to highlight the search text.

I couldn't find a way to exclude the empty region with MeasureCharacterRanges concept. Can anyone share idea to exclude the remaining empty region?

Amal
  • 576
  • 1
  • 6
  • 26
  • `MeasureCharacterRanges` alone won't work. You need to **get** position not just *measure* it. And for that you need to use control API somehow, is it `RichTextBox` or what? See if [this is helpful](https://stackoverflow.com/q/11183599/1997232). – Sinatr Nov 25 '20 at 12:55
  • @Sinatr - This is an custom control. – Amal Nov 25 '20 at 13:02
  • Then you need to prepare [mcve]. How text is rendered? Perhaps you can build-in highlighting function into your text rendering code? – Sinatr Nov 25 '20 at 13:09
  • 1
    Various tests here, including the `MeasureCharacterRanges` method, here: [How to highlight wrapped text in a control using the graphics?](https://stackoverflow.com/a/48257170/7444103) (if you take a look at that code, you'll see that yours is missing one specific part and includes one that doesn't belong) -- A specific implementation here: [How to highlight a word or phrase with a color different from all the other selections in a RichTextBox text?](https://stackoverflow.com/a/62012582/7444103). Another description [here](https://stackoverflow.com/a/61776414/7444103) – Jimi Nov 25 '20 at 13:21

0 Answers0