Changeset 491


Ignore:
Timestamp:
Jun 24, 2005, 1:48:31 PM (16 years ago)
Author:
Sam Hocevar
Message:
  • src/graphics.c: more optimisations in the exporters
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/src/graphics.c

    r490 r491  
    266266int id[94];
    267267unsigned char gl_resized=0, gl_bit=0;
    268 #endif 
     268#endif
    269269
    270270
     
    320320      gl_new_width = w;
    321321      gl_new_height = h;
    322      
     322
    323323      gl_resized = 1;
    324324    }
    325325  else
    326326    gl_bit=1;
    327  
     327
    328328}
    329329#endif
     
    984984            sscanf(getenv("CACA_GEOMETRY"),
    985985                   "%ux%u", &_caca_width, &_caca_height);
    986          
     986
    987987        if(!_caca_width)
    988988            _caca_width = 80;
     
    994994
    995995          gl_width =  _caca_width*gl_font_width;
    996           gl_height = _caca_height*gl_font_height; 
    997 
    998           glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
    999           glutInitWindowSize(gl_width, gl_height); 
     996          gl_height = _caca_height*gl_font_height;
     997
     998          glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
     999          glutInitWindowSize(gl_width, gl_height);
    10001000          gl_window = glutCreateWindow("caca for GL");
    10011001
     
    10031003
    10041004          glDisable(GL_CULL_FACE);
    1005           glDisable(GL_DEPTH_TEST); 
     1005          glDisable(GL_DEPTH_TEST);
    10061006
    10071007          glutKeyboardFunc(gl_handle_keyboard);
     
    10291029          memset(empty, 255, 16*16*4);
    10301030          glEnable(GL_TEXTURE_2D);
    1031          
     1031
    10321032          for(i=0;i<94;i++)
    10331033            {
    1034               glGenTextures(1,&id[i]); 
     1034              glGenTextures(1,&id[i]);
    10351035              glBindTexture(GL_TEXTURE_2D, id[i]);
    10361036              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     
    10421042          for(i=0;i<94;i++)
    10431043            {
    1044              
     1044
    10451045              glDisable(GL_TEXTURE_2D);
    10461046              glClear(GL_COLOR_BUFFER_BIT);
     
    10481048              glColor3f(1,1,1);
    10491049              glRasterPos2f(0,15);
    1050               glutBitmapCharacter(GLUT_BITMAP_9_BY_15,i+32); 
    1051              
     1050              glutBitmapCharacter(GLUT_BITMAP_9_BY_15,i+32);
     1051
    10521052
    10531053              glEnable(GL_TEXTURE_2D);
    1054               glBindTexture(GL_TEXTURE_2D,id[i]);                       
     1054              glBindTexture(GL_TEXTURE_2D,id[i]);
    10551055              glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, gl_height-16, 16,16, 0);
    1056              
     1056
    10571057              glutMainLoopEvent();
    10581058              glutPostRedisplay();
     
    10661066          if(getenv("CACA_GEOMETRY") && *(getenv("CACA_GEOMETRY")))
    10671067            sscanf(getenv("CACA_GEOMETRY"),
    1068                    "%ux%u", &_caca_width, &_caca_height); 
     1068                   "%ux%u", &_caca_width, &_caca_height);
    10691069          if(!_caca_width)
    10701070            _caca_width = 80;
     
    14561456        {
    14571457          unsigned int x, y, offsetx, offsety;
    1458          
     1458
    14591459
    14601460          glClear(GL_COLOR_BUFFER_BIT);
    1461          
     1461
    14621462          offsety=0;
    14631463                for(y=0;y<gl_height;y+=gl_font_height)
     
    14741474                bg = ((gl_bg_palette[offset]&0x0000FF00)>>8)/255.0f;
    14751475                bb = ((gl_bg_palette[offset]&0x000000FF))/255.0f;
    1476        
     1476
    14771477                glDisable(GL_TEXTURE_2D);
    14781478                glColor3f(br, bg, bb);
     
    14831483                glVertex2f(x,y+gl_font_height);
    14841484                glEnd();
    1485        
     1485
    14861486
    14871487                  offsetx++;
    1488               }         
     1488              }
    14891489
    14901490            offsety++;
     
    14971497          glEnable(GL_TEXTURE_2D);
    14981498          glBlendFunc(GL_ONE, GL_ONE);
    1499                
     1499
    15001500          offsety=0;
    15011501                for(y=0;y<gl_height;y+=gl_font_height)
     
    15071507                  unsigned char *chr = cache_char + offsetx + offsety * _caca_width;
    15081508                  float fr, fg, fb;
    1509        
    1510                
     1509
     1510
    15111511                  fr = ((gl_bg_palette[attr[0] & 0xf]&0x00FF0000)>>16)/255.0f;
    15121512                  fg = ((gl_bg_palette[attr[0] & 0xf]&0x0000FF00)>>8)/255.0f;
     
    15161516                    {
    15171517                      glBindTexture(GL_TEXTURE_2D, id[chr[0]-32]);
    1518                    
     1518
    15191519                      glColor3f(fr, fg, fb);
    15201520                      glBegin(GL_QUADS);
     
    15271527                      glTexCoord2f(0,0);
    15281528                      glVertex2f(x,y+gl_font_height);
    1529                       glEnd();   
     1529                      glEnd();
    15301530                    }
    15311531                  offsetx++;
     
    16561656      gl_width = gl_new_width;
    16571657      gl_height = gl_new_height;
    1658          
     1658
    16591659      _caca_width = gl_width/gl_font_width;
    16601660      _caca_height = (gl_height/gl_font_height)+1;
    1661      
     1661
    16621662      glMatrixMode(GL_PROJECTION);
    16631663      glPushMatrix();
    16641664      glLoadIdentity();
    1665      
     1665
    16661666      glViewport(0,0,gl_width, gl_height);
    1667       gluOrtho2D(0, gl_width, gl_height, 0);     
     1667      gluOrtho2D(0, gl_width, gl_height, 0);
    16681668      glMatrixMode(GL_MODELVIEW);
    16691669
     
    17711771/* Exporters */
    17721772
    1773 
    17741773/* HTML */
    1775 static int const html_palette[] =
    1776 {
    1777     0,
    1778     0x007,
    1779     0x070,
    1780     0x077,
    1781     0x700,
    1782     0x707,
    1783     0x770,
    1784     0x777,
    1785     0,
    1786     0x00F,
    1787     0x0F0,
    1788     0x0FF,
    1789     0xF00,
    1790     0xF0F,
    1791     0xFF0,
    1792     0xFFF,
    1793 
    1794 };
    17951774
    17961775/** \brief Generate HTML representation of current image.
    17971776 *
    1798  *  This function generates and returns the HTML representation of 
     1777 *  This function generates and returns the HTML representation of
    17991778 *  the current image.
    1800  *
    18011779 */
    18021780char* caca_get_html(void)
    18031781{
     1782    static int const palette[] =
     1783    {
     1784        0x000, 0x008, 0x080, 0x088, 0x800, 0x808, 0x880, 0x888,
     1785        0x444, 0x44f, 0x4f4, 0x4ff, 0xf44, 0xf4f, 0xff4, 0xfff,
     1786    };
    18041787    char *buffer, *cur;
    18051788    unsigned int x, y, len;
     
    18201803    {
    18211804        cur += sprintf(cur, ".b%02x { color:#%03x; background-color:#%03x; }\n",
    1822                        x, html_palette[x & 0xf ], html_palette[x >> 4]);
     1805                       x, palette[x & 0xf ], palette[x >> 4]);
    18231806    }
    18241807    cur += sprintf(cur, "</style>\n</head>\n<body>\n");
     
    18291812    for(y = 0; y < _caca_height; y++)
    18301813    {
     1814        uint8_t *lineattr = cache_attr + y * _caca_width;
     1815        uint8_t *linechar = cache_char + y * _caca_width;
     1816
    18311817        for(x = 0; x < _caca_width; x += len)
    18321818        {
    1833             uint8_t *cur_attr = cache_attr + y * _caca_width;
    1834             uint8_t *cur_char = cache_char + y * _caca_width;
    1835 
    1836             cur += sprintf(cur, "<span class='b%02x'>", cur_attr[x]);
    1837 
    1838             for(len = 0;
    1839                 x + len < _caca_width && cur_attr[x + len] == cur_attr[x];
     1819            cur += sprintf(cur, "<span class='b%02x'>", lineattr[x]);
     1820
     1821            for(len = 0;
     1822                x + len < _caca_width && lineattr[x + len] == lineattr[x];
    18401823                len++)
    18411824            {
    1842                 if(cur_char[x + len] == ' ')
     1825                if(linechar[x + len] == ' ')
    18431826                    cur += sprintf(cur, "&nbsp;");
    18441827                else
    1845                     cur += sprintf(cur, "%c", cur_char[x + len]);
     1828                    cur += sprintf(cur, "%c", linechar[x + len]);
    18461829            }
    18471830            cur += sprintf(cur, "</span>");
     
    18611844/** \brief Generate HTML3 representation of current image.
    18621845 *
    1863  *  This function generates and returns the HTML3 representation of 
     1846 *  This function generates and returns the HTML3 representation of
    18641847 *  the current image. It is way bigger than caca_get_html(), but
    18651848 *  permits viewing in old browsers (or limited ones such as links)
    1866  *  Won't work under gecko (mozilla rendering engine) unless you set 
     1849 *  Won't work under gecko (mozilla rendering engine) unless you set
    18671850 *  a correct header.
    18681851 */
    18691852char* caca_get_html3(void)
    18701853{
    1871   char *buffer, *cur;
    1872   unsigned int x,y;
    1873 
    1874   /* 13000 -> css palette
    1875      40 -> max size used for a pixel (plus 10, never know)*/
    1876 
    1877   buffer = malloc((13000 + ((_caca_width*_caca_height)*40))*sizeof(char));
    1878   cur = buffer;
    1879 
    1880   /* Table */
    1881   cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n", caca_get_height());
    1882 
    1883   for(y=0;y<_caca_height;y++)
    1884     {
    1885       cur += sprintf(cur, "<tr>");
    1886      
    1887       for(x=0;x<_caca_width;x++)
    1888         {
    1889           int len;
    1890           int i;
    1891           uint8_t *attr = cache_attr + x + y * _caca_width;
    1892 
    1893           /* Use colspan option to factorize cells with same attributes
    1894              (see below) */
    1895           len=1;
    1896           while(x + len < _caca_width
    1897                 && (attr[len]>>4) == (attr[0]>>4) &&
    1898                 (attr[len]&0x0f) == (attr[0]&0x0f))
    1899             len++;
    1900          
    1901           if(len==1)
    1902             {
    1903               cur += sprintf(cur,
    1904                       "<td bgcolor=#%03X ><font color=#%03X>%c</font></td>",
    1905                       html_palette[cache_attr[x+y*caca_get_width()]>>4],
    1906                       html_palette[cache_attr[x+y*caca_get_width()]&0x0f],
    1907                       cache_char[x+y*caca_get_width()]);
    1908             }
    1909           else
    1910             {
    1911               cur += sprintf(cur,
    1912                       "<td bgcolor=#%03X colspan=%d><font color=#%03X>",
    1913                       html_palette[cache_attr[x+y*caca_get_width()]>> 4],
    1914                       len+1,
    1915                       html_palette[cache_attr[x+y*caca_get_width()]&0x0f]);
    1916              
    1917               for(i=0;i<len;i++)
    1918                 {
    1919                   if(cache_char[x+y*caca_get_width()]!=' ')
    1920                     cur += sprintf(cur, "%c", cache_char[x+y*caca_get_width()]);
    1921                   else
    1922                     cur += sprintf(cur, "&nbsp;");
    1923                   x++;
    1924                 }
    1925               cur += sprintf(cur, "</font></td>");
    1926              
    1927             }
    1928 
    1929         }
    1930       cur += sprintf(cur, "</tr>\n");
    1931     }
    1932 
    1933   /* Footer */
    1934   cur += sprintf(cur, "</table>\n");
    1935 
    1936   /* Crop to really used size */
    1937   buffer = realloc(buffer, (strlen(buffer)+1) * sizeof(char));
    1938 
    1939   return buffer;
    1940 }
    1941 
    1942 
    1943 static int const irc_palette[] =
    1944 {
    1945     /* Dark */
    1946     1, 2, 3, 10, 5, 6, 7, 14,
    1947     /* Light */
    1948     1, 12, 9, 11, 4, 13, 8, 16,
    1949 };
    1950 
     1854    static int const palette[] =
     1855    {
     1856        0x000000, 0x000088, 0x008800, 0x008888,
     1857        0x880000, 0x880088, 0x888800, 0x888888,
     1858        0x444444, 0x4444ff, 0x44ff44, 0x44ffff,
     1859        0xff4444, 0xff44ff, 0xffff44, 0xffffff,
     1860    };
     1861    char *buffer, *cur;
     1862    unsigned int x, y, len;
     1863
     1864    /* 13000 -> css palette
     1865     * 40 -> max size used for a pixel (plus 10, never know) */
     1866    buffer = malloc((13000 + ((_caca_width*_caca_height)*40))*sizeof(char));
     1867    cur = buffer;
     1868
     1869    /* Table */
     1870    cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n",
     1871                        _caca_height);
     1872
     1873    for(y = 0; y < _caca_height; y++)
     1874    {
     1875        uint8_t *lineattr = cache_attr + y * _caca_width;
     1876        uint8_t *linechar = cache_char + y * _caca_width;
     1877
     1878        cur += sprintf(cur, "<tr>");
     1879
     1880        for(x = 0; x < _caca_width; x += len)
     1881        {
     1882            int i;
     1883
     1884            /* Use colspan option to factorize cells with same attributes
     1885             * (see below) */
     1886            len = 1;
     1887            while(x + len < _caca_width && lineattr[x + len] == lineattr[x])
     1888                len++;
     1889
     1890            cur += sprintf(cur, "<td bgcolor=#%06x", palette[lineattr[x] >> 4]);
     1891
     1892            if(len > 1)
     1893                cur += sprintf(cur, " colspan=%d", len);
     1894
     1895            cur += sprintf(cur, "><font color=#%06x>",
     1896                                palette[lineattr[x] & 0x0f]);
     1897
     1898            for(i = 0; i < len; i++)
     1899            {
     1900                if(linechar[x + i] == ' ')
     1901                    cur += sprintf(cur, "&nbsp;");
     1902                else
     1903                    cur += sprintf(cur, "%c", linechar[x + i]);
     1904            }
     1905
     1906            cur += sprintf(cur, "</font></td>");
     1907        }
     1908        cur += sprintf(cur, "</tr>\n");
     1909    }
     1910
     1911    /* Footer */
     1912    cur += sprintf(cur, "</table>\n");
     1913
     1914    /* Crop to really used size */
     1915    buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));
     1916
     1917    return buffer;
     1918}
    19511919
    19521920/** \brief Generate IRC representation of current image.
    19531921 *
    1954  *  This function generates and returns an IRC representation of 
     1922 *  This function generates and returns an IRC representation of
    19551923 *  the current image.
    1956  *  This is XChat-like format, %Cf,b  with f the foreground color,
    1957  *  and b the background color.
    1958  *
    19591924 */
    19601925char* caca_get_irc(void)
    19611926{
    1962   char *buffer;
    1963   unsigned int x, y;
    1964   /* 15 bytes assumed for max length per pixel */
    1965   buffer = malloc(((_caca_width*_caca_height*15)+1)*sizeof(char));
    1966 
    1967   sprintf(buffer, "%%O");
    1968 
    1969   for(y = 0; y < _caca_height; y++)
    1970   {
    1971       for(x = 0; x < _caca_width; x++)
    1972         {
    1973           if(cache_char[x+y*caca_get_width()] == ' ')
     1927    static int const palette[] =
     1928    {
     1929        1, 2, 3, 10, 5, 6, 7, 15, /* Dark */
     1930        14, 12, 9, 11, 4, 13, 8, 0, /* Light */
     1931    };
     1932
     1933    char *buffer, *cur;
     1934    unsigned int x, y;
     1935
     1936    /* 11 bytes assumed for max length per pixel. Worst case scenario:
     1937     * ^Cxx,yy   6 bytes
     1938     * ^B^B      2 bytes
     1939     * c         1 byte
     1940     * \r\n      2 bytes
     1941     * In real life, the average bytes per pixel value will be around 5.
     1942     */
     1943    buffer = malloc((2 + (_caca_width * _caca_height * 11)) * sizeof(char));
     1944    cur = buffer;
     1945
     1946    *cur++ = '\x0f';
     1947
     1948    for(y = 0; y < _caca_height; y++)
     1949    {
     1950        uint8_t *lineattr = cache_attr + y * _caca_width;
     1951        uint8_t *linechar = cache_char + y * _caca_width;
     1952
     1953        uint8_t prevfg = -1;
     1954        uint8_t prevbg = -1;
     1955
     1956        for(x = 0; x < _caca_width; x++)
     1957        {
     1958            uint8_t fg = palette[lineattr[x] & 0x0f];
     1959            uint8_t bg = palette[lineattr[x] >> 4];
     1960            uint8_t c = linechar[x];
     1961
     1962            if(bg == prevbg)
    19741963            {
    1975              sprintf(buffer,
    1976                      "%s%%C%d,%d%c", buffer,
    1977                      irc_palette[cache_attr[x+y*caca_get_width()]>>4],
    1978                      irc_palette[cache_attr[x+y*caca_get_width()]>>4],
    1979                      '#');
     1964                if(fg == prevfg)
     1965                    ; /* Same fg/bg, do nothing */
     1966                else if(c == ' ')
     1967                    fg = prevfg; /* Hackety hack */
     1968                else
     1969                {
     1970                    cur += sprintf(cur, "\x03%d", fg);
     1971                    if(c >= '0' && c <= '9')
     1972                        cur += sprintf(cur, "\x02\x02");
     1973                }
    19801974            }
    1981           else if(cache_char[x+y*caca_get_width()] == '%')
     1975            else
    19821976            {
    1983               sprintf(buffer,
    1984                       "%s%%C%d,%d%%%%",  buffer,
    1985                       irc_palette[cache_attr[x+y*caca_get_width()]&0x0f],
    1986                       irc_palette[cache_attr[x+y*caca_get_width()]>> 4]);
     1977                if(fg == prevfg)
     1978                    cur += sprintf(cur, "\x03,%d", bg);
     1979                else
     1980                    cur += sprintf(cur, "\x03%d,%d", fg, bg);
     1981
     1982                if(c >= '0' && c <= '9')
     1983                    cur += sprintf(cur, "\x02\x02");
    19871984            }
    1988           else if(cache_char[x+y*caca_get_width()]>='0' && cache_char[x+y*caca_get_width()]<='9')
    1989             {
    1990               sprintf(buffer,
    1991                       "%s%%C%d,%d%%B%%B%c", buffer,
    1992                       irc_palette[cache_attr[x+y*caca_get_width()]&0x0f],
    1993                       irc_palette[cache_attr[x+y*caca_get_width()]>> 4],
    1994                       cache_char[x+y*caca_get_width()]);
    1995             }
    1996           else
    1997             {
    1998               sprintf(buffer,
    1999                       "%s%%C%d,%d%c", buffer,
    2000                       irc_palette[cache_attr[x+y*caca_get_width()]&0x0f],
    2001                       irc_palette[cache_attr[x+y*caca_get_width()]>> 4],
    2002                       cache_char[x+y*caca_get_width()]);
    2003             }
    2004          
    2005         }
    2006       sprintf(buffer, "%s\n", buffer);
    2007   }
    2008  
    2009   /* Crop to really used size */
    2010   buffer = realloc(buffer, (strlen(buffer)+1) * sizeof(char));
    2011  
    2012   return buffer;
    2013 }
     1985            *cur++ = c;
     1986            prevfg = fg;
     1987            prevbg = bg;
     1988        }
     1989        *cur++ = '\r';
     1990        *cur++ = '\n';
     1991    }
     1992
     1993    *cur++ = '\x0f';
     1994
     1995    /* Crop to really used size */
     1996    buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));
     1997
     1998    return buffer;
     1999}
     2000
Note: See TracChangeset for help on using the changeset viewer.