Здравствуйте, alsemm, Вы писали:
VD>>Чтобы сделать точный скролинг и точное отображение позиции в документе.
A>Вернее чтобы упростить реализацию этих функций
Я в последнее время вообще стараюсь не делать вещи сложенее чем нужно. Но тут это не причем.
При редактировании текстов с большими абзацами (вроде текста этого сообщения) скролинг должен быть не менее удобным чем при редактировании файла с кодом, где стоки почти не переносятся. Отсюда надо заранее рассчитывать переносы строк. Темболее, что это относительно недолго.
VD>>И каждый раз бегать по тексту рассчитывая строку? А смысл? Тормоза от этого конечно увеличатся, а вот бенефиты...
A>Если юзать string[] для хранения текста, то да, смысла нет, не спорю.
Я не понимаю о чем ты говоришь. Что еще можно "юзать"? Массивы символов? Ну, и какая разница?
Объясни мне доходчиво.
A>Загрузили в редактор большой текст и стали его с головы редактировать.
И? Размер файла будет влиять только на время загрузки, ну, и на время изменения размера окна если включен перенос по его границе. А на редактирование это никак не скажется. Стой ты хоть в начале текста, хоть в конце.
A> Ограничения стурктуры данных (в данном случае string[]) не будут видны пока мощности железа хватает, но рано или поздно они вылезут. Вообще IMHO использование Position<Document> для адресации сомволов очень напоминает старничную память с кошмариками в виде long и short pointer-ов.
Ограничения string[]? Ты о чем? В редакторе вообще нет никаких string[]. Строки хранятся в специальном классе храняещем по одному string-гу на строку редактируемого файла.
A>...
VD>>1. Так плохой идеей было использовать дотнетный Font. Это не позволяет менять в стилях отдельные атрибуты шрифта. Например, чтобы сделать жирным ключевые слова. Это же не дает реализовать простое масштабирование шрифтов. Мне очень нравится как в Сцинтиле или ИЕ можно менять размер ширфтов просто покрутив колесико мыши удерживая при этом Ctrl.
A>Думаю это не проблема шрифта, а не совсем удачный дизайн класса Style. Если пользователи захотят что-то большее кроме как рисовать вместо текста картинки? Например обводить подстроку в рамку. Что делать будете? Добавлять поле _drawRectAroundText в Style?
А какие проблемы? Стиль == класс. Создавай наследника и храни хоть черта лысого. Другое дело, что прийдется отрисовку менять. Над расширением процесса отрисовки я даже не думал, так как не нужно. Проект с открытым кодом. Всякие плагины для него не особо то актуальный. Хотя если понадобится, то прикрутить будет не долго.
Тут же речь не о том. Речь о банальном удобстве. Человек решивший создать подсветку для некоторого формата не должен трахаться создвая стили для всех пересечений, или как ты предлагашь писать какой-то код вместо того, чтобы декларативно задать нужные ему свойства.
A>IMHO коряво.
Каждый имеет право на лево. Я считаю корявы знаниматься программированием там где можно без него обойтись.
A>class IDecoratorListener
A>{
A>public:
A> virtual ~IDecoratorListener() {}
A>public:
A> virtual bool
A> onSubstringDecorated(
A> unsigned line,
A> const char_type* str,
A> unsigned strLen,
A> const char_type* substr,
A> unsigned substrLen,
A> const TextStyle& ts) = 0;
A> virtual bool
A> onSubstringDecorated(
A> unsigned line,
A> const char_type* str,
A> unsigned strLen,
A> const char_type* substr,
A> unsigned substrLen,
A> const IDecoratedSubstring& ds) = 0;
A>};
И как это поможет тебе с рисованием той же рамки?
A>Вот, например, как можно сделать изменение размера шрифта "как в Сцинтиле или ИЕ":
A>A>...
A> virtual bool
A> onSubstringDecorated(
A> unsigned line,
A> const char_type* str,
A> unsigned strLen,
A> const char_type* substr,
A> unsigned substrLen,
A> const TextStyle& ts)
A> {
A> HDC dc = getTempDC(); // каким-то образом получить HDC
A> ::SelectFont(dc, ts.font);
A> TEXTMETRICS tm;
A> ::GetTextMetrics(dc, &tm);
A> LOGFONT lf = textMetrics2LogFont(tm); // как-то сконвертировали
A> lf.height += (lf.height * 10) / 100; // увеличить шрифт на 10%
A> TextStyle newTs(ts);
A> newTs.font = ::CreateFontIndirect(lf);
A> // передать в листенер измененный шрифт
A> listener_.onSubstringDecorated(line, str, strLen, substr, substrLen, newTs);
A> }
A>};
A>
Да уж... Прямо как в ИЕ или Сцинтиле... почти! Так как динамическое пересоздание шрифта на каждый токен — это задница для производительности. На относительно старом железе это будет тормозить как АБС.
К тому же изменение размеров шрифта должно быть незаметно для пользователя контрола. Да, и вобще, прямая возня с GDI — это само по себе фигня какая-то. Даже Сцинтила от нее абстрагироуется. Хотя это конечно к делу не относится.
A>Редактор дергает IDecorator::decorate каждый раз когда надо отрисовать строку текста передавая свои реализации интерфейса IDecoratorListener. Есть реализации IDecoratorListener-а которые высчитывают ширину подстроки/целой строки, высоту ну и т.д. Word wrap так же сделан через IDecoratorListener.
Ага. И на каждое вычисление размера токена мы имеем пересоздание шрифата. Плюс его же на отрисовку. Ну, нафиг такие "грамотные решения". К тому же еще и влезание пользовательского кода в низкоуровневые.
Масштибировние шрифта — задача редактора. Это относительно низкоуровневая пробелма и я лично на сегодня вижу ее решение на уровне библиотеки вывода на физическое устройство (ну, нечто вроде замены Graphics из GDI+).
В приложении будет использоваться объект-пустышка который только хранить описание шрифта (что-то вроде высокоуровневого объектно ориентированного LOGFONT). Функции вывода будут получать его и на его основании получать из кэша шрифт. Это будет и быстро, и добноно, и прозрачно для основного кода. Представлние, перед отрисовкой или рассчетом высот строк, будет выставлять свой масштаб, а библиотека отображения будет его отрабатывать.
Что касается прикладного оформления (тех самых стилей), то я считаю совершенно не верным делать какие-то потойные лазейки в данной области. Все форматирование должно определяться стилями. Если нужен новый вид форматировани, то просто добавляй новый стиль.
Я же говорил вообще о том что уже реализовано. Сейчас чтобы создать стилевой набор в котором используется один шрифт у котрого могут меняться характиристики вроде "жирный", "курсив" и т.п. я должен создать новые объекты Font. А ведь некоторые стили могут пересекаться. Если пересекаются стили с разными шрифтами, то возникает проблема. Ведь я не могу логически объеденить описание шрифтов или задать его частично (как это делаетс с цветами). Один шрифт переоределить другой. Вот я и говорю, что это просчет который нужно устранить. Должна быть возможность задавать шрифт частично. Чтобы наложение стилей не перекрывало один шрифт другим, а объеденяло их описания.
A>Бенефиты такого подхода:
A>1. декоратор дергается только для тех строк которые видны на экране — не надо мучать процессор лишней работой;
А как на счет рассчета переноса строк? Забить на него? Лично я против. Мне нужен удобный в использовании редактор, а не набор компромисов.
A>2. легко сделать кэш строк обработанных декоратором, т.к. для этого достаточно просто написать еще одну реализацию IDecoratorListener;
А зачем мне кэш строк? Я и без него отлично живу. Дотнет и так жрет слишком много памти, чтобы забиват ее совершенно не нужными кэшами.
A>3. Визуализация текста не ограничена рисованием текста или рисованием картинки вместо текста, т.к. реализация IDecoratedSubstring ограничена только фантазией юзверя (в разумных пределах конечно
;
Я не заметл, чтобы твой прмер что-то мог изменить в отрисовке. Да и ливно мне это не нужно. Любое расширение дожно быть продумано и ограничено, чтобы оно не мешала остальным частям приложения. Твое предложение убивает к чертям всю диею стилей. Ну, нафиг такие расширения.
A>4. декораторы можно комбинировать. Пример — FontChangeDecorator который изменяет результаты разбора уже существующего декоратора.
А зачем мне вообще заниматься импиратившиной зависящей от последовательности выполнения и приводящей к мутному коду, когда я могу все что нужно вырзить в виде стилей?
На то я их и проектировал, чтобы потом не трахаться с кодированием и не офигивать от побочных эффектов от наложения таких вот расширений.
Мне нужна простота, ясность и скорость.
... << RSDN@Home 1.2.0 alpha rev. 631>>