перенос строк
От: Denis_Orlov  
Дата: 06.06.05 21:39
Оценка:
Помогите пожалуйста с алгоритмом....
Надо следующее...

Есть строка, вывожу в определённую область экрана телефона, ширину области знаю.
Надо отслеживать переход на следующую строчку, чтобы не было выступов текста за область.
Строки доложны переноситься корректно... Ну т.е. минимум пустых мест, перенос можно осуществлять только по словам, внутри слов перенос можно не организовывать ....
Re: перенос строк
От: Михаил  
Дата: 07.06.05 03:34
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Помогите пожалуйста с алгоритмом....

D_O>Надо следующее...

D_O>Есть строка, вывожу в определённую область экрана телефона, ширину области знаю.

D_O>Надо отслеживать переход на следующую строчку, чтобы не было выступов текста за область.
D_O>Строки доложны переноситься корректно... Ну т.е. минимум пустых мест, перенос можно осуществлять только по словам, внутри слов перенос можно не организовывать ....

А платформа какая? Неужто edit-контрола нету?
...А отсюда наливаем, когда рецепт написан совсем неразборчиво...
Re[2]: перенос строк
От: ansi  
Дата: 07.06.05 03:55
Оценка:
Здравствуйте, Михаил, Вы писали:

М>А платформа какая? Неужто edit-контрола нету?


Дык наверное он самый и пишется

Самое простое, что приходит в голову:
Препроцессинг:
0) (Опционально) Нормализовать пробелы (т.е. несколько пробелов заменить одним).
1) Определить среднюю среднюю ширину буквы (это для каждого шрифта отдельно, но ведь там-то набор фиксирован, хотя можно и непосредственно).

Алгоритм:

1) К текущей позиции в строке прибавляешь screen_width/char_width (только за границу не выйди ).

2) Если данная строка помещается на экран, то делаешь поиск вперед до первого разрывного символа. Если опять влезла, пробуешь еще дальше и т.д.

3) Если не влезла, то делаешь поиск назад (с изначальной позиции) до первого разрывного символа.

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

Например:
 ____________
|Is          |
|superlongstr|
|ing cool.   |
 ------------

Лучше заменить на
 ____________
|Is superlong|
|string cool |
 ------------



4) Если и так не влезла, то придется ломать слово — делаешь поиск уже по символам из начальной позиции (сторону поиска определить не проблема).

Как-то так... А вообще, попробуй искать по словам Word-wrap.
Re[3]: перенос строк
От: Михаил  
Дата: 07.06.05 05:38
Оценка:
Здравствуйте, ansi, Вы писали:

A>Здравствуйте, Михаил, Вы писали:


М>>А платформа какая? Неужто edit-контрола нету?


A>Дык наверное он самый и пишется


Постой, паровоз
Как нету — это уже безобразие, что за платформа ??
Еще может быть что-то вроде DrawText() из WinAPI.

A>Самое простое, что приходит в голову:

A>Препроцессинг:
A>0) (Опционально) Нормализовать пробелы (т.е. несколько пробелов заменить одним).
Вот именно — опционально. По крайней мере — стоит срезать только в началах(концах) строк.

A>1) Определить среднюю среднюю ширину буквы (это для каждого шрифта отдельно, но ведь там-то набор фиксирован, хотя можно и непосредственно).

Не. Надо массив из ширин букв. Если не моноширинный шрифт. Сравни: WWWWWW vs iiiiiiii.
...А отсюда наливаем, когда рецепт написан совсем неразборчиво...
Re[3]: перенос строк
От: kfmn Россия  
Дата: 07.06.05 06:17
Оценка:
Здравствуйте, ansi, Вы писали:


A>2) Если данная строка помещается на экран, то делаешь поиск вперед до первого разрывного символа. Если опять влезла, пробуешь еще дальше и т.д.


В свое время пришлось делать что-то подобное, так оказалось, что намного быстрее получается работать половинным делением а не прибавлять по одному символу. Т.е. сперва быстро найти символ, который попадает на конец строки, а потом от него пройти назад до пробела.
Re[4]: перенос строк
От: ansi  
Дата: 07.06.05 07:58
Оценка:
Здравствуйте, Михаил, Вы писали:

A>>Дык наверное он самый и пишется


М>Постой, паровоз

М>Как нету — это уже безобразие, что за платформа ??
М>Еще может быть что-то вроде DrawText() из WinAPI.

DrawText тоже ведь кто-то писал...

М>Вот именно — опционально. По крайней мере — стоит срезать только в началах(концах) строк.

Зависит от того, что требуется в результате.

