/* * mdview2.h — общие определения и интерфейс между модулями mdview2. * * Монолит mdview2.c расщепляется инкрементально; первый отделённый модуль — * RAW-просмотр (mdview2_raw.c). Здесь живут разделяемые константы экрана/ * атрибутов, extern-объявления нужных RAW символов из mdview2.c и API RAW. */ #ifndef MDVIEW2_H #define MDVIEW2_H #include #include /* COLOR(), COLOR_* */ #include "mdview2_conf.h" /* WITH_RAW / WITH_HEX — выбор опциональных модулей */ /* ---- Геометрия экрана -------------------------------------------- */ #define SCREEN_W 80 #define SCREEN_H 32 #define VIEW_TOP_ROW 1 #define VIEW_H 30 /* видимая область: строки 1..30 включительно */ #define MENU_ROW 31 #define TAB_STOP 4 /* ---- Параметры файла и памяти ------------------------------------ */ #define PAGE_BITS 14u #define PAGE_SIZE (1u << PAGE_BITS) /* размер EMM-страницы: 16 КБ */ #define PAGE_MASK ((uint16_t)(PAGE_SIZE - 1u)) #define MAX_PAGES 8 /* 8 страниц × 16 КБ = 128 КБ */ #define MAX_FILE ((uint32_t)MAX_PAGES * PAGE_SIZE) #define FILE_BUF ((char *)0xC000) /* окно W3, куда мапится текущая EMM-страница */ /* ---- Палитра атрибутов ------------------------------------------- */ #define ATTR_RESET COLOR(COLOR_LIGHTGRAY, COLOR_BLACK) #define ATTR_TEXT COLOR(COLOR_LIGHTGRAY, COLOR_BLUE) #define ATTR_TEXT_TITLE1 COLOR(COLOR_YELLOW, COLOR_BLUE) #define ATTR_TEXT_TITLE2 COLOR(COLOR_LIGHTBLUE, COLOR_BLUE) #define ATTR_TEXT_TITLE3 COLOR(COLOR_LIGHTGREEN, COLOR_BLUE) #define ATTR_TEXT_TITLE4 COLOR(COLOR_LIGHTGREEN, COLOR_BLUE) #define ATTR_TEXT_BOLD COLOR(COLOR_LIGHTRED, COLOR_BLUE) #define ATTR_TEXT_ITALIC COLOR(COLOR_LIGHTGREEN, COLOR_BLUE) #define ATTR_TEXT_UNDERSORE COLOR(COLOR_LIGHTMAGENTA, COLOR_BLUE) #define ATTR_TEXT_CODE COLOR(COLOR_WHITE, COLOR_BLUE) #define ATTR_TEXT_STRIKE COLOR(COLOR_DARKGRAY, COLOR_BLUE) #define ATTR_LIST_MARKER COLOR(COLOR_LIGHTCYAN, COLOR_BLUE) #define ATTR_QUOTE_MARKER COLOR(COLOR_CYAN, COLOR_BLUE) #define ATTR_HR COLOR(COLOR_CYAN, COLOR_BLUE) #define ATTR_BOX COLOR(COLOR_CYAN, COLOR_BLUE) #define ATTR_TRUNC COLOR(COLOR_YELLOW, COLOR_BLUE) #define ATTR_BAR COLOR(COLOR_BLACK, COLOR_LIGHTCYAN) #define ATTR_BAR_SPINNER COLOR(COLOR_WHITE, COLOR_LIGHTCYAN) #define ATTR_MENU_T COLOR(COLOR_BLACK, COLOR_LIGHTCYAN) #define ATTR_MENU_K COLOR(COLOR_YELLOW, COLOR_BLACK) /* ---- Атрибуты диалога справки ------------------------------------ */ #define ATTR_HELP_BG COLOR(COLOR_LIGHTGRAY, COLOR_BLACK) #define ATTR_HELP_BDR COLOR(COLOR_WHITE, COLOR_BLACK) #define ATTR_HELP_TIT COLOR(COLOR_YELLOW, COLOR_BLACK) #define ATTR_HELP_HDR COLOR(COLOR_WHITE, COLOR_BLACK) /* ---- Режимы просмотра -------------------------------------------- */ #define VIEW_MD 0 /* markdown с форматированием (по умолчанию) */ #define VIEW_RAW_WRAP 1 /* RAW: длинные строки переносятся кратно 80 */ #define VIEW_RAW_HSCROLL 2 /* RAW: длинные строки в одну, гориз. скролл */ /* ---- Кодировки --------------------------------------------------- */ /* 8-битные (CP866/CP1251/KOI8R) различаются только ремапом глифов [128-255] * на отрисовке; UTF-8 — отдельный декодированный набор. */ #define ENC_CP866 0 #define ENC_CP1251 1 #define ENC_KOI8R 2 #define ENC_UTF8 3 #define CONV_MARGIN 4096u /* на сколько байт держать UTF-конвертацию впереди индексатора */ /* ---- Флаги сегмента индекса (IF_*) — общие для индексатора/кэша/вью ---- */ #define IF_CONT 0x01u /* сегмент является продолжением перенесённой строки */ #define IF_NOWRAP 0x02u /* строка не переносится (кодовый блок / HR / таблица) */ #define IF_BLANK 0x04u /* визуально пустая строка */ #define IF_CODE 0x08u /* тело fenced code-блока (verbatim-режим) */ #define IF_HSCROLL 0x10u /* блок горизонтально скроллируется ЦЕЛИКОМ (код/таблица), * включая строки короче 80 — двигаются как единый блок. * НЕ ставится на HR и границы fence (им нечего прятать). */ /* ---- Словарь сегментов/стилей (общий для индексатора и таблиц) ---- */ /* Тип сегмента-продолжения, передаваемый в emit_seg()/inline_scan(). */ #define CK_PLAIN 0 #define CK_QUOTE 1 #define CK_LIST 2 #define CK_OTHER 3 /* Начальный inline-стиль сегмента (INIT_STYLE_*). */ #define INIT_STYLE_PLAIN 0x0 #define INIT_STYLE_BOLD 0x1 #define INIT_STYLE_ITALIC 0x2 #define INIT_STYLE_UNDER 0x3 #define INIT_STYLE_CODE 0x4 #define INIT_STYLE_STRIKE 0x5 /* ---- Таблицы: CP866 light box-drawing (общий для индексатора и модуля) ---- */ #define TBL_MAX_COLS 16 #define TBL_ATTR ATTR_BOX #define TBL_H 0xC4 /* ─ */ #define TBL_V 0xB3 /* │ */ #define TBL_TL 0xDA /* ┌ */ #define TBL_TM 0xC2 /* ┬ */ #define TBL_TR 0xBF /* ┐ */ #define TBL_ML 0xC3 /* ├ */ #define TBL_MM 0xC5 /* ┼ */ #define TBL_MR 0xB4 /* ┤ */ #define TBL_BL 0xC0 /* └ */ #define TBL_BM 0xC1 /* ┴ */ #define TBL_BR 0xD9 /* ┘ */ /* ================================================================== * * Разделяемые символы mdview2.c, используемые модулем RAW. * ================================================================== */ extern uint8_t g_view; /* активный режим просмотра (VIEW_*) */ extern uint32_t file_size; /* размер активного буфера документа */ extern const uint8_t *g_remap; /* таблица ремапа [128-255] (0 = нет) */ extern uint8_t g_scratch_phys; /* scratch EMM-страница для win_rest */ char fb(uint32_t p); /* байт активного буфера (W3-маппинг) */ void win_rest(uint8_t row, uint8_t col, uint8_t h, uint8_t w, uint8_t page, uint16_t off); void fill_row(uint8_t y, uint8_t attr); uint32_t seg_off(uint16_t idx); /* offset исходника для логической строки idx */ /* ================================================================== * * API модуля RAW (mdview2_raw.c). * ================================================================== */ void raw_seed_from(uint16_t md_top_line); /* вход в RAW: позиция по top_line */ void raw_home(void); /* сброс в начало (смена буфера при F8 в/из UTF-8) */ void raw_draw(void); /* перерисовать область документа в RAW */ void raw_status_numbers(void); /* числовая зона статус-бара для RAW */ uint8_t raw_key(uint8_t scan); /* навигация RAW; 1 = обработано */ void raw_screen_init(void); /* очистка экрана с нужным аттрибутом */ void raw_renorm(void); /* выровнять позицию при смене под-режима (F3) */ /* ================================================================== * * Запись директории рендер-кэша (одна на видимую строку, РОВНО 8 байт — * cache_dir_get/put адресуют сдвигом idx<<3). Контент — len пар (char,attr). * ================================================================== */ typedef struct cache_rec_s { uint8_t page; /* EMM-страница рендер-кэша (физический номер) */ uint16_t off; /* смещение в странице, 0..16383 (байты, не ячейки) */ uint8_t len; /* длина контента в ЯЧЕЙКАХ (char,attr пар), 0..255; 0 = пустая/HR */ uint8_t flags; /* копия IF_NOWRAP/IF_CODE/IF_BLANK на момент рендера */ uint8_t reserved; /* не используется */ uint8_t pad[2]; /* явный резерв, добивка до 8 байт */ } cache_rec_t; void cache_dir_get(uint16_t idx, cache_rec_t *r); /* читатель директории кэша (ядро) */ void put_str_attr(uint8_t x, uint8_t y, const char *s, uint8_t attr); /* печать строки с атрибутом */ /* ================================================================== * * Состояние навигации/представления (определено в mdview2.c). * ================================================================== */ extern uint16_t n_lines; /* всего строк в индексе текущего набора */ extern uint16_t top_line; /* верхняя видимая строка */ extern uint8_t viewport_x; /* горизонтальный сдвиг (nowrap-строки) */ extern char filename[]; /* имя файла для статус-бара */ extern uint8_t g_loading; /* 1 во время index_lines() */ extern uint8_t g_ready; /* 1 когда первичный документ построен (F2 RAW) */ extern uint8_t g_f8_enabled; /* можно ли сейчас переключать кодировку */ /* ================================================================== * * Отрисовка области/статус-бара/меню и прокрутка (mdview2_view.c). * ================================================================== */ void draw_viewport_from_cache(void); /* перерисовать область документа из кэша */ uint16_t drawable_lines(void); /* число строк, готовых к показу */ void render_status_numbers(void); /* числовая часть статус-бара */ void render_full_status(void); /* полная перерисовка статус-бара */ void render_updated_status(void); /* обновить только числа статус-бара */ void render_menu(void); /* перерисовать строку меню */ void clamp_top(void); /* привести top_line к диапазону */ void scroll_up(uint16_t n); void scroll_down(uint16_t n); void scroll_h(int8_t delta); /* горизонтальный сдвиг nowrap-блоков */ /* ================================================================== * * API модуля справки (mdview2_help.c). * ================================================================== */ void show_help(void); /* модальный диалог F1 */ /* ================================================================== * * Парсер/индексатор (mdview2_index.c) и разделяемое с ним состояние. * Хранилище индекса (index_blk/pages/phys, n_lines/max_lines) — в ядре * (аллокация/doc-slot), индексатор пишет в него; cache_*-писатели и * progress_tick/spinner_tick ядро экспортирует индексатору. * ================================================================== */ #define INDEX_RECS_PER_PAGE 2048u /* 16384 / 8; запись всегда в одной странице */ #define MAX_CACHE_LINE_LEN 255u /* кап длины контента строки в ячейках (буфер g_cells) */ extern uint16_t max_lines; /* ёмкость индекса: index_pages * 2048 */ extern uint8_t index_blk, index_pages; /* дескриптор EMM-блока индекса */ extern uint8_t index_phys[]; /* физ. страницы индекса */ extern uint8_t index_truncated; /* индекс упёрся в ёмкость */ extern uint8_t g_abort; /* F10/Esc во время загрузки → прервать индексацию */ uint8_t cache_reserve(uint16_t nbytes, uint8_t *out_page, uint16_t *out_off); void cache_commit(uint8_t page, uint16_t off, const void *buf, uint16_t len); void cache_dir_put(uint16_t idx, const cache_rec_t *r); void spinner_tick(void); /* анимация индикатора загрузки */ void progress_tick(void); /* кооперативный шаг loading-loop (рисует/листает) */ void index_lines(void); /* построить индекс по загруженному файлу */ /* ================================================================== * * Буфер ячеек рендера (mdview2.c) — общий с модулем таблиц. * Таблицы эмитят свои строки теми же примитивами, что и индексатор. * ================================================================== */ extern uint8_t g_ncells; /* ячеек в текущем сегменте */ void gc_put(char ch, uint8_t attr); /* добавить ячейку в g_cells */ void gc_fill(char ch, uint8_t attr, uint8_t n); /* n одинаковых ячеек */ uint8_t inline_scan(uint32_t q, uint32_t q_end, uint8_t col, uint8_t ckind, uint8_t line_style, uint8_t base_attr, uint8_t nowrap); /* ================================================================== * * API модуля таблиц (mdview2_table.c) — вызывается из index_lines(). * ================================================================== */ uint32_t row_end(uint32_t p); /* offset завершающего '\n' (или file_size) */ uint32_t table_first_cell(uint32_t row_start); /* контент первой ячейки строки */ uint8_t table_next_cell(uint32_t *pp, uint32_t lineend, uint32_t *cs, uint32_t *ce); uint8_t table_is_sep_row(uint32_t row_start, uint32_t lineend); void table_border(const uint8_t *widths, uint8_t ncols, char left, char mid, char right); void table_data_row(uint32_t row_start, uint32_t lineend, const uint8_t *widths, uint8_t ncols); /* ================================================================== * * Кодировки и UTF-8 конвертация (mdview2_enc.c). * Состояние кодека владеется модулем; build_doc()/index_lines() ядра * оркестрируют его (привязка UTF-буфера к живому file_*, сборка наборов). * ================================================================== */ extern uint8_t g_encoding; /* активная кодировка (ENC_*) */ extern uint8_t g_utf_building; /* 1 пока UTF-конвертация не дошла до конца исходника */ extern uint8_t utf_avail; /* 1 = страницы UTF-8 выделены */ extern uint8_t utf_blk, utf_pages; /* дескриптор EMM-буфера UTF-набора */ extern uint8_t utf_phys[]; /* физ. страницы UTF-буфера */ extern uint32_t utf_size; /* размер сконвертированного UTF-потока */ /* Ядро-owned состояние, читаемое кодеком (определено в mdview2.c). */ extern uint8_t cur_page; /* текущая страница файла в W3 (инвалидация маппинга) */ extern uint8_t orig_file_phys[]; /* физ. страницы снимка исходного файла */ extern uint8_t orig_file_pages; extern uint32_t orig_file_size; void set_encoding(uint8_t enc); /* активная кодировка + таблица ремапа */ const char *enc_name(uint8_t enc); /* короткое имя для статус-бара */ uint8_t detect_encoding(void); /* автоопределение по сэмплу байт */ void win_rest_remap(uint8_t row, uint8_t w, uint8_t page, uint16_t off); /* вывод среза с ремапом */ void utf_convert_more(uint32_t target); /* инкрементальная конвертация до target байт */ uint8_t utf_alloc(void); /* выделить EMM-страницы под UTF-набор; 0 = нет EMM */ #endif /* MDVIEW2_H */