diff options
author | elfmz <fenix1905@tut.by> | 2022-11-05 20:31:53 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-05 20:31:53 +0300 |
commit | 253a6b140797e035eb9301a1632fed2408a837e2 (patch) | |
tree | ed6be316904b5d5ff11b7bfa46e7037fc2ec51d5 /far2l/src/flshow.cpp | |
parent | 89eaed71c674aadda536408638e3416bc7f4c053 (diff) |
support full-width/composite characters and true color palette in terminal (#1386)
Added normal support for full-width (CJK etc) and composite (using diacritics) characters.
IMPORTANT: WINPORT API changed in binary incompatible way in order to implement this.
Diffstat (limited to 'far2l/src/flshow.cpp')
-rw-r--r-- | far2l/src/flshow.cpp | 180 |
1 files changed, 84 insertions, 96 deletions
diff --git a/far2l/src/flshow.cpp b/far2l/src/flshow.cpp index fcb179bf..a0358518 100644 --- a/far2l/src/flshow.cpp +++ b/far2l/src/flshow.cpp @@ -97,7 +97,7 @@ void FileList::ShowFileList(int Fast) FARString strTitle; FARString strInfoCurDir; - int Length; + int Cells; OpenPluginInfo Info; if (PanelMode==PLUGIN_PANEL) @@ -127,7 +127,7 @@ void FileList::ShowFileList(int Fast) // SetScreen(X1+1,Y1+1,X2-1,Y1+1,' ',COL_PANELTEXT); SetColor(COL_PANELTEXT); //??? //GotoXY(X1+1,Y1+1); - //FS<<fmt::Width(X2-X1-1)<<L""; + //FS<<fmt::Expand(X2-X1-1)<<L""; } for (int I=0,ColumnPos=X1+1; I<ViewSettings.ColumnCount; I++) @@ -203,7 +203,7 @@ void FileList::ShowFileList(int Fast) CenterStr(strTitle,strTitleMsg,ViewSettings.ColumnWidth[I]); SetColor(COL_PANELCOLUMNTITLE); GotoXY(ColumnPos,Y1+1); - FS<<fmt::Precision(ViewSettings.ColumnWidth[I])<<strTitleMsg; + FS << fmt::Cells() << fmt::Truncate(ViewSettings.ColumnWidth[I]) << strTitleMsg; } if (I>=ViewSettings.ColumnCount-1) @@ -343,7 +343,7 @@ void FileList::ShowFileList(int Fast) TruncSize-=2; GetTitle(strTitle,TruncSize,2);//,(PanelMode==PLUGIN_PANEL?0:2)); - Length=(int)strTitle.GetLength(); + Cells=(int)strTitle.CellsCount(); int ClockCorrection=FALSE; if ((Opt.Clock && !Opt.ShowMenuBar) && TitleX2==ScrX-4) @@ -352,11 +352,11 @@ void FileList::ShowFileList(int Fast) TitleX2+=4; } - int TitleX=X1+(TitleX2-X1+1-Length)/2; + int TitleX=X1+(TitleX2-X1+1-Cells)/2; if (ClockCorrection) { - int Overlap=TitleX+Length-TitleX2+5; + int Overlap=TitleX+Cells-TitleX2+5; if (Overlap > 0) TitleX-=Overlap; @@ -374,7 +374,7 @@ void FileList::ShowFileList(int Fast) SetScreen(X1+1,Y2-1,X2-1,Y2-1,L' ',COL_PANELTEXT); SetColor(COL_PANELTEXT); //??? //GotoXY(X1+1,Y2-1); - //FS<<fmt::Width(X2-X1-1)<<L""; + //FS<<fmt::Expand(X2-X1-1)<<L""; } if (PanelMode==PLUGIN_PANEL && FileCount>0 && (Info.Flags & OPIF_REALNAMES)) @@ -559,9 +559,9 @@ void FileList::ShowTotalSize(OpenPluginInfo &Info) Text(strTotalStr); else { - FS<<fmt::Precision(BoxPos)<<strTotalStr; + FS << fmt::Cells() << fmt::Truncate(BoxPos) << strTotalStr; SetColor(COL_PANELBOX); - FS<<fmt::Precision(BoxLength)<<strTotalStr.CPtr()+BoxPos; + FS << fmt::Cells() << fmt::Truncate(BoxLength) << strTotalStr.CPtr() + BoxPos; SetColor(COL_PANELTOTALINFO); Text(strTotalStr.CPtr()+BoxPos+BoxLength); } @@ -589,14 +589,14 @@ int FileList::ConvertName(const wchar_t *SrcName,FARString &strDest,int MaxLengt } } - wchar_t *lpwszDest = strDest.GetBuffer(MaxLength+1); - wmemset(lpwszDest,L' ',MaxLength); - int SrcLength=StrLength(SrcName); + int SrcLength = StrLength(SrcName); + int SrcVisualLength = StrCellsCount(SrcName, SrcLength); - if (RightAlign && SrcLength>MaxLength) + if (RightAlign && SrcVisualLength > MaxLength) { - wmemcpy(lpwszDest,SrcName+SrcLength-MaxLength,MaxLength); - strDest.ReleaseBuffer(MaxLength); + size_t SkipCells = SrcVisualLength - MaxLength; + size_t SkipOfs = StrSizeOfCells(SrcName, SrcLength, SkipCells, true); + strDest.Copy(SrcName + SkipOfs, SrcLength - SkipOfs); return TRUE; } @@ -604,7 +604,7 @@ int FileList::ConvertName(const wchar_t *SrcName,FARString &strDest,int MaxLengt if (!ShowStatus && ((!(FileAttr&FILE_ATTRIBUTE_DIRECTORY) && ViewSettings.AlignExtensions) || ((FileAttr&FILE_ATTRIBUTE_DIRECTORY) && ViewSettings.FolderAlignExtensions)) - && SrcLength<=MaxLength && + && SrcVisualLength<=MaxLength && (DotPtr=wcsrchr(SrcName,L'.')) && DotPtr!=SrcName && (SrcName[0]!=L'.' || SrcName[2]) && !wcschr(DotPtr+1,L' ')) { @@ -615,20 +615,23 @@ int FileList::ConvertName(const wchar_t *SrcName,FARString &strDest,int MaxLengt if (DotPos<=NameLength) DotPos=NameLength+1; - if (DotPos>0 && NameLength>0 && SrcName[NameLength-1]==L' ') - lpwszDest[NameLength]=L'.'; - - wmemcpy(lpwszDest,SrcName,NameLength); - wmemcpy(lpwszDest+DotPos,DotPtr+1,DotLength); + strDest.Copy(SrcName, NameLength); + strDest.Append(L'.'); + strDest.Append(DotPtr+1,DotLength); } else { - wmemcpy(lpwszDest,SrcName,Min(SrcLength, MaxLength)); + size_t CellsCount = MaxLength; + size_t CopyLen = StrSizeOfCells(SrcName, SrcLength, CellsCount, false); + strDest.Copy(SrcName, CopyLen); } - strDest.ReleaseBuffer(MaxLength); - - return(SrcLength>MaxLength); + const size_t CopiedCellsCount = strDest.CellsCount(); + if (CopiedCellsCount < size_t(MaxLength)) { + strDest.Append(L' ', size_t(MaxLength - CopiedCellsCount)); + } + + return (SrcVisualLength > MaxLength); } @@ -884,6 +887,24 @@ int FileList::PrepareColumnWidths(unsigned int *ColumnTypes,int *ColumnWidths, extern void GetColor(int PaletteIndex); +static int MakeCurLeftPos(int ColumnWidth, const wchar_t *Str, int LeftPos, int &MaxLeftPos) +{ + int Cells = Str ? StrZCellsCount(Str) : 0; + if (Cells < ColumnWidth || !Cells) + return 0; + + if (LeftPos > Cells - ColumnWidth) + LeftPos = Cells - ColumnWidth; + + size_t ng = LeftPos; + int out = StrSizeOfCells(Str, wcslen(Str), ng, false); + + if (MaxLeftPos < (int)ng) + MaxLeftPos = (int)ng; + + return out; +} + void FileList::ShowList(int ShowStatus,int StartColumn) { int StatusShown=FALSE; @@ -971,21 +992,10 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (!ShowStatus && LeftPos>0) { - int Length=StrLength(ColumnData); - - if (Length>ColumnWidth) - { - CurLeftPos=LeftPos; - - if (CurLeftPos>Length-ColumnWidth) - CurLeftPos=Length-ColumnWidth; - - if (CurLeftPos>MaxLeftPos) - MaxLeftPos=CurLeftPos; - } + CurLeftPos = MakeCurLeftPos(ColumnWidth, ColumnData, LeftPos, MaxLeftPos); } - FS<<fmt::LeftAlign()<<fmt::Width(ColumnWidth)<<fmt::Precision(ColumnWidth)<<ColumnData+CurLeftPos; + FS << fmt::Cells() << fmt::LeftAlign() << fmt::Size(ColumnWidth) << ColumnData + CurLeftPos; } else { @@ -1033,39 +1043,28 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (!ShowStatus && LeftPos) { - int Length = (int)wcslen(NamePtr); - - if (Length>Width) + if (LeftPos > 0 && !RightAlign) { - if (LeftPos>0) - { - if (!RightAlign) - { - CurLeftPos=LeftPos; - - if (Length-CurLeftPos<Width) - CurLeftPos=Length-Width; - - NamePtr += CurLeftPos; - - if (CurLeftPos>MaxLeftPos) - MaxLeftPos=CurLeftPos; - } - } - else if (RightAlign) + CurLeftPos = MakeCurLeftPos(Width, NamePtr, LeftPos, MaxLeftPos); + NamePtr += CurLeftPos; + } + else if (RightAlign) + { + int Cells = (int)StrZCellsCount(NamePtr); + if (Cells > Width) { - int CurRightPos=LeftPos; - - if (Length+CurRightPos<Width) - CurRightPos=Width-Length; + int CurRightPos = LeftPos; + if (Cells + CurRightPos < Width) + CurRightPos = Width - Cells; else - RightBracket=TRUE; + RightBracket = TRUE; - NamePtr += Length+CurRightPos-Width; - RightAlign=FALSE; + size_t ng = Cells + CurRightPos - Width; + NamePtr += StrSizeOfCells(NamePtr, wcslen(NamePtr), ng, false); + RightAlign = FALSE; - if (CurRightPos<MinLeftPos) - MinLeftPos=CurRightPos; + if (MinLeftPos > CurRightPos) + MinLeftPos = CurRightPos; } } } @@ -1080,7 +1079,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (RightAlign) LeftBracket=TRUE; - if (!RightAlign && StrLength(NamePtr)>Width) + if (!RightAlign && StrZCellsCount(NamePtr) > size_t(Width)) RightBracket=TRUE; } @@ -1173,13 +1172,13 @@ void FileList::ShowList(int ShowStatus,int StartColumn) break; } - FS<<FormatStr_DateTime(FileTime,ColumnType,ColumnTypes[K],ColumnWidth); + FS << FormatStr_DateTime(FileTime,ColumnType,ColumnTypes[K],ColumnWidth); break; } case ATTR_COLUMN: { - FS<<FormatStr_Attribute(ListData[ListPos]->FileAttr,ListData[ListPos]->FileMode,ColumnWidth); + FS << FormatStr_Attribute(ListData[ListPos]->FileAttr,ListData[ListPos]->FileMode,ColumnWidth); break; } @@ -1189,18 +1188,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (!ShowStatus && LeftPos>0) { - int Length=ListData[ListPos]->DizText ? StrLength(ListData[ListPos]->DizText):0; - - if (Length>ColumnWidth) - { - CurLeftPos=LeftPos; - - if (CurLeftPos>Length-ColumnWidth) - CurLeftPos=Length-ColumnWidth; - - if (CurLeftPos>MaxLeftPos) - MaxLeftPos=CurLeftPos; - } + CurLeftPos = MakeCurLeftPos(ColumnWidth, ListData[ListPos]->DizText, LeftPos, MaxLeftPos); } FARString strDizText=ListData[ListPos]->DizText ? ListData[ListPos]->DizText+CurLeftPos:L""; @@ -1209,7 +1197,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (strDizText.Pos(pos,L'\4')) strDizText.Truncate(pos); - FS<<fmt::LeftAlign()<<fmt::Width(ColumnWidth)<<fmt::Precision(ColumnWidth)<<strDizText; + FS << fmt::Cells() << fmt::LeftAlign() << fmt::Size(ColumnWidth) << strDizText; break; } @@ -1233,21 +1221,21 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (!ShowStatus && LeftPos>0) { - int Length=StrLength(Owner); + int Cells=StrZCellsCount(Owner); - if (Length>ColumnWidth) + if (Cells>ColumnWidth) { CurLeftPos=LeftPos; - if (CurLeftPos>Length-ColumnWidth) - CurLeftPos=Length-ColumnWidth; + if (CurLeftPos>Cells-ColumnWidth) + CurLeftPos=Cells-ColumnWidth; if (CurLeftPos>MaxLeftPos) MaxLeftPos=CurLeftPos; } } - FS<<fmt::LeftAlign()<<fmt::Width(ColumnWidth)<<fmt::Precision(ColumnWidth)<<Owner+CurLeftPos; + FS << fmt::Cells() << fmt::LeftAlign() << fmt::Size(ColumnWidth) << Owner+CurLeftPos; break; } @@ -1259,28 +1247,28 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if (!ShowStatus && LeftPos>0) { - int Length=StrLength(Group); + int Cells=StrZCellsCount(Group); - if (Length>ColumnWidth) + if (Cells>ColumnWidth) { CurLeftPos=LeftPos; - if (CurLeftPos>Length-ColumnWidth) - CurLeftPos=Length-ColumnWidth; + if (CurLeftPos>Cells-ColumnWidth) + CurLeftPos=Cells-ColumnWidth; if (CurLeftPos>MaxLeftPos) MaxLeftPos=CurLeftPos; } } - FS<<fmt::LeftAlign()<<fmt::Width(ColumnWidth)<<fmt::Precision(ColumnWidth)<<Group+CurLeftPos; + FS << fmt::Cells() << fmt::LeftAlign() << fmt::Size(ColumnWidth) << Group + CurLeftPos; break; } case NUMLINK_COLUMN: { - FS<<fmt::Width(ColumnWidth)<<fmt::Precision(ColumnWidth)<<ListData[ListPos]->NumberOfLinks; + FS << fmt::Cells() << fmt::Size(ColumnWidth) << ListData[ListPos]->NumberOfLinks; break; } } @@ -1288,7 +1276,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) } else { - FS<<fmt::Width(ColumnWidth)<<L""; + FS << fmt::Cells() << fmt::Expand(ColumnWidth) << L""; } if (ShowDivider==FALSE) @@ -1332,7 +1320,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) if ((!ShowStatus || StatusLine) && WhereX()<X2) { SetColor(COL_PANELTEXT); - FS<<fmt::Width(X2-WhereX())<<L""; + FS << fmt::Cells() << fmt::Expand(X2 - WhereX()) << L""; } } @@ -1341,7 +1329,7 @@ void FileList::ShowList(int ShowStatus,int StartColumn) SetScreen(X1+1,Y2-1,X2-1,Y2-1,L' ',COL_PANELTEXT); SetColor(COL_PANELTEXT); //??? //GotoXY(X1+1,Y2-1); - //FS<<fmt::Width(X2-X1-1)<<L""; + //FS<<fmt::Expand(X2-X1-1)<<L""; } if (!ShowStatus) |