/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. * History:
  26. * ================================================================
  27. * 2011-04-18 Li XianJing <xianjimli@hotmail.com> created
  28. */
  29. #include "ftk_log.h"
  30. #include "ftk_util.h"
  31. #include "ftk_bitmap.h"
  32. #include "ftk_canvas.h"
  33. #include "ftk_globals.h"
  34. #include "directfb_common.h"
  35. typedef struct _CanvasDfbPrivInfo
  36. {
  37. FtkBitmap* bitmap;
  38. IDirectFBFont* font;
  39. IDirectFBSurface* surface;
  40. }PrivInfo;
  41. static Ret ftk_canvas_directfb_sync_gc(FtkCanvas* thiz)
  42. {
  43. DECL_PRIV(thiz, priv);
  44. FtkColor c = thiz->gc.fg;
  45. priv->surface->SetColor(priv->surface, c.r, c.g, c.b, c.a);
  46. if(thiz->gc.font != NULL)
  47. {
  48. //int size = ftk_font_desc_get_size(thiz->gc.font);
  49. /*TODO*/
  50. }
  51. return RET_OK;
  52. }
  53. static Ret ftk_canvas_directfb_set_clip(FtkCanvas* thiz, FtkRegion* clip)
  54. {
  55. DECL_PRIV(thiz, priv);
  56. DFBRegion region = {0};
  57. if(clip != NULL && clip->next == NULL)
  58. {
  59. region.x1 = clip->rect.x;
  60. region.y1 = clip->rect.y;
  61. region.x2 = clip->rect.x + clip->rect.width;
  62. region.y2 = clip->rect.y + clip->rect.height;
  63. }
  64. else
  65. {
  66. region.x1 = 0;
  67. region.y1 = 0;
  68. region.x2 = thiz->width;
  69. region.y2 = thiz->height;
  70. }
  71. priv->surface->SetClip(priv->surface, &region);
  72. return RET_OK;
  73. }
  74. static Ret ftk_canvas_directfb_draw_pixels(FtkCanvas* thiz, FtkPoint* points, int nr)
  75. {
  76. /*TODO:*/
  77. return RET_OK;
  78. }
  79. static Ret ftk_canvas_directfb_draw_line(FtkCanvas* thiz, int x1, int y1, int x2, int y2)
  80. {
  81. DECL_PRIV(thiz, priv);
  82. priv->surface->DrawLine(priv->surface, x1, y1, x2, y2);
  83. return RET_OK;
  84. }
  85. static Ret ftk_canvas_directfb_clear_rect(FtkCanvas* thiz, int x, int y, int w, int h)
  86. {
  87. DECL_PRIV(thiz, priv);
  88. priv->surface->FillRectangle(priv->surface, x, y, w, h);
  89. return RET_OK;
  90. }
  91. static Ret ftk_canvas_directfb_draw_rect(FtkCanvas* thiz, int x, int y, int w, int h,
  92. int round, int fill)
  93. {
  94. DECL_PRIV(thiz, priv);
  95. if(fill)
  96. {
  97. if(round)
  98. {
  99. /*TODO*/
  100. priv->surface->FillRectangle(priv->surface, x, y, w, h);
  101. }
  102. else
  103. {
  104. priv->surface->FillRectangle(priv->surface, x, y, w, h);
  105. }
  106. }
  107. else
  108. {
  109. if(round)
  110. {
  111. /*TODO*/
  112. priv->surface->DrawRectangle(priv->surface, x, y, w, h);
  113. }
  114. else
  115. {
  116. priv->surface->DrawRectangle(priv->surface, x, y, w, h);
  117. }
  118. }
  119. return RET_OK;
  120. }
  121. static Ret ftk_canvas_directfb_draw_bitmap(FtkCanvas* thiz, FtkBitmap* bitmap,
  122. FtkRect* src_r, FtkRect* dst_r, int alpha)
  123. {
  124. Ret ret = RET_FAIL;
  125. DECL_PRIV(thiz, priv);
  126. DFBRectangle dsrc_r;
  127. DFBRectangle ddst_r;
  128. IDirectFBSurface* src_surface = NULL;
  129. return_val_if_fail(bitmap != NULL && src_r != NULL && dst_r != NULL, RET_FAIL);
  130. dsrc_r.x = src_r->x;
  131. dsrc_r.y = src_r->y;
  132. dsrc_r.w = src_r->width;
  133. dsrc_r.h = src_r->height;
  134. ddst_r.x = dst_r->x;
  135. ddst_r.y = dst_r->y;
  136. ddst_r.w = dst_r->width;
  137. ddst_r.h = dst_r->height;
  138. src_surface = ftk_bitmap_get_native(bitmap);
  139. if(src_r->width == dst_r->width && src_r->height == dst_r->height)
  140. {
  141. priv->surface->Blit(priv->surface, src_surface, &dsrc_r, ddst_r.x, ddst_r.y);
  142. }
  143. else
  144. {
  145. priv->surface->StretchBlit(priv->surface, src_surface, &dsrc_r, &ddst_r);
  146. }
  147. return ret;
  148. }
  149. static Ret ftk_canvas_directfb_draw_string(FtkCanvas* thiz, int x, int y,
  150. const char* str, int len, int vcenter)
  151. {
  152. DECL_PRIV(thiz, priv);
  153. DFBSurfaceTextFlags flags = 0;
  154. if(vcenter)
  155. {
  156. y += ftk_font_desc_get_size(thiz->gc.font)/3;
  157. }
  158. priv->surface->DrawString(priv->surface, str, len, x, y, flags);
  159. return RET_OK;
  160. }
  161. static Ret fk_canvas_directfb_lock_buffer(FtkCanvas* thiz, FtkBitmap** bitmap)
  162. {
  163. DECL_PRIV(thiz, priv);
  164. if(bitmap != NULL)
  165. {
  166. *bitmap = priv->bitmap;
  167. }
  168. return RET_OK;
  169. }
  170. static Ret ftk_canvas_directfb_unlock_buffer(FtkCanvas* thiz)
  171. {
  172. return RET_OK;
  173. }
  174. static int ftk_canvas_directfb_get_str_extent(FtkCanvas* thiz, const char* str, int len)
  175. {
  176. int width = 0;
  177. DECL_PRIV(thiz, priv);
  178. priv->font->GetStringWidth(priv->font, str, len, &width);
  179. return width;
  180. }
  181. static int ftk_canvas_directfb_get_char_extent(FtkCanvas* thiz, unsigned short code)
  182. {
  183. char utf8[8] = {0};
  184. utf16_to_utf8(&code, 1, utf8, sizeof(utf8));
  185. return ftk_canvas_directfb_get_str_extent(thiz, utf8, strlen(utf8));
  186. }
  187. static void ftk_canvas_directfb_destroy(FtkCanvas* thiz)
  188. {
  189. DECL_PRIV(thiz, priv);
  190. if(thiz != NULL)
  191. {
  192. ftk_bitmap_unref(priv->bitmap);
  193. priv->font->Release(priv->font);
  194. FTK_FREE(thiz);
  195. }
  196. return;
  197. }
  198. static const FtkCanvasVTable g_canvas_directfb_vtable=
  199. {
  200. ftk_canvas_directfb_sync_gc,
  201. ftk_canvas_directfb_set_clip,
  202. ftk_canvas_directfb_draw_pixels,
  203. ftk_canvas_directfb_draw_line,
  204. ftk_canvas_directfb_clear_rect,
  205. ftk_canvas_directfb_draw_rect,
  206. ftk_canvas_directfb_draw_bitmap,
  207. ftk_canvas_directfb_draw_string,
  208. ftk_canvas_directfb_get_str_extent,
  209. ftk_canvas_directfb_get_char_extent,
  210. fk_canvas_directfb_lock_buffer,
  211. ftk_canvas_directfb_unlock_buffer,
  212. ftk_canvas_directfb_destroy
  213. };
  214. FtkCanvas* ftk_canvas_create(int w, int h, FtkColor* clear_color)
  215. {
  216. int err = 0;
  217. FtkCanvas* thiz = NULL;
  218. char font_file[FTK_MAX_PATH+1] = {0};
  219. return_val_if_fail(w > 0 && h > 0 && clear_color != NULL, NULL);
  220. thiz = (FtkCanvas*)FTK_ZALLOC(sizeof(FtkCanvas) + sizeof(PrivInfo));
  221. if(thiz != NULL)
  222. {
  223. DECL_PRIV(thiz, priv);
  224. FtkColor color = *clear_color;
  225. DFBSurfaceDescription desc = {0};
  226. IDirectFBSurface* surface = NULL;
  227. IDirectFB* dfb = directfb_get();
  228. DFBFontDescription font_desc = {0};
  229. ftk_strs_cat(font_file, FTK_MAX_PATH,
  230. ftk_config_get_data_dir(ftk_default_config()), "/data/", FTK_FONT, NULL);
  231. ftk_normalize_path(font_file);
  232. thiz->width = w;
  233. thiz->height = h;
  234. desc.width = w;
  235. desc.height = h;
  236. desc.caps = DSCAPS_SHARED;
  237. desc.pixelformat = DSPF_ARGB;
  238. desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT;
  239. thiz->gc.bg = *clear_color;
  240. thiz->gc.fg.a = 0xff;
  241. thiz->gc.fg.r = 0xff - clear_color->r;
  242. thiz->gc.fg.g = 0xff - clear_color->g;
  243. thiz->gc.fg.b = 0xff - clear_color->b;
  244. thiz->gc.mask = FTK_GC_FG | FTK_GC_BG;
  245. thiz->vtable = &g_canvas_directfb_vtable;
  246. font_desc.height = 16;
  247. font_desc.flags = DFDESC_HEIGHT;
  248. dfb->CreateSurface(dfb, &desc, &surface);
  249. surface->Clear(priv->surface, color.r, color.g, color.b, color.a);
  250. DFBCHECK(dfb->CreateFont (dfb, font_file, &font_desc, &priv->font));
  251. surface->SetFont (surface, priv->font);
  252. surface->SetDrawingFlags(surface, DSDRAW_BLEND);
  253. surface->SetBlittingFlags(surface, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA);
  254. priv->surface = surface;
  255. priv->bitmap = ftk_bitmap_create_with_native(surface);
  256. }
  257. return thiz;
  258. }