📄 atbeditor.c
字号:
char asciiChar;
int punctuation;
T_ED_LINE *line;
#ifdef TRACE_ATBEDITOR
TRACE_FUNCTION("ATB_edit_WordWrap()");
#endif
editor->endOfLine = FALSE;
line = ATB_edit_LineGet(editor, editor->numLines);
/* Get the character from the buffer */
editor->startPos = editor->thischar.pos;
character = ATB_string_GetChar(&editor->attr->text, editor->thischar.pos);
/* Find the character's dimensions */
/* If we're multi-tapping a character, or in fixed-width mode, it has the maximum width */
if (editor->multitap && editor->thischar.pos==editor->cursor.pos)
editor->thischar.width = ATB_display_GetCharWidth(UNICODE_WIDEST_CHAR, &editor->thischar.format);
else
editor->thischar.width = ATB_display_GetCharWidth(character, &editor->thischar.format); // Character width
editor->thischar.height = ATB_display_GetCharHeight(character, &editor->thischar.format);
/* Check to see if last character was a CR/LF */
if (editor->precedingEOL)
{
editor->endOfLine = TRUE;
editor->precedingEOL = FALSE;
}
else // otherwise, character included on line
{
if (editor->thischar.height > line->height) // if height>height so far...
line->height = editor->thischar.height; // ...adjust the height so far
}
/* Set flags appropriate for the character */
switch(character)
{
case UNICODE_EOLN:
editor->endOfText = TRUE; // We're at the end of the editor text
break;
case UNICODE_LINEFEED:
case UNICODE_CR:
editor->precedingEOL = TRUE; // This is an end of line
break;
default:
break;
}
/* Check if wrapping required */
if ( (editor->thischar.lineWidth+editor->thischar.width)>editor->attr->win_size.sx ) // Current character will go off edge of editor
{
editor->endOfLine = TRUE;
// If we've found a space, and it's a word wrapping mode */
if (editor->space.pos > 0 && editor->precedingSpace==FALSE
&& !ATB_edit_Mode(editor, ED_MODE_OVERWRITE))
{
editor->thischar.pos = editor->space.pos; // reset character position back to here
editor->startPos = editor->space.pos; // character is space, so start of block=character pos
editor->thischar.width = editor->space.width;
editor->thischar.height = editor->space.height;
ATB_display_CopyFormat(&editor->thischar.format,&editor->space.format);
line->height = editor->space.lineHeight;
editor->endOfText = FALSE; // If we're wrapping on an EOLN, we've gone back
}
editor->space.pos = 0; // Reset space position to start of line
editor->precedingSpace = FALSE;
}
else
{
if (editor->precedingSpace) // Remember enough info so that this point can be restored
{
editor->space.pos = editor->startPos; // Store position of start of current block, or just character pos.
editor->space.width = editor->thischar.width;
editor->space.height = editor->thischar.height;
ATB_display_CopyFormat(&editor->space.format,&editor->thischar.format);
editor->space.lineHeight = line->height;
editor->precedingSpace = FALSE;
}
punctuation = FALSE;
if (character==UNICODE_SPACE) // Wrap only on spaces
{
punctuation = TRUE;
}
if ((punctuation) && (editor->thischar.lineWidth > 0)) //A space is a good point for a soft break
{
editor->precedingSpace = TRUE;
}
}
return;
}
/*******************************************************************************
$Function: ATB_edit_UpdateCursorPos
$Description: Update the cursor's vertical position, based on its position within
the string.
$Returns: None
$Arguments: editor - The editor data
*******************************************************************************/
static void ATB_edit_UpdateCursorPos(T_ED_DATA *editor)
{
USHORT lineNo;
USHORT lineHeight;
USHORT editHeight = editor->attr->win_size.sy;
T_ED_LINE *line;
#ifdef TRACE_ATBEDITOR
TRACE_FUNCTION("ATB_edit_UpdateCursorPos()");
#endif
editor->cursor.y = 0; // Recalculate cursor Y position...
editor->viewHeight = 0; // ...and height of viewable screen...
editor->totalHeight = 0; // ...and total height of screen...
editor->viewStartPos = 0; // ...and the start pixel position of the view...
editor->linesPerScreen = 0; // ...and number of lines to the screen
lineNo = 0;
while (lineNo<editor->numLines)
{
line = ATB_edit_LineGet(editor, lineNo);
lineHeight = line->height;
if (lineNo==editor->cursor.line)
editor->cursor.y = editor->viewHeight; // Y position of cursor
if (lineNo==editor->winStartLine) // starting posn rel to start of editor text
editor->viewStartPos = editor->totalHeight;
if (lineNo>=editor->winStartLine && (editor->viewHeight+lineHeight)<=editHeight)
{
editor->viewHeight += lineHeight;
editor->linesPerScreen++;
}
editor->totalHeight += lineHeight;
lineNo++;
}
line = ATB_edit_LineGet(editor, editor->cursor.line);
editor->cursor.height = line->height; // Change its height
return;
}
/************************************/
/* GLOBAL PROCEDURES */
/* Add/removing words in the editor */
/************************************/
/*******************************************************************************
$Function: ATB_edit_InsertString
$Description: Insert a string at the cursor.
$Returns: ED_BAD_HANDLE - Editor data pointer is null
ED_OK - OK
$Arguments: editor - The editor data
insText - The text to insert
*******************************************************************************/
ED_RES ATB_edit_InsertString (T_ED_DATA *editor, T_ATB_TEXT *insText)
{
T_ATB_TEXT *text;
int textIndex;
USHORT character;
TRACE_FUNCTION("ATB_edit_InsertString()");
if (!editor) // Make sure editor exists
return ED_BAD_HANDLE;
if (insText==NULL || insText->len==0)
return ED_OK; /* No string to insert - trivial operation. */
if (ATB_edit_Mode(editor, ED_MODE_READONLY) ) /* Don't insert in read-only mode*/
return ED_ERROR;
text = &editor->attr->text;
if ((text->len+insText->len) >= editor->attr->size)
return ED_ERROR; /* String too long */
/* Move text up by the length of insText */
ATB_string_MoveRight(text, editor->cursor.pos, insText->len, editor->attr->size);
/* Copy string into buffer */
for (textIndex=0; textIndex<insText->len; textIndex++)
{
character = ATB_string_GetChar(insText, textIndex);
ATB_string_SetChar(text, editor->cursor.pos+textIndex, character);
}
editor->cursor.pos = editor->cursor.pos+insText->len;
/* Reformat updated text */
ATB_edit_Update(editor, 0);
return ED_OK;
}
/*******************************************************************************
$Function: ATB_edit_GetCursorChar
$Description: Return the character at a position offset from the current cursor
position by the value supplied.
$Returns: The character, or UNICODE_EOLN if goes beyond bounds of string.
$Arguments: editor - The editor data
offset - The offset from the current cursor position from which
to get the character
*******************************************************************************/
USHORT ATB_edit_GetCursorChar(T_ED_DATA *editor, int offset)
{
USHORT textIndex;
USHORT character;
TRACE_FUNCTION("ATB_edit_GetCursorChar");
textIndex = editor->cursor.pos+offset;
if (textIndex<0 || textIndex > editor->attr->text.len)
character = UNICODE_EOLN;
else
character = ATB_string_GetChar(&editor->attr->text, textIndex);
return character;
}
/*******************************************************************************
$Function: ATB_edit_CapitaliseWord
$Description: Returns TRUE if next word after cursor ought to be capitalised
$Returns: None.
$Arguments: editor - The editor data
*******************************************************************************/
BOOL ATB_edit_CapitaliseWord(T_ED_DATA *editor)
{
USHORT LastChar;
USHORT CharBefore;
/* First check to see if first word is to be capitalised */
if (editor->textcase==ED_CASE_CAPS)
return TRUE;
/* If not, look at preceding characters */
LastChar = ATB_edit_GetCursorChar(editor, -1);
CharBefore = ATB_edit_GetCursorChar(editor, -2);
if (LastChar==UNICODE_FULLSTOP || LastChar==UNICODE_EXCLAMATION
|| LastChar==UNICODE_QUESTION || LastChar==UNICODE_EOLN)
return TRUE;
if (LastChar==UNICODE_SPACE)
if(CharBefore==UNICODE_FULLSTOP || CharBefore==UNICODE_EXCLAMATION || CharBefore==UNICODE_QUESTION)
return TRUE;
return FALSE;
}
/*******************************************************************************
$Function: ATB_edit_FindCapital
$Description: returns the code of the input char converted to a capital. If char has no
upper case equivalent returns original char.
Added for issue 1508
$Returns: UBYTE
$Arguments: char
*******************************************************************************/
USHORT ATB_edit_FindCapital(USHORT small_char)
{ char ascii_code= ATB_char_Ascii(small_char);
/*if "normal" character*/
if (ascii_code>96 && ascii_code< 123)
return (ATB_char_Unicode(ascii_code - 0x20));
switch (ascii_code)
{
case (130): return ATB_char_Unicode(154);break;/*U with umlaut*/
case (132): return ATB_char_Unicode(142);break;/*A with umlaut*/
case (148): return ATB_char_Unicode(153);break;/*O with umlaut*/
default: return ATB_char_Unicode(ascii_code);
}
}
/*******************************************************************************
$Function: ATB_edit_HiddenInit
$Description: Initialize editor for hidden mode.
$Returns: None.
$Arguments: editor - The editor data
*******************************************************************************/
ED_RES ATB_edit_HiddenInit(T_ED_DATA *editor)
{
USHORT len = editor->attr->text.len;
TRACE_FUNCTION("ATB_edit_HiddenInit()");
if (!editor)
return ED_BAD_HANDLE; // element does not exist
if (editor->hiddenText)
return ED_ERROR;
/* get memory for the temporary buffer */
editor->hiddenText = (T_ATB_TEXT *) ATB_mem_Alloc(sizeof(T_ATB_TEXT));
editor->hiddenText->len = 0;
editor->hiddenText->data = (UBYTE *)ATB_mem_Alloc(editor->attr->size*ATB_string_Size(&editor->attr->text));
/* copy text to the temporary buffer */
ATB_string_Copy(editor->hiddenText, &editor->attr->text);
/* overwrite the string in the editor buffer with stars */
memset(editor->attr->text.data,'\0',editor->attr->size*ATB_string_Size(&editor->attr->text)); /* Clear buffer */
editor->attr->text.len = 0;
ATB_edit_Reset(editor); /* Send cursor to start */
while (editor->attr->text.len < len)
ATB_edit_AsciiChar(editor,'*',FALSE);
return ED_OK;
}
/*******************************************************************************
$Function: ATB_edit_HiddenExit
$Description: Deinitialize editor for hidden mode.
$Returns: None.
$Arguments: editor - The editor data
*******************************************************************************/
ED_RES ATB_edit_HiddenExit(T_ED_DATA *editor)
{
TRACE_FUNCTION("ATB_edit_HiddenExit()");
if (!editor)
return ED_BAD_HANDLE; // element does not exist
if (!editor->hiddenText)
return ED_ERROR;
/* For hidden mode, copy the hidden text into the buffer & free memory */
ATB_string_Copy(&editor->attr->text, editor->hiddenText);
ATB_mem_Free ((void *)editor->hiddenText->data, editor->attr->size*ATB_string_Size(editor->hiddenText));
ATB_mem_Free ((void *)editor->hiddenText, sizeof(T_ATB_TEXT));
editor->hiddenText = NULL;
return;
}
/*******************************************************************************
$Function: ATB_edit_Mode
$Description: Returns TRUE if the appropriate bits are set in the editor mode
$Returns: None.
$Arguments: editor - The editor data
mode - The mode bits to check
*******************************************************************************/
void ATB_edit_SetAttr(T_ED_DATA *editor, T_ATB_WIN_SIZE *win_size, ULONG colour, UBYTE font, USHORT mode, USHORT cursor, T_ATB_TEXT *text, USHORT size)
{
memcpy(&editor->attr->win_size, win_size, sizeof(T_ATB_WIN_SIZE));
editor->attr->colour = colour;
edito
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -