/* (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) (c) Copyright 2000-2004 Convergence (integrated media) GmbH All rights reserved. Written by Denis Oliver Kropp , Andreas Hundt , Sven Neumann , Ville Syrjälä and Claudio Ciccani . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "default_font.h" #define DEFAULT_FONT_HEIGHT 24 #define DEFAULT_FONT_ASCENDER 16 #define DEFAULT_FONT_DESCENDER -4 static DFBResult Probe( IDirectFBFont_ProbeContext *ctx ); static DFBResult Construct( IDirectFBFont *thiz, CoreDFB *core, IDirectFBFont_ProbeContext *ctx, DFBFontDescription *desc ); #include DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBFont, Default ) static DFBResult Probe( IDirectFBFont_ProbeContext *ctx ) { /* default font is created with a NULL filename */ if (ctx->filename) return DFB_UNSUPPORTED; return DFB_OK; } static DFBResult Construct( IDirectFBFont *thiz, CoreDFB *core, IDirectFBFont_ProbeContext *ctx, DFBFontDescription *desc ) { DFBResult ret; CoreFont *font; CoreSurface *surface; CoreFontCacheRow *row; u8 *pixels; int i; CoreSurfaceConfig config; D_DEBUG( "DirectFB/FontDefault: Construct default font"); if (desc->flags & DFDESC_ROTATION) { DIRECT_DEALLOCATE_INTERFACE( thiz ); return DFB_UNSUPPORTED; } ret = dfb_font_create( core, desc, "", &font ); if (ret) { DIRECT_DEALLOCATE_INTERFACE( thiz ); return ret; } D_ASSERT( font->pixel_format == DSPF_ARGB || font->pixel_format == DSPF_AiRGB || font->pixel_format == DSPF_ARGB4444 || font->pixel_format == DSPF_RGBA4444 || font->pixel_format == DSPF_ARGB2554 || font->pixel_format == DSPF_ARGB1555 || font->pixel_format == DSPF_A8 || font->pixel_format == DSPF_A4 || font->pixel_format == DSPF_A1 ); font->height = DEFAULT_FONT_HEIGHT; font->ascender = DEFAULT_FONT_ASCENDER; font->descender = DEFAULT_FONT_DESCENDER; font->up_unit_x = 0.0; font->up_unit_y = -1.0; row = D_CALLOC( 1, sizeof(CoreFontCacheRow) ); if (!row) { D_OOM(); dfb_font_destroy( font ); DIRECT_DEALLOCATE_INTERFACE( thiz ); return DFB_NOSYSTEMMEMORY; } config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS; config.size.w = font_desc.width; config.size.h = font_desc.height; config.format = font->pixel_format; config.caps = font->surface_caps; ret = dfb_surface_create( core, &config, CSTF_FONT, 0, NULL, &surface ); if (ret) { dfb_font_destroy( font ); return ret; } font->num_rows = 1; font->row_width = font_desc.width; font->rows = D_MALLOC(sizeof (void *)); font->rows[0] = row; row->surface = surface; D_MAGIC_SET( row, CoreFontCacheRow ); pixels = font_data; { CoreGlyphData *data; int use_unicode; int start = 0; int index = 0; int key; const char *glyphs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "01234567890!\"$%&/()=?^<>" // FIXME: '0' is repeated! "|,;.:-_{[]}\\`+*~#'"; if (desc && (desc->flags & DFDESC_ATTRIBUTES) && (desc->attributes & DFFA_NOCHARMAP)) use_unicode = 0; else use_unicode = 1; for (i = 0; i < font_desc.width; i++) { if (pixels[i] == 0xFF) { if (use_unicode) key = glyphs[index]; else key = index; if (!direct_hash_lookup( font->layers[0].glyph_hash, key )) { data = D_CALLOC( 1, sizeof(CoreGlyphData) ); data->surface = surface; data->start = start; data->width = i - start + 1; data->height = font_desc.height - 1; data->left = 0; data->top = 0; data->xadvance = ((desc && (desc->flags & DFDESC_FIXEDADVANCE)) ? desc->fixed_advance : data->width + 1); data->yadvance = 0; D_DEBUG( "DirectFB/core/fonts: " "glyph '%c' at %d, width %d\n", glyphs[index], start, i-start ); D_MAGIC_SET( data, CoreGlyphData ); if (font->maxadvance < data->xadvance) font->maxadvance = data->xadvance; direct_hash_insert( font->layers[0].glyph_hash, key, data ); } start = i + 1; index++; } if (glyphs[index] == '\0') break; } /* space */ data = D_CALLOC( 1, sizeof(CoreGlyphData) ); data->xadvance = 5; data->yadvance = 0; D_MAGIC_SET( data, CoreGlyphData ); if (use_unicode) key = 32; else key = index; direct_hash_insert( font->layers[0].glyph_hash, key, data ); } { CoreSurfaceBufferLock lock; ret = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); if (ret) { D_DERROR( ret, "IDirectFBFont_Default: Could not lock surface buffer!\n" ); } else { for (i = 1; i < font_desc.height; i++) { int i, j, n; u8 *dst8 = lock.addr; u16 *dst16 = lock.addr; u32 *dst32 = lock.addr; pixels += font_desc.preallocated[0].pitch; switch (surface->config.format) { case DSPF_ARGB: if (surface->config.caps & DSCAPS_PREMULTIPLIED) { for (i=0; iconfig.caps & DSCAPS_PREMULTIPLIED) { for (i=0; i> 4) * 0x1111; } else { if( surface->config.format == DSPF_ARGB4444 ) { for (i=0; i> 4) | 0xFFF0; } } break; case DSPF_ARGB2554: for (i=0; i> 4); break; case DSPF_A1: for (i=0, j=0; i < font_desc.width; ++j) { register u8 p = 0; for (n=0; n<8 && i> n; dst8[j] = p; } break; case DSPF_LUT2: for (i=0, j=0; i < font_desc.width; ++j) { register u8 p = 0; for (n=0; n<8 && i> n; dst8[j] = p; } break; default: D_UNIMPLEMENTED(); break; } lock.addr += lock.pitch; } dfb_surface_unlock_buffer( surface, &lock ); } } return IDirectFBFont_Construct (thiz, font); }