diff --git a/comp/src/gb.form.terminal/.project b/comp/src/gb.form.terminal/.project index 2f68f484d..528ff9d73 100644 --- a/comp/src/gb.form.terminal/.project +++ b/comp/src/gb.form.terminal/.project @@ -7,7 +7,7 @@ VersionFile=1 Component=gb.image Component=gb.gui Component=gb.form -Environment="GB_GUI=gb.qt5" +Environment="GB_GUI=gb.gtk3" TabSize=2 Language=fr Type=Component diff --git a/comp/src/gb.form.terminal/.src/TerminalView/CTerminalLine.class b/comp/src/gb.form.terminal/.src/TerminalView/CTerminalLine.class index 543e57c50..d454e1416 100644 --- a/comp/src/gb.form.terminal/.src/TerminalView/CTerminalLine.class +++ b/comp/src/gb.form.terminal/.src/TerminalView/CTerminalLine.class @@ -4,38 +4,102 @@ Public Text As String Public Length As Integer Public Attr As New Integer[] -Enum FLAG_BG, FLAG_FG, FLAG_BOLD, FLAG_DIM, FLAG_REV, FLAG_UND, FLAG_BLK +Private Enum FLAG_BG, FLAG_FG, FLAG_BOLD, FLAG_DIM, FLAG_REV, FLAG_UND, FLAG_BLK -Public Sub GetAttr(hAttr As TerminalAttr, X As Integer) - +Private Sub Uncompress() As Integer[] + + Dim I As Integer Dim iAttr As Integer - - Try iAttr = Attr[X] - - If BTst(iAttr, FLAG_BG) Then - hAttr.Background = Lsr(iAttr, 16) And 255 - Else - hAttr.Background = Color.Default - Endif + Dim iCount As Integer + Dim aAttr As New Integer[] + Dim aTemp As Integer[] - If BTst(iAttr, FLAG_FG) Then - hAttr.Foreground = Lsr(iAttr, 24) And 255 - Else - hAttr.Foreground = Color.Default - Endif + For I = 0 To Attr.Max + iAttr = Attr[I] + iCount = (Lsr(iAttr, 8) And 255) + 1 + iAttr = iAttr And &HFFFF00FF + aTemp = New Integer[iCount] + aTemp.Fill(iAttr) + aAttr.Insert(aTemp) + Next - hAttr.Bold = BTst(iAttr, FLAG_BOLD) - hAttr.Dim = BTst(iAttr, FLAG_DIM) - hAttr.Reverse = BTst(iAttr, FLAG_REV) - hAttr.Underscore = BTst(iAttr, FLAG_UND) - hAttr.Blink = BTst(iAttr, FLAG_BLK) + 'If aAttr.Count > String.Len(Text) Then Stop + + Return aAttr + +End + +Private Sub Compress(aAttr As Integer[]) + + Dim I As Integer + Dim iAttr As Integer + Dim iOldAttr As Integer + Dim iCount As Integer + Dim N As Integer + + Attr.Clear + + For I = 0 To aAttr.Max + + iAttr = aAttr[I] + If iAttr = iOldAttr And If iCount < 256 Then + Inc iCount + Continue + Endif + + GoSub ADD_ATTR + iCount = 1 + iOldAttr = iAttr + + Next + + GoSub ADD_ATTR + 'Debug aAttr.Count; " -> "; N;; "/";; String.Len(Text) + 'If N > String.Len(Text) Then Stop + Return + +ADD_ATTR: + + If iCount Then + N += iCount + Attr.Add(iOldAttr Or Lsl(iCount - 1, 8)) + Endif + Return End + +' Public Sub GetAttr(hAttr As TerminalAttr, X As Integer) +' +' Dim iAttr As Integer +' +' Try iAttr = Attr[X] +' +' If BTst(iAttr, FLAG_BG) Then +' hAttr.Background = Lsr(iAttr, 16) And 255 +' Else +' hAttr.Background = Color.Default +' Endif +' +' If BTst(iAttr, FLAG_FG) Then +' hAttr.Foreground = Lsr(iAttr, 24) And 255 +' Else +' hAttr.Foreground = Color.Default +' Endif +' +' hAttr.Bold = BTst(iAttr, FLAG_BOLD) +' hAttr.Dim = BTst(iAttr, FLAG_DIM) +' hAttr.Reverse = BTst(iAttr, FLAG_REV) +' hAttr.Underscore = BTst(iAttr, FLAG_UND) +' hAttr.Blink = BTst(iAttr, FLAG_BLK) +' +' End +' Public Sub SetAttr(hAttr As TerminalAttr, X As Integer, Optional L As Integer = 1, Optional bInsert As Boolean) Dim iAttr As Integer Dim aAttr As Integer[] + Dim aTemp As Integer[] If hAttr.Background <> Color.Default Then iAttr = BSet(iAttr, FLAG_BG) + Lsl(hAttr.Background And 255, 16) If hAttr.Foreground <> Color.Default Then iAttr = BSet(iAttr, FLAG_FG) + Lsl(hAttr.Foreground And 255, 24) @@ -46,18 +110,30 @@ Public Sub SetAttr(hAttr As TerminalAttr, X As Integer, Optional L As Integer = If hAttr.Underscore Then iAttr = BSet(iAttr, FLAG_UND) If hAttr.Blink Then iAttr = BSet(iAttr, FLAG_BLK) - If iAttr = 0 And If X + L >= Attr.Count Then - Attr.Resize(X) + aAttr = Uncompress() + + If iAttr = 0 And If X >= aAttr.Count Then + 'aAttr.Resize(X) Else If bInsert Then - aAttr = New Integer[L] - aAttr.Fill(iAttr) - Attr.Insert(aAttr, X) + If aAttr.Count < X Then aAttr.Resize(X) + aTemp = New Integer[L] + aTemp.Fill(iAttr) + aAttr.Insert(aTemp, X) Else - If Attr.Count < X + L Then Attr.Resize(X + L) - Attr.Fill(iAttr, X, L) + If aAttr.Count < X + L Then aAttr.Resize(X + L) + aAttr.Fill(iAttr, X, L) Endif Endif + Compress(aAttr) + End +Public Sub Clear() + + Text = "" + Length = 0 + Attr.Clear + +End diff --git a/comp/src/gb.form.terminal/.src/TerminalView/TerminalAttr.class b/comp/src/gb.form.terminal/.src/TerminalView/TerminalAttr.class index eaf60c0df..b7d8465fe 100644 --- a/comp/src/gb.form.terminal/.src/TerminalView/TerminalAttr.class +++ b/comp/src/gb.form.terminal/.src/TerminalView/TerminalAttr.class @@ -2,6 +2,8 @@ Export +Private Enum FLAG_BG, FLAG_FG, FLAG_BOLD, FLAG_DIM, FLAG_REV, FLAG_UND, FLAG_BLK + Public Foreground As Integer = -1 Public Background As Integer = -1 Public Bold As Boolean @@ -31,3 +33,24 @@ Public Sub IsVoid() As Boolean End +Public Sub FillFrom(iAttr As Integer) + + If BTst(iAttr, FLAG_BG) Then + Background = Lsr(iAttr, 16) And 255 + Else + Background = Color.Default + Endif + + If BTst(iAttr, FLAG_FG) Then + Foreground = Lsr(iAttr, 24) And 255 + Else + Foreground = Color.Default + Endif + + Bold = BTst(iAttr, FLAG_BOLD) + {Dim} = BTst(iAttr, FLAG_DIM) + Reverse = BTst(iAttr, FLAG_REV) + Underscore = BTst(iAttr, FLAG_UND) + Blink = BTst(iAttr, FLAG_BLK) + +End diff --git a/comp/src/gb.form.terminal/.src/TerminalView/TerminalScreen.class b/comp/src/gb.form.terminal/.src/TerminalView/TerminalScreen.class index 34a0b3854..80d0879cb 100644 --- a/comp/src/gb.form.terminal/.src/TerminalView/TerminalScreen.class +++ b/comp/src/gb.form.terminal/.src/TerminalView/TerminalScreen.class @@ -170,9 +170,8 @@ Private Sub ClearLine(Y As Integer) If Y > Lines.Max Then Return hLine = Lines[Y] If Not hLine Then Return - hLine.Text = "" - hLine.Length = 0 - hLine.Attr.Clear + + hLine.Clear() End @@ -202,17 +201,19 @@ Private Sub Insert(sText As String, Optional X As Integer = $X) If hLine.Length < X Then hLine.Text &= Space$(X - hLine.Length) & sText & String.Mid(hLine.Text, X + iLen) + hLine.Length = String.Len(hLine.Text) hLine.SetAttr($hAttr, X, iLen) Else If InsertMode Then hLine.Text = String.Left(String.Left(hLine.Text, X) & sText & String.Mid(hLine.Text, X + 1), $W) + hLine.Length = String.Len(hLine.Text) hLine.SetAttr($hAttr, X, iLen, True) Else hLine.Text = String.Left(hLine.Text, X) & sText & String.Mid(hLine.Text, X + iLen + 1) + hLine.Length = String.Len(hLine.Text) hLine.SetAttr($hAttr, X, iLen) Endif Endif - hLine.Length = String.Len(hLine.Text) GetView()._RefreshLine($Y) @@ -454,8 +455,7 @@ Public Sub EraseStartOfLine() hLine = GetLine($Y) If hLine.Length <= $X Then - hLine.Text = "" - hLine.Length = 0 + hLine.Clear() GetView()._RefreshLine($Y) Else hLine.Text = Space$($X + 1) & String.Mid$(hLine.Text, $X + 1) @@ -470,8 +470,7 @@ Public Sub EraseLine() hLine = GetLine($Y) If $hAttr.IsVoid() Then - hLine.Text = "" - hLine.Length = 0 + hLine.Clear() Else Insert(Space$($W), 0) Endif @@ -664,8 +663,6 @@ Fast Private Sub DrawLine(L As Integer, X As Float, Y As Integer, LH As Integer, Dim I As Integer 'Dim sText As String Dim aAttr As Integer[] - Dim iAttr As Integer - Dim iOldAttr As Integer Dim hAttr As New TerminalAttr Dim iFg As Integer = hView.Foreground Dim iBg As Integer = hView.Background @@ -688,137 +685,137 @@ Fast Private Sub DrawLine(L As Integer, X As Float, Y As Integer, LH As Integer, aAttr = hLine.Attr P = 1 - For I = 1 To hLine.Length - - If aAttr.Count >= I Then - iAttr = aAttr[I - 1] + + For I = 0 To aAttr.Max + + If P > hLine.Length Then Break + + hAttr.FillFrom(aAttr[I]) + iLen = Min((Lsr(aAttr[I], 8) And 255), hLine.Length - P) + 1 + + iBg = hAttr.Background + If iBg >= 0 Then + iBg = $aColor[iBg] Else - iAttr = 0 + iBg = hView.Background Endif - If iAttr <> iOldAttr Then - - GoSub DRAW_TEXT - - iOldAttr = iAttr - - hLine.GetAttr(hAttr, I - 1) - - iBg = hAttr.Background - If iBg >= 0 Then - iBg = $aColor[iBg] - Else - iBg = hView.Background - Endif - - iFg = hAttr.Foreground - If iFg >= 0 Then - 'Debug iFg - iFg = $aColor[iFg] - Else - iFg = hView.Foreground - Endif - - If hAttr.Reverse Then Swap iBg, iFg - - If hAttr.Dim Then iFg = Color.Merge(iFg, hView.Background) - - Paint.Background = Color.White - - If hAttr.Bold Then - HC = LH - Else - HC = 0 - Endif - + iFg = hAttr.Foreground + If iFg >= 0 Then + 'Debug iFg + iFg = $aColor[iFg] + Else + iFg = hView.Foreground Endif - ' Paint.FillRect(X, Y, $CW, $LH, iBg) - ' If iFg = $hView.Foreground And If String.Code(sCar) <= 255 Then - ' hRect = Rect(String.Code(sCar) * $CW, 0, $CW, $LH) - ' Paint.DrawImage($hCacheFont, X, Y, $CW, $LH,, hRect) - ' If hAttr.Bold Then Paint.DrawImage($hCacheFont, X + 1, Y, $CW, $LH,, hRect) - ' Else - ' Paint.DrawText(sCar, X, Y + $iAscent) - ' If hAttr.Bold Then Paint.DrawText(sCar, X + 1, Y + $iAscent) - ' Endif - ' X += $CW + If hAttr.Reverse Then Swap iBg, iFg + + If hAttr.Dim Then iFg = Color.Merge(iFg, hView.Background) + + Paint.Background = Color.White + + If hAttr.Bold Then + HC = LH + Else + HC = 0 + Endif + + GoSub DRAW_TEXT Next - GoSub DRAW_TEXT - - Paint.Operator = Paint.OperatorOver + If P <= hLine.Length Then + iLen = hLine.Length - P + 1 + iFg = hView.Foreground + iBg = hView.Background + HC = 0 + hAttr.FillFrom(0) + GoSub DRAW_TEXT + Endif + Return DRAW_TEXT: - iLen = I - P If iLen <= 0 Then Return W = iLen * CW - Paint.Begin($hLineCache) + If hFontCache Then - Paint.FillRect(0, 0, W, LH, iFg) - - XT = 0 - - hRect = Rect(0, 0, CW, LH) - - Paint.Operator = Paint.OperatorDestATop - For J = P To P + iLen - 1 - 'sCar = String.Mid$(hLine.Text, J, 1) - C = String.Code(hLine.Text, J) - If C <= 255 Then - hRect.Move(C * CW, HC) - Paint.DrawImage(hFontCache, XT, 0, CW, LH,, hRect) - Else - - If $cCharCache.Exist(C) Then - - C = $cCharCache[C] - hRect.Move(C * CW, 0) + Paint.Begin($hLineCache) + + Paint.FillRect(0, 0, W, LH, iFg) + + XT = 0 + + hRect = Rect(0, 0, CW, LH) + + Paint.Operator = Paint.OperatorDestATop + For J = P To P + iLen - 1 + 'sCar = String.Mid$(hLine.Text, J, 1) + C = String.Code(hLine.Text, J) + If C = 0 Then Stop + If C <= 255 Then + hRect.Move(C * CW, HC) Paint.DrawImage(hFontCache, XT, 0, CW, LH,, hRect) - Else - If $cCharCache.Count < 32 Then - XC = $cCharCache.Count * CW - YC = 0 + If $cCharCache.Exist(C) Then + + C = $cCharCache[C] + hRect.Move(C * CW, 0) + Paint.DrawImage(hFontCache, XT, 0, CW, LH,, hRect) + Else - XC = 0 - YC = LH + + If $cCharCache.Count < 32 Then + XC = $cCharCache.Count * CW + YC = 0 + Else + XC = 0 + YC = LH + Endif + + Paint.Begin(hFontCache) + Paint.Operator = Paint.OperatorSource + Paint.FillRect(XC, YC, CW, LH, Color.Transparent) + Paint.Font = hFont + Paint.DrawText(String.Chr$(C), XC, YC, CW, LH, Align.Center) + If hAttr.Bold Then Paint.DrawText(String.Chr$(C), XC + 1, YC, CW, LH, Align.Center) + Paint.End + hRect.Move(XC, YC) + Paint.DrawImage(hFontCache, XT, 0, CW, LH,, hRect) + + If YC = 0 Then $cCharCache[C] = $cCharCache.Count + Endif - - Paint.Begin(hFontCache) - Paint.Operator = Paint.OperatorSource - Paint.FillRect(XC, YC, CW, LH, Color.Transparent) - Paint.Font = hFont - Paint.DrawText(String.Chr$(C), XC, YC, CW, LH, Align.Center) - If hAttr.Bold Then Paint.DrawText(String.Chr$(C), XC + 1, YC, CW, LH, Align.Center) - Paint.End - hRect.Move(XC, YC) - Paint.DrawImage(hFontCache, XT, 0, CW, LH,, hRect) - - If YC = 0 Then $cCharCache[C] = $cCharCache.Count - Endif - Endif - XT += CW - Next - - Paint.End - - XT = X - - Paint.FillRect(XT, Y, W, LH, iBg) - Paint.DrawImage($hLineCache, XT, Y, W, LH,, Rect(0, 0, W, LH)) + XT += CW + Next + + Paint.End + + XT = X + + Paint.FillRect(XT, Y, W, LH, iBg) + Paint.DrawImage($hLineCache, XT, Y, W, LH,, Rect(0, 0, W, LH)) + + Else + + XT = X + + Paint.FillRect(XT, Y, W, LH, iBg) + Paint.Background = iFg + Paint.DrawText(String.Mid$(hLine.Text, P, iLen), XT, Y + LA) + If hAttr.Bold Then Paint.DrawText(String.Mid$(hLine.Text, P, iLen), XT + 1, Y + LA) + + Endif If hAttr.Underscore Then Paint.FillRect(XT, Y + LH - 1, W, 1, Color.SetAlpha(iFg, 64)) X += W - P = I + P += iLen Return End diff --git a/comp/src/gb.form.terminal/.src/TerminalView/TerminalView.class b/comp/src/gb.form.terminal/.src/TerminalView/TerminalView.class index 675424fbc..e0ce1e061 100644 --- a/comp/src/gb.form.terminal/.src/TerminalView/TerminalView.class +++ b/comp/src/gb.form.terminal/.src/TerminalView/TerminalView.class @@ -155,25 +155,33 @@ Private Sub UpdateFont() 'Debug $CW $CW = Ceil($CW) + ' If .Fixed Then + ' + ' $hCacheFont = Null + ' + ' Else + + $hCacheFont = New Image($CW * 256, $LH * 2, Color.Transparent) + Paint.Begin($hCacheFont) + Paint.Background = Color.White + Paint.Font = $hView.Font + For I = 33 To 126 + Paint.DrawText(String.Chr(I), I * $CW, 0, $CW, $LH, Align.Center) + Next + For I = 160 To 255 + Paint.DrawText(String.Chr(I), I * $CW, 0, $CW, $LH, Align.Center) + Next + Paint.End + + Paint.Begin($hCacheFont) + Paint.DrawImage($hCacheFont, 0, $LH, $hCacheFont.W, $LH,, Rect(0, 0, $hCacheFont.W, $LH)) + Paint.DrawImage($hCacheFont, 1, $LH, $hCacheFont.W, $LH, 0.8, Rect(0, 0, $hCacheFont.W, $LH)) + Paint.End + + ' Endif + End With - $hCacheFont = New Image($CW * 256, $LH * 2, Color.Transparent) - Paint.Begin($hCacheFont) - Paint.Background = Color.White - Paint.Font = $hView.Font - For I = 33 To 126 - Paint.DrawText(String.Chr(I), I * $CW, 0, $CW, $LH, Align.Center) - Next - For I = 160 To 255 - Paint.DrawText(String.Chr(I), I * $CW, 0, $CW, $LH, Align.Center) - Next - Paint.End - - Paint.Begin($hCacheFont) - Paint.DrawImage($hCacheFont, 0, $LH, $hCacheFont.W, $LH,, Rect(0, 0, $hCacheFont.W, $LH)) - Paint.DrawImage($hCacheFont, 1, $LH, $hCacheFont.W, $LH, 0.8, Rect(0, 0, $hCacheFont.W, $LH)) - Paint.End - ' For I = 33 To 255 ' Paint.DrawText(String.Chr(I), I * $CW, $LH, $CW, $LH, Align.Center) ' Paint.DrawText(String.Chr(I), I * $CW + 1, $LH, $CW, $LH, Align.Center) diff --git a/main/gbx/gbx_c_string.c b/main/gbx/gbx_c_string.c index 6f7257669..94d3aaef2 100644 --- a/main/gbx/gbx_c_string.c +++ b/main/gbx/gbx_c_string.c @@ -747,6 +747,13 @@ BEGIN_METHOD(String_Code, GB_STRING str; GB_INTEGER index) str = STRING(str); len = LENGTH(str); + + if (index > len) + { + GB_ReturnInteger(0); + return; + } + pos = utf8_get_pos(VARG(str).addr, str, len, index - 1); lc = STRING_utf8_get_char_length(str[pos]);