https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b41299470b8d5d7fe43a9…
commit b41299470b8d5d7fe43a90e9d9bc16ab428b5652
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Jan 12 22:04:57 2020 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Jan 12 22:04:57 2020 +0900
[WIN32SS][WINSRV] Fullwidth character handling Part 2 (#2240)
Follow-up of #2231. Also fix FillConsoleOutputAttribute, WriteConsoleOutputCharacterW
and WriteConsoleOutputAttribute functions.
CORE-12451
---
win32ss/user/winsrv/consrv/condrv/text.c | 310 ++++++++++++++-------
win32ss/user/winsrv/consrv/frontends/gui/conwnd.c | 13 +-
win32ss/user/winsrv/consrv/frontends/gui/guiterm.h | 7 -
win32ss/user/winsrv/consrv/frontends/gui/text.c | 152 ++++++----
win32ss/user/winsrv/consrv/frontends/terminal.c | 11 +
5 files changed, 316 insertions(+), 177 deletions(-)
diff --git a/win32ss/user/winsrv/consrv/condrv/text.c
b/win32ss/user/winsrv/consrv/condrv/text.c
index de0c740e58f..92a6f4dfcfa 100644
--- a/win32ss/user/winsrv/consrv/condrv/text.c
+++ b/win32ss/user/winsrv/consrv/condrv/text.c
@@ -14,6 +14,8 @@
#define NDEBUG
#include <debug.h>
+#define COMMON_LEAD_TRAIL (COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE)
+
/* GLOBALS ********************************************************************/
/*
@@ -512,8 +514,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
WideCharToMultiByte(Console->OutputCodePage, 0,
&Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
- CurCharInfo->Attributes =
- (Ptr->Attributes & ~(COMMON_LVB_LEADING_BYTE |
COMMON_LVB_TRAILING_BYTE));
+ CurCharInfo->Attributes = (Ptr->Attributes & ~COMMON_LEAD_TRAIL);
++Ptr;
++CurCharInfo;
}
@@ -734,7 +735,7 @@ IntReadConsoleOutputStringAscii(IN PCONSOLE Console,
SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) %
Buffer->ScreenBufferSize.Y;
ULONG i;
PCHAR_INFO Ptr;
- BOOL bCJK = Console->IsCJK;
+ BOOLEAN bCJK = Console->IsCJK;
for (i = 0; i < NumCodesToRead; ++i)
{
@@ -791,7 +792,7 @@ IntReadConsoleOutputStringUnicode(IN PCONSOLE Console,
SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) %
Buffer->ScreenBufferSize.Y;
ULONG i, nNumChars = 0;
PCHAR_INFO Ptr;
- BOOL bCJK = Console->IsCJK;
+ BOOLEAN bCJK = Console->IsCJK;
for (i = 0; i < NumCodesToRead; ++i, ++nNumChars)
{
@@ -932,138 +933,236 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
}
}
-NTSTATUS NTAPI
-ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
- IN PTEXTMODE_SCREEN_BUFFER Buffer,
- IN CODE_TYPE CodeType,
- IN PVOID StringBuffer,
- IN ULONG NumCodesToWrite,
- IN PCOORD WriteCoord,
- // OUT PCOORD EndCoord,
- OUT PULONG NumCodesWritten OPTIONAL)
+static NTSTATUS
+IntWriteConsoleOutputStringUnicode(
+ IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PVOID StringBuffer,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
- PVOID WriteBuffer = NULL;
- PWCHAR tmpString = NULL;
- ULONG X, Y, Length; // , Written = 0;
- ULONG CodeSize;
+ PWCHAR WriteBuffer = StringBuffer;
+ ULONG i, X, Y, Length;
PCHAR_INFO Ptr;
+ BOOLEAN bCJK = Console->IsCJK;
- if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL
*/)
- {
- return STATUS_INVALID_PARAMETER;
- }
+ if (!StringBuffer)
+ goto Cleanup;
- /* Validity checks */
- ASSERT(Console == Buffer->Header.Console);
- ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite ==
0));
-
- //
- // FIXME: Make overflow checks on WriteCoord !!!!!!
- //
-
- if (NumCodesWritten) *NumCodesWritten = 0;
+ X = WriteCoord->X;
+ Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
+ Length = NumCodesToWrite;
- switch (CodeType)
+ for (i = 0; i < Length; ++i)
{
- case CODE_ASCII:
- CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
- break;
-
- case CODE_UNICODE:
- CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
- break;
-
- case CODE_ATTRIBUTE:
- CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
- break;
+ Ptr = ConioCoordToPointer(Buffer, X, Y);
- default:
- return STATUS_INVALID_PARAMETER;
- }
+ Ptr->Char.UnicodeChar = *WriteBuffer;
+ ++WriteBuffer;
- if (CodeType == CODE_ASCII)
- {
- /* Convert the ASCII string into Unicode before writing it to the console */
- Length = MultiByteToWideChar(Console->OutputCodePage, 0,
- (PCHAR)StringBuffer,
- NumCodesToWrite,
- NULL, 0);
- tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length *
sizeof(WCHAR));
- if (WriteBuffer)
+ ++X;
+ if (X == Buffer->ScreenBufferSize.X)
{
- MultiByteToWideChar(Console->OutputCodePage, 0,
- (PCHAR)StringBuffer,
- NumCodesToWrite,
- (PWCHAR)WriteBuffer, Length);
+ X = 0;
+ ++Y;
+ if (Y == Buffer->ScreenBufferSize.Y)
+ {
+ Y = 0;
+ }
}
- else
+
+ /* For Chinese, Japanese and Korean */
+ if (bCJK && Ptr->Char.UnicodeChar >= 0x80 &&
+ mk_wcwidth_cjk(Ptr->Char.UnicodeChar) == 2)
{
- Status = STATUS_NO_MEMORY;
- }
+ /* A full-width character cannot cross a line boundary */
+ if (X == Buffer->ScreenBufferSize.X - 1)
+ {
+ /* go to next line */
+ X = 0;
+ ++Y;
+ if (Y == Buffer->ScreenBufferSize.Y)
+ {
+ Y = 0;
+ }
+ Ptr = ConioCoordToPointer(Buffer, X, Y);
+ }
- // FIXME: Quick fix: fix the CodeType and CodeSize since the
- // ASCII string was converted into UNICODE.
- // A proper fix needs to be written.
- CodeType = CODE_UNICODE;
- CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
+ /* the leading byte */
+ Ptr->Attributes = Buffer->ScreenDefaultAttrib;
+ Ptr->Attributes |= COMMON_LVB_LEADING_BYTE;
+ ++i;
+
+ /* the trailing byte */
+ Ptr = ConioCoordToPointer(Buffer, X, Y);
+ Ptr->Attributes = Buffer->ScreenDefaultAttrib;
+ Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE;
+
+ ++X;
+ if (X == Buffer->ScreenBufferSize.X)
+ {
+ X = 0;
+ ++Y;
+ if (Y == Buffer->ScreenBufferSize.Y)
+ {
+ Y = 0;
+ }
+ }
+ }
}
- else
+
+Cleanup:
+ if (NumCodesWritten)
+ *NumCodesWritten = NumCodesToWrite;
+ return Status;
+}
+
+static NTSTATUS
+IntWriteConsoleOutputStringAscii(
+ IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PVOID StringBuffer,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
+{
+ NTSTATUS Status;
+ PWCHAR tmpString;
+ ULONG Length;
+
+ if (!StringBuffer)
{
- /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
- WriteBuffer = StringBuffer;
+ if (NumCodesWritten)
+ *NumCodesWritten = NumCodesToWrite;
+
+ return STATUS_SUCCESS;
}
- if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
+ /* Convert the ASCII string into Unicode before writing it to the console */
+ Length = MultiByteToWideChar(Console->OutputCodePage, 0,
+ StringBuffer,
+ NumCodesToWrite,
+ NULL, 0);
+ tmpString = ConsoleAllocHeap(0, Length * sizeof(WCHAR));
+ if (!tmpString)
+ return STATUS_NO_MEMORY;
+
+ MultiByteToWideChar(Console->OutputCodePage, 0,
+ StringBuffer,
+ NumCodesToWrite,
+ tmpString, Length);
+
+ Status = IntWriteConsoleOutputStringUnicode(Console,
+ Buffer,
+ tmpString,
+ Length,
+ WriteCoord,
+ NumCodesWritten);
+ ConsoleFreeHeap(tmpString);
+ return Status;
+}
+
+static NTSTATUS
+IntWriteConsoleOutputStringAttribute(
+ IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PVOID StringBuffer,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PWORD WriteBuffer = StringBuffer;
+ ULONG i, X, Y, Length;
+ PCHAR_INFO Ptr;
+
+ if (!StringBuffer)
+ goto Cleanup;
X = WriteCoord->X;
Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
Length = NumCodesToWrite;
- while (Length--)
+ for (i = 0; i < Length; ++i)
{
Ptr = ConioCoordToPointer(Buffer, X, Y);
- switch (CodeType)
- {
- case CODE_ASCII:
- case CODE_UNICODE:
- Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer;
- break;
-
- case CODE_ATTRIBUTE:
- Ptr->Attributes = *(PWORD)WriteBuffer;
- break;
- }
- WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize);
- // ++Ptr;
+ Ptr->Attributes = (*WriteBuffer & ~COMMON_LEAD_TRAIL);
+ ++WriteBuffer;
- // Written++;
- if (++X == Buffer->ScreenBufferSize.X)
+ ++X;
+ if (X == Buffer->ScreenBufferSize.X)
{
X = 0;
-
- if (++Y == Buffer->ScreenBufferSize.Y)
+ ++Y;
+ if (Y == Buffer->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
+Cleanup:
+ if (NumCodesWritten)
+ *NumCodesWritten = NumCodesToWrite;
+ return Status;
+}
+
+NTSTATUS NTAPI
+ConDrvWriteConsoleOutputString(
+ IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN CODE_TYPE CodeType,
+ IN PVOID StringBuffer,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
+{
+ NTSTATUS Status;
+ SMALL_RECT UpdateRect;
+
+ if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL
*/)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validity checks */
+ ASSERT(Console == Buffer->Header.Console);
+ ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite ==
0));
+
+ if (NumCodesWritten)
+ *NumCodesWritten = 0;
+
+ switch (CodeType)
+ {
+ case CODE_ASCII:
+ Status = IntWriteConsoleOutputStringAscii(
+ Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord,
NumCodesWritten);
+ break;
+
+ case CODE_UNICODE:
+ Status = IntWriteConsoleOutputStringUnicode(
+ Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord,
NumCodesWritten);
+ break;
+
+ case CODE_ATTRIBUTE:
+ Status = IntWriteConsoleOutputStringAttribute(
+ Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord,
NumCodesWritten);
+ break;
+
+ default:
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
- SMALL_RECT UpdateRect;
ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
TermDrawRegion(Console, &UpdateRect);
}
- // EndCoord->X = X;
- // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) %
Buffer->ScreenBufferSize.Y;
-
-Cleanup:
- if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
-
- if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
return Status;
}
@@ -1078,7 +1177,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
{
ULONG X, Y, i;
PCHAR_INFO Ptr;
- BOOL bLead, bFullwidth;
+ BOOLEAN bLead, bFullwidth;
if (Console == NULL || Buffer == NULL || WriteCoord == NULL)
{
@@ -1133,7 +1232,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = Code.UnicodeChar;
- Ptr->Attributes &= ~(COMMON_LVB_LEADING_BYTE |
COMMON_LVB_TRAILING_BYTE);
+ Ptr->Attributes &= ~COMMON_LEAD_TRAIL;
if (bFullwidth)
{
if (bLead)
@@ -1144,18 +1243,17 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
break;
case CODE_ATTRIBUTE:
- Ptr->Attributes &= ~0xFF;
- Ptr->Attributes |= (Code.Attribute & 0xFF);
+ Ptr->Attributes &= ~COMMON_LEAD_TRAIL;
+ Ptr->Attributes |= (Code.Attribute & ~COMMON_LEAD_TRAIL);
break;
}
- // ++Ptr;
- // Written++;
- if (++X == Buffer->ScreenBufferSize.X)
+ ++X;
+ if (X == Buffer->ScreenBufferSize.X)
{
X = 0;
-
- if (++Y == Buffer->ScreenBufferSize.Y)
+ ++Y;
+ if (Y == Buffer->ScreenBufferSize.Y)
{
Y = 0;
}
@@ -1170,7 +1268,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
{
Ptr = ConioCoordToPointer(Buffer, X - 1, Y);
Ptr->Char.UnicodeChar = L' ';
- Ptr->Attributes &= ~(COMMON_LVB_LEADING_BYTE |
COMMON_LVB_TRAILING_BYTE);
+ Ptr->Attributes &= ~COMMON_LEAD_TRAIL;
}
}
diff --git a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
index eda0e822861..633317cd039 100644
--- a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
+++ b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
@@ -991,17 +991,8 @@ OnPaint(PGUI_CONSOLE_DATA GuiData)
/* Compose the current screen-buffer on-memory */
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
- if (IsCJKCodePage(ActiveBuffer->Header.Console->OutputCodePage))
- {
- /* For Chinese, Japanese and Korean */
- GuiPaintTextModeBufferCJK((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer,
- GuiData, &ps.rcPaint, &rcPaint);
- }
- else
- {
- GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer,
- GuiData, &ps.rcPaint, &rcPaint);
- }
+ GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer,
+ GuiData, &ps.rcPaint, &rcPaint);
}
else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
{
diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h
b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h
index 2e4a6dfd90f..4ed6c1e8c19 100644
--- a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h
+++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h
@@ -121,11 +121,4 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PRECT rcView,
PRECT rcFramebuffer);
-/* For Chinese, Japanese and Korean */
-VOID
-GuiPaintTextModeBufferCJK(PTEXTMODE_SCREEN_BUFFER Buffer,
- PGUI_CONSOLE_DATA GuiData,
- PRECT rcView,
- PRECT rcFramebuffer);
-
/* EOF */
diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c
b/win32ss/user/winsrv/consrv/frontends/gui/text.c
index 8b12645df77..1751dfeb865 100644
--- a/win32ss/user/winsrv/consrv/frontends/gui/text.c
+++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c
@@ -405,54 +405,88 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL];
OldFont = SelectObject(GuiData->hMemDC, NewFont);
- for (Line = TopLine; Line <= BottomLine; Line++)
+ if (Console->IsCJK)
{
- WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be
displayed
- From = ConioCoordToPointer(Buffer, LeftColumn, Line); // Get the first code of
the line
- Start = LeftColumn;
- To = LineBuffer;
-
- for (Char = LeftColumn; Char <= RightColumn; Char++)
+ for (Line = TopLine; Line <= BottomLine; Line++)
{
- /*
- * We flush the buffer if the new attribute is different
- * from the current one, or if the buffer is full.
- */
- if (From->Attributes != LastAttribute || (Char - Start ==
sizeof(LineBuffer) / sizeof(WCHAR)))
+ for (Char = LeftColumn; Char <= RightColumn; Char++)
{
- TextOutW(GuiData->hMemDC,
- Start * GuiData->CharWidth,
- Line * GuiData->CharHeight,
- LineBuffer,
- Char - Start);
- Start = Char;
- To = LineBuffer;
+ From = ConioCoordToPointer(Buffer, Char, Line);
Attribute = From->Attributes;
- if (Attribute != LastAttribute)
+ SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
TextAttribFromAttrib(Attribute)));
+ SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
BkgdAttribFromAttrib(Attribute)));
+
+ /* Change underline state if needed */
+ if (!!(Attribute & COMMON_LVB_UNDERSCORE) != IsUnderline)
{
- LastAttribute = Attribute;
- SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
TextAttribFromAttrib(LastAttribute)));
- SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
BkgdAttribFromAttrib(LastAttribute)));
+ IsUnderline = !!(Attribute & COMMON_LVB_UNDERSCORE);
+
+ /* Select the new font */
+ NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL];
+ SelectObject(GuiData->hMemDC, NewFont);
+ }
+
+ if (Attribute & COMMON_LVB_TRAILING_BYTE)
+ continue;
+
+ TextOutW(GuiData->hMemDC,
+ Char * GuiData->CharWidth,
+ Line * GuiData->CharHeight,
+ &From->Char.UnicodeChar, 1);
+ }
+ }
+ }
+ else
+ {
+ for (Line = TopLine; Line <= BottomLine; Line++)
+ {
+ WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be
displayed
+ From = ConioCoordToPointer(Buffer, LeftColumn, Line); // Get the first code
of the line
+ Start = LeftColumn;
+ To = LineBuffer;
- /* Change underline state if needed */
- if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderline)
+ for (Char = LeftColumn; Char <= RightColumn; Char++)
+ {
+ /*
+ * We flush the buffer if the new attribute is different
+ * from the current one, or if the buffer is full.
+ */
+ if (From->Attributes != LastAttribute || (Char - Start ==
sizeof(LineBuffer) / sizeof(WCHAR)))
+ {
+ TextOutW(GuiData->hMemDC,
+ Start * GuiData->CharWidth,
+ Line * GuiData->CharHeight,
+ LineBuffer,
+ Char - Start);
+ Start = Char;
+ To = LineBuffer;
+ Attribute = From->Attributes;
+ if (Attribute != LastAttribute)
{
- IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
- /* Select the new font */
- NewFont = GuiData->Font[IsUnderline ? FONT_BOLD :
FONT_NORMAL];
- /* OldFont = */ SelectObject(GuiData->hMemDC, NewFont);
+ LastAttribute = Attribute;
+ SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
TextAttribFromAttrib(LastAttribute)));
+ SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console,
BkgdAttribFromAttrib(LastAttribute)));
+
+ /* Change underline state if needed */
+ if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) !=
IsUnderline)
+ {
+ IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
+ /* Select the new font */
+ NewFont = GuiData->Font[IsUnderline ? FONT_BOLD :
FONT_NORMAL];
+ SelectObject(GuiData->hMemDC, NewFont);
+ }
}
}
+
+ *(To++) = (From++)->Char.UnicodeChar;
}
- *(To++) = (From++)->Char.UnicodeChar;
+ TextOutW(GuiData->hMemDC,
+ Start * GuiData->CharWidth,
+ Line * GuiData->CharHeight,
+ LineBuffer,
+ RightColumn - Start + 1);
}
-
- TextOutW(GuiData->hMemDC,
- Start * GuiData->CharWidth,
- Line * GuiData->CharHeight,
- LineBuffer,
- RightColumn - Start + 1);
}
/* Restore the old font */
@@ -479,12 +513,35 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
CursorBrush = CreateSolidBrush(PaletteRGBFromAttrib(Console,
TextAttribFromAttrib(Attribute)));
OldBrush = SelectObject(GuiData->hMemDC, CursorBrush);
- PatBlt(GuiData->hMemDC,
- CursorX * GuiData->CharWidth,
- CursorY * GuiData->CharHeight + (GuiData->CharHeight -
CursorHeight),
- GuiData->CharWidth,
- CursorHeight,
- PATCOPY);
+ if (Attribute & COMMON_LVB_LEADING_BYTE)
+ {
+ /* The caret is on the leading byte */
+ PatBlt(GuiData->hMemDC,
+ CursorX * GuiData->CharWidth,
+ CursorY * GuiData->CharHeight + (GuiData->CharHeight -
CursorHeight),
+ GuiData->CharWidth * 2,
+ CursorHeight,
+ PATCOPY);
+ }
+ else if (Attribute & COMMON_LVB_TRAILING_BYTE)
+ {
+ /* The caret is on the trailing byte */
+ PatBlt(GuiData->hMemDC,
+ (CursorX - 1) * GuiData->CharWidth,
+ CursorY * GuiData->CharHeight + (GuiData->CharHeight -
CursorHeight),
+ GuiData->CharWidth * 2,
+ CursorHeight,
+ PATCOPY);
+ }
+ else
+ {
+ PatBlt(GuiData->hMemDC,
+ CursorX * GuiData->CharWidth,
+ CursorY * GuiData->CharHeight + (GuiData->CharHeight -
CursorHeight),
+ GuiData->CharWidth,
+ CursorHeight,
+ PATCOPY);
+ }
SelectObject(GuiData->hMemDC, OldBrush);
DeleteObject(CursorBrush);
@@ -494,15 +551,4 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
LeaveCriticalSection(&Console->Lock);
}
-/* For Chinese, Japanese and Korean */
-VOID
-GuiPaintTextModeBufferCJK(PTEXTMODE_SCREEN_BUFFER Buffer,
- PGUI_CONSOLE_DATA GuiData,
- PRECT rcView,
- PRECT rcFramebuffer)
-{
- /* FIXME */
- GuiPaintTextModeBuffer(Buffer, GuiData, rcView, rcFramebuffer);
-}
-
/* EOF */
diff --git a/win32ss/user/winsrv/consrv/frontends/terminal.c
b/win32ss/user/winsrv/consrv/frontends/terminal.c
index 6603d844050..bae13a880a2 100644
--- a/win32ss/user/winsrv/consrv/frontends/terminal.c
+++ b/win32ss/user/winsrv/consrv/frontends/terminal.c
@@ -558,6 +558,17 @@ ConioWriteConsole(PFRONTEND FrontEnd,
}
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X,
Buff->CursorPosition.Y);
Ptr->Char.UnicodeChar = L' ';
+
+ if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE)
+ {
+ /* Delete a full-width character */
+ Ptr->Attributes = Buff->ScreenDefaultAttrib;
+ if (Buff->CursorPosition.X > 0)
+ Buff->CursorPosition.X--;
+ Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X,
Buff->CursorPosition.Y);
+ Ptr->Char.UnicodeChar = L' ';
+ }
+
Ptr->Attributes = Buff->ScreenDefaultAttrib;
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);