LifeAct
@LifeAct
Создаем и раскручиваем, не ставим на конвейер

Как реализовать алгоритм word wrap?

Всем привет!

Есть задача написать на картинке заголовок, сейчас реализовал вот так:

9E2pkb4CoqoamY.png

код:
...
 // ТЕКСТ  заголовок         
                            ImageResizer.Plugins.Watermark.ImageLayer y = new ImageResizer.Plugins.Watermark.ImageLayer(c); //ImageLayer needs a Config instance so it knows where to locate images       
                            string title = BL.Title;

                            t.Text = TextWrap(title, 38);
                            t.Fill = false;
                            t.Align = System.Drawing.ContentAlignment.MiddleCenter;

                            wp.NamedWatermarks["img"] = new ImageResizer.Plugins.Watermark.Layer[] { y };
                            wp.NamedWatermarks["text"] = new ImageResizer.Plugins.Watermark.Layer[] { t };
...

 public string TextWrap(string myString, int n)
        {
            // int n - количество cимволов для строки (ширина картинки)

            int length = myString.Length;


            char[] arrayOfSimbols = myString.ToCharArray();
            myString = "";
            for (int i = 0; i < length / n; i++)
            {
                foreach (char z in arrayOfSimbols.Skip(i * n).Take(n).ToArray())
                    myString += z;
                myString += Environment.NewLine;
            }

            //остаток прибавим в конец
            foreach (char x in arrayOfSimbols.Skip(arrayOfSimbols.Count() - arrayOfSimbols.Count() % n).ToArray())
                myString += x;

            return myString;

        }


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

Может у кого опыт в этом есть, буду благодарен за подсказку.

UPD:
спасибо, получилось проще чем думал

public string TextWrap(string myString, int LengthRow)
        {
             
            int  CurrentLengthRow = 0;
            string ReadyRezult = "";
            string [] TextArr  = myString.Split(' ');

            foreach (string Word in TextArr)
            {
                if( (CurrentLengthRow) + (Word.Length) < LengthRow)
                {
                    ReadyRezult += Word + " ";
                    CurrentLengthRow += (Word.Length) + 1;
                }

                else
                {
                    ReadyRezult += Environment.NewLine;
                    CurrentLengthRow = 0;
                }

            }
                       

            return ReadyRezult;

        }
  • Вопрос задан
  • 475 просмотров
Решения вопроса 2
xpert13
@xpert13
Full Stack Developer
Я бы сделал следующим образом:
1. Определил оптимальную длину строки в символах
2. Резал бы по словам так, чтобы оставшиеся в строке слова суммарно не превышали максимальную длину строки
3. Выравнивал бы строки равномерным добавлением пробелов между словами в строке

Визуально это будет смотреться как выравнивание по ширине в ворде.

После разбивки по словами будет так:
Политолог Бортник: скоро власть 
придумает новых реформаторов, чтобы
...

После добавления пробелов так:
Политолог   Бортник:  скоро  власть 
придумает новых реформаторов, чтобы
...
Ответ написан
@Sing303
Используйте StringBuilder вместо ReadyRezult += Word + " "
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
AxisPod
@AxisPod
Вот не знаю как в .NET, но помнится в WinAPI есть механизм определения размера в пикселах для блока текста. В итоге берем размер пробела, берем размер каждого слова и вычисляем. И в данном случае будет правильно работать с символами разной ширины. А посимвольно только для моноширинных шрифтов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы