From fac8e0d96a547be432f7a1902f7758730d4402ee Mon Sep 17 00:00:00 2001 From: gunboy001 Date: Sat, 30 Nov 2019 21:37:46 +0100 Subject: [PATCH] working render of unicode characters everything is to document and I left a lot of garbage comments :p --- .sconsign.dblite | Bin 3124 -> 3124 bytes src/config.h | 1 + src/fbuffer.c | 31 ++++++++++++++++++++++++------- src/fbuffer.h | 4 +++- src/fbuffer.o | Bin 6392 -> 5944 bytes src/ste.c | 27 +++++++++++++++++++-------- src/ste.o | Bin 13536 -> 13872 bytes 7 files changed, 47 insertions(+), 16 deletions(-) diff --git a/.sconsign.dblite b/.sconsign.dblite index 24894544c1b928a833c30fad9ede14ebe9160b89..f5f9f97b46364e8f62ba01e0e185785cb55ec258 100644 GIT binary patch delta 550 zcmaixyGlbr5QfPO(U2mIN$CY47Qx+}y&}GVA(f;ti0+=<%~~ELrHG(lCCDlB0+vGT zZ3MB9fY?YnA4FU+@z~i8^ZnmH%zg8|d3RfYr^&}bsC0^<+FJo)i6RCYPZ=<8jkbyQ z0M0t$WkS;RQ0vM@HZ43r{W<4!BC(=YF)k2OiXpEAHyU%`(kjeS8aY8S7p*=VWx delta 550 zcmajcxk^Jp6b4|j5sX-*5K_7zXc4@3&fGIIg)g93Ng5aQo>?-MgQN^1;seMn^8(rl zNnz&`h>aF%p}vKU;DFJjvmNI9&o*j}S~piEIKO^7@U^Y7pY1Gg%!OeF5~au>ptFu; zS!yI`BSns3+0Si%wu;x%9rULhk+Ue7B?eX^qzX}3Cm_*iasm~2bT5_SzC3{aDaW*w z!WcnDYUU6bpg`dqAaP+?5;mfHnlA>G_2#6WAE&)m4x5uSKmNN_-2+$u_?yWnZB&Lj zA)cwkrI_R?0w~Q=M9fXtjWynR@m#$CJ>|6JBt`0!imh#@>ncEpYHjYZ)Usb1y diff --git a/src/config.h b/src/config.h index b771f41..4c645ad 100644 --- a/src/config.h +++ b/src/config.h @@ -2,5 +2,6 @@ #define _CONFIG_H_ #define TABSIZE 4 // Tab size as used in render +#define MAX_LINE 1024 // maximum line length on screen #endif \ No newline at end of file diff --git a/src/fbuffer.c b/src/fbuffer.c index daa7910..dd62454 100644 --- a/src/fbuffer.c +++ b/src/fbuffer.c @@ -3,6 +3,7 @@ #include #include #include +#include void bufInit (FileBuffer *b) { @@ -172,11 +173,27 @@ void updateRender (Row *rw) { /* count the special characters * spaces, utf-8 continuation chars */ - static int tabs, i, off, cc, ut; - for (i = 0, tabs = 0, cc = 0, ut = 0; i < rw->size; i++) { + static int tabs, i, off/*, utf_width, utf_chars*/; + //static wchar_t wc_tmp; + //static char *mb_p; + + tabs = 0; + //utf_width = 0; + //utf_chars = 0; + + for (i = 0; i < rw->size; i++) { if (rw->chars[i] == '\t') tabs++; - else if (isCont(rw->chars[i])) cc++; - else if (isUtf(rw->chars[i])) ut++; + + /*else if (isStart(rw->chars[i])) { + utf_chars++; + wc_tmp = 0; + mb_p = &rw->chars[i]; + //int utf_len = mblen(mb_p, rw->size - i); + + mbtowc(&wc_tmp, mb_p, rw->size - i); + utf_width += wcwidth(wc_tmp); + //utf_len += utf_chars; + } */ } rw->render = NULL; free(rw->render); @@ -200,6 +217,6 @@ void updateRender (Row *rw) } } rw->render[off] = '\0'; - rw->r_size = off - cc; - rw->utf = cc + ut; -} + rw->r_size = off; + //rw->utf = utf_width - utf_chars; +} \ No newline at end of file diff --git a/src/fbuffer.h b/src/fbuffer.h index 8ad3053..77fe96c 100644 --- a/src/fbuffer.h +++ b/src/fbuffer.h @@ -1,6 +1,8 @@ #ifndef _FBUFFER_H_ #define _FBUFFER_H_ - +#ifndef _XOPEN_SOURCE + #define _XOPEN_SOURCE /* See feature_test_macros(7) */ +#endif /* Row structure, defines actual and * render chars, actual and render size * and difference between render and diff --git a/src/fbuffer.o b/src/fbuffer.o index f4d81d80ecd5840f3174bf627eb97915ff0ae4a4..276aa5979143d85b266365f1ec3cd25d6394df62 100644 GIT binary patch delta 2198 zcmZ{le{2(F7{~8zi}c#{`fKgAYAhik84w4@uWl-%6_ry4DDtd8WjOBu<7bI!0Meg?+Q|u}eQAUaBtuy_9WrpUD`wIb)uIPE0m5nmfd(4Ws z*KTXm)%@@pQ`Y>Q9L)^36klQb$kv2zTw|@#f&HRlVJ>*-WK3%BnJOM-?W~j;H0AzZ zVS+u=HKF(XW*5-eOktzQd`prF$2_`m!~6Qd>$&D&YDiFt)}F6c)(cw`|5<_YlWSZ7 z#>OW%ySB9@fH-A-L#$mX%=6+rdJRl~Zgjbjz#R8&Kr)FkF^9*euAta@dO%Ja~>l*sroD zVWt1geuiC@6{&!OqsJTF2vq$UreDk_Bd;kfF9a43}*G(zalb)tVK zJWAph2^T*KC;M7_JtBXM@WX`jy7_+>d_)9V;C>zcfNk3&$ z%S;napUNEJwESWn{seB-LZ;aj3+b$a_bqc+L2s4s&%T(3kRl4y%9$aY`jxHtIttsi<5tL4udY~?PTNu=dj@ih79f;;il EBV9a8m;e9( delta 2732 zcmaKudu&rx9LLY;DzshOd)xJ~CSoU<%3NJ6aW9#qWkasG2yD!-Ar98qWHAD|E*eqp zu*}euk&R;vgg=}{jfqPPnUDF14v5VCwTw5Gs9VsOs@DOUDm8z9_ z)tgGVi4ZeGQ}zxKCVP*#4>ZK+R1^IvJwdfZ&hX5Z*jivcf{{`jP7TH@}~my6==vb41* zOC9dgxLe)ewmn!(NFA5Fz;@Zz(J^+?wuRc*6Mg0w}mzO zK3LTv6Q{v?7WgpmZs3!`OP>a-3R7$W>pbxNz$>7xYruz%x0%0HPzyvjF0zW( z=WqVTi}pc*9@ddo-E+%G1+$>nk^7I3*7*Z;-W z!H9Pb*ia$#@k=K50+)$pf--i<9rj2n%m0*Za|d;=z`TiA0e;C?5yWwh^@s`86~LCAj7Sw(mBNO zO8kL1E~paruW&`$(YP8MO4AF40vQVJb@{W(S1lIevI?N0Ne$ry-Vs8a1?OTn%PlQ}I;$01t O+fVpSZM#7te&;_3;C8hD diff --git a/src/ste.c b/src/ste.c index a1bc626..f5dfbfd 100644 --- a/src/ste.c +++ b/src/ste.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "fbuffer.h" #include "config.h" @@ -14,6 +15,7 @@ #define CTRL(k) ((k) & 0x1f) // Control mask modifier #define STAT_SIZE 128 #define CBUF_SIZE 2048 +#define MAX_LINE 1024 #define MODE_MASK 0x1 #define COMMAND_MASK 0x06 @@ -103,6 +105,10 @@ static void sbMove (CharBuffer *buf, int x); /* --------------------------------- main ------------------------------------ */ int main (int argc, char *argv[]) { + /* Init locales */ + setlocale(LC_ALL, ""); + setlocale(LC_CTYPE, ""); + /* Initialize the first row */ bufInit(&rows); @@ -210,9 +216,6 @@ int main (int argc, char *argv[]) void termInit (void) { - /* Init locales */ - setlocale(LC_ALL, ""); - /* Init the screen and refresh */ initscr(); refresh(); @@ -324,9 +327,17 @@ void drawLines (void) /* Draw the line matcing render memory */ if (&rows.rw[ln] == NULL) termDie("drawlines NULL"); if (rows.rw[ln].r_size > t.cur.off_x) { + start = t.cur.off_x; - while (isCont(rows.rw[ln].render[start])) start++; - addnstr(&rows.rw[ln].render[start], (t.dim.x + 1) + (rows.rw[ln].utf >> 2)); + while (isCont(rows.rw[ln].render[start])) start++; + + static wchar_t converted_line[MAX_LINE]; + static int x = 0; + for (x = 0; x < MAX_LINE; x++) converted_line[x] = 0; + mbstowcs(converted_line, &rows.rw[ln].render[start], MAX_LINE); + addnwstr(converted_line, t.dim.x + 1); + + //addnstr(&rows.rw[ln].render[start], (t.dim.x + 1) + rows.rw[ln].utf); } } lnMove(i + 1, 0); @@ -354,9 +365,9 @@ void drawBar (char *s) for (i = len; i <= t.dim.x + t.pad; i++) mvaddch(t.dim.y, i, ' '); - static char m[40]; - sprintf(m, "x: %d y: %d Zoom: %c", t.cur.x, t.cur.y, whatsThat()); - mvaddstr(t.dim.y, t.dim.x + t.pad - strlen(m), m); + static char right_message[40]; + sprintf(right_message, "x: %d y: %d Zoom: %c", t.cur.x, t.cur.y, whatsThat()); + mvaddstr(t.dim.y, t.dim.x + t.pad - strlen(right_message), right_message); /* Return to normal contrast mode */ attroff(COLOR_PAIR(2)); diff --git a/src/ste.o b/src/ste.o index a37910b8e8c287005d416fa6efe21d7e5de8202b..4ed4075115b26c8cd6dfde04ba8521ddea2d56c1 100644 GIT binary patch literal 13872 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 olu*m#aZ(*SK