PageRenderTime 1038ms CodeModel.GetById 654ms app.highlight 114ms RepoModel.GetById 141ms app.codeStats 0ms

/src/canvas/directfb/ftk_canvas_directfb.c

http://ftk.googlecode.com/
C | 313 lines | 225 code | 55 blank | 33 comment | 28 complexity | 8aff2148b3aeeee065622cb90520ce10 MD5 | raw file
  1/*
  2 * File: ftk_canvas_directfb.c
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   directfb canvas implemntation.
  5 *
  6 * Copyright (c) 2009 - 2011  Li XianJing <xianjimli@hotmail.com>
  7 *
  8 * Licensed under the Academic Free License version 2.1
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, write to the Free Software
 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23 */
 24
 25/*
 26 * History:
 27 * ================================================================
 28 * 2011-04-18 Li XianJing <xianjimli@hotmail.com> created
 29 */
 30
 31#include "ftk_log.h"
 32#include "ftk_util.h"
 33#include "ftk_bitmap.h"
 34#include "ftk_canvas.h"
 35#include "ftk_globals.h"
 36#include "directfb_common.h"
 37
 38typedef struct _CanvasDfbPrivInfo
 39{
 40	FtkBitmap* bitmap;
 41	IDirectFBFont* font;
 42	IDirectFBSurface* surface;
 43}PrivInfo;
 44
 45static Ret ftk_canvas_directfb_sync_gc(FtkCanvas* thiz)
 46{
 47	DECL_PRIV(thiz, priv);
 48	FtkColor c = thiz->gc.fg;
 49
 50	priv->surface->SetColor(priv->surface, c.r, c.g, c.b, c.a);
 51	if(thiz->gc.font != NULL)
 52	{
 53		//int size = ftk_font_desc_get_size(thiz->gc.font);
 54		/*TODO*/
 55	}
 56
 57	return RET_OK;
 58}
 59
 60static Ret ftk_canvas_directfb_set_clip(FtkCanvas* thiz, FtkRegion* clip)
 61{
 62	DECL_PRIV(thiz, priv);
 63	DFBRegion region = {0};
 64
 65	if(clip != NULL && clip->next == NULL)
 66	{
 67		region.x1 = clip->rect.x;
 68		region.y1 = clip->rect.y;
 69		region.x2 = clip->rect.x + clip->rect.width;
 70		region.y2 = clip->rect.y + clip->rect.height;
 71	}
 72	else
 73	{
 74		region.x1 = 0;
 75		region.y1 = 0;
 76		region.x2 = thiz->width;
 77		region.y2 = thiz->height;
 78	}
 79	priv->surface->SetClip(priv->surface, &region);
 80	
 81	return RET_OK;
 82}
 83
 84static Ret ftk_canvas_directfb_draw_pixels(FtkCanvas* thiz, FtkPoint* points, int nr)
 85{
 86	/*TODO:*/
 87
 88	return RET_OK;
 89}
 90
 91static Ret ftk_canvas_directfb_draw_line(FtkCanvas* thiz, int x1, int y1, int x2, int y2)
 92{
 93	DECL_PRIV(thiz, priv);
 94
 95	priv->surface->DrawLine(priv->surface, x1, y1, x2, y2);
 96
 97	return RET_OK;
 98}
 99
