... | ... |
@@ -29,13 +29,28 @@ |
29 | 29 |
//#define CHUNKSIZE 4096 |
30 | 30 |
//#define CHUNKSIZE 1024 |
31 | 31 |
//#define CHUNKSIZE 160 |
32 |
-#define CHUNKSIZE 16 |
|
32 |
+//#define CHUNKSIZE 16 |
|
33 |
+#define CHUNKSIZE 3 |
|
34 |
+#warning XXX: TODO: CHANGE CHUNKSIZE TO A SANE VALUE (not 1!), THIS IS ONLY FOR TESTING UTF-8 multi-byte CHARS |
|
35 |
+ |
|
33 | 36 |
#define UNDOBLOCK 1024 |
34 | 37 |
#define ADDNBLOCK 1024 |
35 | 38 |
#define UNDOGROWSIZE (256*1024) |
36 | 39 |
#define SECURESAVEPREFIX "." |
37 | 40 |
#define SECURESAVEPOSTFIX ".saving" |
38 | 41 |
|
42 |
+#define UTF8_IS_ASCII_OR_START(c) (((c)&0xc0)!=0x80) |
|
43 |
+#define UTF8_IS_ASCII(c) (((c)&0x80)==0) |
|
44 |
+#define UTF8_IS_MULTIBYTESTART(c) ((((c)&0x80)==0x80)&&(((c)&(0x80|0x40))!=0x80)) |
|
45 |
+#define UTF8_IS_MULTIBYTECONT(c) (((c)&(0x80|0x40))==0x80) |
|
46 |
+ |
|
47 |
+#define UTF8_MULTIBYTESTART2LEN(c) ((((c)&0xe0)==0xc0)?2: \ |
|
48 |
+ (((c)&0xf0)==0xe0)?3: \ |
|
49 |
+ (((c)&0xf8)==0xf0)?4: \ |
|
50 |
+ (((c)&0xfc)==0xf8)?5: \ |
|
51 |
+ (((c)&0xfe)==0xfc)?6: \ |
|
52 |
+ 1) |
|
53 |
+ |
|
39 | 54 |
static int redata_hash_gen(redata_t *redata, char *filename, char *buf, long buflen, char *resbuf129bytes); |
40 | 55 |
static char *securesave_genname(char *filename, char *buf, int bufsize); |
41 | 56 |
static void *mymemrchr(const void *s, int c, size_t n); |
... | ... |
@@ -1587,6 +1602,50 @@ redata_memcmp(redata_t *redata, long pos, char *str, int len) |
1587 | 1602 |
|
1588 | 1603 |
} |
1589 | 1604 |
|
1605 |
+int |
|
1606 |
+redata_getutf8char(redata_t *redata, long pos, char *buf, int len, int *usedbuf) |
|
1607 |
+{ |
|
1608 |
+ int numchunk; |
|
1609 |
+ int offset; |
|
1610 |
+ rechunk_t *chunk; |
|
1611 |
+ int ooff; |
|
1612 |
+ int req; |
|
1613 |
+ int c; |
|
1614 |
+ if(redata==NULL || pos<0 || pos>redata_getsize(redata) || buf==NULL || len<1 || usedbuf==NULL) |
|
1615 |
+ return(-1); /* sanity check failed */ |
|
1616 |
+ ooff=0; |
|
1617 |
+ if(redata_getposptr(redata,pos,&numchunk,&offset)!=0) |
|
1618 |
+ return(-1); /* couldn't get pos */ |
|
1619 |
+ while(numchunk<redata->sizechunks && redata->chunks[numchunk]!=NULL && offset>=redata->chunks[numchunk]->useddata) { |
|
1620 |
+ numchunk++; |
|
1621 |
+ offset=0; |
|
1622 |
+ } |
|
1623 |
+ if(numchunk>=redata->sizechunks) |
|
1624 |
+ return(-1); /* at end; no data */ |
|
1625 |
+ chunk=redata->chunks[numchunk]; |
|
1626 |
+ c=chunk->data[offset]; |
|
1627 |
+ ((unsigned char *)buf)[ooff++]=c; |
|
1628 |
+ if(UTF8_IS_ASCII(c) || UTF8_IS_MULTIBYTECONT(c)) |
|
1629 |
+ req=1; |
|
1630 |
+ else |
|
1631 |
+ req=UTF8_MULTIBYTESTART2LEN(c); |
|
1632 |
+ offset++; |
|
1633 |
+ for(;ooff<len && ooff<req && numchunk<redata->sizechunks |
|
1634 |
+ ;numchunk++,chunk=redata->chunks[numchunk],offset=0) { |
|
1635 |
+ if(offset>=chunk->useddata) |
|
1636 |
+ continue; |
|
1637 |
+ c=0x80|0x40; /* initialize c to whatever multibycont for the check after the while */ |
|
1638 |
+ while(ooff<len && ooff<req |
|
1639 |
+ && (c=chunk->data[offset])!=0 && UTF8_IS_MULTIBYTECONT(c)) { |
|
1640 |
+ ((unsigned char *)buf)[ooff++]=c; |
|
1641 |
+ } |
|
1642 |
+ if(!UTF8_IS_MULTIBYTECONT(c)) |
|
1643 |
+ break; |
|
1644 |
+ } |
|
1645 |
+ *usedbuf=ooff; |
|
1646 |
+ return(0); |
|
1647 |
+} |
|
1648 |
+ |
|
1590 | 1649 |
|
1591 | 1650 |
int |
1592 | 1651 |
redata_generic_utf8len(char *ptr, int size) |
... | ... |
@@ -1606,6 +1665,63 @@ redata_generic_utf8len(char *ptr, int size) |
1606 | 1665 |
/*#warning TODO: XXX Also consider tabs*/ |
1607 | 1666 |
} |
1608 | 1667 |
|
1668 |
+int |
|
1669 |
+redata_generic_utf8lenincomplete(char *ptr, int size, int *nstartincomplete,int *nendincomplete, int *nendrequired) |
|
1670 |
+{ |
|
1671 |
+ int len,i; |
|
1672 |
+ int lastistart,lastclen; |
|
1673 |
+/*#warning TODO: XXX support combining code points (at least U+0300 - U+036F ( https://en.wikipedia.org/wiki/Combining_character ) */ |
|
1674 |
+ if(size<0 || (ptr==NULL && size!=0) || nstartincomplete==NULL || nendincomplete==NULL) |
|
1675 |
+ return(-1); |
|
1676 |
+ /* from RFC2279/RFC3629, one character is up to 6 bytes: |
|
1677 |
+ first last Byte1 Byte2 Byte3 Byte4 |
|
1678 |
+ U+0000 U+007F 0xxxxxxx |
|
1679 |
+ U+0080 U+07FF 110xxxxx 10xxxxxx |
|
1680 |
+ U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx |
|
1681 |
+ U+10000 U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
|
1682 |
+ ... |
|
1683 |
+ */ |
|
1684 |
+ i=0; |
|
1685 |
+ len=0; |
|
1686 |
+ /* nstartincomplete */ |
|
1687 |
+ *nstartincomplete=0; |
|
1688 |
+ while(i<size && (ptr[i]&(0x80|0x40))==0x80) { |
|
1689 |
+ (*nstartincomplete)++; |
|
1690 |
+ i++; |
|
1691 |
+ } |
|
1692 |
+ /* len */ |
|
1693 |
+ lastistart=-1; |
|
1694 |
+ lastclen=0; |
|
1695 |
+ for(;i<size;i++) { |
|
1696 |
+ len+=((ptr[i]&0xc0)!=0x80)?1:0; |
|
1697 |
+ if((ptr[i]&0x80)==0x00) { |
|
1698 |
+ /* ASCII */ |
|
1699 |
+ lastistart=i; |
|
1700 |
+ lastclen=1; |
|
1701 |
+ } else if((ptr[i]&0xc0)!=0x80) { |
|
1702 |
+ /* multibytechar start (as ASCII case has already been processed) */ |
|
1703 |
+ lastistart=i; |
|
1704 |
+ lastclen=((ptr[i]&0xe0)==0xc0)?2: |
|
1705 |
+ ((ptr[i]&0xf0)==0xe0)?3: |
|
1706 |
+ ((ptr[i]&0xf8)==0xf0)?4: |
|
1707 |
+ ((ptr[i]&0xfc)==0xf8)?5: |
|
1708 |
+ ((ptr[i]&0xfe)==0xfc)?6: |
|
1709 |
+ 1; /* unknown type of multibytechar */ |
|
1710 |
+ } |
|
1711 |
+ } |
|
1712 |
+ /* nendincomplete */ |
|
1713 |
+ *nendincomplete=0; |
|
1714 |
+ *nendrequired=0; |
|
1715 |
+ if(lastistart!=-1 && (lastistart+lastclen)>size) { |
|
1716 |
+ *nendrequired=lastclen; |
|
1717 |
+ *nendincomplete=(lastistart+lastclen-size); |
|
1718 |
+ len--; |
|
1719 |
+ } |
|
1720 |
+ /* all done */ |
|
1721 |
+ return(len); |
|
1722 |
+/*#warning TODO: XXX Also consider tabs*/ |
|
1723 |
+} |
|
1724 |
+ |
|
1609 | 1725 |
char * |
1610 | 1726 |
redata_generic_utf8col(char *ptr, int size, int col) |
1611 | 1727 |
{ |
... | ... |
@@ -1654,7 +1770,6 @@ redata_generic_utf8isstartbyte(int candidate) |
1654 | 1770 |
return(0); |
1655 | 1771 |
} |
1656 | 1772 |
|
1657 |
- |
|
1658 | 1773 |
static int |
1659 | 1774 |
redata_hash_gen(redata_t *redata, char *filename, char *buf, long buflen, char *resbuf129bytes) |
1660 | 1775 |
{ |
... | ... |
@@ -1933,7 +2048,7 @@ redata_linecol2pos(redata_t *redata, int line, int colrequest, long *pos, int *c |
1933 | 2048 |
int i,n; |
1934 | 2049 |
char *ptr; |
1935 | 2050 |
int len; |
1936 |
- int done; |
|
2051 |
+ int done; |
|
1937 | 2052 |
if(redata==NULL || line<0 || colrequest<0) |
1938 | 2053 |
return(-1); |
1939 | 2054 |
/* find line */ |
... | ... |
@@ -1958,21 +2073,18 @@ redata_linecol2pos(redata_t *redata, int line, int colrequest, long *pos, int *c |
1958 | 2073 |
return(-1); /* line not found */ |
1959 | 2074 |
realstart=chunkpos+i; |
1960 | 2075 |
/* find col */ |
1961 |
- for(n=0,curpos=realstart;n<colrequest;) { |
|
2076 |
+ for(n=-1,curpos=realstart;n<colrequest;) { |
|
1962 | 2077 |
if(redata_line_rawinfo(redata,curpos,&startpos,&ptr,&len,NULL)==-1 || len==0) |
1963 | 2078 |
return(-1); /* couldn't get current line data */ |
1964 | 2079 |
done=0; |
1965 |
- for(i=0;colrequest>0 && i<len && n<=colrequest;i++) { |
|
1966 |
- if(redata_generic_utf8isstartbyte(ptr[i])) { |
|
1967 |
- if(n==colrequest) { |
|
1968 |
- done=1; |
|
1969 |
- break; |
|
1970 |
- } |
|
1971 |
- n++; |
|
1972 |
- } |
|
2080 |
+ for(i=0;i<len && n<colrequest;i++) { |
|
1973 | 2081 |
if(ptr[i]=='\n') { |
1974 | 2082 |
done=1; |
1975 | 2083 |
break; |
2084 |
+ } else if(UTF8_IS_ASCII_OR_START(ptr[i])) { |
|
2085 |
+ n++; |
|
2086 |
+ if(n==colrequest) |
|
2087 |
+ break; |
|
1976 | 2088 |
} |
1977 | 2089 |
} |
1978 | 2090 |
curpos=startpos+i; |
... | ... |
@@ -171,10 +171,17 @@ long redata_searchforward(redata_t *redata, long posini, char *str, int len); |
171 | 171 |
long redata_searchbackwards(redata_t *redata, long posini, char *str, int len); |
172 | 172 |
int redata_memcmp(redata_t *redata, long pos, char *str, int len); |
173 | 173 |
|
174 |
+int redata_getutf8char(redata_t *redata, long pos, char *buf, int len, int *usedbuf); |
|
175 |
+ |
|
174 | 176 |
/* utf8 convenience functions */ |
175 | 177 |
|
176 | 178 |
/* calculate the number of utf8-charaters in buffer */ |
177 | 179 |
int redata_generic_utf8len(char *ptr, int size); |
180 |
+ |
|
181 |
+/* calculate the number of utf8-charaters in buffer ignoring incomplete multibytechars at start and end */ |
|
182 |
+int redata_generic_utf8lenincomplete(char *ptr, int size, int *nstartincomplete,int *nendincomplete, int *nendrequired |
|
183 |
+); |
|
184 |
+ |
|
178 | 185 |
/* return a pointer to the "n"th ("col"th) utf8-character in buffer */ |
179 | 186 |
char *redata_generic_utf8col(char *ptr, int size, int col); |
180 | 187 |
/* returns the len in bytes of the character starting at ptr (zero on error)*/ |
... | ... |
@@ -1889,31 +1889,24 @@ re_drawcontents(re_t *re, printout_t *printout) |
1889 | 1889 |
int curline,curcol; |
1890 | 1890 |
int maxcol,maxrow; |
1891 | 1891 |
long pos,newpos; |
1892 |
- char *ptr; |
|
1893 |
- int len; |
|
1894 | 1892 |
int y,row,tmprow; |
1895 |
- char *curptr; |
|
1896 |
- int curptrlen; |
|
1897 |
- int has_nl; |
|
1893 |
+ long cursorpos; |
|
1898 | 1894 |
int is_continuation; |
1899 |
- int tmpcol,availcol; |
|
1900 |
- int in_error; |
|
1901 |
- long realstart,realend; |
|
1902 |
- int drawn_cursor; |
|
1903 |
- hcolor_t *colors; |
|
1895 |
+ printout_t fakeprintout; |
|
1896 |
+ hcolor_t *colors,fakecolor; |
|
1904 | 1897 |
int ncolors; |
1905 |
- linecolor_t *linecolors; |
|
1898 |
+ const char selcolornormal[]={"\xde\xcf\x7f\xff"}; |
|
1899 |
+ const char selcolorcurline[]={"\xf0\xea\xc9\xff"}; |
|
1900 |
+ long realstart,realend; |
|
1901 |
+ linecolor_t *linecolors,fakelinecolors; |
|
1906 | 1902 |
int nlinecolors; |
1903 |
+ int drawn_cursor; |
|
1907 | 1904 |
int matchingpos; |
1908 | 1905 |
char matchingchar; |
1909 | 1906 |
int mline,mcol; |
1910 |
- long cursorpos; |
|
1911 |
- printout_t fakeprintout; |
|
1912 |
- const char *hint; |
|
1913 |
- const char selcolornormal[]={"\xde\xcf\x7f\xff"}; |
|
1914 |
- const char selcolorcurline[]={"\xf0\xea\xc9\xff"}; |
|
1915 | 1907 |
if(re==NULL || (printout!=NULL && (printout->ui==NULL || printout->data==NULL))) |
1916 | 1908 |
return(-1); |
1909 |
+ /* init vars and clear screen */ |
|
1917 | 1910 |
ui=re->ui; |
1918 | 1911 |
data=re->data; |
1919 | 1912 |
x0=re->x; |
... | ... |
@@ -1950,6 +1943,7 @@ re_drawcontents(re_t *re, printout_t *printout) |
1950 | 1943 |
reui_fill(ui,x0,y0,w,h,"\xdf\xdf\xdf\xff"); |
1951 | 1944 |
row=curline-originline; |
1952 | 1945 |
pos=cursorpos; |
1946 |
+ /* get position/row/col of character at top left of screen */ |
|
1953 | 1947 |
while(row>0 && pos>0) { |
1954 | 1948 |
if(redata_line_rawinfo(data,pos,&newpos,NULL,NULL,&is_continuation)==-1) |
1955 | 1949 |
return(-1); |
... | ... |
@@ -1985,70 +1979,108 @@ re_drawcontents(re_t *re, printout_t *printout) |
1985 | 1979 |
if(x2>(x0)) |
1986 | 1980 |
reui_fill(ui,x0,y0+row*ui->fontheight,x2-x0,ui->fontheight+1,selcolor); |
1987 | 1981 |
} |
1988 |
- |
|
1989 | 1982 |
} |
1990 | 1983 |
row=tmprow; |
1991 | 1984 |
} |
1992 | 1985 |
/* draw the lines */ |
1986 |
+ if((colors=redata_highlighter_getcolors(data,&ncolors))==NULL) { |
|
1987 |
+ colors=&fakecolor; |
|
1988 |
+ ncolors=1; |
|
1989 |
+ memcpy(fakecolor.rgba,"\x00\x00\x00\xff",5); |
|
1990 |
+ } |
|
1993 | 1991 |
drawn_cursor=0; |
1994 |
- colors=redata_highlighter_getcolors(data,&ncolors); |
|
1995 | 1992 |
matchingpos=-1; |
1996 | 1993 |
matchingchar='\0'; |
1997 | 1994 |
for(y=y0;y<(y0+h);y+=ui->fontheight,row++) { |
1995 |
+ int in_error; |
|
1996 |
+ int availcol,tmpcol,len; |
|
1997 |
+ char *lastcolor; |
|
1998 | 1998 |
/* definition of vars for tracking linecolor usage */ |
1999 | 1999 |
int curlinecolor; /* current linecolor */ |
2000 | 2000 |
int usedlenlinecolor; /* number of bytes of current linecolor already drawn */ |
2001 |
- /* end of definitions */ |
|
2002 |
- if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1) { |
|
2001 |
+ /* get start/end of line */ |
|
2002 |
+ if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1) |
|
2003 | 2003 |
break; /* couldn't get real start/end */ |
2004 |
+ /* setup colors */ |
|
2005 |
+ if(colors==(&fakecolor) || (linecolors=redata_highlighter_getline(data,originline+row,&nlinecolors))==NULL) { |
|
2006 |
+ linecolors=&fakelinecolors; |
|
2007 |
+ fakelinecolors.len=1; |
|
2008 |
+ fakelinecolors.color=0; |
|
2004 | 2009 |
} |
2005 |
- in_error=0; |
|
2006 |
- linecolors=(colors==NULL)?NULL:redata_highlighter_getline(data,originline+row,&nlinecolors); |
|
2007 | 2010 |
curlinecolor=0; |
2008 | 2011 |
usedlenlinecolor=0; |
2012 |
+ lastcolor="\x00\x00\x00\xff"; |
|
2013 |
+ in_error=0; |
|
2014 |
+ /* draw each part of this line */ |
|
2009 | 2015 |
for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(origincol+maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) { |
2016 |
+ int has_nl; |
|
2017 |
+ char *ptr; |
|
2018 |
+ int incompletestart,incompleteend,endreq; |
|
2019 |
+ int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */ |
|
2010 | 2020 |
if(redata_line_rawinfo(data,pos,&newpos,&ptr,&len,&is_continuation)==-1) { |
2011 | 2021 |
in_error=1; |
2012 | 2022 |
break; /* couldn't get this line part info */ |
2013 | 2023 |
} |
2014 | 2024 |
has_nl=((len>0 && ptr[len-1]=='\n')?1:0); |
2015 |
- availcol=redata_generic_utf8len(ptr,len-has_nl); |
|
2016 |
-#warning TODO: consider tabs |
|
2017 |
- if(linecolors!=NULL) { |
|
2018 |
- int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */ |
|
2019 |
- used=usedcol=0; |
|
2020 |
- /* while the avail text is larger than the linecolor len */ |
|
2021 |
- while(curlinecolor<nlinecolors && (len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) { |
|
2022 |
- reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor); |
|
2023 |
- usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor); |
|
2024 |
- used+=linecolors[curlinecolor].len-usedlenlinecolor; |
|
2025 |
- curlinecolor++; |
|
2026 |
- usedlenlinecolor=0; |
|
2027 |
- } |
|
2028 |
- /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */ |
|
2029 |
- if(curlinecolor<nlinecolors && (len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) { |
|
2030 |
- reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used)); |
|
2031 |
- usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used)); |
|
2032 |
- usedlenlinecolor+=(len-has_nl-used); |
|
2033 |
- used+=(len-has_nl-used); |
|
2025 |
+ availcol=redata_generic_utf8lenincomplete(ptr,len-has_nl,&incompletestart,&incompleteend,&endreq); |
|
2026 |
+ /* display the line */ |
|
2027 |
+ used=incompletestart; |
|
2028 |
+ usedcol=0; |
|
2029 |
+ /* while the avail text is larger than the linecolor len */ |
|
2030 |
+ while(curlinecolor<nlinecolors && (len-has_nl-incompleteend-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) { |
|
2031 |
+ lastcolor=colors[linecolors[curlinecolor].color].rgba; |
|
2032 |
+ reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor); |
|
2033 |
+ usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor); |
|
2034 |
+ used+=linecolors[curlinecolor].len-usedlenlinecolor; |
|
2035 |
+ curlinecolor++; |
|
2036 |
+ usedlenlinecolor=0; |
|
2037 |
+ } |
|
2038 |
+ /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */ |
|
2039 |
+ if((len-has_nl-incompleteend-used)>0) { |
|
2040 |
+ if(curlinecolor<nlinecolors && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-incompleteend-used)) { |
|
2041 |
+ lastcolor=colors[linecolors[curlinecolor].color].rgba; |
|
2042 |
+ usedlenlinecolor+=(len-has_nl-incompleteend-used); |
|
2043 |
+ if(usedlenlinecolor==linecolors[curlinecolor].len) { |
|
2044 |
+ curlinecolor++; |
|
2045 |
+ usedlenlinecolor=0; |
|
2046 |
+ } |
|
2034 | 2047 |
} |
2035 |
- } else { |
|
2036 |
- reui_write(ui,x0+(tmpcol-origincol)*ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl); |
|
2048 |
+ reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,(len-has_nl-incompleteend-used)); |
|
2049 |
+ usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-incompleteend-used)); |
|
2050 |
+ used+=(len-has_nl-incompleteend-used); |
|
2037 | 2051 |
} |
2038 |
- if(printout==NULL && row==(curline-originline)) { |
|
2039 |
- if(curcol>=tmpcol && curcol<(tmpcol+availcol)) { |
|
2040 |
- int utf8charlen; |
|
2041 |
- /* draw cursor */ |
|
2042 |
- reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff"); |
|
2043 |
- drawn_cursor=1; |
|
2044 |
- curptr=redata_generic_utf8col(ptr,len-has_nl,curcol-tmpcol); |
|
2045 |
- curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr); |
|
2046 |
- utf8charlen=redata_generic_utf8charlen(curptr,curptrlen); |
|
2047 |
- reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen); |
|
2048 |
- /* get matching braces/parens/anglebracket/curlybraces for highlighting */ |
|
2049 |
- if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL) |
|
2050 |
- matchingpos=re_getmatchingbracket(re,cursorpos,*curptr,&matchingchar); |
|
2052 |
+ /* if the last utf-8 char is broken into several blocks */ |
|
2053 |
+ if(incompleteend>0) { |
|
2054 |
+ char broken[7]; |
|
2055 |
+ int usedbroken; |
|
2056 |
+ usedbroken=0; |
|
2057 |
+ redata_getutf8char(re->data,newpos+len-has_nl-incompleteend,broken,sizeof(broken),&usedbroken); |
|
2058 |
+ /* write the just-recomposer character in the correct color */ |
|
2059 |
+ if(curlinecolor<nlinecolors && (linecolors[curlinecolor].len-usedlenlinecolor)>=1) { |
|
2060 |
+ lastcolor=colors[linecolors[curlinecolor].color].rgba; |
|
2061 |
+ usedlenlinecolor+=1; |
|
2062 |
+ if(usedlenlinecolor==linecolors[curlinecolor].len) { |
|
2063 |
+ curlinecolor++; |
|
2064 |
+ usedlenlinecolor=0; |
|
2065 |
+ } |
|
2051 | 2066 |
} |
2067 |
+ reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,broken,usedbroken); |
|
2068 |
+ usedcol++; |
|
2069 |
+ availcol++; |
|
2070 |
+ } |
|
2071 |
+ /* draw cursor if applicable */ |
|
2072 |
+ if(printout==NULL && row==(curline-originline) && curcol>=tmpcol && curcol<(tmpcol+availcol)) { |
|
2073 |
+ char cursorchar[7]; |
|
2074 |
+ int usedcursorchar; |
|
2075 |
+ /* draw cursor */ |
|
2076 |
+ reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff"); |
|
2077 |
+ drawn_cursor=1; |
|
2078 |
+ usedcursorchar=0; |
|
2079 |
+ redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar); |
|
2080 |
+ reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar); |
|
2081 |
+ /* get matching braces/parens/anglebracket/curlybraces for highlighting */ |
|
2082 |
+ if(usedcursorchar==1 && strchr("[]{}<>()",*cursorchar)!=NULL) |
|
2083 |
+ matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar); |
|
2052 | 2084 |
} |
2053 | 2085 |
} |
2054 | 2086 |
if(printout==NULL && row==(curline-originline) && !drawn_cursor) |
... | ... |
@@ -2056,7 +2088,6 @@ re_drawcontents(re_t *re, printout_t *printout) |
2056 | 2088 |
if(in_error) |
2057 | 2089 |
break; |
2058 | 2090 |
pos=realend+1; |
2059 |
-/*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/ |
|
2060 | 2091 |
} |
2061 | 2092 |
/* highlight matching parens/brace/... if applicable */ |
2062 | 2093 |
if(printout==NULL && matchingpos!=-1 && redata_pos2linecol(data,matchingpos,&mline,&mcol)!=-1) { |
... | ... |
@@ -2078,14 +2109,14 @@ re_drawcontents(re_t *re, printout_t *printout) |
2078 | 2109 |
else |
2079 | 2110 |
reui_balloon(ui, '\0', x,y, fg, bg, &matchingchar,1); |
2080 | 2111 |
} |
2081 |
- /* display prototypes info if applicable */ |
|
2082 | 2112 |
if(printout==NULL) { |
2113 |
+ const char *hint; |
|
2083 | 2114 |
hint=redata_prototypes_get(data, cursorpos); |
2084 | 2115 |
if(hint!=NULL) { |
2085 |
- if((curline-originline)>=(maxrow/2)) |
|
2116 |
+ if((curline-originline)>=3) |
|
2086 | 2117 |
reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint)); |
2087 | 2118 |
else |
2088 |
- reui_balloon(ui, '\0', x0+w/2, y0+h-ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *)hint,strlen(hint)); |
|
2119 |
+ reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*((curline-originline)*2+5)/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint)); |
|
2089 | 2120 |
} |
2090 | 2121 |
} |
2091 | 2122 |
/* all done */ |