⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textdocument.cpp

📁 支持Unicode及Uniscribe的多语言输入的文本编辑器源码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		else
		{
			xpos ++;
		}
	}

	longest = max(longest, xpos);*/
	return 100;//longest;
}

//
//	Return information about specified line
//
bool TextDocument::lineinfo_from_lineno(ULONG lineno, ULONG *lineoff_chars,  ULONG *linelen_chars, ULONG *lineoff_bytes, ULONG *linelen_bytes)
{
	if(lineno < m_nNumLines)
	{
		if(linelen_chars) *linelen_chars  = m_pLineBuf_char[lineno+1] - m_pLineBuf_char[lineno];
		if(lineoff_chars) *lineoff_chars  = m_pLineBuf_char[lineno];

		if(linelen_bytes) *linelen_bytes  = m_pLineBuf_byte[lineno+1] - m_pLineBuf_byte[lineno];
		if(lineoff_bytes) *lineoff_bytes  = m_pLineBuf_byte[lineno];

		return true;
	}
	else
	{
		return false;
	}
}

//
//	Perform a reverse lookup - file-offset to line number
//
bool TextDocument::lineinfo_from_offset(ULONG offset_chars, ULONG *lineno, ULONG *lineoff_chars, ULONG *linelen_chars, ULONG *lineoff_bytes, ULONG *linelen_bytes)
{
	ULONG low  = 0;
	ULONG high = m_nNumLines-1;
	ULONG line = 0;

	if(m_nNumLines == 0)
	{
		if(lineno)			*lineno			= 0;
		if(lineoff_chars)	*lineoff_chars	= 0;
		if(linelen_chars)	*linelen_chars  = 0;
		if(lineoff_bytes)	*lineoff_bytes	= 0;
		if(linelen_bytes)	*linelen_bytes  = 0;

		return false;
	}

	while(low <= high)
	{
		line = (high + low) / 2;

		if(offset_chars >= m_pLineBuf_char[line] && offset_chars < m_pLineBuf_char[line+1])
		{
			break;
		}
		else if(offset_chars < m_pLineBuf_char[line])
		{
			high = line-1;
		}
		else
		{
			low = line+1;
		}
	}

	if(lineno)			*lineno			= line;
	if(lineoff_bytes)	*lineoff_bytes	= m_pLineBuf_byte[line];
	if(linelen_bytes)	*linelen_bytes  = m_pLineBuf_byte[line+1] - m_pLineBuf_byte[line];
	if(lineoff_chars)	*lineoff_chars  = m_pLineBuf_char[line];
	if(linelen_chars)	*linelen_chars  = m_pLineBuf_char[line+1] - m_pLineBuf_char[line];

	return true;
}

int TextDocument::getformat()
{
	return m_nFileFormat;
}

ULONG TextDocument::size()
{
	return m_nDocLength_bytes;
}

TextIterator TextDocument::iterate(ULONG offset_chars)
{
	ULONG off_bytes = charoffset_to_byteoffset(offset_chars);
	ULONG len_bytes = m_nDocLength_bytes - off_bytes;

	//if(!lineinfo_from_offset(offset_chars, 0, linelen, &offset_bytes, &length_bytes))
	//	return TextIterator();

	return TextIterator(off_bytes, len_bytes, this);
}


//
//
//
TextIterator TextDocument::iterate_line(ULONG lineno, ULONG *linestart, ULONG *linelen)
{
	ULONG offset_bytes;
	ULONG length_bytes;

	if(!lineinfo_from_lineno(lineno, linestart, linelen, &offset_bytes, &length_bytes))
		return TextIterator();
	
	return TextIterator(offset_bytes, length_bytes, this);
}

TextIterator TextDocument::iterate_line_offset(ULONG offset_chars, ULONG *lineno, ULONG *linestart)
{
	ULONG offset_bytes;
	ULONG length_bytes;

	if(!lineinfo_from_offset(offset_chars, lineno, linestart, 0, &offset_bytes, &length_bytes))
		return TextIterator();
	
	return TextIterator(offset_bytes, length_bytes, this);
}

ULONG TextDocument::lineno_from_offset(ULONG offset)
{
	ULONG lineno = 0;
	lineinfo_from_offset(offset, &lineno, 0, 0, 0, 0);
	return lineno;
}

ULONG TextDocument::offset_from_lineno(ULONG lineno)
{
	ULONG lineoff = 0;
	lineinfo_from_lineno(lineno, &lineoff, 0, 0, 0);
	return lineoff;
}

//
//	Retrieve an entire line of text
//	
ULONG TextDocument::getline(ULONG nLineNo, TCHAR *buf, ULONG buflen, ULONG *off_chars)
{
	ULONG offset_bytes;
	ULONG length_bytes;
	ULONG offset_chars;
	ULONG length_chars;

	if(!lineinfo_from_lineno(nLineNo, &offset_chars, &length_chars, &offset_bytes, &length_bytes))
	{
		*off_chars = 0;	
		return 0;
	}

	gettext(offset_bytes, length_bytes, buf, &buflen);
	
	*off_chars = offset_chars;
	return buflen;
}

