Page 1 of 1
Marker - просмотр Markdown
Posted: Sat Apr 08, 2023 5:42 pm
by qullarwee
Доброго времени суток. Написал простой просмотрщик Markdown, кое-что брал
здесь. Реализовано пока не много функционала, но открывать и читать простые md файлы он может.
Неочевидный функционал:
- открытие через аргумент командной строки.
- скролл колесиком, стрелками, PgUp, PgDown, скроллбар.
- горизонтальный скролл пока что только стрелками и shift+колесико.
В общем, потестируйте, и дайте обратную связь

Есть некоторые моменты, которые я не знаю как сделать/исправить. Если надо будет, код выложу позже.
Re: Marker - просмотр Markdown
Posted: Tue Apr 11, 2023 7:12 pm
by qullarwee

-
marker-dev2.png (6.92 KiB)
Viewed 13044 times
Добавил горизонтальный scrollbar. Нововведения все, в основном работал над кодом.
(Насколько я понял, фактический размер скроллбара (xsize) на 1 пиксель больше, чем мы указываем, но это нигде не написано (либо плохо искал

))
Re: Marker - просмотр Markdown
Posted: Thu Apr 13, 2023 9:08 pm
by qullarwee
Добавил поддержку (если так можно сказать) цитат, и выкладываю исходники. Буду рад, если кто-то подскажет как лучше сделать тот или иной момент.

-
pic.png (7.96 KiB)
Viewed 12938 times
Re: Marker - просмотр Markdown
Posted: Thu Apr 13, 2023 10:12 pm
by ArenElchinyan
135 строчка, файл marker.c - а free где?
Также отдели функции друг от друга (см 34-35, 39-40)
Re: Marker - просмотр Markdown
Posted: Thu Apr 13, 2023 10:26 pm
by qullarwee
Не совсем понял про второе. Имеется в виду поставить пустую строку?
Re: Marker - просмотр Markdown
Posted: Thu Apr 13, 2023 11:34 pm
by ArenElchinyan
qullarwee wrote: ↑Thu Apr 13, 2023 10:26 pm
Не совсем понял про второе. Имеется в виду поставить пустую строку?
Да, тут конечно вкусовщина. Но будет визуально лучше.
Re: Marker - просмотр Markdown
Posted: Fri Apr 14, 2023 2:29 pm
by qullarwee
Хочу спросить у знающих как лучше. Сейчас отрисовка происходит с помощью rasterworks, он может рисовать только в буфер (буду рад, если ошибаюсь), а это не очень оптимально, каждый раз рисовать блок пикселей. Другой способ сделать жирные и курсивные - kf шрифты. Но для них нет общей библиотеки, и вероятно нет части функционала rasterworks. Но если рисовать без буфера, то надо ещё продумать как отрисовывать в окно.
В общем, слушаю ваше мнение.
А ну и ещё, не работает кириллица. Пытался исправить - не получилось. Кто знает как сделать напишите.
Re: Marker - просмотр Markdown
Posted: Sat Apr 15, 2023 12:52 am
by akron1
Рисовать текст сразу в окно можно только с ф.4 (системный моноширинный шрифт фиксированного размера и начертания). Все другие способы вывода текста работают только через буфер, и это правильно - позволяет избежать мерцания изображения (ф.4 при выводе в окно работает довольно быстро, поэтому мерцание обычно незначительное).
Вообще, в рисовании в буфер нет ничего плохого (есть только некоторые расходы оперативной памяти): FB2 Reader и CEdit рисуют текст в буфер и это получается вполне эффективно. Вот только буфер должен соответствовать размеру окна (рисовать только тот текст, который попадает в окно), а для этого нужна какая-нибудь связная структура документа (типа DOM или хотя бы список строк).
Для kf-шрифтов в системе нет общей библиотеки, есть только исходные коды (модули) на C-- и Обероне. Хотя, это не совсем так: я когда-то всё же сделал obj-библиотеку
https://board.kolibrios.org/viewtopic.p ... 241#p66241 (но в образе ее нет).
Файл kf-шрифта (/sys/fonts/tahoma.kf) содержит только набор символов Windows-1251, курсива нет (может имитироваться наклоном текста, но выглядит плохо).
По поводу кириллицы
render.c:
Code: Select all
void render_DrawLen(pen_t *pen, char *buf, char *text, int len) {
int mask = pen->bold | (pen->italic << 1) | (pen->underline << 2) | (pen->strike << 3);
drawText(buf, pen->pos.x, pen->pos.y, text, len, pen->color + (0xFF << 24), ((mask * 0x100 + 0x03) * 0x100 + (int)(pen->font_size.x * pen->mul)) * 0x100 + (int)(pen->font_size.y * pen->mul));
pen->pos.x += (int)(pen->font_size.x * pen->mul) * len;
}
последний параметр функции drawText определяет в том числе и кодировку:
1*0x10000 - CP866
2*0x10000 - UTF-16LE
3*0x10000 - UTF-8
т.е надо прибавить одно из этих значений к последнему параметру функции drawText (видимо, по умолчанию используется CP866) и передавать текст в функцию в соответствующей кодировке.
Re: Marker - просмотр Markdown
Posted: Sun Apr 16, 2023 7:30 pm
by qullarwee
Вот только буфер должен соответствовать размеру окна (рисовать только тот текст, который попадает в окно), а для этого нужна какая-нибудь связная структура документа (типа DOM или хотя бы список строк).
У меня есть один буфер, я сразу все на него рисую, а потом вывожу подпрямоугольники в окно. Вы, как я понял, предлагаете каждый раз заново отрисовывать в буфер, но только то, что необходимо в окне прямо сейчас? Мне кажется что так не очень эффективно - в моем способе просто вывести буфер, а здесь его надо каждый раз создавать. Хотя в любом случае вы лучше знаете про это
Насчёт кириллицы - если просто выводить с помощью drawlen, то работает. А если посимвольно - то нет. Вероятно это связано с тем, что кириллический символ занимает больше одного байта, но как исправить я не придумал...
P.S спасибо за ответ
Re: Marker - просмотр Markdown
Posted: Sun Apr 16, 2023 10:10 pm
by akron1
qullarwee wrote: ↑Sun Apr 16, 2023 7:30 pm
У меня есть один буфер, я сразу все на него рисую, а потом вывожу подпрямоугольники в окно. Вы, как я понял, предлагаете каждый раз заново отрисовывать в буфер, но только то, что необходимо в окне прямо сейчас? Мне кажется что так не очень эффективно - в моем способе просто вывести буфер, а здесь его надо каждый раз создавать.
Графический буфер, при обновлении изображения, не создается заново, а стирается (заполняется цветом фона). Новый буфер создается только при изменении размера окна. В вашем случае, большой документ может не поместиться в буфере, или буфер не поместится в оперативной памяти.
qullarwee wrote: ↑Sun Apr 16, 2023 7:30 pm
Насчёт кириллицы - если просто выводить с помощью drawlen, то работает. А если посимвольно - то нет. Вероятно это связано с тем, что кириллический символ занимает больше одного байта, но как исправить я не придумал...
Значит используется кодировка utf-8. Длину символа можно определить по значению первого байта:
0******* - 1 байт
110***** - 2 байта
1110**** - 3 байта
...
Алгоритм посимвольного вывода будет такой:
- определить длину текущего символа
- вывести символ
- сместить указатель на текущий символ на n байт вперед (n - длина символа)
- повторять пока есть символы
Re: Marker - просмотр Markdown
Posted: Wed Apr 19, 2023 8:17 pm
by qullarwee
Добавил utf-8, теперь кириллица работает как надо. Буферы пока не трогал.

