https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b41299470b8d5d7fe43a90...
commit b41299470b8d5d7fe43a90e9d9bc16ab428b5652 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Jan 12 22:04:57 2020 +0900 Commit: GitHub noreply@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);