//
//	Convert the RAW buffer in underlying file-format to UTF-16
//
//	
//	utf16len	- [in/out]	on input holds size of utf16str buffer, 
//							on output holds number of utf16 characters stored
//
//	returns bytes processed from rawdata
//
size_t TextDocument::rawdata_to_utf16(BYTE *rawdata, size_t rawlen, TCHAR *utf16str, size_t *utf16len)
{
	switch(m_nFileFormat)
	{
	// convert from ANSI->UNICODE
	case NCP_ASCII:
		return ascii_to_utf16(rawdata, rawlen, (UTF16 *)utf16str, utf16len);
		
	case NCP_UTF8:
		return utf8_to_utf16(rawdata, rawlen, (UTF16 *)utf16str, utf16len);

	// already unicode, do a straight memory copy
	case NCP_UTF16:
		rawlen /= sizeof(TCHAR);
		return copy_utf16((UTF16 *)rawdata, rawlen, (UTF16 *)utf16str, utf16len) * sizeof(TCHAR);

	// need to convert from big-endian to little-endian
	case NCP_UTF16BE:
		rawlen /= sizeof(TCHAR);
		return swap_utf16((UTF16 *)rawdata, rawlen, (UTF16 *)utf16str, utf16len) * sizeof(TCHAR);

	// error! we should *never* reach this point
	default:
		*utf16len = 0;
		return 0;	
	}
}

//
//	Converts specified UTF16 string to the underlying RAW format of the text-document
//	(i.e. UTF-16 -> UTF-8
//		  UTF-16 -> UTF-32 etc)
//
//	returns number of WCHARs processed from utf16str
//
size_t TextDocument::utf16_to_rawdata(TCHAR *utf16str, size_t utf16len, BYTE *rawdata, size_t *rawlen)
{
	switch(m_nFileFormat)
	{
	// convert from UTF16 -> ASCII
	case NCP_ASCII:
		return utf16_to_ascii((UTF16 *)utf16str, utf16len, rawdata, rawlen);
		
	// convert from UTF16 -> UTF8
	case NCP_UTF8:
		return utf16_to_utf8((UTF16 *)utf16str, utf16len, rawdata, rawlen);

	// already unicode, do a straight memory copy
	case NCP_UTF16:
		*rawlen /= sizeof(TCHAR);
		utf16len = copy_utf16((UTF16 *)utf16str, utf16len, (UTF16 *)rawdata, rawlen);
		*rawlen *= sizeof(TCHAR);
		return utf16len;

	// need to convert from big-endian to little-endian
	case NCP_UTF16BE:
		*rawlen /= sizeof(TCHAR);
		utf16len = swap_utf16((UTF16 *)utf16str, utf16len, (UTF16 *)rawdata, rawlen);
		*rawlen *= sizeof(TCHAR);
		return utf16len;

	// error! we should *never* reach this point
	default:
		*rawlen = 0;
		return 0;	
	}

}

//
//	Insert UTF-16 text at specified BYTE offset
//
//	returns number of BYTEs stored
//
ULONG TextDocument::insert_raw(ULONG offset_bytes, TCHAR *text, ULONG length)
{
	BYTE  buf[0x100];
	ULONG buflen;
	ULONG copied;
	ULONG rawlen = 0;
	ULONG offset = offset_bytes+ m_nHeaderSize;

	while(length)
	{
		buflen = 0x100;
		copied = utf16_to_rawdata(text, length, buf, (size_t *)&buflen);

		// do the piece-table insertion!
		if(!m_seq.insert(offset, buf, buflen))
			break;

		text   += copied;
		length -= copied;
		rawlen += buflen;
		offset += buflen;
	}

	m_nDocLength_bytes = m_seq.size();
	return rawlen;
}

ULONG TextDocument::replace_raw(ULONG offset_bytes, TCHAR *text, ULONG length, ULONG erase_chars)
{
	BYTE  buf[0x100];
	ULONG buflen;
	ULONG copied;
	ULONG rawlen = 0;
	ULONG offset = offset_bytes + m_nHeaderSize;

	ULONG erase_bytes = count_chars(offset_bytes, erase_chars);

	while(length)
	{
		buflen = 0x100;
		copied = utf16_to_rawdata(text, length, buf, (size_t *)&buflen);

		// do the piece-table replacement!
		if(!m_seq.replace(offset, buf, buflen, erase_bytes))
			break;

		text   += copied;
		length -= copied;
		rawlen += buflen;
		offset += buflen;

		erase_bytes = 0;
	}

	m_nDocLength_bytes = m_seq.size();
	return rawlen;
}

