Changeset 1024


Ignore:
Timestamp:
Sep 16, 2006, 2:40:37 PM (13 years ago)
Author:
Jean-Yves Lamoureux
Message:
  • OpenGL builtin font support
Location:
libcaca/trunk
Files:
3 edited

Legend:

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

    r1008 r1024  
    3939#include "cucul_internals.h"
    4040
     41
    4142/*
    4243 * Global variables
     
    5758#endif
    5859static void _display(void);
     60void gl_generate_glyph(uint32_t c, uint32_t tid, caca_display_t *dp);
     61void gl_generate_unicode_glyph(uint32_t c, uint32_t tid, caca_display_t *dp);
    5962
    6063struct driver_private
     
    6366    unsigned int width, height;
    6467    unsigned int new_width, new_height;
     68    cucul_font_t *f;
    6569    float font_width, font_height;
    6670    float incx, incy;
     
    7781
    7882    float sw, sh;
     83
    7984};
    8085
     
    8489    char const *geometry;
    8590    char *argv[2] = { "", NULL };
     91    char const * const * fonts;
    8692    unsigned int width = 0, height = 0;
    8793    int argc = 1;
     
    101107        _cucul_set_canvas_size(dp->cv, width, height);
    102108
    103     dp->drv.p->font_width = 9;
    104     dp->drv.p->font_height = 15;
     109
     110    /* Load a libcucul internal font */
     111    fonts = cucul_get_font_list();
     112    if(fonts[0] == NULL)
     113    {
     114        fprintf(stderr, "error: libcucul was compiled without any fonts\n");
     115        return -1;
     116    }
     117    dp->drv.p->f = cucul_load_font(fonts[0], 0);
     118    if(dp->drv.p->f == NULL)
     119    {
     120        fprintf(stderr, "error: could not load font \"%s\"\n", fonts[0]);
     121        return -1;
     122    }
     123
     124    dp->drv.p->font_width = cucul_get_font_width(dp->drv.p->f);
     125    dp->drv.p->font_height = cucul_get_font_height(dp->drv.p->f);
    105126
    106127    dp->drv.p->width = dp->cv->width * dp->drv.p->font_width;
     
    118139    dp->drv.p->special_key = 0;
    119140
    120     dp->drv.p->sw = 9.0f / 16.0f;
    121     dp->drv.p->sh = 15.0f / 16.0f;
     141    dp->drv.p->sw = ((float)dp->drv.p->font_width) / 16.0f;
     142    dp->drv.p->sh = ((float)dp->drv.p->font_height) / 16.0f;
    122143
    123144    glutInit(&argc, argv);
    124145
    125     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
     146    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    126147    glutInitWindowSize(dp->drv.p->width, dp->drv.p->height);
    127148    dp->drv.p->window = glutCreateWindow("caca for GL");
     
    163184    glEnable(GL_TEXTURE_2D);
    164185
     186    /* ASCII glyphes textures initialisation */
    165187    for(i = 32; i < 128; i++)
    166188    {
     
    169191        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    170192        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    171         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
    172                      16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, empty_texture);
    173     }
    174 
     193        glTexImage2D(GL_TEXTURE_2D, 0, 4,
     194                     16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
     195    }
     196
     197    /* Unicode (CP437) glyphes textures initialisation */
    175198    for(i = 0; i < 8; i++)
    176199    {
     
    179202        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    180203        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    181         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
    182                      16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, empty_texture);
    183     }
    184 
     204        glTexImage2D(GL_TEXTURE_2D, 0, 4,
     205                     16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
     206    }
     207
     208    /* Get textures for ASCII glyphs */
    185209    for(i = 32; i < 128; i++)
    186     {
    187         glDisable(GL_TEXTURE_2D);
    188         glClear(GL_COLOR_BUFFER_BIT);
    189 
    190         glColor3f(1, 1, 1);
    191         glRasterPos2f(0, 15);
    192         glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i);
    193 
    194         glEnable(GL_TEXTURE_2D);
    195         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[i - 32]);
    196         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
    197                          0, dp->drv.p->height - 16, 16, 16, 0);
    198 
    199 #ifdef HAVE_GLUTCHECKLOOP
    200         glutCheckLoop();
    201 #else
    202         glutMainLoopEvent();
    203 #endif
    204         glutSwapBuffers();
    205 
    206     }
    207 
    208     /* CP437 hack */
    209     for(i = 0; i < 8; i++)
    210     {
    211         glDisable(GL_TEXTURE_2D);
    212         glClear(GL_COLOR_BUFFER_BIT);
    213         glColor3f(1, 1, 1);
    214         glTranslatef(0.5,0.5,0);
    215 
    216         switch(i)
    217         {
    218         case 0: /* 0x00002580 */
    219             glBegin(GL_QUADS);
    220             glVertex2f(0,0); glVertex2f(9,0); glVertex2f(9,7); glVertex2f(0,7);
    221             glEnd();
    222             break;
    223         case 1: /* 0x00002584 */
    224             glBegin(GL_QUADS);
    225             glVertex2f(0,7); glVertex2f(9,7); glVertex2f(9,15); glVertex2f(0,15);
    226             glEnd();
    227             break;
    228         case 2: /* 0x00002588 */
    229             glBegin(GL_QUADS);
    230             glVertex2f(0,0); glVertex2f(9,0); glVertex2f(9,15); glVertex2f(0,15);
    231             glEnd();
    232             break;
    233         case 3: /* 0x0000258c */
    234             glBegin(GL_QUADS);
    235             glVertex2f(0,0); glVertex2f(4,0); glVertex2f(4,15); glVertex2f(0,15);
    236             glEnd();
    237             break;
    238         case 4: /* 0x00002590 */
    239             glBegin(GL_QUADS);
    240             glVertex2f(4,0); glVertex2f(9,0); glVertex2f(9,15); glVertex2f(4,15);
    241             glEnd();
    242             break;
    243         default: /* 0x0000259[123] */
    244             {
    245                 int a, j, k = i - 5;
    246                 for(j = dp->drv.p->font_height; j--; )
    247                     for(a = dp->drv.p->font_width; a--; )
    248                     {
    249                         if(((a + 2 * (j & 1)) & 3) > k)
    250                             continue;
    251 
    252                         glBegin(GL_POINTS);
    253                         glVertex2f(a, j);
    254                         glEnd();
    255                     }
    256             }
    257         }
    258 
    259         glEnable(GL_TEXTURE_2D);
    260         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[i]);
    261         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
    262                          0, dp->drv.p->height - 16, 16, 16, 0);
    263 #ifdef HAVE_GLUTCHECKLOOP
    264         glutCheckLoop();
    265 #else
    266         glutMainLoopEvent();
    267 #endif
    268         glutSwapBuffers();
    269         glutPostRedisplay();
    270     }
     210        gl_generate_glyph(i, i-32, dp);
     211
     212
     213    gl_generate_unicode_glyph(0x00002580, 0, dp);
     214    gl_generate_unicode_glyph(0x00002584, 1, dp);
     215    gl_generate_unicode_glyph(0x00002588, 2, dp);
     216    gl_generate_unicode_glyph(0x0000258c, 3, dp);
     217    gl_generate_unicode_glyph(0x00002590, 4, dp);
     218    gl_generate_unicode_glyph(0x00002591, 5, dp);
     219    gl_generate_unicode_glyph(0x00002592, 6, dp);
     220    gl_generate_unicode_glyph(0x00002593, 7, dp);
    271221
    272222    return 0;
     
    311261            uint16_t bg = _cucul_argb32_to_rgb12bg(*attr++);
    312262            glDisable(GL_TEXTURE_2D);
    313             glColor3b(((bg & 0xf00) >> 8) * 8,
     263            glColor4b(((bg & 0xf00) >> 8) * 8,
    314264                      ((bg & 0x0f0) >> 4) * 8,
    315                       (bg & 0x00f) * 8);
     265                      (bg & 0x00f) * 8,
     266                      0xff);
    316267            glBegin(GL_QUADS);
    317268            glVertex2f(x, y);
     
    329280    glEnable(GL_TEXTURE_2D);
    330281    glEnable(GL_BLEND);
    331     glBlendFunc(GL_ONE, GL_ONE);
     282    glBlendFunc(GL_SRC_ALPHA,GL_ONE);
    332283
    333284    line = 0;
     
    612563}
    613564
     565
     566
     567void gl_generate_glyph(uint32_t c, uint32_t tid, caca_display_t *dp) {
     568    int s,d;
     569    uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
     570    uint8_t *glyph32 = calloc(16*16*4, 1);
     571
     572    cucul_render_glyph(dp->drv.p->f, c,
     573                       glyph8, dp->drv.p->font_width, dp->drv.p->font_height);
     574
     575
     576    /* Convert resulting 8bbp glyph to 32bits, 16x16*/
     577    for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++) {
     578        for(d=0;d<dp->drv.p->font_width;d++)
     579        {
     580            uint32_t offset = d*4+(15-s)*16*4;
     581            uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
     582            glyph32[offset] = c;
     583            glyph32[1+offset] = c;
     584            glyph32[2+offset] = c;
     585            glyph32[3+offset] = c;
     586        }
     587    }
     588
     589    glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[tid]);
     590    glTexImage2D(GL_TEXTURE_2D,
     591                 0, 4,
     592                 16,16,
     593                 0, GL_RGBA, GL_UNSIGNED_BYTE,
     594                 glyph32);
     595    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
     596    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
     597    free(glyph8);
     598    free(glyph32);
     599}
     600
     601void gl_generate_unicode_glyph(uint32_t c, uint32_t tid, caca_display_t *dp) {
     602    int s,d;
     603    uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
     604    uint8_t *glyph32 = calloc(16*16*4, 1);
     605
     606    cucul_render_glyph(dp->drv.p->f, c,
     607                       glyph8, dp->drv.p->font_width, dp->drv.p->font_height);
     608
     609
     610    /* Convert resulting 8bbp glyph to 32bits, 16x16*/
     611    for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++) {
     612        for(d=0;d<(dp->drv.p->font_width<=16?dp->drv.p->font_width:16);d++)
     613        {
     614            uint32_t offset = d*4+(15-s)*16*4;
     615            uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
     616            glyph32[offset] = c;
     617            glyph32[1+offset] = c;
     618            glyph32[2+offset] = c;
     619            glyph32[3+offset] = c;
     620        }
     621    }
     622
     623    glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[tid]);
     624    glTexImage2D(GL_TEXTURE_2D,
     625                 0, 4,
     626                 16,16,
     627                 0, GL_RGBA, GL_UNSIGNED_BYTE,
     628                 glyph32);
     629    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
     630    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
     631    free(glyph8);
     632    free(glyph32);
     633}
     634
     635
     636
     637
     638
     639
    614640#endif /* USE_GL */
    615641
  • libcaca/trunk/cucul/cucul.h

    r982 r1024  
    209209int cucul_render_canvas(cucul_canvas_t *, cucul_font_t *, void *,
    210210                         unsigned int, unsigned int, unsigned int);
     211int cucul_render_glyph(cucul_font_t *, unsigned int, void *,
     212                       unsigned int, unsigned int);
    211213int cucul_free_font(cucul_font_t *);
    212214/*  @} */
  • libcaca/trunk/cucul/font.c

    r961 r1024  
    446446}
    447447
     448/** \brief Render the given character onto given buffer
     449 *
     450 *  This function renders the given character on an image buffer using a specific
     451 *  font. The pixel format is fixed (8 bits per pixel).
     452 *
     453 *  The required buffer width can be computed using
     454 *  cucul_get_canvas_width() and cucul_get_font_width(). The required
     455 *  height can be computed using cucul_get_canvas_height() and
     456 *  cucul_get_font_height().
     457 *
     458 *  Glyphs that do not fit in the image buffer are currently not rendered at
     459 *  all. They may be cropped instead in future versions.
     460 *
     461 *  This function never fails.
     462 *
     463 *  \param f The font, as returned by cucul_load_font()
     464 *  \param ch The character to render
     465 *  \param buf The image buffer
     466 *  \param width The width (in pixels) of the image buffer
     467 *  \param height The height (in pixels) of the image buffer
     468 *  \return This function return 1 if glyph is succesfully renderer, 0 otherwise
     469 */
     470int cucul_render_glyph(cucul_font_t *f, unsigned int ch, void *buffer,
     471                       unsigned int width, unsigned int height)
     472{
     473    unsigned int b;
     474    struct glyph_info *g;
     475    uint8_t *glyph = buffer;
     476
     477
     478
     479    /* Find the Unicode block where our glyph lies */
     480    for(b = 0; b < f->header.blocks; b++)
     481    {
     482        if(ch < f->block_list[b].start)
     483        {
     484            b = f->header.blocks;
     485            break;
     486        }
     487        if(ch < f->block_list[b].stop) {
     488            break;
     489        }
     490    }
     491
     492    /* Glyph not in font? Skip it. */
     493    if(b == f->header.blocks)
     494        return 0;
     495
     496    g = &f->glyph_list[f->block_list[b].index
     497                       + ch - f->block_list[b].start];
     498
     499    /* Step 1: unpack glyph */
     500    switch(f->header.bpp)
     501    {
     502    case 8:
     503        glyph = f->font_data + g->data_offset;
     504        break;
     505    case 4:
     506        unpack_glyph4(glyph, f->font_data + g->data_offset,
     507                      g->width * g->height);
     508        break;
     509    case 2:
     510        unpack_glyph2(glyph, f->font_data + g->data_offset,
     511                      g->width * g->height);
     512        break;
     513    case 1:
     514        unpack_glyph1(glyph, f->font_data + g->data_offset,
     515                      g->width * g->height);
     516        break;
     517    }
     518    return 1;
     519}
     520
     521
     522
    448523/*
    449524 * The libcaca font format, version 1
Note: See TracChangeset for help on using the changeset viewer.