Marker - просмотр Markdown

...
  • marker-dev2.kex (10.7 KiB)
    Downloaded 267 times
    marker-dev2.png
    marker-dev2.png (6.92 KiB)
    Viewed 13000 times
    Добавил горизонтальный scrollbar. Нововведения все, в основном работал над кодом.

    (Насколько я понял, фактический размер скроллбара (xsize) на 1 пиксель больше, чем мы указываем, но это нигде не написано (либо плохо искал :)))
  • Добавил поддержку (если так можно сказать) цитат, и выкладываю исходники. Буду рад, если кто-то подскажет как лучше сделать тот или иной момент.
    Downloaded 245 times
    marker-dev3.kex (10.77 KiB)
    Downloaded 268 times
    pic.png
    pic.png (7.96 KiB)
    Viewed 12894 times
  • 135 строчка, файл marker.c - а free где?
    Также отдели функции друг от друга (см 34-35, 39-40)
    SynapseOS - ОС совместимая с KolibriOS
    KolibriRPG
    Мой Github
  • Не совсем понял про второе. Имеется в виду поставить пустую строку?
  • qullarwee wrote: Thu Apr 13, 2023 10:26 pm Не совсем понял про второе. Имеется в виду поставить пустую строку?
    Да, тут конечно вкусовщина. Но будет визуально лучше.
    SynapseOS - ОС совместимая с KolibriOS
    KolibriRPG
    Мой Github
  • Хочу спросить у знающих как лучше. Сейчас отрисовка происходит с помощью rasterworks, он может рисовать только в буфер (буду рад, если ошибаюсь), а это не очень оптимально, каждый раз рисовать блок пикселей. Другой способ сделать жирные и курсивные - kf шрифты. Но для них нет общей библиотеки, и вероятно нет части функционала rasterworks. Но если рисовать без буфера, то надо ещё продумать как отрисовывать в окно.
    В общем, слушаю ваше мнение.

    А ну и ещё, не работает кириллица. Пытался исправить - не получилось. Кто знает как сделать напишите.
  • Рисовать текст сразу в окно можно только с ф.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) и передавать текст в функцию в соответствующей кодировке.
  • Вот только буфер должен соответствовать размеру окна (рисовать только тот текст, который попадает в окно), а для этого нужна какая-нибудь связная структура документа (типа DOM или хотя бы список строк).
    У меня есть один буфер, я сразу все на него рисую, а потом вывожу подпрямоугольники в окно. Вы, как я понял, предлагаете каждый раз заново отрисовывать в буфер, но только то, что необходимо в окне прямо сейчас? Мне кажется что так не очень эффективно - в моем способе просто вывести буфер, а здесь его надо каждый раз создавать. Хотя в любом случае вы лучше знаете про это :)

    Насчёт кириллицы - если просто выводить с помощью drawlen, то работает. А если посимвольно - то нет. Вероятно это связано с тем, что кириллический символ занимает больше одного байта, но как исправить я не придумал...

    P.S спасибо за ответ
  • 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 - длина символа)
    - повторять пока есть символы
  • Добавил utf-8, теперь кириллица работает как надо. Буферы пока не трогал.
    marker.png
    marker.png (14.26 KiB)
    Viewed 12672 times
    marker.kex (10.94 KiB)
    Downloaded 255 times
  • 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.
    Attachments
    marker_0.1.0.png
    marker_0.1.0.png (33.27 KiB)
    Viewed 5313 times
  • 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.
  • Who is online

    Users browsing this forum: No registered users and 2 guests