//
//	Erase is a little different. Need to work out how many
//  bytes the specified number of UTF16 characters takes up
//
ULONG TextDocument::erase_raw(ULONG offset_bytes, ULONG length)
{
	/*TCHAR  buf[0x100];
	ULONG  buflen;
	ULONG  bytes;
	ULONG  erase_bytes  = 0;
	ULONG  erase_offset = offset_bytes;

	while(length)
	{
		buflen = min(0x100, length);
		bytes = gettext(offset_bytes, 0x100, buf, &buflen); 

		erase_bytes  += bytes;
		offset_bytes += bytes;
		length       -= buflen;
	}

	// do the piece-table deletion!
	if(m_seq.erase(erase_offset + m_nHeaderSize, erase_bytes))
	{
		m_nDocLength_bytes = m_seq.size();
		return length;
	}*/

	ULONG erase_bytes  = count_chars(offset_bytes, length);
	
	if(m_seq.erase(offset_bytes + m_nHeaderSize, erase_bytes))
	{
		m_nDocLength_bytes = m_seq.size();
		return length;
	}
		
	return 0;
}

//
//	return number of bytes comprising 'length_chars' characters
//	in the underlying raw file
//
ULONG TextDocument::count_chars(ULONG offset_bytes, ULONG length_chars)
{
	switch(m_nFileFormat)
	{
	case NCP_ASCII:
		return length_chars;

	case NCP_UTF16:
	case NCP_UTF16BE:
		return length_chars * sizeof(WCHAR);

	default:
		break;
	}

	ULONG offset_start = offset_bytes;

	while(length_chars && offset_bytes < m_nDocLength_bytes)
	{
		TCHAR buf[0x100];
		ULONG charlen = min(length_chars, 0x100);
		ULONG bytelen;

		bytelen = gettext(offset_bytes, m_nDocLength_bytes - offset_bytes, buf, &charlen);

		length_chars -= charlen;
		offset_bytes += bytelen;
	}

	return offset_bytes - offset_start;
}

ULONG TextDocument::byteoffset_to_charoffset(ULONG offset_bytes)
{
	switch(m_nFileFormat)
	{
	case NCP_ASCII:
		return offset_bytes;

	case NCP_UTF16:
	case NCP_UTF16BE:
		return offset_bytes / sizeof(WCHAR);

	case NCP_UTF8:
	case NCP_UTF32:
	case NCP_UTF32BE:
		// bug bug! need to implement this. 
	default:
		break;
	}

	return 0;
}

ULONG TextDocument::charoffset_to_byteoffset(ULONG offset_chars)
{
	switch(m_nFileFormat)
	{
	case NCP_ASCII:
		return offset_chars;

	case NCP_UTF16:
	case NCP_UTF16BE:
		return offset_chars * sizeof(WCHAR);

	case NCP_UTF8:
	case NCP_UTF32:
	case NCP_UTF32BE:
	default:
		break;
	}

	ULONG lineoff_chars;
	ULONG lineoff_bytes;

	if(lineinfo_from_offset(offset_chars, 0, &lineoff_chars, 0, &lineoff_bytes, 0))
	{
		return count_chars(lineoff_bytes, offset_chars - lineoff_chars) 
				+ lineoff_bytes;
	}
	else
	{
		return 0;
	}
}

//
//	Insert text at specified character-offset
//
ULONG TextDocument::insert_text(ULONG offset_chars, TCHAR *text, ULONG length)
{
	ULONG offset_bytes = charoffset_to_byteoffset(offset_chars);
	return insert_raw(offset_bytes, text, length);
}

//
//	Overwrite text at specified character-offset
//
ULONG TextDocument::replace_text(ULONG offset_chars, TCHAR *text, ULONG length, ULONG erase_len)
{
	ULONG offset_bytes = charoffset_to_byteoffset(offset_chars);
	return replace_raw(offset_bytes, text, length, erase_len);
}

//
//	Erase text at specified character-offset
//
ULONG TextDocument::erase_text(ULONG offset_chars, ULONG length)
{
	ULONG offset_bytes = charoffset_to_byteoffset(offset_chars);
	return erase_raw(offset_bytes, length);
}

bool TextDocument::Undo(ULONG *offset_start, ULONG *offset_end)
{
	ULONG start, length;

	if(!m_seq.undo())
		return false;

	start  = m_seq.event_index() - m_nHeaderSize;
	length = m_seq.event_length();

	*offset_start = byteoffset_to_charoffset(start);
	*offset_end   = byteoffset_to_charoffset(start+length);

	m_nDocLength_bytes = m_seq.size();
	
	return true;
}

bool TextDocument::Redo(ULONG *offset_start, ULONG *offset_end)
{
	ULONG start, length;

	if(!m_seq.redo())
		return false;

	start  = m_seq.event_index() - m_nHeaderSize;
	length = m_seq.event_length();

	*offset_start = byteoffset_to_charoffset(start);
	*offset_end   = byteoffset_to_charoffset(start+length);
	
	m_nDocLength_bytes = m_seq.size();

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -