#help_index "DolDoc" I64 DocWordWrapDel(CDoc *doc, CDocEntry *doc_e, Bool full_refresh, Bool same_win, I64 left_margin, I64 right_margin, CDocEntry **_best_doc_e, I64 *_best_col) { CDocEntry *doc_e2; U8 *ptr; I64 j, k; if (doc_e->de_flags & DOCEF_TAG && doc_e->tag) k = StrLen(doc_e->tag); else k = 0; if (full_refresh) while (TRUE) { doc_e2 = doc_e->next; if (doc_e2->type_u8 == DOCT_SOFT_NEW_LINE && !same_win) { if (doc->cur_entry == doc_e2) { doc->cur_entry = doc_e2->next; doc->cur_col = doc->cur_entry->min_col; } if (*_best_doc_e == doc_e2) { *_best_doc_e = doc_e2->next; *_best_col = 0; } DocEntryDel(doc, doc_e2); } else if (IsEditableText(doc_e) && doc_e->de_flags == doc_e2->de_flags && doc_e->type == doc_e2->type) { j = StrLen(doc_e2->tag); ptr = MAlloc(k + j + 1, doc->mem_task); MemCopy(ptr, doc_e->tag, k); MemCopy(ptr + k, doc_e2->tag, j + 1); Free(doc_e->tag); doc_e->tag = ptr; if (doc->cur_entry == doc_e2) { doc->cur_entry = doc_e; doc->cur_col += k; } if (*_best_doc_e == doc_e2) { *_best_doc_e = doc_e; *_best_col = 0; } DocEntryDel(doc, doc_e2); k += j; if (k > (right_margin - left_margin + 1) << 1) break; } else break; } if (doc_e->de_flags & DOCEF_SCROLLING_X) k = doc_e->scroll_len; return k; } U0 DocRecalcXY(CDoc *doc, CDocEntry *doc_e, I64 k, I64 left, I64 width, I64 height, I64 left_margin, I64 right_margin, I64 x0, I64 y0, I64 *_x, I64 *_y) { I64 i, x = *_x, y = *_y; if (doc_e->de_flags & DOCEF_MARGIN_REL_X) { if (doc_e->de_flags & DOCEF_LEFT_X) x = left_margin - left; else if (doc_e->de_flags & DOCEF_RIGHT_X) x = right_margin - (k - 1) - left; else if (doc_e->de_flags & DOCEF_CENTER_X) x = (right_margin + left_margin) >> 1 - k >> 1 - left; } else { if (doc_e->de_flags & DOCEF_LEFT_X) x = x0; else if (doc_e->de_flags & DOCEF_RIGHT_X) x = width + x0 - k; else if (doc_e->de_flags & DOCEF_CENTER_X) x = (width + x0 - k) >> 1; } i = y; if (doc_e->de_flags & DOCEF_PAGE_REL_Y) { doc->flags |= DOCF_BWD_MOVEMENT; if (doc_e->de_flags & DOCEF_TOP_Y) y -= doc_e->page_line_num; else if (doc_e->de_flags & DOCEF_BOTTOM_Y) y += doc_e->settings.page_len - doc_e->page_line_num; else if (doc_e->de_flags & DOCEF_CENTER_Y) y += doc_e->settings.page_len >> 1 - doc_e->page_line_num; } else { doc->flags |= DOCF_BWD_MOVEMENT; if (doc_e->de_flags & DOCEF_TOP_Y) y = y0; else if (doc_e->de_flags & DOCEF_BOTTOM_Y) y = height - 1 + y0; else if (doc_e->de_flags & DOCEF_CENTER_Y) y = height >> 1 + y0; } if (y != i) { doc->page_line_num += y - i; if (doc->page_line_num < 0) doc->page_line_num = doc_e->settings.page_len + doc->page_line_num % doc_e->settings.page_len; else doc->page_line_num = doc->page_line_num % doc_e->settings.page_len; if (doc_e->settings.header != DOC_DEFAULT && doc->page_line_num < doc_e->settings.header) { y += doc_e->settings.header - doc->page_line_num; doc->page_line_num = doc_e->settings.header; } if (doc_e->settings.footer == DOC_DEFAULT) { if (doc->page_line_num >= doc_e->settings.page_len) { if (doc_e->settings.header == DOC_DEFAULT) doc->page_line_num = 0; else { doc->page_line_num = doc_e->settings.header; y += doc_e->settings.header; } } } else { if (doc->page_line_num >= doc_e->settings.page_len - doc_e->settings.footer) { y += doc_e->settings.footer; if (doc_e->settings.header == DOC_DEFAULT) doc->page_line_num = 0; else { doc->page_line_num = doc_e->settings.header; y += doc_e->settings.header; } } } } *_x = x; *_y = y; } CDocEntry *DocSplitTag(CDoc *doc, CDocEntry *doc_e, I64 i, I64 x, I64 y, I64 type_u8) {//Split tag at i, insert DOCT_SOFT_NEW_LINE, DOCT_MARKER or DOCT_CURSOR U8 *ptr; CDocEntry *doc_e2; if (doc_e->type_u8 == DOCT_TEXT && i) { if (i < StrLen(doc_e->tag)) { doc_e2 = MAllocIdent(doc_e, doc->mem_task); doc_e2->tag = StrNew(doc_e->tag + i, doc->mem_task); doc_e2->de_flags = doc_e->de_flags & ~DOCEG_HAS_ALLOC | DOCEF_TAG; QueueInsert(doc_e2, doc_e); if (doc->cur_entry == doc_e && doc->cur_col>=i) { doc->cur_entry = doc_e2; doc->cur_col = doc->cur_col - i; } doc_e->tag[i] = 0; ptr = StrNew(doc_e->tag, doc->mem_task); Free(doc_e->tag); doc_e->tag = ptr; } } else doc_e = doc_e->last; doc_e2 = DocEntryNewBase(doc, type_u8 | doc_e->type & 0xFFFFFF00, doc_e->de_flags & ~DOCEG_HAS_ARG, x, y, doc_e->page_line_num); MemCopy(&doc_e2->settings, &doc_e->settings, sizeof(CDocSettings)); QueueInsert(doc_e2, doc_e); return doc_e2; } CDocEntry *DocWordWrapAdd(CDoc *doc, CDocEntry *doc_e, I64 *_k, I64 left, I64 right_margin, I64 x, I64 y) { CDocEntry *doc_e2; I64 j, i = right_margin + 1 - (x + left), //Space left on line ii = x + 1 - doc_e->settings.left_margin; if (IsEditableText(doc_e)) { if (doc->cur_entry == doc_e->next) { if (doc->cur_col == doc_e->next->min_col) i--; } else { if (doc->cur_entry == doc_e && doc->cur_col == i) i--; } if (*_k > i) { for (j = i; j > 8 - ii && j >= 0; j--) if (doc_e->tag[j] == CH_SPACE) { i = j + 1; break; } if (0 < i < *_k) { DocSplitTag(doc, doc_e, i, x, y, DOCT_SOFT_NEW_LINE); *_k = StrLen(doc_e->tag); return NULL; } } if (*_k == i) return NULL; } if (*_k >= i) { doc_e2 = doc_e->last; if (doc_e2->type_u8 != DOCT_SOFT_NEW_LINE && doc_e2->type_u8 != DOCT_NEW_LINE && doc_e2->type_u8 != DOCT_CURSOR_MOVEMENT) { doc_e2 = DocEntryNewBase(doc, DOCT_SOFT_NEW_LINE | doc_e->type & 0xFFFFFF00, DOCEF_WORD_WRAP | doc_e->de_flags & (DOCEF_HIGHLIGHT | DOCG_BL_IV_UL | DOCEF_SKIP | DOCEF_FILTER_SKIP), x, y, doc_e->last->page_line_num); MemCopy(&doc_e2->settings, &doc_e->settings, sizeof(CDocSettings)); QueueInsert(doc_e2, doc_e->last); return doc_e2; } } return NULL; } I64 DocTmpAttr(CDoc *doc, CDocEntry *doc_e, I64 cur_u8_attr) { I64 tmp_u32_attr; doc_e->de_flags = doc->flags & (DOCG_BL_IV_UL | DOCEF_WORD_WRAP | DOCEF_HIGHLIGHT) | doc_e->de_flags & ~(DOCG_BL_IV_UL | DOCEF_WORD_WRAP | DOCEF_HIGHLIGHT); tmp_u32_attr = (cur_u8_attr & 0xF0) << 8 | doc->flags & DOCG_BL_IV_UL | (doc_e->settings.shifted_x & 0x1F) << 16 | (doc_e->settings.shifted_y & 0x1F) << 21; if (doc_e->de_flags & DOCEF_HAS_BIN && *doc_e->tag == '<') tmp_u32_attr.u8[1] |= DOC_COLOR_BIN; else switch (doc_e->type_u8) { case DOCT_SPRITE: if (doc_e->de_flags & DOCEF_LEFT_EXP) tmp_u32_attr.u8[1] |= cur_u8_attr & 15; else if (doc_e->de_flags & DOCEF_LINK) tmp_u32_attr.u8[1] |= DOC_COLOR_LINK; else if (doc_e->de_flags & DOCEF_LEFT_MACRO) tmp_u32_attr.u8[1] |= DOC_COLOR_MACRO; else if (doc_e->de_flags & (DOCEF_TREE | DOCEF_LIST)) tmp_u32_attr.u8[1] |= DOC_COLOR_TREE; else tmp_u32_attr.u8[1] |= DOC_COLOR_BIN; break; case DOCT_HTML_CODE: tmp_u32_attr.u8[1] |= DOC_COLOR_BIN; break; case DOCT_LINK: tmp_u32_attr.u8[1] |= DOC_COLOR_LINK; break; case DOCT_MACRO: tmp_u32_attr.u8[1] |= DOC_COLOR_MACRO; break; case DOCT_ANCHOR: tmp_u32_attr.u8[1] |= DOC_COLOR_ANCHOR; break; case DOCT_TREE: case DOCT_LIST: tmp_u32_attr.u8[1] |= DOC_COLOR_TREE; break; default: tmp_u32_attr.u8[1] |= cur_u8_attr & 15; } doc_e->type.u8[1] = tmp_u32_attr.u8[1]; tmp_u32_attr |= doc_e->type & 0xFFFF0000; if (doc_e == doc->cur_entry && !(doc->flags & DOCF_DONT_HIGHLIGHT_CURSOR) && doc_e->type_u8 != DOCT_TEXT) tmp_u32_attr ^= 0xFF00; doc_e->settings.final_u32_attr = tmp_u32_attr; return tmp_u32_attr; } public Bool DocRecalc(CDoc *doc, I64 recalc_flags=RECALCt_NORMAL) {//Recalc and format. Also used by WinMgr to draw on screen. I64 i, ii, j, k, x, x0, y, y0, D, d2, col, col2, best_col = 0, best_d = I64_MAX, xx, yy, zz, num_entries = 0, i_jif, cur_u8_attr, tmp_u32_attr, cursor_y = I64_MIN, left_margin, right_margin, y_plot_top, y_plot_bottom, top, left, bottom, right, width, height, scroll_x, scroll_y, pix_top, pix_left; CDocEntry reg *doc_e, reg *doc_e2, *best_doc_e, *next_clear_found = NULL, *added_cursor = NULL; CDocBin *tmpb; CDocSettings *s; Bool del_doc_e, skipped_update, tree_collapsed, same_win, more = FALSE, find_cursor = FALSE, blink_flag, full_refresh = TRUE, unlock, clear_holds; CTask *win_task, *mem_task; CDC *dc; U8 *bptr, *ptr, buf[STR_LEN], ch; U32 *u32_ptr, *hl; I32 *depth_buf = NULL; F64 cur_time = tS; CWinScroll *vss, *hss; CHashDefineStr *tmph; if (!doc || doc->doc_signature != DOC_SIGNATURE_VAL) return FALSE; //WinMgr updates all wins (60000.0 / 1001), 33.33333mS if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && doc->owning_task != Fs) { i_jif = counts.jiffies + JIFFY_FREQ / 250; //4 mouse while (Bt(&doc->locked_flags, DOClf_LOCKED)) { if (counts.jiffies >= i_jif) return FALSE; //Bail-out if doc locked. Yield; } } unlock = DocLock(doc); if (doc->doc_signature != DOC_SIGNATURE_VAL) { DocUnlock(doc); return FALSE; } win_task = doc->win_task; mem_task = doc->mem_task; blink_flag = Blink; dc = NULL; switch [recalc_flags & RECALCG_MASK] { case RECALCt_FIND_CURSOR: find_cursor = TRUE; if (win_task) dc = DCAlias(gr.dc2, win_task); //Necessary for sprites break; case RECALCt_TO_SCREEN: if (doc->updates_count++ % (ToI64(winmgr.fps / 10) + 1) && !Bt(&doc->flags, DOCf_DO_FULL_REFRESH) && !(doc->flags & DOCF_BWD_MOVEMENT)) full_refresh = FALSE; if (win_task) dc = DCAlias(gr.dc2, win_task); break; } PUSHFD CLI left = win_task->win_left; right = win_task->win_right; width = win_task->win_width; scroll_x = win_task->scroll_x; scroll_y = win_task->scroll_y; top = win_task->win_top; bottom = win_task->win_bottom; height = win_task->win_height; pix_left = win_task->pix_left; pix_top = win_task->pix_top; left_margin = left; right_margin = right; POPFD if (doc->flags & DOCF_BORDER_DOC) { scroll_x = 0; scroll_y = 0; } best_doc_e = doc->cur_entry; if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_TABS)) && FilesFindMatch(doc->filename.name, FILEMASK_SRC)) doc->flags |= DOCF_HIGHLIGHT; else doc->flags &= ~DOCF_HIGHLIGHT; x = y = 0; doc->page_line_num = 0; if (full_refresh && !find_cursor) { doc->x = x; doc->y = y; } hss = &win_task->horz_scroll; vss = &win_task->vert_scroll; if (doc->flags & DOCF_BORDER_DOC) { doc->top_line_num = 0; doc->line_start_col = 0; recalc_flags &= ~RECALCF_HAS_CURSOR; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN) doc->settings_head.cur_text_attr = doc->settings_head.default_text_attr = win_task->border_attr; } else { if (recalc_flags & RECALCF_HAS_CURSOR && full_refresh) { if (Bt(&hss->flags, WSSf_SET_TO_POS) || Bt(&vss->flags, WSSf_SET_TO_POS)) { if (!(doc->flags & DOCF_NO_SCROLL_BARS)) { if (Bt(&hss->flags, WSSf_SET_TO_POS)) { doc->line_start_col = hss->pos; LBtr(&hss->flags, WSSf_SET_TO_POS); } if (Bt(&vss->flags, WSSf_SET_TO_POS)) { doc->top_line_num = vss->pos; LBtr(&vss->flags, WSSf_SET_TO_POS); } } doc->x = doc->line_start_col + width / 2; doc->y = doc->top_line_num + height / 2; find_cursor = TRUE; } } if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN) doc->settings_head.cur_text_attr = doc->settings_head.default_text_attr = win_task->text_attr; } x0 = doc->line_start_col; y0 = doc->top_line_num; same_win = top == doc->old_win_top && bottom == doc->old_win_bottom && left == doc->old_win_left && right == doc->old_win_right && doc->cur_entry == doc->old_cur_entry && doc->cur_col == doc->old_cur_col; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN) { y_plot_top = y0 - scroll_y / FONT_HEIGHT; y_plot_bottom = y0 + height - 1 - scroll_y / FONT_HEIGHT; if (!(doc->flags & DOCF_BORDER_DOC) && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) DocBorderListDraw(doc); } if (doc->cur_col <= doc->cur_entry->min_col) doc->cur_col = doc->cur_entry->min_col; doc_e = doc->head.next; doc_e->de_flags &= ~(DOCG_BL_IV_UL | DOCEF_WORD_WRAP | DOCEF_HIGHLIGHT); if (doc_e == doc->head.next) s = &doc->settings_head; else s = &doc_e->last->settings; doc->flags = doc_e->de_flags & (DOCG_BL_IV_UL | DOCEF_WORD_WRAP) | doc->flags & ~(DOCG_BL_IV_UL | DOCEF_WORD_WRAP); cur_u8_attr = s->cur_text_attr; if (doc_e == doc->head.next) { doc->flags &= ~DOCF_BWD_MOVEMENT; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && full_refresh) doc->flags &= ~DOCF_HAS_SONG; } else doc->flags = doc_e->de_flags & DOCEF_HIGHLIGHT | doc->flags & ~DOCEF_HIGHLIGHT; if (doc->head.next == doc) { best_doc_e = doc; best_col = 0; doc->cur_entry = doc; doc->cur_col = 0; doc_e = doc; } skipped_update = doc_e == doc && doc->head.next != doc; if (full_refresh) { doc->min_x = I32_MAX; doc->min_y = I32_MAX; doc->max_x = I32_MIN; doc->max_y = I32_MIN; } while (doc_e != doc) { while (TRUE) { del_doc_e = FALSE; if (doc_e->de_flags & (DOCEF_SKIP | DOCEF_FILTER_SKIP)) { doc_e2 = doc_e; goto rc_skip; } MemCopy(&doc_e->settings, s, sizeof(CDocSettings)); s = &doc_e->settings; if (doc_e->de_flags & (DOCEF_TAG_CB | DOCEF_DEFINE) && !(doc_e->de_flags & DOCEF_LIST)) { Free(doc_e->tag); if (doc_e->de_flags & DOCEF_TAG_CB) { if (doc_e->tag_cb) doc_e->tag = (*doc_e->tag_cb)(doc, doc_e, mem_task); else doc_e->tag = StrNew("", mem_task); } else { if (tmph = HashFind(doc_e->define_str, win_task->hash_table, HTT_DEFINE_STR)) doc_e->tag = StrNew(tmph->data, mem_task); else doc_e->tag = CAlloc(1, mem_task); } doc_e->max_col = StrLen(doc_e->tag); if (doc->cur_entry == doc_e && doc->cur_col >= doc_e->max_col) { if (doc_e->max_col) doc->cur_col = doc_e->max_col - 1; else doc->cur_col = 0; } } k = DocWordWrapDel(doc, doc_e, full_refresh, same_win, left_margin, right_margin, &best_doc_e, &best_col); if (doc_e->de_flags & (DOCEF_LEFT_X | DOCEF_RIGHT_X | DOCEF_CENTER_X | DOCEF_TOP_Y | DOCEF_BOTTOM_Y | DOCEF_CENTER_Y)) DocRecalcXY(doc, doc_e, k, left, width, height, left_margin, right_margin, x0, y0, &x, &y); if (full_refresh && k > 0 && doc->flags & DOCF_WORD_WRAP && (doc_e2 = DocWordWrapAdd(doc, doc_e, &k, left, right_margin, x, y))) doc_e = doc_e2; else break; } if (full_refresh) { doc_e->x = x; doc_e->y = y; doc_e->page_line_num = doc->page_line_num; if (x < doc->min_x) doc->min_x = x; if (y < doc->min_y) doc->min_y = y; if (find_cursor) { D = DocCharDist(doc, x, y); col = 0; } } col2 = 0; tmp_u32_attr = DocTmpAttr(doc, doc_e, cur_u8_attr); if (doc_e == doc->cur_entry) { cursor_y = doc_e->y; if (recalc_flags & RECALCF_ADD_CURSOR && !added_cursor) { if (doc_e->type_u8 == DOCT_TEXT && 0 < doc->cur_col < k && !(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) && !(doc_e->type & DOCG_BL_IV_UL)) { added_cursor = DocSplitTag(doc, doc_e, doc->cur_col, x, y, DOCT_CURSOR); k = StrLen(doc_e->tag); } else { added_cursor = doc_e2 = DocEntryNewBase(doc, DOCT_CURSOR | doc_e->type & 0xFFFFFF00, doc_e->de_flags & ~DOCEG_HAS_ARG, x, y, doc->page_line_num); MemCopy(&doc_e2->settings, &doc_e->settings, sizeof(CDocSettings)); if (doc_e->type_u8 == DOCT_TEXT && doc->cur_col >= k) QueueInsert(doc_e2, doc_e); else QueueInsertRev(doc_e2, doc_e); } } } if (doc_e->de_flags & DOCEF_REFRESH_DATA && (doc_e->type_u8 == DOCT_DATA || doc_e->type_u8 == DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LIST)) { DocDataFormat(doc, doc_e); k = StrLen(doc_e->tag); } if (doc_e->de_flags & DOCEF_TAG) { ptr = doc_e->tag; if (doc_e->de_flags & DOCEF_TREE) { if (k >= 2) { if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED) *ptr++ = '+'; else *ptr++ = '-'; *ptr++ = ']'; ptr = doc_e->tag; } } else if (doc_e->de_flags & DOCEF_HAS_BIN) { if (*ptr == '<' && full_refresh && '0' <= ptr[1] <= '9') { ptr = MStrPrint("<%d>", doc_e->bin_num); Free(doc_e->tag); doc_e->tag = StrNew(ptr, mem_task); Free(ptr); ptr = doc_e->tag; k = StrLen(ptr); } } else if (doc_e->type_u8 == DOCT_CHECK_BOX) { if (k >= 3) { *ptr++ = '['; if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED) *ptr++ = 'X'; else *ptr++ = CH_SPACE; *ptr++ = ']'; ptr = doc_e->tag; } } if (doc_e->de_flags & DOCEF_SCROLLING_X) { j = StrLen(doc_e->tag); if (j && doc_e->scroll_len) { i_jif = ToI64(cur_time * FONT_WIDTH * DOC_SCROLL_SPEED) % (j * FONT_WIDTH); tmp_u32_attr = tmp_u32_attr & 0xFFE0FF00 | (FONT_WIDTH - 1 - i_jif & (FONT_WIDTH - 1)) << 16; #assert FONT_WIDTH == 8 i_jif >>= 3; for (k = 0; k < doc_e->scroll_len; k++) { ch = ptr[(i_jif + k) % j]; if (!Bt(char_bmp_displayable, ch)) ch = '.'; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + ch); else TextChar(win_task, FALSE, x - x0, y - y0, tmp_u32_attr + ch); } x++; } } if (find_cursor) { D = DocCharDist(doc, doc_e->x, doc_e->y); col = doc_e->min_col; } col2 = doc_e->scroll_len; //TODO This is flawed } else { if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) { while (ch = *ptr++) { if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + ch); else if (find_cursor) { d2 = DocCharDist(doc, x, y); if (d2 < D) { D = d2; col = col2; } } col2++; x++; } } else { if (doc_e->type_u8 == DOCT_TEXT && doc_e->de_flags & DOCEF_HIGHLIGHT) hl = DocHighlight(doc_e, ptr, k, tmp_u32_attr); else hl = NULL; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { //Technically we should do this for scrolling_x, too. if (y > y_plot_bottom) more = TRUE; else if (y >= y_plot_top) { if (hl) TextLenAttrStr(win_task, x - x0, y - y0, k, hl); else TextLenStr(win_task, x - x0, y - y0, k, tmp_u32_attr, ptr); } col2 += k; x += k; } else { if (find_cursor) { while (k--) { d2 = DocCharDist(doc, x, y); if (d2 < D) { D = d2; col = col2; } col2++; x++; } } else { col2 += k; x += k; } } Free(hl); } } } switch [doc_e->type_u8] { case DOCT_TEXT: if (!col2 && !(doc_e->de_flags & (DOCEF_TREE | DOCEF_LIST | DOCEF_TAG_CB | DOCEF_DEFINE | DOCEF_AUX_STR | DOCEF_HTML_LINK | DOCEF_BIN_PTR_LINK))) del_doc_e = TRUE; break; case DOCT_HEX_ED: if (doc_e->de_flags & DOCEF_DEREF_DATA && !(doc_e->de_flags & DOCEF_REMALLOC_DATA)) bptr = doc_e->data; else bptr = &doc_e->data; k = doc_e->hex_ed_width; //columns for (i = 0; i < doc_e->len; i += k) { if (doc_e->de_flags & DOCEF_ZERO_BASED) StrPrint(buf, "%08tX ", i); else StrPrint(buf, "%08tX ", bptr); ptr = buf; while (ch = *ptr++) { if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + ch); else TextChar(win_task, FALSE, x - x0, y - y0, tmp_u32_attr + ch); } if (find_cursor) { d2 = DocCharDist(doc, x, y); if (d2 < D) { D = d2; col = i * 3; } } x++; } if (i + k > doc_e->len) k = doc_e->len - i; for (j = 0; j < k; j++) { StrPrint(buf, "%02tX", *bptr++); ptr = buf; while (ch = *ptr++) { if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + ch); else TextChar(win_task, FALSE, x - x0, y - y0, tmp_u32_attr + ch); } if (find_cursor) { d2 = DocCharDist(doc, x, y); if (d2 < D) { D = d2; col = col2; } } col2++; x++; } x++; } bptr -= j; x += (doc_e->hex_ed_width - k) * 3; for (j = 0; j < k; j++) { ch = *bptr++; if (!Bt(char_bmp_displayable, ch)) ch = '.'; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + ch); else TextChar(win_task, FALSE, x - x0, y - y0, tmp_u32_attr + ch); } if (find_cursor) { d2 = DocCharDist(doc, x, y); if (d2 < D) { D = d2; col = col2; } } col2++; x++; } y++; x -= doc_e->hex_ed_width * 3 + k + 9; } break; case DOCT_NEW_LINE: case DOCT_SOFT_NEW_LINE: if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)&& y_plot_top <= y <= y_plot_bottom) TextLenAttr(win_task, x - x0, y - y0, width - (x - x0), cur_u8_attr << 8); if (doc_e->de_flags & DOCEF_HIGHLIGHT && s->state == DOCSS_CPP_Z_COMMENT) s->state = DOCSS_NORMAL; y++; doc->page_line_num++; rc_start_of_line: if (s->left_margin == DOC_DEFAULT) x = s->indent; else x = s->indent + s->left_margin; rc_adjust_xy: i = s->indent + s->left_margin; if (x < i) x = i; if (doc->page_line_num < 0) doc->page_line_num = s->page_len + doc->page_line_num % s->page_len; else { if (doc->page_line_num >= s->page_len) { doc->page_line_num -= s->page_len; if (doc->page_line_num >= s->page_len) //avoid extra divide doc->page_line_num = doc->page_line_num % s->page_len; } } if (s->header != DOC_DEFAULT) { if (doc->page_line_num < s->header) { y += s->header - doc->page_line_num; doc->page_line_num = s->header; goto rc_start_of_line; } } if (s->footer == DOC_DEFAULT) { if (doc->page_line_num >= s->page_len) { if (s->header == DOC_DEFAULT) doc->page_line_num = 0; else { doc->page_line_num = s->header; y += s->header; } goto rc_start_of_line; } } else { if (doc->page_line_num >= s->page_len - s->footer) { y += s->footer; if (s->header == DOC_DEFAULT) doc->page_line_num = 0; else { doc->page_line_num = s->header; y += s->header; } goto rc_start_of_line; } } break; case DOCT_TAB: k = (x + 4) & ~3; if (doc_e->de_flags & DOCEF_BORDER_PLOT && !Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) { while (x < k) { if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) TextChar(win_task, TRUE, x - x0, y - y0, tmp_u32_attr + CH_SPACE); if (find_cursor) { d2 = DocCharDist(doc, x, y); if (d2 < D) D = d2; } x++; } } else { k -= x; if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (y_plot_top <= y <= y_plot_bottom) TextLenStr(win_task, x - x0, y - y0, k, tmp_u32_attr, " "); x += k; } else { if (find_cursor) { while (k--) { d2 = DocCharDist(doc, x, y); if (d2 < D) D = d2; x++; } } else x += k; } } break; case DOCT_PAGE_BREAK: doc->flags |= DOCF_BWD_MOVEMENT; y += s->page_len - doc_e->page_line_num; doc->page_line_num = 0; goto rc_start_of_line; case DOCT_CURSOR: if (!find_cursor && !(doc->flags & DOCF_NO_CURSOR)) { doc->cur_entry = doc_e->next; doc->cur_col = doc->cur_entry->min_col; } if (doc_e != added_cursor) del_doc_e = TRUE; break; case DOCT_PROMPT: cur_u8_attr = cur_u8_attr & 0xF0 | DOC_COLOR_PROMPT; if (y == cursor_y) { doc->cur_entry = doc_e->next; doc->cur_col = doc->cur_entry->min_col; } break; case DOCT_CLEAR: next_clear_found = doc_e; if (doc_e->de_flags & DOCEF_HOLD) clear_holds = TRUE; else clear_holds = FALSE; break; case DOCT_PAGE_LEN: s->page_len = doc_e->attr; if (doc_e->de_flags & DOCEF_WIN_REL) s->page_len += height; goto rc_adjust_xy; case DOCT_LEFT_MARGIN: i = doc_e->attr; left_margin = left+i; s->left_margin = i; goto rc_start_of_line; case DOCT_RIGHT_MARGIN: if (doc_e->de_flags & DOCEF_WIN_REL) i = width - 1 - doc_e->attr; else i = doc_e->attr; right_margin = left + i; s->right_margin = i; goto rc_adjust_xy; case DOCT_HEADER: s->header = doc_e->attr; goto rc_adjust_xy; case DOCT_FOOTER: s->footer = doc_e->attr; goto rc_adjust_xy; case DOCT_INDENT: if (doc_e->de_flags & DOCEF_LEFT_X) i = doc_e->attr; else i = s->indent + doc_e->attr; s->indent=i; goto rc_start_of_line; case DOCT_FOREGROUND: cur_u8_attr &= 0xF0; if (doc_e->attr == DOC_DEFAULT) cur_u8_attr |= s->default_text_attr & 0x0F; else cur_u8_attr |= doc_e->attr; s->cur_text_attr = cur_u8_attr; break; case DOCT_BACKGROUND: cur_u8_attr &= 0x0F; if (doc_e->attr == DOC_DEFAULT) cur_u8_attr |= s->default_text_attr & 0xF0; else cur_u8_attr |= doc_e->attr << 4; s->cur_text_attr = cur_u8_attr; break; case DOCT_DEFAULT_FOREGROUND: cur_u8_attr &= 0xF0; if (doc_e->attr == DOC_DEFAULT) cur_u8_attr |= s->default_text_attr & 0xF; else cur_u8_attr |= doc_e->attr; s->default_text_attr = s->default_text_attr & 0xF0 | cur_u8_attr & 0x0F; s->cur_text_attr = cur_u8_attr; break; case DOCT_DEFAULT_BACKGROUND: cur_u8_attr &= 0x0F; if (doc_e->attr == DOC_DEFAULT) cur_u8_attr |= s->default_text_attr & 0xF0; else cur_u8_attr |= doc_e->attr << 4; s->default_text_attr = s->default_text_attr & 0x0F | cur_u8_attr & 0xF0; s->cur_text_attr = cur_u8_attr; break; case DOCT_WORD_WRAP: if (doc_e->attr) doc->flags |= DOCF_WORD_WRAP; else doc->flags &= ~DOCF_WORD_WRAP; break; case DOCT_HIGHLIGHT: if (doc_e->attr) doc->flags |= DOCF_HIGHLIGHT; else doc->flags &= ~DOCF_HIGHLIGHT; break; case DOCT_BLINK: if (doc_e->attr) doc->flags |= DOCF_BLINK; else doc->flags &= ~DOCF_BLINK; break; case DOCT_INVERT: if (doc_e->attr) doc->flags |= DOCF_INVERT; else doc->flags &= ~DOCF_INVERT; break; case DOCT_UNDERLINE: if (doc_e->attr) doc->flags |= DOCF_UNDERLINE; else doc->flags &= ~DOCF_UNDERLINE; break; case DOCT_SHIFTED_X: s->shifted_x = doc_e->attr; break; case DOCT_SHIFTED_Y: s->shifted_y = doc_e->attr; break; case DOCT_CURSOR_MOVEMENT: doc->flags |= DOCF_BWD_MOVEMENT; x += doc_e->cursor_x_offset; if (doc_e->de_flags & DOCEF_PAGE_REL_Y) { i = doc->page_line_num; if (doc_e->de_flags & DOCEF_TOP_Y) doc->page_line_num = 0; else if (doc_e->de_flags & DOCEF_BOTTOM_Y) doc->page_line_num = s->page_len - 1; else if (doc_e->de_flags & DOCEF_CENTER_Y) doc->page_line_num = s->page_len >> 1; y += doc->page_line_num - i; } y += doc_e->cursor_y_offset; doc->page_line_num += doc_e->cursor_y_offset; goto rc_adjust_xy; case DOCT_SPRITE: if (!doc_e->bin_data && doc->flags & DOCEF_HAS_BIN) doc_e->bin_data = DocBinFindNum(doc, doc_e->bin_num); if ((tmpb = doc_e->bin_data) && !tmpb->tag && doc_e->tag && *doc_e->tag) tmpb->tag = StrNew(doc_e->tag, mem_task); if (tmpb && dc) { DCReset(dc); dc->flags &= ~(DCF_DONT_DRAW | DCF_LOCATE_NEAREST); if (recalc_flags & RECALCG_MASK != RECALCt_TO_SCREEN || doc_e->de_flags & DOCEF_DONT_DRAW) dc->flags |= DCF_DONT_DRAW; bptr = tmpb->data; ii = SpriteTypeMask(bptr); if (ii & 1 << SPT_TYPES_NUM) { bptr = gr.empty_sprite; ii = SpriteTypeMask(bptr); } if (ii & (1 << SPT_FLOOD_FILL | 1 << SPT_FLOOD_FILL_NOT)) i = cur_u8_attr >> 4 & 0xF ^ win_task->text_attr >> 4 & 0xF; else { i = tmp_u32_attr >> 12 & 0xF ^ win_task->text_attr >> 4 & 0xF; if (tmp_u32_attr & DOCET_SEL) i ^= 0xF; if (tmp_u32_attr & DOCET_INVERT) i ^= 0xF; if (blink_flag && (doc_e == doc->cur_entry || tmp_u32_attr & DOCET_BLINK)) i ^= 0xF; } dc->color = i; if (find_cursor) dc->flags |= DCF_LOCATE_NEAREST; dc->cur_x = (doc->x - x0) * FONT_WIDTH + pix_left + scroll_x; dc->cur_y = (doc->y - y0) * FONT_HEIGHT + pix_top + scroll_y; dc->cur_z = 0; dc->bkcolor = i; if (doc_e->de_flags & DOCEF_FROM_START) { xx = (x - k - x0) * FONT_WIDTH; //TODO: scrolling text is not length k yy = (y - y0) * FONT_HEIGHT; zz = 0; } else { xx = (x - x0) * FONT_WIDTH; yy = (y - y0) * FONT_HEIGHT; zz = 0; } if (ii & (1 << SPT_MESH | 1 << SPT_SHIFTABLE_MESH)) { if (!depth_buf) { DCDepthBufAlloc(dc); depth_buf = dc->depth_buf; } else dc->depth_buf = depth_buf; Mat4x4IdentEqu(dc->r); Mat4x4RotZ(dc->r, cur_time * 3.1); Mat4x4RotY(dc->r, cur_time * 1.9); Mat4x4RotX(dc->r, cur_time); dc->flags |= DCF_TRANSFORMATION; dc->x = xx; dc->y = yy; dc->z = GR_Z_ALL; xx = 0; yy = 0; zz = 0; } Sprite3(dc, xx, yy, zz, bptr); dc->depth_buf = NULL; dc->flags &= ~(DCF_LOCATE_NEAREST | DCF_DONT_DRAW | DCF_TRANSFORMATION); if (dc->nearest_dist <= D) { D = dc->nearest_dist; col = doc_e->min_col; } } break; case DOCT_SONG: if (sys_focus_task == win_task && recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && !(doc_e->de_flags & DOCEF_DONT_DRAW)) { if (doc_e->aux_str && (!music.cur_song || StrCompare(music.cur_song, doc_e->aux_str))) { Free(music.cur_song); MusicSettingsReset; music.cur_song = SysStrNew(doc_e->aux_str); } } doc->flags |= DOCF_HAS_SONG; break; case DOCT_HTML_CODE: if (recalc_flags & RECALCF_TO_HTML && doc_e->de_flags & DOCEF_TAG && doc_e->tag) x -= StrLen(doc_e->tag); break; case DOCT_TYPES_NUM - 1: //nobound switch default: break; } if (doc_e->de_flags & DOCEF_HAS_BORDER) TextBorder(win_task, doc_e->x - x0, x - x0 - 1, doc_e->y - y0, y - y0, tmp_u32_attr.u8[1], ToBool(doc_e->de_flags & DOCEF_SOLID_BORDER)); if (full_refresh) { switch (doc_e->type_u8) { case DOCT_CHECK_BOX: doc_e->max_col = 2; break; case DOCT_LIST: case DOCT_TREE: case DOCT_BTTN: case DOCT_LINK: case DOCT_MENU_VAL: case DOCT_MACRO: doc_e->max_col = 1; break; default: if (doc_e->de_flags & (DOCEF_TREE | DOCEF_LIST)) doc_e->max_col = 1; else doc_e->max_col = col2; } if (x > doc->max_x) doc->max_x = x; if (y > doc->max_y) doc->max_y = y; if (D <= best_d && !(doc_e->de_flags & DOCEF_NO_CLICK_ON)) { best_d = D; best_doc_e = doc_e; best_col = col; } if (doc_e->de_flags & DOCEF_TREE) { if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED) tree_collapsed = TRUE; else tree_collapsed = FALSE; doc_e2 = doc_e->next; while (doc_e2 != doc && doc_e2->type_u8 != DOCT_INDENT && !(doc_e2->de_flags & DOCEF_TREE)) doc_e2 = doc_e2->next; if (doc_e2->type_u8 == DOCT_INDENT) { j = i = s->indent; do { if (tree_collapsed) doc_e2->de_flags |= DOCEF_SKIP; else doc_e2->de_flags &= ~DOCEF_SKIP; if (doc_e2->type_u8 == DOCT_INDENT) { if (doc_e2->de_flags & DOCEF_LEFT_X) j = doc_e2->attr; else j += doc_e2->attr; } doc_e2 = doc_e2->next; } while (doc_e2 != doc && j > i); } } } doc_e2 = doc_e->next; rc_skip: while (doc_e2 != doc && doc_e2->de_flags & (DOCEF_SKIP | DOCEF_FILTER_SKIP)) { if (doc_e2 == doc->cur_entry) { doc->cur_entry = doc_e2->next; doc->cur_col = doc->cur_entry->min_col; } if (full_refresh) { doc_e2->x = x; doc_e2->y = y; doc_e2->page_line_num = doc->page_line_num; MemCopy(&doc_e2->settings, s, sizeof(CDocSettings)); doc_e2->type.u8[1] = cur_u8_attr; doc_e2->de_flags = doc->flags & (DOCG_BL_IV_UL|DOCEF_WORD_WRAP | DOCEF_HIGHLIGHT) | doc_e2->de_flags & ~(DOCG_BL_IV_UL | DOCEF_WORD_WRAP | DOCEF_HIGHLIGHT); } doc_e2 = doc_e2->next; } if (full_refresh) { if (del_doc_e) { if (!(doc_e->de_flags & (DOCEF_HOLD | DOCEF_FILTER_SKIP))) { if (doc_e == doc->cur_entry) { doc->cur_entry = doc_e2; doc->cur_col = doc_e2->min_col; } if (best_doc_e == doc_e) { best_doc_e = doc_e2; best_col = doc_e2->min_col; //TODO: might be bug } DocEntryDel(doc, doc_e); } } } num_entries++; if (!full_refresh && doc_e->y > y_plot_bottom) break; doc_e = doc_e2; } if (full_refresh) { if (doc->cur_entry == doc && recalc_flags & RECALCF_ADD_CURSOR) { doc_e2 = DocEntryNewBase(doc, DOCT_CURSOR,, x, y, doc->page_line_num); MemCopy(&doc_e2->settings, s, sizeof(CDocSettings)); QueueInsertRev(doc_e2, doc); } if (doc->min_x > doc->max_x) { doc->max_x = 0; doc->min_x = 0; } if (doc->min_y > doc->max_y) { doc->max_y = 0; doc->min_y = 0; } //Update header if (!skipped_update) { doc_e->x = x; doc_e->y = y; doc_e->page_line_num = doc->page_line_num; MemCopy(&doc_e->settings, s, sizeof(CDocSettings)); doc_e->type.u8[1] = cur_u8_attr; if (find_cursor) { D = DocCharDist(doc, x, y); if (D < best_d && !(doc_e->de_flags & DOCEF_NO_CLICK_ON)) { best_d = D; best_doc_e = doc_e; best_col = 0; } } } if (doc->flags & DOCF_SIZE_MIN) { if (Bt(&win_task->display_flags, DISPLAYf_NO_BORDER)) { if (left < 0) left = 0; i = left + doc->max_x - doc->min_x; if (i > TEXT_COLS - 1) i = TEXT_COLS - 1; WinHorz(left, i, win_task); if (top < 0) top = 0; i = top + doc->max_y - doc->min_y; if (i > TEXT_ROWS - 1) i = TEXT_ROWS - 1; WinVert(top, i, win_task); } else { if (left < 1) left = 1; i = left + doc->max_x - doc->min_x; if (i > TEXT_COLS - 2) i = TEXT_COLS - 2; WinHorz(left, i, win_task); if (top < 1) top = 1; i = top + doc->max_y - doc->min_y; if (i > TEXT_ROWS - 2) i = TEXT_ROWS - 2; WinVert(top, i, win_task); } } if (find_cursor) { doc->cur_entry = best_doc_e; doc->cur_col = best_col; DocFormBwd(doc); //We need this because text coordinates are used if (best_d < FONT_WIDTH) best_d = 0; doc->best_d = best_d; } if (doc->cur_entry->type_u8 != DOCT_HEX_ED) { doc->y = doc->cur_entry->y; doc->x = doc->cur_entry->x + doc->cur_col; } else { doc->y = doc->cur_entry->y + doc->cur_col / 3 / doc->cur_entry->hex_ed_width; x = doc->cur_col % (doc->cur_entry->hex_ed_width * 3); i = x / doc->cur_entry->hex_ed_width; doc->x = doc->cur_entry->x + 9; if (i < 2) doc->x += x >> 1 * 3 + x & 1; else doc->x += doc->cur_entry->hex_ed_width * 3 + (x - doc->cur_entry->hex_ed_width << 1); } doc->line = doc->y + 1; doc->col = doc->x + 1; if (recalc_flags & RECALCF_HAS_CURSOR) { if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN) { x = 0; y = 0; } else { x = scroll_x / FONT_WIDTH; y = scroll_y / FONT_HEIGHT; } if (doc->top_line_num - y + height - 1 > doc->max_y) doc->top_line_num = doc->max_y - (height - 1) + y; if (doc->top_line_num - y < doc->min_y) doc->top_line_num = doc->min_y + y; if (doc->y - doc->top_line_num + y > height - 1) doc->top_line_num = doc->y - (height - 1) + y; if (doc->y - doc->top_line_num + y < 0) doc->top_line_num = doc->y + y; if (doc->line_start_col - x + width - 1 > doc->max_x) doc->line_start_col = doc->max_x - (width - 1) + x; if (doc->line_start_col - x < doc->min_x) doc->line_start_col = doc->min_x + x; if (doc->x - doc->line_start_col + x > width - 1) doc->line_start_col = doc->x-(width - 1) + x; if (doc->x - doc->line_start_col + x < 0) doc->line_start_col = doc->x + x; } } if (recalc_flags & RECALCG_MASK == RECALCt_TO_SCREEN && recalc_flags & RECALCF_HAS_CURSOR) { x = doc->x - doc->line_start_col + left + scroll_x / FONT_WIDTH; y = doc->y - doc->top_line_num + top + scroll_y / FONT_HEIGHT; if (0 <= x <= right && 0 <= y <= bottom && x < TEXT_COLS && y < TEXT_ROWS && !(doc->flags & DOCF_HIDE_CURSOR)) { u32_ptr = gr.text_base + y * TEXT_COLS + x; *u32_ptr |= DOCET_BLINK; *u32_ptr ^= 0xFF00; } if (full_refresh) { if (!(doc->flags & DOCF_NO_SCROLL_BARS)) { if (!Bt(&hss->flags, WSSf_SET_TO_POS)) { hss->min = doc->min_x; if (doc->max_x - width + 1 < hss->min) hss->max = hss->min; else hss->max = doc->max_x - width + 1; hss->pos = doc->line_start_col; } if (!Bt(&vss->flags, WSSf_SET_TO_POS)) { vss->min = doc->min_y; if (doc->max_y - height + 1 < vss->min) vss->max = vss->min; else vss->max = doc->max_y - height + 1; vss->pos = doc->top_line_num; } } LBEqual(&doc->flags, DOCf_MORE, more); } } if (!same_win) { doc->old_win_top = top; doc->old_win_bottom = bottom; doc->old_win_left = left; doc->old_win_right = right; doc->old_cur_entry = doc->cur_entry; doc->old_cur_col = doc->old_cur_col; } if (doc->flags & DOCF_HAS_SONG) LBts(&win_task->task_flags, TASKf_HAS_SONG); if (full_refresh) { i = num_entries - doc->max_entries; if (next_clear_found) { DocDelToEntry(doc, next_clear_found, clear_holds); DocRecalc(doc, recalc_flags); } else if (i > 1024) { DocDelToNum(doc, i); DocRecalc(doc, recalc_flags); } } DCDel(dc); Free(depth_buf); if (unlock) DocUnlock(doc); return TRUE; }