Board.KolibriOS.org

Official KolibriOS board
It is currently Mon May 20, 2019 2:01 pm

All times are UTC+03:00




Post new topic  Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Sat Oct 07, 2017 9:16 pm 
Offline
Designer
User avatar

Joined: Thu Jan 25, 2007 3:33 pm
Posts: 5047
Я уже давно очень хочу две вещи (на самом деле пять). Те, которые я теоретически смогу реализовать это текстовый редактор и редактор иконок (а которые не смогу это unarchiver, wifi и С-- в Колибри).

Эта тема посвящена теории разработки текстового редактора с подсветкой синтаксиса.
Дабы не велосипедить, я вначале хочу обсудить как правильно его реализовать.

Основные вещи, которые вызовут трудности. Интересует ваше мнение. Я буду писать как я это вижу.

1. как хранить текст документа.
При открытиии все строки разбиваем на массив данных: id (unic, enum), line_number, string_data
Пример:
Code:
Примет мир
Я вторая строка.
Будет хранится как: 0, 0, "Привет мир"
1, 1, "Я вторая строка"
Для текста используется один буффер, в котором хранятся строки. Если строка именяется, она переносится в конец буфера. При этом старая строка больше не будет использоваться в программе.
"Привет мир\0Я вторая строка\0" > "Привет мир\0Я вторая строка\0\Привет мир измененная"
При сохранении документа можно проводить дефрагментацию.

2. поиск лексем для применения стилей
Стили могут применятся или к словам или к блокам.
Слова: int, void, else, #define
Блоки: после //, между /* */, между ""
Как правильно реализовать такой поиск и как хранить стили?
Каждую подстроку разбивать еще на массив строк-стилей? Звучит сложно...

3. как выводить текст
Надо решить или в буфер или рисовать фоновый прямоугольник, а наверх текст - не знаю.

_________________
Через тернии к звездам


Top
   
PostPosted: Sun Oct 08, 2017 12:19 am 
Offline

Joined: Mon Mar 27, 2006 6:33 am
Posts: 658
Leency wrote:
Дабы не велосипедить, я вначале хочу обсудить как правильно его реализовать.

А вариант переноса или идей компонента Scintilla не рассматривался?


Top
   
PostPosted: Sun Oct 08, 2017 1:39 am 
Offline
Mentor/Kernel Developer
User avatar

Joined: Thu Mar 26, 2015 5:16 pm
Posts: 1262
Учитывая, что Scintilla разрабатывают уже 16 лет, портирование - наиболее логичный вариант.

Leency
Я ещё когда с TinyPad возился, чуть фейспалмом лоб не пробил... А массив указателей на строки сделать не вариант? Зачем в массив структур включать сами строки? Почто текст мучить? Может даже лучше связный список структур с указателями на строки.


Top
   
PostPosted: Sun Oct 08, 2017 3:01 am 
Offline

Joined: Sun Oct 27, 2013 8:13 pm
Posts: 141
Leency, во-первых в твоих программах вывод текста в буфер сделан неправильно. Ты создаешь огромный буфер и рисуешь туда текст, затем, выводишь в окно программы ту часть буфера, которая требуется. Это совершенно неприличный расход памяти (и её может не хватить). Надо, чтобы буфер соответствовал размеру окна программы. При обновлении окна программы, содержимое буфера стирается и текст рисуется заново, естественно, только те строки, которые попадают в окно.

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

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

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

К сожалению, когда я это делал, опыта у меня не хватало и о кроссплатформенности я не заботился. Программа жестко привязана к WINAPI.

Spoiler: Show
Attachment:
1.png
1.png [ 16.9 KiB | Viewed 1418 times ]


Top
   
PostPosted: Sun Oct 08, 2017 11:11 am 
Offline
Designer
User avatar

Joined: Thu Jan 25, 2007 3:33 pm
Posts: 5047
Kopa
В идеале было бы круто, но я такое не потяну.

Leency
string_data и предполагался быть указателем.
> Может даже лучше связный список структур с указателями на строки.
Интересно, очень даже может быть.

_________________
Через тернии к звездам


Top
   
PostPosted: Sun Oct 08, 2017 11:50 am 
Offline
Designer
User avatar

Joined: Thu Jan 25, 2007 3:33 pm
Posts: 5047
akron1
Спасибо за развернутое объяснение.

Quote:
Leency, во-первых в твоих программах вывод текста в буфер сделан неправильно. Ты создаешь огромный буфер и рисуешь туда текст, затем, выводишь в окно программы ту часть буфера, которая требуется. Это совершенно неприличный расход памяти (и её может не хватить). Надо, чтобы буфер соответствовал размеру окна программы. При обновлении окна программы, содержимое буфера стирается и текст рисуется заново, естественно, только те строки, которые попадают в окно.
В WebView такое сделать сейчас нельзя, т.к. процесс парсинга и рисования однопроходный. Для того, чтобы реализовать буфер окна нужен DOM.
В Calypte такое можно попробовать следать уже сейчас.
Для TxtView чтобы такое сделать нужно две вещи:
1. перевести каждый символ KF шрифта в растр (как делаешь ты в BF view)
2. написать функцию, которая будет накладывать партинку на картинку

