Changeset 1060


Ignore:
Timestamp:
Sep 19, 2006, 12:32:25 AM (14 years ago)
Author:
Sam Hocevar
Message:
  • Full Unicode support in the GL driver.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/driver_gl.c

    r1050 r1060  
    6969    float font_width, font_height;
    7070    float incx, incy;
    71     int id[(128 - 32)];
    72     int id_uni[8]; /* Hack, FIXME */
     71    unsigned long int const *blocks;
     72    int *txid;
    7373    unsigned char close;
    7474    unsigned char bit;
     
    9191    unsigned int width = 0, height = 0;
    9292    int argc = 1;
    93     int i;
     93    int i, b;
    9494
    9595    dp->drv.p = malloc(sizeof(struct driver_private));
     
    177177    glEnable(GL_TEXTURE_2D);
    178178    glEnable(GL_BLEND);
    179     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
     179    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    180180
    181181
     
    187187    glEnable(GL_TEXTURE_2D);
    188188
    189     /* ASCII glyphes textures initialisation */
    190     for(i = 32; i < 128; i++)
    191     {
    192         glGenTextures(1, (GLuint*)&dp->drv.p->id[i - 32]);
    193         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[i - 32]);
    194         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    195         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    196         glTexImage2D(GL_TEXTURE_2D, 0, 4,
    197                      16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
    198     }
    199 
    200     /* Unicode (CP437) glyphes textures initialisation */
    201     for(i = 0; i < 8; i++)
    202     {
    203         glGenTextures(1, (GLuint*)&dp->drv.p->id_uni[i]);
    204         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[i]);
    205         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    206         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    207         glTexImage2D(GL_TEXTURE_2D, 0, 4,
    208                      16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
    209     }
    210 
    211     /* Get textures for ASCII glyphs */
    212     for(i = 32; i < 128; i++)
    213         gl_generate_glyph(i, i-32, dp);
    214 
    215 
    216     gl_generate_unicode_glyph(0x00002580, 0, dp);
    217     gl_generate_unicode_glyph(0x00002584, 1, dp);
    218     gl_generate_unicode_glyph(0x00002588, 2, dp);
    219     gl_generate_unicode_glyph(0x0000258c, 3, dp);
    220     gl_generate_unicode_glyph(0x00002590, 4, dp);
    221     gl_generate_unicode_glyph(0x00002591, 5, dp);
    222     gl_generate_unicode_glyph(0x00002592, 6, dp);
    223     gl_generate_unicode_glyph(0x00002593, 7, dp);
     189    dp->drv.p->blocks = cucul_get_font_blocks(dp->drv.p->f);
     190
     191    for(b = 0, i = 0; dp->drv.p->blocks[i + 1]; i += 2)
     192        b += dp->drv.p->blocks[i + 1] - dp->drv.p->blocks[i];
     193
     194    dp->drv.p->txid = malloc(b * sizeof(int));
     195
     196    for(b = 0, i = 0; dp->drv.p->blocks[i + 1]; i += 2)
     197    {
     198        int j, n = dp->drv.p->blocks[i + 1] - dp->drv.p->blocks[i];
     199
     200        for(j = 0; j < n; j++)
     201        {
     202            glGenTextures(1, (GLuint*)&dp->drv.p->txid[b + j]);
     203            glBindTexture(GL_TEXTURE_2D, dp->drv.p->txid[b + j]);
     204            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     205            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     206            glTexImage2D(GL_TEXTURE_2D, 0, 4,
     207                         16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
     208
     209            gl_generate_unicode_glyph(dp->drv.p->blocks[i] + j, b + j, dp);
     210        }
     211
     212        b += dp->drv.p->blocks[i + 1] - dp->drv.p->blocks[i];
     213    }
    224214
    225215    return 0;
     
    229219{
    230220    glutDestroyWindow(dp->drv.p->window);
     221    free(dp->drv.p->txid);
    231222    free(dp->drv.p);
    232223    return 0;
     
    252243{
    253244    unsigned int x, y, line;
    254     static int old_texture = 0;
    255245
    256246    glClear(GL_COLOR_BUFFER_BIT);
     
    296286            uint32_t cv = *chars++;
    297287            uint16_t fg;
    298 
    299             if(cv == ' ')
    300                 continue;
    301 
    302             if(cv > 0x00000020 && cv < 0x00000080)
     288            int i, b;
     289
     290            for(b = 0, i = 0; dp->drv.p->blocks[i + 1]; i += 2)
    303291            {
    304                 if(old_texture != dp->drv.p->id[cv - 32])
     292                if(cv < dp->drv.p->blocks[i])
     293                    break;
     294
     295                if(cv >= dp->drv.p->blocks[i + 1])
    305296                {
    306                     glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[cv - 32]);
    307                     old_texture = dp->drv.p->id[cv - 32];
     297                    b += dp->drv.p->blocks[i + 1] - dp->drv.p->blocks[i];
     298                    continue;
    308299                }
     300
     301                glBindTexture(GL_TEXTURE_2D,
     302                              dp->drv.p->txid[b + cv - dp->drv.p->blocks[i]]);
     303
     304                fg = _cucul_argb32_to_rgb12fg(*attr);
     305                glColor3b(((fg & 0xf00) >> 8) * 8,
     306                          ((fg & 0x0f0) >> 4) * 8,
     307                          (fg & 0x00f) * 8);
     308                glBegin(GL_QUADS);
     309                glTexCoord2f(0, dp->drv.p->sh);
     310                glVertex2f(x, y);
     311                glTexCoord2f(dp->drv.p->sw, dp->drv.p->sh);
     312                glVertex2f(x + dp->drv.p->font_width, y);
     313                glTexCoord2f(dp->drv.p->sw, 0);
     314                glVertex2f(x + dp->drv.p->font_width,
     315                           y + dp->drv.p->font_height);
     316                glTexCoord2f(0, 0);
     317                glVertex2f(x, y + dp->drv.p->font_height);
     318                glEnd();
    309319            }
    310             else switch(cv)
    311             {
    312                 case 0x00002580: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[0]); break;
    313                 case 0x00002584: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[1]); break;
    314                 case 0x00002588: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[2]); break;
    315                 case 0x0000258c: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[3]); break;
    316                 case 0x00002590: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[4]); break;
    317                 case 0x00002591: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[5]); break;
    318                 case 0x00002592: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[6]); break;
    319                 case 0x00002593: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[7]); break;
    320                 default:         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id['?' - 32]); break;
    321             }
    322 
    323             fg = _cucul_argb32_to_rgb12fg(*attr);
    324             glColor3b(((fg & 0xf00) >> 8) * 8,
    325                       ((fg & 0x0f0) >> 4) * 8,
    326                       (fg & 0x00f) * 8);
    327             glBegin(GL_QUADS);
    328             glTexCoord2f(0, dp->drv.p->sh);
    329             glVertex2f(x, y);
    330             glTexCoord2f(dp->drv.p->sw, dp->drv.p->sh);
    331             glVertex2f(x + dp->drv.p->font_width, y);
    332             glTexCoord2f(dp->drv.p->sw, 0);
    333             glVertex2f(x + dp->drv.p->font_width,
    334                        y + dp->drv.p->font_height);
    335             glTexCoord2f(0, 0);
    336             glVertex2f(x, y + dp->drv.p->font_height);
    337             glEnd();
    338320        }
    339321    }
     
    541523}
    542524
    543 static void gl_generate_glyph(uint32_t c, uint32_t tid, caca_display_t *dp)
    544 {
    545     int s,d;
    546     uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
    547     uint8_t *glyph32 = calloc(16*16*4, 1);
     525static void gl_generate_unicode_glyph(uint32_t c, uint32_t tid,
     526                                      caca_display_t *dp)
     527{
     528    int y, x, w, h;
     529    uint8_t *glyph8 = calloc(dp->drv.p->font_width * dp->drv.p->font_height, 1);
     530    uint8_t *glyph32 = calloc(16 * 16 * 4, 1);
    548531
    549532    cucul_render_glyph(dp->drv.p->f, c, glyph8, dp->drv.p->font_width);
    550533
    551     /* Convert resulting 8bbp glyph to 32bits, 16x16*/
    552     for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++)
    553     {
    554         for(d=0;d<dp->drv.p->font_width;d++)
     534    w = dp->drv.p->font_width <= 16 ? dp->drv.p->font_width : 16;
     535    h = dp->drv.p->font_height <= 16 ? dp->drv.p->font_height : 16;
     536
     537    /* Convert resulting 8bbp glyph to 32bits, 16x16 */
     538    for(y = 0; y < h; y++)
     539    {
     540        for(x = 0; x < w; x++)
    555541        {
    556             uint32_t offset = d*4+(15-s)*16*4;
    557             uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
     542            uint32_t offset = x * 4 + (15 - y) * 16 * 4;
     543            uint8_t c = glyph8[x + y * (int)dp->drv.p->font_width];
    558544            glyph32[offset] = c;
    559             glyph32[1+offset] = c;
    560             glyph32[2+offset] = c;
    561             glyph32[3+offset] = c;
     545            glyph32[1 + offset] = c;
     546            glyph32[2 + offset] = c;
     547            glyph32[3 + offset] = c;
    562548        }
    563549    }
    564550
    565     glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[tid]);
     551    glBindTexture(GL_TEXTURE_2D, dp->drv.p->txid[tid]);
    566552    glTexImage2D(GL_TEXTURE_2D,
    567553                 0, 4,
     
    569555                 0, GL_RGBA, GL_UNSIGNED_BYTE,
    570556                 glyph32);
    571     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    572     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    573     free(glyph8);
    574     free(glyph32);
    575 }
    576 
    577 static void gl_generate_unicode_glyph(uint32_t c, uint32_t tid,
    578                                       caca_display_t *dp)
    579 {
    580     int s,d;
    581     uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
    582     uint8_t *glyph32 = calloc(16*16*4, 1);
    583 
    584     cucul_render_glyph(dp->drv.p->f, c, glyph8, dp->drv.p->font_width);
    585 
    586     /* Convert resulting 8bbp glyph to 32bits, 16x16*/
    587     for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++)
    588     {
    589         for(d=0;d<(dp->drv.p->font_width<=16?dp->drv.p->font_width:16);d++)
    590         {
    591             uint32_t offset = d*4+(15-s)*16*4;
    592             uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
    593             glyph32[offset] = c;
    594             glyph32[1+offset] = c;
    595             glyph32[2+offset] = c;
    596             glyph32[3+offset] = c;
    597         }
    598     }
    599 
    600     glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[tid]);
    601     glTexImage2D(GL_TEXTURE_2D,
    602                  0, 4,
    603                  16,16,
    604                  0, GL_RGBA, GL_UNSIGNED_BYTE,
    605                  glyph32);
    606     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    607     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
     557    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     558    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    608559    free(glyph8);
    609560    free(glyph32);
Note: See TracChangeset for help on using the changeset viewer.