A>>1) Определить среднюю среднюю ширину буквы (это для каждого шрифта отдельно, но ведь там-то набор фиксирован, хотя можно и непосредственно).

М>Не. Надо массив из ширин букв. Если не моноширинный шрифт. Сравни: WWWWWW vs iiiiiiii.
Дык это понятно. Это лишь как первое приближение. К тому же в подавляющем большинстве случаев оно будет весьма неплохим, а твои примеры — это лишь частные случаи.
Re[4]: перенос строк
От: Denis_Orlov  
Дата: 07.06.05 08:00
Оценка:
Только до работы добрался...

Платформа J2me (java для трубок)
Надо попробывать с шириной букв... проблема только в другом — деление там без плавующей точки... поэтому, деление целочисленное...

В строке нет лишних пробелов, т.к. она формируется нами же....
Re[4]: перенос строк
От: ansi  
Дата: 07.06.05 08:00
Оценка:
Здравствуйте, kfmn, Вы писали:

K>Здравствуйте, ansi, Вы писали:



A>>2) Если данная строка помещается на экран, то делаешь поиск вперед до первого разрывного символа. Если опять влезла, пробуешь еще дальше и т.д.


K>В свое время пришлось делать что-то подобное, так оказалось, что намного быстрее получается работать половинным делением а не прибавлять по одному символу. Т.е. сперва быстро найти символ, который попадает на конец строки, а потом от него пройти назад до пробела.

Что-то я не понял тебя... Ты имеешь в виду двоичный поиск?
Re: перенос строк
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 07.06.05 09:01
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Есть строка, вывожу в определённую область экрана телефона, ширину области знаю.


В данном случае, имхо, подойдет простейший алгоритм --- как только строка переполнилась, слово на котором она переполнилась помещается в следующую строчку. Если надо более серьезное --- поищи статью Д. Кнута об алгоритме переносов, используемых в TeX. Там задача выбора разрывов строк сводится к задаче динамического программирования и решается методом ветвей и границ
... << RSDN@Home 1.1.3 stable >>
Re[2]: перенос строк
От: raskin Россия  
Дата: 09.06.05 17:59
Оценка:
Mystic wrote:
> Здравствуйте, Denis_Orlov, Вы писали:
>
> D_O>Есть строка, вывожу в определённую область экрана телефона, ширину области знаю.
>
> В данном случае, имхо, подойдет простейший алгоритм --- как только строка переполнилась, слово на котором она переполнилась помещается в следующую строчку. Если надо более серьезное --- поищи статью Д. Кнута об алгоритме переносов, используемых в TeX. Там задача выбора разрывов строк сводится к задаче динамического программирования и решается методом ветвей и границ
Добрые вы все... Там же ещё отдельное развлечение думать, что лучше:
удлинить пробел(!) или перенести слово. Ни того ни другого здесь,
похоже, делать не хочется.
Posted via RSDN NNTP Server 1.9
Re[3]: перенос строк
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 10.06.05 09:14
Оценка:
Здравствуйте, raskin, Вы писали:

R>Добрые вы все... Там же ещё отдельное развлечение думать, что лучше:

R>удлинить пробел(!) или перенести слово.

Мы такие Там еще учитывается средняя величина пробела между словами в двух соседних строчках. И много чего еще... (штрафы за переносы, премии перед знаками препинания, ...)

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


Уже лучше
Это строка  из очень  малых слов  с малыми пробелами  вот 
так   за   этойстрокой   следуетбольшая   строкаизбольших 
словзакоторойидет неважно что.


Совсем хорошо
Это  строка  из  очень  малых  слов  с  малыми  пробелами  
вот  так  за этойстрокой  следуетбольшая  строкаизбольших 
словзакоторойидет неважно что.
... << RSDN@Home 1.1.3 stable >>
Re[5]: Вы меня, конечно, извините но...
От: Аноним  
Дата: 11.06.05 21:56
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Надо попробывать с шириной букв... проблема только в другом — деление там без плавующей точки... поэтому, деление целочисленное...

Проблемму с цельночисленным делением, я решаю, ведя вычисления, сдвинув на n разрядов (умножив на 2^n) влево исходные данные, а после этого сдвигаю результат обратно. Сам-то я про трубковые языки ничего не знаю, но по своей работе мне часто приходится делать такой финт, для оптимизации (float'ы, чертовски, долго работают).

Надеюсь помог.

PS: если идея пригодится, расскажу, на всякий случай, о маленьких граблях, на примере: Если C = A * B, то сдвинув входные данные на один разряд a = A * 2, b = B * 2, получитм c = a * b = A / 2 * B / 2 = A * B / (2 * 2), т.е. C = c / 4!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.