Quote:
Подсветку синтаксиса я делал так:
Каждая строка перед выводом в буфер парсится и, по мере нахождения в строке той или иной лексемы, лексема выводится в графический буфер заданным цветом. Никакие списки лексем не создаются, потому что строки изменяемы и списки лексем тоже придется менять. Парсить надо только те строки, которые попадают в окно программы. На экране помещается всего несколько десятков строк, и поэтому такой способ, если сделать правильно, будет эффективен.
Здесь еще надо обратить внимание на многострочные комментарии. Начало комментария может быть выше видимой части текста. Поэтому, перед началом работы с текстом, надо найти все комментарии и пометить строки, в которых комментарий начинается, заканчивается или продолжается. И после изменения любой строки, проверить её на наличие в ней начала или конца комментария, чтобы поддерживать информацию о расположении комментариев актуальной.
Интересно. Вообще дело в том, что не только комментарии могут быть многострочными, но и строки "". Если реализовыватть только подсветку Си - вроде просто.
Но если универстально, чтобы использовались файлы подсветки разных систаксисов не думаю что твой вариант "надо найти все комментарии и пометить строки, в которых комментарий начинается, заканчивается или продолжается". Например в HTML таких мест будет очень много.

Quote:
Разработка текстового редактора -- дело сложное. У меня есть некоторый опыт, хотя на идеал я не притендую.
У меня нет и я даже не имею ИТ образования. Многие студенты как курсовую делают редакторы. Смотрю исходники других проектов, анализирую. Возможно, стоит нанять человека на разработку или портирование редактора...

_________________
Через тернии к звездам


Top
   
PostPosted: Mon Oct 09, 2017 1:42 am 
Offline

Joined: Tue Apr 12, 2011 11:19 pm
Posts: 1148
Некоторые рассматривали возможность портирования Scintilla. Интересует их мнение на этот счёт. Детально ещё не смотрел, возможно ли обойтись без GTK+?

_________________
я лишь учусь


Top
   
PostPosted: Mon Oct 09, 2017 5:04 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
punk_joker wrote:
возможно ли обойтись без GTK+
Siemargl писал, что можно FLTK.


Top
   
PostPosted: Mon Oct 09, 2017 3:35 pm 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 436
Да, только я никак не возьмусь за ФЛТК - все же большой объем непонятного кода


Top
   
PostPosted: Tue Oct 10, 2017 11:42 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Siemargl, если можно как-то разбить задачу на части, то может кто-нибудь ещё примет участие и тогда это будет быстрее.


Top
   
PostPosted: Fri Oct 13, 2017 1:24 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Leency wrote:
2. поиск лексем для применения стилей
Там вон какой-то лексер http://websvn.kolibrios.org/filedetails ... %2Flexer.h


Top
   
PostPosted: Wed Feb 07, 2018 7:07 am 
Offline

Joined: Sat Apr 22, 2017 6:11 pm
Posts: 222
Если актуально...

Открытый документ лучше всего хранить в виде: кол-во строк + указатель на список указателей строк документа, текущая позиция курсора ввода, цвет фона подложки и так далее. Почему указатель - чтобы задачу можно было разбить на более простые и разделить между людьми (+ если кому-то надо список, то просто даём ему указатель), а в случае чего (например переделка gui) будет просто отделить обёртку от основной структуры.

Предлагаю на каждую строку отдельно хранить: символы строки, битовую (или байтовую) маску изменения цвета, список цветов, байт характеристик строки (номер цвета фона строки и знаки: брейкпоинт, ошибка, строка изменена и не сохранена, изменения сохранены и так далее).
Список цветов хранить в виде буфера нужного размера с расчётом по 4 байта на один цвет. В большинстве случаев при добавлении символа маску придётся пересчитать для всей строки заново, а может и для всей видимой области. В других же случаях можно будет сдвигать её вправо на 1 разряд и заполнять+изменять её и соседние биты.
Битовая маска должна обозначать 1 - символ, с которого начинается новый цвет (увеличиваем +4 смещение на цвет в буфере списка цветов), 0 - цвет не изменяется (используем тот же).
Рисовать всё следует в буфере и потом выводить на экран/в окно. Для старта можно воспользоваться моим koView.
Следует создать и описать API такого компонента: получения/установка цвета, символа и так далее.

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

Есть другой вариант: можно идти от формата лексера, преобразовывать его формат и красить. Но тут можно споткнуться с устройством самого текстового редактора (задача редактора не просто вывести подсвеченный текст, а изменять его).

Могу помочь сделать описанную выше структуру строк и средний компонент, который будет рисовать заданный цветной текст. Нужен тот, кто напишет оболочку программы (загрузка и сохранение файла, вкладки, меню, копировать/вставить, растянуть окно и прочее). От кого-то потом потребуется написать лексер, который будет обновлять маску какими цветами красить.

Attachment:
File comment: Общая схема
0.png
0.png [ 112.86 KiB | Viewed 1017 times ]


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 12 posts ] 

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Limited