-
marker.png (14.26 KiB)
Viewed 12716 times
Re: Marker - просмотр Markdown
Posted: Wed Jan 29, 2025 3:24 pm
by Burer
Updated Marker a little bit.
What was done:
- Use of SF 4 instead of rasterworks.obj, as it made regular text blurry.
- Automatic calculation of buffer size for document, now any document can be displayed in full.
- Line break by letters (works only if program is opened to the full width of screen).
- Interface for opening a file, editing it in CEdit and updating the edited file.
- Parser and renderer for block quotes has been tweaked a little bit.
What problems it has:
- Buffer is allocated for the whole document at once, so RAM consumption is very high.
- Works only with CP866 encoding.
Posting it “as is”, in case someone could use it as a reader.
Binary and sources can be downloaded here:
http://ftp.kolibrios.org/users/Burer/marker/
qullarwee, could you share sources of latest version of Marker with UTF-8 support, please? I would like to continue Marker development, and already implemented UTF-8 support will make it much easier.
Re: Marker - просмотр Markdown
Posted: Mon Apr 14, 2025 3:02 pm
by qullarwee
UTF-8 was implemented something like this:
Code: Select all
// utf-8
int get_octet(char c) {
int octet = 0, bit = 7;
while (c & (1 << bit)) {
++octet;
--bit;
}
if (!octet) ++octet;
return octet;
}
void parse(char *filename) {
ksys_ufile_t ld = _ksys_load_file(filename);
if (ld.data == NULL) {
_ksys_exec("/sys/@notify", "'Marker\nFile not found!' -E -t");
exit(0);
}
int n = ld.size, octet;
data = ld.data;
//puts(data);
for (int i = 0; i < ld.size; i += octet) {
octet = get_octet(data[i]);
if (data[i] == '\n') {
render_NewLn(&pen);
if (pen.mode == header) {
pen.mul = 1;
pen.mode = plain;
}
if (pen.mode == quote) {
pen.color = 0xF7F7F7;
pen.mode = plain;
}
} else if (data[i] == '\\' && i + 1 < n) {
i++;
octet = get_octet(data[i]);
render_DrawLen(&pen, buffer, data + i, 1);
} else if (data[i] == '*' || data[i] == '_') {
if (i + 1 < n && data[i + 1] == data[i]) {
pen.bold ^= 1;
i++;
} else {
pen.italic ^= 1;
}
} else if (data[i] == '~' && i + 1 < n && data[i + 1] == '~') {
pen.strike ^= 1;
i++;
} else if (data[i] == '`') {
pen.underline ^= 1;
} else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '#') {
int cnt = 1;
while (i + cnt < n && data[i + cnt] == '#') cnt++;
if (cnt <= 6) {
pen.mode = header;
pen.mul = 1 + (6 - cnt) * 0.2;
i += cnt - 1;
while (i + 1 < n && data[i + 1] == ' ') i++;
}
} else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '>') {
pen.color = 0xF4FF00;
pen.mode = quote;
i++;
} else {
render_DrawLen(&pen, buffer, data + i, 1);
}
}
free(data);
}
Perhaps it's worth rewriting from scratch.