void Genefx_Aop_xy( GenefxState *gfxs, int x, int y ) { int pitch = gfxs->dst_pitch; gfxs->Aop[0] = gfxs->dst_org[0]; gfxs->AopY = y; if (gfxs->dst_caps & DSCAPS_SEPARATED) { gfxs->Aop_field = y & 1; if (gfxs->Aop_field) gfxs->Aop[0] += gfxs->dst_field_offset; y /= 2; } D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->dst_format)) ); gfxs->Aop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, x ); if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) { int dst_field_offset = gfxs->dst_field_offset; switch (gfxs->dst_format) { case DSPF_YV12: case DSPF_I420: dst_field_offset /= 4; pitch /= 2; y /= 2; x /= 2; break; case DSPF_YV16: dst_field_offset /= 2; pitch /= 2; x /= 2; break; case DSPF_NV12: case DSPF_NV21: dst_field_offset /= 2; y /= 2; case DSPF_NV16: x &= ~1; break; case DSPF_YUV444P: /* nothing to adjust */ default: break; } gfxs->Aop[1] = gfxs->dst_org[1]; gfxs->Aop[2] = gfxs->dst_org[2]; if (gfxs->dst_caps & DSCAPS_SEPARATED && gfxs->Aop_field) { gfxs->Aop[1] += dst_field_offset; gfxs->Aop[2] += dst_field_offset; } gfxs->Aop[1] += y * pitch + x; gfxs->Aop[2] += y * pitch + x; } }
DFBResult dfb_font_get_glyph_data( CoreFont *font, unichar glyph, CoreGlyphData **ret_data ) { DFBResult ret; CoreGlyphData *data; D_MAGIC_ASSERT( font, CoreFont ); D_ASSERT( ret_data != NULL ); if ((data = direct_tree_lookup (font->glyph_infos, (void *)glyph)) != NULL) { *ret_data = data; return DFB_OK; } data = (CoreGlyphData *) D_CALLOC(1, sizeof (CoreGlyphData)); if (!data) return DFB_NOSYSTEMMEMORY; if (font->GetGlyphInfo && font->GetGlyphInfo (font, glyph, data) == DFB_OK && data->width > 0 && data->height > 0) { if (font->next_x + data->width > font->row_width) { CoreSurface *surface; if (font->row_width == 0) { int width = 8192 / font->height; if (width > 2048) width = 2048; if (width < font->maxadvance) width = font->maxadvance; font->row_width = (width + 7) & ~7; } ret = dfb_surface_create( font->core, font->row_width, MAX( font->height + 1, 8 ), font->pixel_format, CSP_VIDEOLOW, DSCAPS_NONE, NULL, &surface ); if (ret) { D_ERROR( "DirectFB/core/fonts: " "Could not create glyph surface! (%s)\n", DirectFBErrorString( ret ) ); D_FREE( data ); return ret; } font->next_x = 0; font->rows++; font->surfaces = D_REALLOC( font->surfaces, sizeof(void *) * font->rows ); font->surfaces[font->rows - 1] = surface; } if (font->RenderGlyph(font, glyph, data, font->surfaces[font->rows - 1]) == DFB_OK) { int align = DFB_PIXELFORMAT_ALIGNMENT(font->pixel_format); data->surface = font->surfaces[font->rows - 1]; data->start = font->next_x; font->next_x += (data->width + align) & ~align; dfb_gfxcard_flush_texture_cache(); } else { data->start = data->width = data->height = 0; } } else { data->start = data->width = data->height = 0; } direct_tree_insert (font->glyph_infos, (void *) glyph, data); *ret_data = data; return DFB_OK; }
static int do_face( const Face *face ) { int i, ret; int align = DFB_PIXELFORMAT_ALIGNMENT( m_format ); int num_glyphs = 0; int num_rows = 1; int row_index = 0; int row_offset = 0; int next_face = sizeof(DGIFFFaceHeader); int total_height = 0; Entity::vector glyph_vector; unsigned int glyph_count = 0; DGIFFFaceHeader header; DGIFFGlyphInfo *glyphs; DGIFFGlyphRow *rows; void **row_data; DFBSurfaceDescription *descs; D_DEBUG_AT( mkdgiff, "%s( %p )\n", __FUNCTION__, face ); get_entities( face->buf, face->length, glyph_vector ); glyph_count = glyph_vector.size(); /* Clear to not leak any data into file. */ memset( &header, 0, sizeof(header) ); /* Allocate glyph info array. */ glyphs = (DGIFFGlyphInfo*) D_CALLOC( glyph_count, sizeof(DGIFFGlyphInfo) ); rows = (DGIFFGlyphRow*) D_CALLOC( glyph_count, sizeof(DGIFFGlyphRow) ); /* WORST case :) */ row_data = (void**) D_CALLOC( glyph_count, sizeof(void*) ); /* WORST case :) */ descs = (DFBSurfaceDescription*) D_CALLOC( glyph_count, sizeof(DFBSurfaceDescription) ); /* WORST case :) */ for (Entity::vector::const_iterator iter = glyph_vector.begin(); iter != glyph_vector.end(); iter++) { const Glyph *glyph = dynamic_cast<const Glyph*>( *iter ); glyph->Dump(); DGIFFGlyphInfo *info = &glyphs[num_glyphs]; DGIFFGlyphRow *row = &rows[num_rows - 1]; D_DEBUG_AT( mkdgiff, " -> code %3u\n", glyph->unicode ); ret = load_image( glyph->file.c_str(), &descs[num_glyphs] ); if (ret) continue; info->unicode = glyph->unicode; info->width = descs[num_glyphs].width; info->height = descs[num_glyphs].height; info->left = glyph->left; info->top = glyph->top; info->advance = glyph->advance; num_glyphs++; if (row->width > 0 && row->width + info->width > MAX_ROW_WIDTH) { num_rows++; row++; } row->width += (info->width + align) & ~align; if (row->height < info->height) row->height = info->height; } for (i=0; i<num_rows; i++) { DGIFFGlyphRow *row = &rows[i]; D_DEBUG_AT( mkdgiff, " -> row %d, width %d, height %d\n", i, row->width, row->height ); total_height += row->height; row->pitch = (DFB_BYTES_PER_LINE( m_format, row->width ) + 7) & ~7; row_data[i] = D_CALLOC( row->height, row->pitch ); next_face += row->height * row->pitch; } D_DEBUG_AT( mkdgiff, " -> %d glyphs, %d rows, total height %d\n", num_glyphs, num_rows, total_height ); next_face += num_glyphs * sizeof(DGIFFGlyphInfo); next_face += num_rows * sizeof(DGIFFGlyphRow); for (i=0; i<num_glyphs; i++) { DGIFFGlyphInfo *glyph = &glyphs[i]; D_DEBUG_AT( mkdgiff, " -> writing character 0x%x (%d)\n", glyph->unicode, i ); if (row_offset > 0 && row_offset + glyph->width > MAX_ROW_WIDTH) { row_index++; row_offset = 0; } D_DEBUG_AT( mkdgiff, " -> row offset %d\n", row_offset ); write_glyph( glyph, descs[i], (char*) row_data[row_index] + DFB_BYTES_PER_LINE( m_format, row_offset ), rows[row_index].pitch ); glyph->row = row_index; glyph->offset = row_offset; row_offset += (glyph->width + align) & ~align; } D_ASSERT( row_index == num_rows - 1 ); header.next_face = next_face; header.size = face->size; header.ascender = face->ascender; header.descender = face->descender; header.height = face->height; header.max_advance = face->maxadvance; header.pixelformat = m_format; header.num_glyphs = num_glyphs; header.num_rows = num_rows; header.blittingflags = face->blittingflags; D_DEBUG_AT( mkdgiff, " -> ascender %d, descender %d\n", header.ascender, header.descender ); D_DEBUG_AT( mkdgiff, " -> height %d, max advance %d\n", header.height, header.max_advance ); fwrite( &header, sizeof(header), 1, stdout ); fwrite( glyphs, sizeof(*glyphs), num_glyphs, stdout ); for (i=0; i<num_rows; i++) { DGIFFGlyphRow *row = &rows[i]; fwrite( row, sizeof(*row), 1, stdout ); fwrite( row_data[i], row->pitch, row->height, stdout ); } for (i=0; i<num_rows; i++) { if (row_data[i]) D_FREE( row_data[i] ); } D_FREE( row_data ); D_FREE( rows ); D_FREE( glyphs ); return 0; }