PageRenderTime 366ms CodeModel.GetById 110ms app.highlight 115ms RepoModel.GetById 137ms app.codeStats 0ms

/src/canvas/skia/ftk_canvas_skia.cpp

http://ftk.googlecode.com/
C++ | 322 lines | 233 code | 61 blank | 28 comment | 24 complexity | c4415b11904b6f0b7bcbf46adc88bdba MD5 | raw file
  1/*
  2 * File: ftk_canvas_skia.c
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   skia 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 "SkColor.h"
 36#include "SkCanvas.h"
 37#include "ftk_globals.h"
 38#include "SkImageEncoder.h"
 39#include "effects/SkPorterDuff.h"
 40
 41using namespace android;
 42
 43typedef struct _CanvasSkiaPrivInfo
 44{
 45	int w;
 46	int h;
 47	SkPaint*   paint;
 48	SkCanvas*  canvas;
 49	FtkBitmap* bitmap;
 50}PrivInfo;
 51
 52static Ret ftk_canvas_skia_sync_gc(FtkCanvas* thiz)
 53{
 54	int size = 0;
 55	DECL_PRIV(thiz, priv);
 56	FtkColor c = thiz->gc.fg;
 57#ifdef ANDROID
 58	SkColor color = SkColorSetARGB(c.a, c.r, c.g, c.b);
 59#else
 60	SkColor color = SkColorSetARGBInline(c.a, c.r, c.g, c.b);
 61#endif
 62
 63	priv->paint->setColor(color);
 64	if(thiz->gc.font != NULL)
 65	{
 66		char desc[64] = {0};
 67		size = ftk_font_desc_get_size(thiz->gc.font);
 68		priv->paint->setTextSize(SkIntToScalar(size));
 69	}
 70
 71	return RET_OK;
 72}
 73
 74static Ret ftk_canvas_skia_set_clip(FtkCanvas* thiz, FtkRegion* clip)
 75{
 76	SkRegion clipReg;
 77	DECL_PRIV(thiz, priv);
 78
 79	if(clip != NULL)
 80	{
 81		SkIRect rect;
 82		FtkRegion* iter = clip;
 83
 84		while(iter != NULL)
 85		{
 86			rect.set(iter->rect.x, iter->rect.y, iter->rect.x + iter->rect.width, iter->rect.y + iter->rect.height);
 87			clipReg.op(rect, SkRegion::kUnion_Op);
 88			ftk_logd("set_clip: %d %d %d %d\n", iter->rect.x, iter->rect.y, iter->rect.width, iter->rect.height);
 89			iter = iter->next;
 90		}
 91	}
 92	else
 93	{
 94		clipReg.setRect(0, 0, priv->w, priv->h);
 95		ftk_logd("set_clip: %d %d %d %d\n", 0, 0, priv->w, priv->h);
 96	}
 97
 98	priv->canvas->clipRegion(clipReg, SkRegion::kReplace_Op);
 99
100	return RET_OK;
101}
102
103static Ret ftk_canvas_skia_draw_pixels(FtkCanvas* thiz, FtkPoint* points, int nr)
104{
105	int i = 0;
106	DECL_PRIV(thiz, priv);
107
108	for(i = 0; i < nr; i++)
109	{
110		priv->canvas->drawPoint(SkIntToScalar(points[i].x), SkIntToScalar(points[i].y), *priv->paint);
111	}
112
113	return RET_OK;
114}
115
116static Ret ftk_canvas_skia_draw_line(FtkCanvas* thiz, int x1, int y1, int x2, int y2)
117{
118	DECL_PRIV(thiz, priv);
119
120	priv->canvas->drawLine(SkIntToScalar(x1), SkIntToScalar(y1), SkIntToScalar(x2), SkIntToScalar(y2), *priv->paint);
121
122	return RET_OK;
123}
124
125static Ret ftk_canvas_skia_clear_rect(FtkCanvas* thiz, int x, int y, int w, int h)
126{
127	SkRect rect;
128	DECL_PRIV(thiz, priv);
129	
130	rect.iset(x, y, x + w, y + h);
131	priv->paint->setStyle(SkPaint::kStrokeAndFill_Style);
132	priv->canvas->drawRect(rect, *priv->paint);
133
134	return RET_OK;
135}
136
137static Ret ftk_canvas_skia_draw_rect(FtkCanvas* thiz, int x, int y, int w, int h, 
138	int round, int fill)
139{
140	SkRect rect;
141	Ret ret = RET_FAIL;
142	DECL_PRIV(thiz, priv);
143
144	rect.iset(x, y, x + w, y + h);
145
146	if(fill)
147	{
148		priv->paint->setStyle(SkPaint::kStrokeAndFill_Style);
149	}
150	else
151	{
152		priv->paint->setStyle(SkPaint::kStroke_Style);
153	}
154
155	if(round)
156	{
157		priv->canvas->drawRoundRect(rect, SkIntToScalar(5), SkIntToScalar(5), *priv->paint);
158	}
159	else
160	{
161		priv->canvas->drawRect(rect, *priv->paint);
162	}
163	priv->paint->setStyle(SkPaint::kStroke_Style);
164
165	return ret;
166}
167
168static Ret ftk_canvas_skia_draw_bitmap(FtkCanvas* thiz, FtkBitmap* bitmap, 
169	FtkRect* src_r, FtkRect* dst_r, int alpha)
170{
171	SkRect dst;
172	SkIRect src;
173	Ret ret = RET_FAIL;
174	DECL_PRIV(thiz, priv);
175	return_val_if_fail(thiz != NULL && bitmap != NULL && dst_r != NULL && src_r != NULL, RET_FAIL);
176
177	src.set(src_r->x, src_r->y, src_r->x + src_r->width, src_r->y + src_r->height);
178	dst.iset(dst_r->x, dst_r->y, dst_r->x + dst_r->width, dst_r->y + dst_r->height);
179
180	SkBitmap* b = (SkBitmap*)ftk_bitmap_get_native(bitmap);
181	priv->canvas->drawBitmapRect(*b, &src, dst, priv->paint);
182
183	return ret;
184}
185
186static Ret ftk_canvas_skia_draw_string(FtkCanvas* thiz, int x, int y, 
187	const char* str, int len, int vcenter)
188{
189	DECL_PRIV(thiz, priv);
190
191	if(vcenter)
192	{
193		y += ftk_font_desc_get_size(thiz->gc.font)/3;
194	}
195
196	priv->paint->setAntiAlias(true);
197	priv->canvas->drawText(str, len, SkIntToScalar(x), SkIntToScalar(y), *priv->paint);
198	priv->paint->setAntiAlias(false);
199
200	return RET_OK;
201}
202
203static Ret fk_canvas_skia_lock_buffer(FtkCanvas* thiz, FtkBitmap** bitmap)
204{
205	DECL_PRIV(thiz, priv);
206	return_val_if_fail(bitmap != NULL, RET_FAIL);
207
208	*bitmap = priv->bitmap;
209
210	return RET_OK;
211}
212
213static Ret ftk_canvas_skia_unlock_buffer(FtkCanvas* thiz)
214{
215	return RET_OK;
216}
217
218static void ftk_canvas_skia_destroy(FtkCanvas* thiz)
219{
220	DECL_PRIV(thiz, priv);
221
222	if(thiz != NULL)
223	{
224		priv->canvas->setBitmapDevice(SkBitmap());
225		ftk_bitmap_unref(priv->bitmap);
226		delete priv->canvas;
227		delete priv->paint;
228		FTK_FREE(thiz);
229	}
230
231	return;
232}
233
234static int ftk_canvas_skia_get_char_extent(FtkCanvas* thiz, unsigned short code)
235{
236	int width = 0;
237	char utf8[8] = {0};
238	DECL_PRIV(thiz, priv);
239	SkScalar fwidth = 0;
240
241	utf16_to_utf8(&code, 1, utf8, sizeof(utf8));
242	fwidth = priv->paint->measureText(utf8, strlen(utf8));
243	width = SkFixedFloor(SkScalarToFixed(fwidth));
244
245	return width;
246}
247
248static int ftk_canvas_skia_get_str_extent(FtkCanvas* thiz, const char* str, int len)
249{
250	int width = 0;
251	DECL_PRIV(thiz, priv);
252	SkScalar fwidth = 0;
253	
254	fwidth = priv->paint->measureText(str, len);
255	width = SkFixedFloor(SkScalarToFixed(fwidth));
256	ftk_logd("%s: %s width=%d\n", __func__, str, width);
257
258	return width;
259}
260
261static const FtkCanvasVTable g_canvas_skia_vtable=
262{
263	ftk_canvas_skia_sync_gc,
264	ftk_canvas_skia_set_clip,
265	ftk_canvas_skia_draw_pixels,
266	ftk_canvas_skia_draw_line,
267	ftk_canvas_skia_clear_rect,
268	ftk_canvas_skia_draw_rect,
269
270	ftk_canvas_skia_draw_bitmap,
271	ftk_canvas_skia_draw_string,
272	ftk_canvas_skia_get_str_extent,
273	ftk_canvas_skia_get_char_extent,
274	fk_canvas_skia_lock_buffer,
275	ftk_canvas_skia_unlock_buffer,
276	ftk_canvas_skia_destroy
277};
278
279static void destroy_bitmap(void* data)
280{
281    SkBitmap* b = (SkBitmap*)data;
282
283    delete b;
284
285    return;
286}
287
288FtkCanvas* ftk_canvas_create(int w, int h, FtkColor* clear_color)
289{
290	FtkCanvas* thiz = NULL;
291	return_val_if_fail(w > 0 && h > 0 && clear_color != NULL, NULL);
292
293	thiz = (FtkCanvas*)FTK_ZALLOC(sizeof(FtkCanvas) + sizeof(PrivInfo));
294
295	if(thiz != NULL)
296	{
297		SkBitmap* bitmap = new SkBitmap();
298		DECL_PRIV(thiz, priv);
299
300		thiz->gc.bg = *clear_color;
301		thiz->gc.fg.a = 0xff;
302		thiz->gc.fg.r = 0xff - clear_color->r;
303		thiz->gc.fg.g = 0xff - clear_color->g;
304		thiz->gc.fg.b = 0xff - clear_color->b;
305		thiz->gc.mask = FTK_GC_FG | FTK_GC_BG;
306		thiz->vtable = &g_canvas_skia_vtable;
307
308		bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h, w * 4);
309		bitmap->allocPixels(NULL);
310
311		priv->paint = new SkPaint();
312		priv->canvas = new SkCanvas();
313		priv->canvas->setBitmapDevice(*bitmap);
314		
315		priv->bitmap = ftk_bitmap_create_with_native(bitmap);
316		priv->w = ftk_bitmap_width(priv->bitmap);
317		priv->h = ftk_bitmap_height(priv->bitmap);
318	}
319
320	return thiz;
321}
322