summaryrefslogtreecommitdiff
path: root/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c')
-rwxr-xr-xSource/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c
new file mode 100755
index 0000000..323d61a
--- /dev/null
+++ b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c
@@ -0,0 +1,322 @@
+/*
+ (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 <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ 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 <config.h>
+#include <stdarg.h>
+
+#include <directfb.h>
+
+#include <core/fonts.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+#include <gfx/convert.h>
+
+#include <media/idirectfbfont.h>
+
+#include <direct/hash.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/utf8.h>
+
+#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.h>
+
+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; i<font_desc.width; i++)
+ dst32[i] = pixels[i] * 0x01010101;
+ }
+ else
+ for (i=0; i<font_desc.width; i++)
+ dst32[i] = (pixels[i] << 24) | 0xFFFFFF;
+ break;
+ case DSPF_AiRGB:
+ for (i=0; i<font_desc.width; i++)
+ dst32[i] = ((pixels[i] ^ 0xFF) << 24) | 0xFFFFFF;
+ break;
+ case DSPF_ARGB4444:
+ case DSPF_RGBA4444:
+ if (surface->config.caps & DSCAPS_PREMULTIPLIED) {
+ for (i=0; i<font_desc.width; i++)
+ dst16[i] = (pixels[i] >> 4) * 0x1111;
+ }
+ else {
+ if( surface->config.format == DSPF_ARGB4444 ) {
+ for (i=0; i<font_desc.width; i++)
+ dst16[i] = (pixels[i] << 8) | 0x0FFF;
+ } else {
+ for (i=0; i<font_desc.width; i++)
+ dst16[i] = (pixels[i] >> 4) | 0xFFF0;
+ }
+ }
+ break;
+ case DSPF_ARGB2554:
+ for (i=0; i<font_desc.width; i++)
+ dst16[i] = (pixels[i] << 8) | 0x3FFF;
+ break;
+ case DSPF_ARGB1555:
+ for (i=0; i<font_desc.width; i++)
+ dst16[i] = (pixels[i] << 8) | 0x7FFF;
+ break;
+ case DSPF_A8:
+ direct_memcpy( lock.addr, pixels, font_desc.width );
+ break;
+ case DSPF_A4:
+ for (i=0, j=0; i<font_desc.width; i+=2, j++)
+ dst8[j] = (pixels[i] & 0xF0) | (pixels[i+1] >> 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<font_desc.width; ++i, ++n)
+ p |= (pixels[i] & 0x80) >> 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<font_desc.width; ++i, n+=2)
+ p |= (pixels[i] & 0xC0) >> n;
+
+ dst8[j] = p;
+ }
+ break;
+ default:
+ D_UNIMPLEMENTED();
+ break;
+ }
+
+ lock.addr += lock.pitch;
+ }
+
+ dfb_surface_unlock_buffer( surface, &lock );
+ }
+ }
+
+ return IDirectFBFont_Construct (thiz, font);
+}