PageRenderTime 407ms CodeModel.GetById 141ms app.highlight 150ms RepoModel.GetById 112ms app.codeStats 0ms

/src/ftk_canvas.c

http://ftk.googlecode.com/
C | 352 lines | 271 code | 51 blank | 30 comment | 56 complexity | 060d491f32dea5d2f790bb23de965463 MD5 | raw file
  1/*
  2 * File: ftk_canvas.c    
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   
  5 *
  6 * Copyright (c) 2009 - 2010  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 * 2009-10-03 Li XianJing <xianjimli@hotmail.com> created
 29 * 2010-3-16 woodysu<yapo_su@hotmail.com> modified. 
 30 */
 31
 32#include "ftk_log.h"
 33#include "ftk_util.h"
 34#include "ftk_bitmap.h"
 35#include "ftk_canvas.h"
 36
 37Ret ftk_canvas_reset_gc(FtkCanvas* thiz, FtkGc* gc)
 38{
 39	return_val_if_fail(thiz != NULL && gc != NULL, RET_FAIL);
 40
 41	ftk_gc_reset(&thiz->gc);
 42	
 43	ftk_gc_copy(&thiz->gc, gc);
 44
 45	return ftk_canvas_sync_gc(thiz);
 46}
 47
 48Ret ftk_canvas_set_gc(FtkCanvas* thiz, FtkGc* gc)
 49{
 50	return_val_if_fail(thiz != NULL && gc != NULL, RET_FAIL);
 51
 52	ftk_gc_copy(&thiz->gc, gc);
 53
 54	return ftk_canvas_sync_gc(thiz);
 55}
 56
 57FtkGc* ftk_canvas_get_gc(FtkCanvas* thiz)
 58{
 59	return_val_if_fail(thiz != NULL, NULL);
 60
 61	return &thiz->gc;
 62}
 63
 64Ret    ftk_canvas_set_clip_rect(FtkCanvas* thiz, FtkRect* rect)
 65{
 66	if(rect != NULL)
 67	{
 68		FtkRegion region;
 69		region.rect = *rect;
 70		region.next = NULL;
 71
 72		return ftk_canvas_set_clip(thiz, &region);
 73	}
 74	else
 75	{
 76		return ftk_canvas_set_clip(thiz, NULL);
 77	}
 78}
 79
 80Ret    ftk_canvas_set_clip_region(FtkCanvas* thiz, FtkRegion* region)
 81{
 82	return ftk_canvas_set_clip(thiz, region);
 83}
 84
 85Ret ftk_canvas_draw_vline(FtkCanvas* thiz, int x, int y, int h)
 86{
 87	return ftk_canvas_draw_line(thiz, x, y, x, y + h);
 88}
 89
 90Ret ftk_canvas_draw_hline(FtkCanvas* thiz, int x, int y, int w)
 91{
 92	return ftk_canvas_draw_line(thiz, x, y, x + w, y);
 93}
 94
 95Ret ftk_canvas_draw_bitmap_simple(FtkCanvas* thiz, FtkBitmap* b, int x, int y, int w, int h, int ox, int oy)
 96{
 97	FtkRect src_r;
 98	FtkRect dst_r;
 99
100	src_r.x = x;
101	src_r.y = y;
102	dst_r.x = ox;
103	dst_r.y = oy;
104	src_r.width = dst_r.width = w;
105	src_r.height = dst_r.height = h;
106
107	return ftk_canvas_draw_bitmap(thiz, b, &src_r, &dst_r, 0xff);
108}
109
110static Ret ftk_canvas_fill_background_four_corner(FtkCanvas* thiz, int x, int y, 
111	int w, int h, FtkBitmap* bitmap)
112{
113	int i = 0;
114	int ox = 0;
115	int oy = 0;
116	int ow = 0;
117	int oh = 0;
118	FtkColor fg  = thiz->gc.fg;
119	int bw = ftk_bitmap_width(bitmap);
120	int bh = ftk_bitmap_height(bitmap);
121	int tile_w = FTK_MIN(bw, w) >> 1;
122	int tile_h = FTK_MIN(bh, h) >> 1;
123	
124	if ( bw == w && bh == h )
125	{
126		ftk_canvas_draw_bitmap_simple(thiz, bitmap, 0, 0, w, h, x, y);
127	}
128	else
129	{
130		ftk_canvas_draw_bitmap_simple(thiz, bitmap, 0, 0, tile_w, tile_h, x, y);
131		ftk_canvas_draw_bitmap_simple(thiz, bitmap, bw - tile_w, 0, tile_w, tile_h, x + w - tile_w, y);
132		ftk_canvas_draw_bitmap_simple(thiz, bitmap, 0, bh - tile_h, tile_w, tile_h, x, y + h - tile_h);
133		ftk_canvas_draw_bitmap_simple(thiz, bitmap, bw - tile_w, bh - tile_h, tile_w, tile_h, x + w - tile_w, y + h - tile_h);
134	}
135
136	if(bw < w)
137	{
138		ox = x + tile_w;
139		ow = w - 2 * tile_w;
140		for(i = 0; i < tile_h; i++)
141		{
142			thiz->gc.fg = ftk_bitmap_get_pixel(bitmap, tile_w, i);
143			ftk_canvas_sync_gc(thiz);
144			ftk_canvas_draw_hline(thiz, ox, y + i, ow);
145		}
146		
147		oy = y + tile_h;
148		oh = h - 2 * tile_h;
149		thiz->gc.fg = ftk_bitmap_get_pixel(bitmap, tile_w, i);
150		ftk_canvas_sync_gc(thiz);
151		ftk_canvas_draw_rect(thiz, ox, oy, ow, oh, 0, 1); 
152	
153		oy = y + h - tile_h;
154		for(i = 0; i < tile_h; i++)
155		{
156			thiz->gc.fg = ftk_bitmap_get_pixel(bitmap, tile_w, (bh - tile_h) + i);
157			ftk_canvas_sync_gc(thiz);
158			ftk_canvas_draw_hline(thiz, ox, (oy + i), ow);
159		}
160	}
161
162	if(bh < h)
163	{
164		oy = y + tile_h;
165		oh = h - 2 * tile_h;
166		for(i = 0; i < tile_w; i++)
167		{
168			thiz->gc.fg = ftk_bitmap_get_pixel(bitmap, i, tile_h);
169			ftk_canvas_sync_gc(thiz);
170			ftk_canvas_draw_vline(thiz, x + i, oy, oh);
171		}
172		
173		ox = x + w - tile_w;
174		for(i = 0; i < tile_w; i++)
175		{
176			thiz->gc.fg = ftk_bitmap_get_pixel(bitmap, bw - tile_w + i, tile_h);
177			ftk_canvas_sync_gc(thiz);
178			ftk_canvas_draw_vline(thiz, ox + i, oy, oh);
179		}
180	}
181	thiz->gc.fg = fg;
182	ftk_canvas_sync_gc(thiz);
183
184	return RET_OK;
185}
186
187static Ret ftk_canvas_fill_background_normal(FtkCanvas* thiz, int x, int y, 
188	int w, int h, FtkBitmap* bitmap)
189{
190	int bw = ftk_bitmap_width(bitmap);
191	int bh = ftk_bitmap_height(bitmap);
192
193	w = FTK_MIN(bw, w);
194	h = FTK_MIN(bh, h);
195
196	return ftk_canvas_draw_bitmap_simple(thiz, bitmap, 0, 0, w, h, x, y);
197}
198
199static Ret ftk_canvas_fill_background_tile(FtkCanvas* thiz, int x, int y, 
200	int w, int h, FtkBitmap* bitmap)
201{
202	int dx = 0;
203	int dy = 0;
204	int bw = ftk_bitmap_width(bitmap);
205	int bh = ftk_bitmap_height(bitmap);
206
207	if(bw > w && bh > h)
208	{
209		return ftk_canvas_fill_background_normal(thiz, x, y, w, h, bitmap);
210	}
211
212	for(dy = 0; dy < h; dy += bh)
213	{
214		for(dx = 0; dx < w; dx += bw)
215		{
216			int draw_w = (dx + bw) < w ? bw : w - dx;
217			int draw_h = (dy + bh) < h ? bh : h - dy;
218
219			ftk_canvas_draw_bitmap_simple(thiz, bitmap, 0, 0, draw_w, draw_h, x + dx, y + dy);
220		}
221	}
222	
223	return RET_OK;
224}
225
226static Ret ftk_canvas_fill_background_center(FtkCanvas* thiz, int x, int y, int w, int h, FtkBitmap* bitmap)
227{
228	int bw = ftk_bitmap_width(bitmap);
229	int bh = ftk_bitmap_height(bitmap);
230	int ox = bw < w ? x + (w - bw)/2 : x;
231	int oy = bh < h ? y + (h - bh)/2 : y;
232	int bx = bw < w ? 0 : (bw - w)/2;
233	int by = bh < h ? 0 : (bh - h)/2;
234	
235	w = FTK_MIN(bw, w);
236	h = FTK_MIN(bh, h);
237
238	return ftk_canvas_draw_bitmap_simple(thiz, bitmap, bx, by, w, h, ox, oy);
239}
240
241Ret ftk_canvas_draw_bg_image(FtkCanvas* thiz, FtkBitmap* bitmap, FtkBgStyle style, 
242	int x, int y, int w, int h)
243{
244	Ret ret = RET_FAIL;
245	return_val_if_fail(thiz != NULL && bitmap != NULL, ret);
246
247	switch(style)
248	{
249		case FTK_BG_TILE: 
250			ret = ftk_canvas_fill_background_tile(thiz, x, y, w, h, bitmap);break;
251		case FTK_BG_CENTER: 
252			ret = ftk_canvas_fill_background_center(thiz, x, y, w, h, bitmap);break;
253		case FTK_BG_FOUR_CORNER:
254		{
255			int bw = ftk_bitmap_width(bitmap);
256			int bh = ftk_bitmap_height(bitmap);
257			if(w <= bw && h <= bh)
258			{
259				ret = ftk_canvas_fill_background_center(thiz, x, y, w, h, bitmap);break;
260			}
261			else
262			{
263				ret = ftk_canvas_fill_background_four_corner(thiz, x, y, w, h, bitmap);
264			}
265			break;
266		}
267		default:
268			ret = ftk_canvas_fill_background_normal(thiz, x, y, w, h, bitmap);break;
269	}
270
271	return ret;
272}
273
274Ret ftk_canvas_show(FtkCanvas* thiz, FtkDisplay* display, FtkRect* rect, int ox, int oy)
275{
276	FtkBitmap* bitmap = NULL;
277
278	ftk_canvas_lock_buffer(thiz, &bitmap);
279	ftk_display_update_and_notify(display, bitmap, rect, ox, oy);
280	ftk_canvas_unlock_buffer(thiz);
281
282	return RET_OK;
283}
284
285const char* ftk_canvas_calc_str_visible_range(FtkCanvas* thiz, 
286	const char* start, int vstart, int vend, int width, int* ret_extent)
287{
288	int extent = 0;
289	int line_extent = 0;
290	unsigned short unicode = 0;
291	const char* iter = NULL;
292	const char* prev_iter = NULL;
293
294	if(vstart >= 0)
295	{
296		iter = start + vstart;
297		prev_iter = iter;
298		while(width > 0)
299		{
300			prev_iter = iter;
301			unicode = utf8_get_char(iter, &iter);
302			if(unicode == '\r') continue;
303			if(unicode == 0 || unicode == 0xffff)
304			{
305				break;
306			}
307			else if( unicode == '\n') 
308			{	
309				prev_iter = iter;
310				break;
311			}
312
313			extent = ftk_canvas_get_char_extent(thiz, unicode);
314			if(extent > width) break;
315			width -= extent;
316			line_extent += extent;
317			prev_iter = iter;
318		}
319		if(ret_extent != NULL) 
320			*ret_extent = line_extent;
321	
322		return prev_iter;
323	}
324	else if(vend > 0)
325	{
326		iter = start + vend;
327		prev_iter = iter;
328		while(width > 0 && iter >= start)
329		{
330			prev_iter = iter;
331			if(iter <= start) break;
332			unicode = utf8_get_prev_char(iter, &iter);
333			if(unicode == '\r') continue;
334			if(unicode == 0 || unicode == 0xffff || unicode == '\n')
335			{
336			//	prev_iter = iter;
337				break;
338			}
339			extent = ftk_canvas_get_char_extent(thiz, unicode);
340			if(extent > width) break;
341			width -= extent;
342			line_extent += extent;
343		}
344
345		if(ret_extent != NULL) 
346			*ret_extent = line_extent;
347
348		return prev_iter;
349	}
350		
351	return start;
352}