#include <glib.h>
#include "scbcolor.h"
#include "scbpoints.h"
#include "scbtype.h"
#include "scbstream.h"
Go to the source code of this file.
typedef struct _ScbHitTestCtx ScbHitTestCtx |
typedef ScbHitTestCtx* ScbHitTestCtxPtr |
Definition at line 95 of file scbstroke.h.
typedef struct _ScbStroke ScbStroke |
typedef G_BEGIN_DECLS struct _ScbStrokeAttributes ScbStrokeAttributes |
Copyright (C) 2008 iRex Technologies B.V. All rights reserved.
Definition at line 76 of file scbstroke.h.
typedef ScbStroke* ScbStrokePtr |
Definition at line 86 of file scbstroke.h.
int erscribble_stroke_add_point | ( | ScbStrokePtr | stroke, | |
ScbDevPointPtr | point | |||
) |
Definition at line 194 of file scbstroke.c.
References _ScbRect::bottom, erscribble_points_append(), ERSCRIBBLE_RET_ERR, ERSCRIBBLE_RET_INT_IF, ERSCRIBBLE_RET_OK, _ScbRect::left, _ScbDevPoint::point, _ScbStroke::points, _ScbStroke::rect, _ScbRect::right, _ScbRect::top, _ScbPoint::x, and _ScbPoint::y.
Referenced by erscribble_stroke_load(), notepad::CNotepadDoc::on_scribble_begin(), notepad::CNotepadDoc::on_scribble_end(), and notepad::CNotepadDoc::on_scribble_move().
00195 { 00196 ERSCRIBBLE_RET_INT_IF(NULL == stroke, ERSCRIBBLE_RET_ERR, "stroke pointer is NULL!"); 00197 ERSCRIBBLE_RET_INT_IF(NULL == point, ERSCRIBBLE_RET_ERR, "Invalid point pointer!"); 00198 00199 // for debug. report points whose x or y is incorrect. 00200 // It maybe not correct, the coordinates can be very large. 00201 // if (point->x >= 1024 || point->y >= 1024) 00202 // { 00203 // WARNPRINTF("Odd points found! (%d %d)", point->x, point->y); 00204 // } 00205 00206 erscribble_points_append(&stroke->points, point); 00207 00208 // adjust rectangle 00209 if (stroke->rect.left > point->point.x) 00210 { 00211 stroke->rect.left = point->point.x; 00212 } 00213 00214 if (stroke->rect.right < point->point.x) 00215 { 00216 stroke->rect.right = point->point.x; 00217 } 00218 00219 if (stroke->rect.top > point->point.y) 00220 { 00221 stroke->rect.top = point->point.y; 00222 } 00223 00224 if (stroke->rect.bottom < point->point.y) 00225 { 00226 stroke->rect.bottom = point->point.y; 00227 } 00228 00229 return ERSCRIBBLE_RET_OK; 00230 }
void erscribble_stroke_driver_draw | ( | ScbStrokePtr | stroke | ) |
Definition at line 285 of file scbstroke.c.
References _ScbStroke::attributes, ERSCRIBBLE_DEF_DRIVER_DRAW_BUF_LEN, erscribble_driver_draw_points(), ERSCRIBBLE_RET_IF, _ScbStroke::points, _ScbPoint::x, _DrvPointInfo::x, and _ScbPoint::y.
Referenced by erscribble_strokes_erase_driver_draw().
00286 { 00287 ERSCRIBBLE_RET_IF(NULL == stroke || NULL == stroke->points.points, "NULL pointer!"); 00288 00289 int len = stroke->points.points->len; 00290 if (len <= 0) return; 00291 00292 ScbPointPtr ip = (ScbPointPtr)stroke->points.points->data; 00293 00294 DrvPointsBuf output; 00295 int output_size = 0; 00296 00297 int brush_size = stroke->attributes.size_id; 00298 unsigned char brush_color = stroke->attributes.color; 00299 00300 // divide into ioctl's 00301 DrvPointInfo* op = &output.points[0]; 00302 int i = 0; 00303 for(i = 0; i < len; ++i) 00304 { 00305 // copy points 00306 op->x = ip->x; 00307 op->y = ip->y; 00308 op->size = brush_size; 00309 op->color = brush_color; 00310 if (i == len-1) op->pen_down = FALSE; // force pen_up for last point of stroke 00311 else op->pen_down = TRUE; 00312 00313 output_size++; 00314 ip++; 00315 op++; 00316 00317 if (output_size == ERSCRIBBLE_DEF_DRIVER_DRAW_BUF_LEN || i == len-1) 00318 { 00319 // call ioctl 00320 output.count = output_size; 00321 erscribble_driver_draw_points(&output); 00322 output_size = 0; 00323 op = &output.points[0]; 00324 } 00325 } 00326 }
void erscribble_stroke_driver_draw_point | ( | ScbStrokePtr | stroke, | |
ScbDevPointPtr | point, | |||
gboolean | is_last_point | |||
) |
Definition at line 247 of file scbstroke.c.
References _ScbStroke::attributes, erscribble_driver_draw(), erscribble_driver_draw_now(), erscribble_driver_draw_record(), erscribble_driver_draw_reset_context(), and ERSCRIBBLE_RET_IF.
Referenced by notepad::CNotepadDoc::on_scribble_begin(), notepad::CNotepadDoc::on_scribble_end(), and notepad::CNotepadDoc::on_scribble_move().
00248 { 00249 ERSCRIBBLE_RET_IF(NULL == stroke || NULL == point, "NULL storke or point!"); 00250 00251 // Fast draw points by using the additional global points buffer. 00252 // Here, we have two choices: 00253 // 1. use a timer, but the application should have a message loop. Gtk/X11 00254 // 2. check timestamp and points, draw them if necessary. 00255 00256 if (erscribble_driver_draw_now() || is_last_point) 00257 { 00258 if (is_last_point) 00259 { 00260 // add the last point 00261 erscribble_driver_draw_record(point, 00262 stroke->attributes.size_id, 00263 stroke->attributes.color, 00264 FALSE); 00265 } 00266 00267 // draw it right now 00268 erscribble_driver_draw(); 00269 00270 // reset 00271 erscribble_driver_draw_reset_context(); 00272 } 00273 00274 if (!is_last_point) 00275 { 00276 // record this point 00277 erscribble_driver_draw_record(point, 00278 stroke->attributes.size_id, 00279 stroke->attributes.color, 00280 TRUE); 00281 } 00282 }
void erscribble_stroke_dump | ( | ScbStrokePtr | ptr | ) |
Definition at line 549 of file scbstroke.c.
References DUMPPRINTF, ERSCRIBBLE_RET_IF, _ScbStroke::points, _ScbPoint::x, and _ScbPoint::y.
Referenced by _stroke_dump().
00550 { 00551 ERSCRIBBLE_RET_IF(NULL == ptr || NULL == ptr->points.points, ""); 00552 00553 int count = ptr->points.points->len; 00554 ScbPointPtr p = (ScbPointPtr)ptr->points.points->data; 00555 int *pp = (int *)ptr->points.pressures->data; 00556 while(count > 0) 00557 { 00558 DUMPPRINTF("\t(%d,\t%d,\t%d)", p->x, p->y, *pp); 00559 --count; ++ p; ++pp; 00560 } 00561 }
void erscribble_stroke_free | ( | ScbStrokePtr | stroke | ) |
Definition at line 183 of file scbstroke.c.
References erscribble_points_free(), ERSCRIBBLE_RET_IF, and _ScbStroke::points.
Referenced by _stroke_release(), and erscribble_strokes_load().
00184 { 00185 ERSCRIBBLE_RET_IF(NULL == stroke, "Attempt to release NULL pointer!"); 00186 if (stroke->points.points) 00187 { 00188 erscribble_points_free(&stroke->points); 00189 } 00190 g_free(stroke); 00191 }
ScbDevColor erscribble_stroke_get_color | ( | ScbStrokePtr | stroke | ) |
Definition at line 574 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_DEV_COLOR_UNKNOWN.
00575 { 00576 if (NULL == stroke) 00577 { 00578 return ERSCRIBBLE_DEV_COLOR_UNKNOWN; 00579 } 00580 return stroke->attributes.color; 00581 }
int erscribble_stroke_get_point_count | ( | ScbStrokePtr | stroke | ) |
Definition at line 233 of file scbstroke.c.
References ERSCRIBBLE_INVALID_COUNT, ERSCRIBBLE_RET_INT_IF, and _ScbStroke::points.
Referenced by erscribble_page_get_length().
00234 { 00235 ERSCRIBBLE_RET_INT_IF(NULL == stroke || NULL == stroke->points.points, ERSCRIBBLE_INVALID_COUNT, "Invalid pointer(s)!"); 00236 return stroke->points.points->len; 00237 }
ScbPointPtr erscribble_stroke_get_point_data | ( | ScbStrokePtr | stroke | ) |
Definition at line 240 of file scbstroke.c.
References erscribble_points_get_data(), ERSCRIBBLE_RET_NULL_IF, and _ScbStroke::points.
00241 { 00242 ERSCRIBBLE_RET_NULL_IF(NULL == stroke, "Invalid pointer!"); 00243 return erscribble_points_get_data(&stroke->points); 00244 }
int erscribble_stroke_get_shape | ( | ScbStrokePtr | stroke | ) |
Definition at line 527 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_INVALID_SHAPE.
00528 { 00529 if (NULL == stroke) 00530 { 00531 return ERSCRIBBLE_INVALID_SHAPE; 00532 } 00533 00534 return stroke->attributes.shape_id; 00535 }
int erscribble_stroke_get_size | ( | ScbStrokePtr | stroke | ) |
Definition at line 538 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_INVALID_SIZE.
00539 { 00540 if (NULL == stroke) 00541 { 00542 return ERSCRIBBLE_INVALID_SIZE; 00543 } 00544 00545 return stroke->attributes.size_id; 00546 }
gboolean erscribble_stroke_line_hit_test | ( | ScbStrokePtr | stroke, | |
ScbDevPointPtr | point1, | |||
ScbDevPointPtr | point2, | |||
const ScbHitTestCtxPtr | ctx | |||
) |
Definition at line 380 of file scbstroke.c.
References _ScbStroke::attributes, _ScbRect::bottom, erscribble_is_lines_intersect(), erscribble_is_rect_intersect(), ERSCRIBBLE_RET_FALSE_IF, _ScbRect::left, LOGPRINTF, _ScbDevPoint::point, _ScbStroke::points, _ScbStroke::rect, _ScbRect::right, _ScbHitTestCtx::size, _ScbRect::top, _ScbPoint::x, _ScbPoint::y, and _ScbHitTestCtx::zoom.
Referenced by erscribble_strokes_line_hit_test().
00384 { 00385 ERSCRIBBLE_RET_FALSE_IF(NULL == stroke || NULL == point1 || NULL == point2 || NULL == ctx, 00386 "Invalid pointer(s)!"); 00387 00388 // check line and line segment in stroke 00389 // not consider the line width here... 00390 00391 // fast check 00392 ScbRect tmp; 00393 double ratio = 1.0; 00394 ScbDevPoint p1, p2; 00395 if (fabs(stroke->attributes.zoom - ctx->zoom) >= e) 00396 { 00397 ratio = stroke->attributes.zoom / ctx->zoom; 00398 p1.point.x = (int)point1->point.x * ratio; 00399 p1.point.y = (int)point1->point.y * ratio; 00400 p2.point.x = (int)point2->point.x * ratio; 00401 p2.point.y = (int)point2->point.y * ratio; 00402 } 00403 else 00404 { 00405 p1 = *point1; p2 = *point2; 00406 } 00407 00408 00409 tmp.left = MIN(p1.point.x, p2.point.x) - ctx->size; 00410 tmp.right = MAX(p1.point.x, p2.point.x) + ctx->size; 00411 tmp.top = MIN(p1.point.y, p2.point.y) - ctx->size; 00412 tmp.bottom = MAX(p1.point.y, p2.point.y) + ctx->size; 00413 if (!erscribble_is_rect_intersect(&stroke->rect, &tmp)) 00414 { 00415 return FALSE; 00416 } 00417 00418 // check each line segment in stroke 00419 int len = stroke->points.points->len; 00420 ScbPointPtr begin = (ScbPointPtr)stroke->points.points->data; 00421 ScbPointPtr end = begin; 00422 00423 // only one point 00424 if (len == 1) 00425 { 00426 if (erscribble_is_lines_intersect((ScbPointPtr)&p1, (ScbPointPtr)&p2, begin, end)) 00427 { 00428 LOGPRINTF("one point hit!"); 00429 LOGPRINTF("line in stroke: (%d %d) - (%d %d)", 00430 begin->x, begin->y, end->x, end->y); 00431 LOGPRINTF("user line: (%d %d) - (%d %d)", 00432 p1.point.x, p1.point.y, p2.point.x, p2.point.y); 00433 return TRUE; 00434 } 00435 return FALSE; 00436 } 00437 00438 // others 00439 while (len > 1) 00440 { 00441 ++end; 00442 if (erscribble_is_lines_intersect((ScbPointPtr)&p1, (ScbPointPtr)&p2, begin, end)) 00443 { 00444 // for debug 00445 LOGPRINTF("line in stroke: (%d %d) - (%d %d)", 00446 begin->x, begin->y, end->x, end->y); 00447 LOGPRINTF("user line: (%d %d) - (%d %d)", 00448 p1.point.x, p1.point.y, p2.point.x, p2.point.y); 00449 return TRUE; 00450 } 00451 begin = end; --len; 00452 } 00453 return FALSE; 00454 }
gboolean erscribble_stroke_load | ( | ScbStrokePtr | stroke, | |
ScbStreamPtr | stream | |||
) |
Definition at line 457 of file scbstroke.c.
References _ScbStroke::attributes, erscribble_point_load(), erscribble_read_stream(), ERSCRIBBLE_RET_FALSE_IF, and erscribble_stroke_add_point().
Referenced by erscribble_strokes_load().
00458 { 00459 ERSCRIBBLE_RET_FALSE_IF(NULL == stroke || NULL == stream, "Invalid stroke pointer or stream!"); 00460 00461 gboolean ret = erscribble_read_stream(stream, &stroke->attributes, sizeof(stroke->attributes)); 00462 00463 if (ret == FALSE) 00464 { 00465 return ret; 00466 } 00467 00468 ScbDevPoint point; 00469 int i = 0; 00470 for (; i < stroke->attributes.points_number; ++i) 00471 { 00472 if (erscribble_point_load(&point, stream) == FALSE) 00473 { 00474 return FALSE; 00475 } 00476 00477 erscribble_stroke_add_point(stroke, &point); 00478 } 00479 00480 return TRUE; 00481 }
ScbStrokePtr erscribble_stroke_new | ( | ) |
Definition at line 122 of file scbstroke.c.
References _ScbStroke::attributes, _ScbRect::bottom, ERSCRIBBLE_DEF_SHAPE_LINE, ERSCRIBBLE_DEF_STROKE_LAYER, ERSCRIBBLE_DEF_STROKE_PENSIZE, ERSCRIBBLE_DEF_STROKE_POINTSIZE, ERSCRIBBLE_DEV_COLOR_BLACK, erscribble_driver_draw_reset_context(), erscribble_points_new(), ERSCRIBBLE_RET_NULL_IF, _ScbRect::left, _ScbStroke::points, _ScbStroke::rect, _ScbRect::right, and _ScbRect::top.
Referenced by erscribble_strokes_load().
00123 { 00124 ScbStrokePtr ptr = g_new0(ScbStroke, 1); 00125 ERSCRIBBLE_RET_NULL_IF(NULL == ptr, "Not enough memory for stroke!"); 00126 00127 // allocate points array 00128 if (!erscribble_points_new(&ptr->points, ERSCRIBBLE_DEF_STROKE_POINTSIZE)) 00129 { 00130 // could not alloc memory for list 00131 g_free(ptr); 00132 return NULL; 00133 } 00134 00135 // init the stroke paramters 00136 ptr->attributes.color = ERSCRIBBLE_DEV_COLOR_BLACK; 00137 ptr->attributes.layer = ERSCRIBBLE_DEF_STROKE_LAYER; 00138 ptr->attributes.shape_id = ERSCRIBBLE_DEF_SHAPE_LINE; 00139 ptr->attributes.size_id = ERSCRIBBLE_DEF_STROKE_PENSIZE; 00140 00141 // init out bound rect. used to fast hit test 00142 ptr->rect.left = INT_MAX; 00143 ptr->rect.top = INT_MAX; 00144 ptr->rect.right = INT_MIN; 00145 ptr->rect.bottom = INT_MIN; 00146 00147 // init fast draw context 00148 erscribble_driver_draw_reset_context(); 00149 return ptr; 00150 }
ScbStrokePtr erscribble_stroke_new_with_attributes | ( | ScbStrokeAttributesPtr | pAttr | ) |
Definition at line 153 of file scbstroke.c.
References _ScbStroke::attributes, _ScbRect::bottom, ERSCRIBBLE_DEF_STROKE_POINTSIZE, erscribble_driver_draw_reset_context(), erscribble_points_new(), ERSCRIBBLE_RET_NULL_IF, _ScbRect::left, _ScbStroke::points, _ScbStroke::rect, _ScbRect::right, and _ScbRect::top.
Referenced by notepad::CNotepadDoc::on_scribble_begin().
00154 { 00155 ERSCRIBBLE_RET_NULL_IF(NULL == pAttr, "Invalid pointer!"); 00156 00157 ScbStrokePtr ptr = g_new0(ScbStroke, 1); 00158 ERSCRIBBLE_RET_NULL_IF(NULL == ptr, "Not enough memory for stroke!"); 00159 00160 // allocate points array 00161 if (!erscribble_points_new(&ptr->points, ERSCRIBBLE_DEF_STROKE_POINTSIZE)) 00162 { 00163 // could not alloc memory for list 00164 g_free(ptr); 00165 return NULL; 00166 } 00167 00168 // init the stroke paramters 00169 ptr->attributes = *pAttr; 00170 00171 // init out bound rect. used to fast hit test 00172 ptr->rect.left = INT_MAX; 00173 ptr->rect.top = INT_MAX; 00174 ptr->rect.right = INT_MIN; 00175 ptr->rect.bottom = INT_MIN; 00176 00177 // init fast draw context 00178 erscribble_driver_draw_reset_context(); 00179 return ptr; 00180 }
gboolean erscribble_stroke_point_hit_test | ( | ScbStrokePtr | stroke, | |
ScbDevPointPtr | point, | |||
const ScbHitTestCtxPtr | ctx | |||
) |
Definition at line 329 of file scbstroke.c.
References _ScbStroke::attributes, _ScbRect::bottom, erscribble_is_rect_intersect(), ERSCRIBBLE_RET_FALSE_IF, _ScbRect::left, LOGPRINTF, _ScbDevPoint::point, _ScbStroke::points, _ScbStroke::rect, _ScbRect::right, _ScbHitTestCtx::size, _ScbRect::top, _ScbPoint::x, _ScbPoint::y, and _ScbHitTestCtx::zoom.
Referenced by erscribble_strokes_point_hit_test().
00332 { 00333 ERSCRIBBLE_RET_FALSE_IF(NULL == stroke || NULL == point || NULL == ctx, 00334 "Invalid pointer(s)!"); 00335 00336 // hit test 00337 // 1. check out bound and the point (fast check) 00338 // 2. check points in the stroke 00339 00340 // fast check 00341 ScbRect tmp; 00342 double ratio = 1.0; 00343 if (fabs(stroke->attributes.zoom - ctx->zoom) >= e) 00344 { 00345 ratio = stroke->attributes.zoom / ctx->zoom; 00346 } 00347 tmp.left = point->point.x * ratio - ctx->size; 00348 tmp.right = point->point.x * ratio + ctx->size; 00349 tmp.top = point->point.y * ratio - ctx->size; 00350 tmp.bottom = point->point.y * ratio + ctx->size; 00351 if (!erscribble_is_rect_intersect(&stroke->rect, &tmp)) 00352 { 00353 return FALSE; 00354 } 00355 00356 // check each point in stroke 00357 ScbRect src; 00358 int size = stroke->attributes.size_id; 00359 int len = stroke->points.points->len; 00360 ScbPointPtr pts = (ScbPointPtr)stroke->points.points->data; 00361 while (len) 00362 { 00363 src.left = pts->x - size; 00364 src.right = pts->x + size; 00365 src.top = pts->y - size; 00366 src.bottom = pts->y + size; 00367 if (erscribble_is_rect_intersect(&src, &tmp)) 00368 { 00369 LOGPRINTF("\nrect1: (%d %d %d %d)\nrect2: (%d %d %d %d)", 00370 src.left, src.top, src.right, src.bottom, 00371 tmp.left, tmp.top, tmp.right, tmp.bottom); 00372 return TRUE; 00373 } 00374 ++pts; --len; 00375 } 00376 return FALSE; 00377 }
void erscribble_stroke_set_color | ( | ScbStrokePtr | stroke, | |
const ScbDevColor | color | |||
) |
Definition at line 567 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_RET_IF.
00568 { 00569 ERSCRIBBLE_RET_IF(NULL == stroke, "Invalid pointer!"); 00570 stroke->attributes.color = color; 00571 }
void erscribble_stroke_set_shape | ( | ScbStrokePtr | stroke, | |
const int | shape_id | |||
) |
Definition at line 513 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_RET_IF.
00514 { 00515 ERSCRIBBLE_RET_IF(NULL == stroke, "Invalid pointer!"); 00516 stroke->attributes.shape_id = shape_id; 00517 }
void erscribble_stroke_set_size | ( | ScbStrokePtr | stroke, | |
const int | size_id | |||
) |
Definition at line 520 of file scbstroke.c.
References _ScbStroke::attributes, and ERSCRIBBLE_RET_IF.
00521 { 00522 ERSCRIBBLE_RET_IF(NULL == stroke, "Invalid pointer!"); 00523 stroke->attributes.size_id = size_id; 00524 }
gboolean erscribble_stroke_write_stream | ( | ScbStrokePtr | stroke, | |
ScbStreamPtr | stream | |||
) |
Definition at line 484 of file scbstroke.c.
References _ScbStroke::attributes, ERSCRIBBLE_RET_FALSE_IF, erscribble_write_stream(), and _ScbStroke::points.
Referenced by erscribble_strokes_write_stream().
00485 { 00486 ERSCRIBBLE_RET_FALSE_IF(NULL == stroke || NULL == stream, "Invalid stroke pointer or stream!"); 00487 00488 if (erscribble_write_stream(stream, &stroke->attributes, sizeof(stroke->attributes)) == FALSE) 00489 { 00490 return FALSE; 00491 } 00492 00493 int i = 0; 00494 for (; i < stroke->attributes.points_number; ++i) 00495 { 00496 ScbPoint point = g_array_index(stroke->points.points, ScbPoint, i); 00497 if (erscribble_write_stream(stream, &point, sizeof(ScbPoint)) == FALSE) 00498 { 00499 return FALSE; 00500 } 00501 00502 int pressure = g_array_index(stroke->points.pressures, int, i); 00503 if (erscribble_write_stream(stream, &pressure, sizeof(int)) == FALSE) 00504 { 00505 return FALSE; 00506 } 00507 } 00508 00509 return TRUE; 00510 }