100static Ret ftk_canvas_directfb_clear_rect(FtkCanvas* thiz, int x, int y, int w, int h)
101{
102	DECL_PRIV(thiz, priv);
103	
104	priv->surface->FillRectangle(priv->surface, x, y, w, h);
105
106	return RET_OK;
107}
108
109static Ret ftk_canvas_directfb_draw_rect(FtkCanvas* thiz, int x, int y, int w, int h, 
110	int round, int fill)
111{
112	DECL_PRIV(thiz, priv);
113
114	if(fill)
115	{
116		if(round)
117		{
118			/*TODO*/
119			priv->surface->FillRectangle(priv->surface, x, y, w, h);
120		}
121		else
122		{
123			priv->surface->FillRectangle(priv->surface, x, y, w, h);
124		}
125	}
126	else
127	{
128		if(round)
129		{
130			/*TODO*/
131			priv->surface->DrawRectangle(priv->surface, x, y, w, h);
132		}
133		else
134		{
135			priv->surface->DrawRectangle(priv->surface, x, y, w, h);
136		}
137	}
138
139	return RET_OK;
140}
141
142static Ret ftk_canvas_directfb_draw_bitmap(FtkCanvas* thiz, FtkBitmap* bitmap, 
143	FtkRect* src_r, FtkRect* dst_r, int alpha)
144{
145	Ret ret = RET_FAIL;
146	DECL_PRIV(thiz, priv);
147	DFBRectangle dsrc_r;
148	DFBRectangle ddst_r;
149	IDirectFBSurface* src_surface = NULL;
150	return_val_if_fail(bitmap != NULL && src_r != NULL && dst_r != NULL, RET_FAIL);
151
152	dsrc_r.x = src_r->x;
153	dsrc_r.y = src_r->y;
154	dsrc_r.w = src_r->width;
155	dsrc_r.h = src_r->height;
156	
157	ddst_r.x = dst_r->x;
158	ddst_r.y = dst_r->y;
159	ddst_r.w = dst_r->width;
160	ddst_r.h = dst_r->height;
161
162	src_surface = ftk_bitmap_get_native(bitmap);
163	if(src_r->width == dst_r->width && src_r->height == dst_r->height)
164	{
165		priv->surface->Blit(priv->surface, src_surface, &dsrc_r, ddst_r.x, ddst_r.y);
166	}
167	else
168	{
169		priv->surface->StretchBlit(priv->surface, src_surface, &dsrc_r, &ddst_r);
170	}
171
172	return ret;
173}
174
175static Ret ftk_canvas_directfb_draw_string(FtkCanvas* thiz, int x, int y, 
176	const char* str, int len, int vcenter)
177{
178	DECL_PRIV(thiz, priv);
179	DFBSurfaceTextFlags flags = 0;
180	
181	if(vcenter)
182	{
183		y += ftk_font_desc_get_size(thiz->gc.font)/3;
184	}
185
186	priv->surface->DrawString(priv->surface, str, len, x, y, flags);
187
188	return RET_OK;
189}
190
191static Ret fk_canvas_directfb_lock_buffer(FtkCanvas* thiz, FtkBitmap** bitmap)
192{
193	DECL_PRIV(thiz, priv);
194
195	if(bitmap != NULL)
196	{
197		*bitmap = priv->bitmap;
198	}
199
200	return RET_OK;
201}
202
203static Ret ftk_canvas_directfb_unlock_buffer(FtkCanvas* thiz)
204{
205	return RET_OK;
206}
207
208static int ftk_canvas_directfb_get_str_extent(FtkCanvas* thiz, const char* str, int len)
209{
210	int width = 0;
211	DECL_PRIV(thiz, priv);
212
213	priv->font->GetStringWidth(priv->font, str, len, &width);
214
215	return width;
216}
217
218static int ftk_canvas_directfb_get_char_extent(FtkCanvas* thiz, unsigned short code)
219{
220	char utf8[8] = {0};
221
222	utf16_to_utf8(&code, 1, utf8, sizeof(utf8));
223	return ftk_canvas_directfb_get_str_extent(thiz, utf8, strlen(utf8));
224}
225
226static void ftk_canvas_directfb_destroy(FtkCanvas* thiz)
227{
228	DECL_PRIV(thiz, priv);
229
230	if(thiz != NULL)
231	{
232		ftk_bitmap_unref(priv->bitmap);
233		priv->font->Release(priv->font);
234		FTK_FREE(thiz);
235	}
236
237	return;
238}
239
240static const FtkCanvasVTable g_canvas_directfb_vtable=
241{
242	ftk_canvas_directfb_sync_gc,
243	ftk_canvas_directfb_set_clip,
244	ftk_canvas_directfb_draw_pixels,
245	ftk_canvas_directfb_draw_line,
246	ftk_canvas_directfb_clear_rect,
247	ftk_canvas_directfb_draw_rect,
248
249	ftk_canvas_directfb_draw_bitmap,
250	ftk_canvas_directfb_draw_string,
251	ftk_canvas_directfb_get_str_extent,
252	ftk_canvas_directfb_get_char_extent,
253	fk_canvas_directfb_lock_buffer,
254	ftk_canvas_directfb_unlock_buffer,
255	ftk_canvas_directfb_destroy
256};
257
258FtkCanvas* ftk_canvas_create(int w, int h, FtkColor* clear_color)
259{
260	int err = 0;
261	FtkCanvas* thiz = NULL;
262	char font_file[FTK_MAX_PATH+1] = {0};
263	return_val_if_fail(w > 0 && h > 0 && clear_color != NULL, NULL);
264
265	thiz = (FtkCanvas*)FTK_ZALLOC(sizeof(FtkCanvas) + sizeof(PrivInfo));
266
267	if(thiz != NULL)
268	{
269		DECL_PRIV(thiz, priv);
270		FtkColor color = *clear_color;
271		DFBSurfaceDescription  desc = {0};
272		IDirectFBSurface* surface = NULL;
273		IDirectFB* dfb = directfb_get();
274		DFBFontDescription font_desc = {0};
275
276		ftk_strs_cat(font_file, FTK_MAX_PATH,
277          ftk_config_get_data_dir(ftk_default_config()), "/data/", FTK_FONT, NULL);
278		ftk_normalize_path(font_file);
279
280		thiz->width = w;
281		thiz->height = h;
282		desc.width  = w;
283		desc.height = h;
284		desc.caps   = DSCAPS_SHARED;
285		desc.pixelformat = DSPF_ARGB;
286		desc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT;
287
288		thiz->gc.bg = *clear_color;
289		thiz->gc.fg.a = 0xff;
290		thiz->gc.fg.r = 0xff - clear_color->r;
291		thiz->gc.fg.g = 0xff - clear_color->g;
292		thiz->gc.fg.b = 0xff - clear_color->b;
293		thiz->gc.mask = FTK_GC_FG | FTK_GC_BG;
294		thiz->vtable = &g_canvas_directfb_vtable;
295
296		font_desc.height  = 16;
297		font_desc.flags = DFDESC_HEIGHT;
298    	
299		dfb->CreateSurface(dfb, &desc, &surface);
300		surface->Clear(priv->surface, color.r, color.g, color.b, color.a);
301
302    	DFBCHECK(dfb->CreateFont (dfb, font_file, &font_desc, &priv->font));
303        surface->SetFont (surface, priv->font);
304		surface->SetDrawingFlags(surface, DSDRAW_BLEND);
305		surface->SetBlittingFlags(surface, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA);
306
307		priv->surface = surface;
308		priv->bitmap = ftk_bitmap_create_with_native(surface);
309	}
310
311	return thiz;
312}
313