#include "scbcolor.h"#include "scbpoints.h"#include "scbtype.h"#include "scbxml.h"#include <glib.h>

Go to the source code of this file.
| typedef struct _ScbHitTestCtx ScbHitTestCtx |
| typedef ScbHitTestCtx* ScbHitTestCtxPtr |
Definition at line 60 of file scbstroke.h.
| typedef struct _ScbStroke ScbStroke |
| typedef ScbStroke* ScbStrokePtr |
Definition at line 53 of file scbstroke.h.
| typedef struct _ScbStrokeStyle ScbStrokeStyle |
Copyright (C) 2005-2008 iRex Technologies B.V. All rights reserved.
| typedef ScbStrokeStyle* ScbStrokeStylePtr |
Definition at line 45 of file scbstroke.h.
| int scb_stroke_add_point | ( | ScbStrokePtr | stroke, | |
| ScbDevPointPtr | point | |||
| ) |
Definition at line 170 of file scbstroke.c.
00171 { 00172 SCB_RET_INT_IF(NULL == stroke, SCB_RET_ERR, "stroke pointer is NULL!"); 00173 SCB_RET_INT_IF(NULL == point, SCB_RET_ERR, "Invalid point pointer!"); 00174 00175 // for debug. report points whose x or y is incorrect. 00176 // It maybe not correct, the coordinates can be very large. 00177 #if (SCB_DEBUG_ON) 00178 // if (point->x >= 1024 || point->y >= 1024) 00179 // { 00180 // SCB_WARN("Odd points found! (%d %d)", point->x, point->y); 00181 // } 00182 #endif 00183 00184 scb_points_append(&stroke->points, point); 00185 00186 // adjust rectangle 00187 if (stroke->rect.left > point->x) 00188 { 00189 stroke->rect.left = point->x; 00190 } 00191 if (stroke->rect.right < point->x) 00192 { 00193 stroke->rect.right = point->x; 00194 } 00195 00196 if (stroke->rect.top > point->y) 00197 { 00198 stroke->rect.top = point->y; 00199 } 00200 if (stroke->rect.bottom < point->y) 00201 { 00202 stroke->rect.bottom = point->y; 00203 } 00204 return SCB_RET_OK; 00205 }

| void scb_stroke_dump | ( | ScbStrokePtr | ptr | ) |
Definition at line 624 of file scbstroke.c.
00625 { 00626 SCB_RET_IF(NULL == ptr || NULL == ptr->points.points, ""); 00627 00628 int count = ptr->points.points->len; 00629 ScbPointPtr p = (ScbPointPtr)ptr->points.points->data; 00630 int *pp = (int *)ptr->points.pressures->data; 00631 while(count > 0) 00632 { 00633 SCB_DUMP("\t(%d,\t%d,\t%d)", p->x, p->y, *pp); 00634 --count; ++ p; ++pp; 00635 } 00636 }
| void scb_stroke_fast_draw | ( | ScbStrokePtr | stroke | ) |
Definition at line 299 of file scbstroke.c.
00300 { 00301 SCB_RET_IF(NULL == stroke || NULL == stroke->points.points, "NULL pointer!"); 00302 00303 // construct a temp PointsBufPtr, copy stroke data into points buf 00304 DrvPointsBuf tmp; 00305 gboolean end_of_stroke; 00306 int i = 0; 00307 int len = stroke->points.points->len; 00308 ScbPointPtr pt = (ScbPointPtr)stroke->points.points->data; 00309 00310 // do nothing 00311 if (len < 0) return; 00312 00313 // collect valid points 00314 tmp.count = 0; 00315 00316 // construct the buffer 00317 end_of_stroke = FALSE; 00318 for(i = 0; i < len; ++i, ++pt) 00319 { 00320 // split stroke in smaller ones containing max. SCB_DEF_FAST_DRAW_BUF_LEN valid points 00321 if ( pt->x >= SCB_DEF_BOUNDARY_LEFT && pt->x <= SCB_DEF_BOUNDARY_RIGHT 00322 && pt->y >= SCB_DEF_BOUNDARY_TOP && pt->y <= SCB_DEF_BOUNDARY_BOTTOM ) 00323 { 00324 // valid point: add to stroke to be drawn 00325 tmp.points[tmp.count].x = pt->x; 00326 tmp.points[tmp.count].y = pt->y; 00327 tmp.points[tmp.count].size = stroke->style.penSize; 00328 tmp.points[tmp.count].pen_down = TRUE; 00329 tmp.points[tmp.count].color = stroke->style.color; 00330 ++tmp.count; 00331 if ( i >= len - 1 00332 || tmp.count >= SCB_DEF_FAST_DRAW_BUF_LEN) 00333 { 00334 end_of_stroke = TRUE; 00335 } 00336 } 00337 else 00338 { 00339 // invalid point: end stroke to be drawn, if any 00340 if (tmp.count > 0) 00341 { 00342 end_of_stroke = TRUE; 00343 } 00344 } 00345 00346 // draw the valid (sub)stroke as needed 00347 if (end_of_stroke) 00348 { 00349 // force pen_up for last point of stroke 00350 tmp.points[tmp.count - 1].pen_down = FALSE; 00351 scb_driver_draw(&tmp); 00352 tmp.count = 0; 00353 end_of_stroke = FALSE; 00354 } 00355 } 00356 }

| void scb_stroke_fast_draw_point | ( | ScbStrokePtr | stroke, | |
| ScbDevPointPtr | point | |||
| ) |
Definition at line 255 of file scbstroke.c.
00256 { 00257 SCB_RET_IF(NULL == stroke || NULL == point, "NULL storke or point!"); 00258 00259 if (scb_fast_draw_now()) 00260 { 00261 // draw it right now 00262 scb_fast_draw(); 00263 00264 // reset 00265 scb_fast_draw_reset_context(); 00266 } 00267 00268 // record this point 00269 scb_fast_draw_record(point, 00270 stroke->style.penSize, 00271 stroke->style.color, 00272 TRUE); 00273 }

| void scb_stroke_fast_draw_point_done | ( | ScbStrokePtr | stroke, | |
| ScbDevPointPtr | point | |||
| ) |
Definition at line 279 of file scbstroke.c.
00280 { 00281 SCB_RET_IF(NULL == stroke || NULL == point, "NULL storke or point!"); 00282 00283 // add the last point 00284 scb_fast_draw_record(point, 00285 stroke->style.penSize, 00286 stroke->style.color, 00287 FALSE); 00288 00289 // fast draw 00290 scb_fast_draw(); 00291 00292 // reset 00293 scb_fast_draw_reset_context(); 00294 }

| void scb_stroke_free | ( | ScbStrokePtr | stroke | ) |
Definition at line 158 of file scbstroke.c.
00159 { 00160 SCB_RET_IF(NULL == stroke, "Attempt to release NULL pointer!"); 00161 if (stroke->points.points) 00162 { 00163 scb_points_free(&stroke->points); 00164 } 00165 g_free(stroke); 00166 }

| ScbDevColor scb_stroke_get_color | ( | ScbStrokePtr | stroke | ) |
Definition at line 612 of file scbstroke.c.
00613 { 00614 if (NULL == stroke) 00615 { 00616 return SCB_DEV_COLOR_UNKNOWN; 00617 } 00618 return stroke->style.color; 00619 }
| int scb_stroke_get_point_count | ( | ScbStrokePtr | stroke | ) |
Definition at line 208 of file scbstroke.c.
00209 { 00210 SCB_RET_INT_IF(NULL == stroke || NULL == stroke->points.points, SCB_INVALID_COUNT, "Invalid pointer(s)!"); 00211 return stroke->points.points->len; 00212 }
| ScbPointPtr scb_stroke_get_point_data | ( | ScbStrokePtr | stroke | ) |
Definition at line 216 of file scbstroke.c.
00217 { 00218 SCB_RET_NULL_IF(NULL == stroke, "Invalid pointer!"); 00219 return scb_points_get_data(&stroke->points); 00220 }

| gboolean scb_stroke_line_hit_test | ( | ScbStrokePtr | stroke, | |
| ScbDevPointPtr | point1, | |||
| ScbDevPointPtr | point2, | |||
| const ScbHitTestCtxPtr | ctx | |||
| ) |
Definition at line 413 of file scbstroke.c.
00417 { 00418 SCB_RET_FALSE_IF(NULL == stroke || NULL == point1 || NULL == point2 || NULL == ctx, 00419 "Invalid pointer(s)!"); 00420 00421 // fast check 00422 ScbRect tmp; 00423 double ratio = 1.0; 00424 ScbDevPoint p1, p2; 00425 if (fabs(stroke->style.zoom - ctx->zoom) >= e) 00426 { 00427 ratio = stroke->style.zoom / ctx->zoom; 00428 p1.x = (int)point1->x * ratio; p1.y = (int)point1->y * ratio; 00429 p2.x = (int)point2->x * ratio; p2.y = (int)point2->y * ratio; 00430 } 00431 else 00432 { 00433 p1 = *point1; p2 = *point2; 00434 } 00435 00436 00437 tmp.left = MIN(p1.x, p2.x) - ctx->size; 00438 tmp.right = MAX(p1.x, p2.x) + ctx->size; 00439 tmp.top = MIN(p1.y, p2.y) - ctx->size; 00440 tmp.bottom = MAX(p1.y, p2.y) + ctx->size; 00441 if (!scb_is_rect_intersect(&stroke->rect, &tmp)) 00442 { 00443 return FALSE; 00444 } 00445 00446 // check each line segment in stroke 00447 int len = stroke->points.points->len; 00448 ScbPointPtr begin = (ScbPointPtr)stroke->points.points->data; 00449 ScbPointPtr end = begin; 00450 00451 // only one point 00452 if (len == 1) 00453 { 00454 if (scb_is_lines_intersect((ScbPointPtr)&p1, (ScbPointPtr)&p2, begin, end)) 00455 { 00456 #if (SCB_DEBUG_ON) 00457 SCB_TRACE("one point hit!"); 00458 SCB_TRACE("line in stroke: (%d %d) - (%d %d)", 00459 begin->x, begin->y, end->x, end->y); 00460 SCB_TRACE("user line: (%d %d) - (%d %d)", 00461 p1.x, p1.y, p2.x, p2.y); 00462 #endif 00463 return TRUE; 00464 } 00465 return FALSE; 00466 } 00467 00468 // others 00469 while (len > 1) 00470 { 00471 ++end; 00472 if (scb_is_lines_intersect((ScbPointPtr)&p1, (ScbPointPtr)&p2, begin, end)) 00473 { 00474 // for debug 00475 #if (SCB_DEBUG_ON) 00476 SCB_TRACE("line in stroke: (%d %d) - (%d %d)", 00477 begin->x, begin->y, end->x, end->y); 00478 SCB_TRACE("user line: (%d %d) - (%d %d)", 00479 p1.x, p1.y, p2.x, p2.y); 00480 #endif 00481 return TRUE; 00482 } 00483 begin = end; --len; 00484 } 00485 return FALSE; 00486 }

| gboolean scb_stroke_load | ( | ScbStrokePtr | stroke, | |
| ScbXmlPtr | ||||
| ) |
Definition at line 545 of file scbstroke.c.
00546 { 00547 // check 00548 SCB_RET_FALSE_IF(NULL == stroke || NULL == ptr, "Invalid pointer!"); 00549 00550 // construct xpath 00551 char xPath[SCB_MAX_XML_PATH] = {0}; 00552 strncpy(xPath, ptr->xPath, SCB_MAX_XML_PATH); 00553 char * addr = xPath + strnlen(xPath, SCB_MAX_XML_PATH); 00554 snprintf(addr, SCB_MAX_XML_PATH, "/stroke[%d]", ptr->index); 00555 // SCB_TRACE("xPath %s", xPath); 00556 00557 // read attributes 00558 const int MAX_BUF_LEN = SCB_MAX_XML_PATH; 00559 char buf[SCB_MAX_XML_PATH] = {0}; 00560 ermXmlGetAttributeString(&ptr->handle, xPath, "color", buf, MAX_BUF_LEN); 00561 stroke->style.color = scb_html_color_to_dev_color(buf, MAX_BUF_LEN); 00562 ermXmlGetAttributeInt(&ptr->handle, xPath, "layer", &stroke->style.layer); 00563 ermXmlGetAttributeInt(&ptr->handle, xPath, "penSize", (int *)&stroke->style.penSize); 00564 ermXmlGetAttributeString(&ptr->handle, xPath, "linestyle", buf, MAX_BUF_LEN); 00565 stroke->style.lineStyle = scb_line_style_from_str(buf); 00566 ermXmlGetAttributeString(&ptr->handle, xPath, "zoom", buf, MAX_BUF_LEN); 00567 sscanf(buf, "%lf", &stroke->style.zoom); 00568 00569 // read stroke data from stroke node 00570 int len = 0; 00571 const char *data = ermXmlGetStringBuffer(&ptr->handle, xPath, &len); 00572 addr = (char *)data; // remember the address 00573 if (len <= 0 || NULL == data) 00574 { 00575 #if (SCB_DEBUG_ON) 00576 // in fact, it's not an error. when no data could read, just return false 00577 // SCB_TRACE("No data in this stroke!"); 00578 #endif 00579 return FALSE; 00580 } 00581 00582 // here, we assume that the xmlchar is zero terminated 00583 ScbDevPoint point; 00584 while (data && 0 != *data) 00585 { 00586 if (3 != sscanf(data, "%d %d %d", &point.x, &point.y, &point.pressure)) 00587 { 00588 break; 00589 } 00590 00591 scb_stroke_add_point(stroke, &point); 00592 data = strchr(data, '\n'); // to next begin 00593 if (NULL == data) 00594 { 00595 SCB_ERROR("Could not find new line!"); 00596 ermXmlFreeStringBuffer(addr); 00597 return FALSE; 00598 } 00599 ++data; 00600 } 00601 ermXmlFreeStringBuffer(addr); 00602 return TRUE; 00603 }

| ScbStrokePtr scb_stroke_new | ( | ) |
Definition at line 97 of file scbstroke.c.
00098 { 00099 ScbStrokePtr ptr = g_new0(ScbStroke, 1); 00100 SCB_RET_NULL_IF(NULL == ptr, "Not enough memory for stroke!"); 00101 00102 // allocate points array 00103 if (!scb_points_new(&ptr->points, SCB_DEF_STROKE_POINTSIZE)) 00104 { 00105 // could not alloc memory for list 00106 g_free(ptr); 00107 return NULL; 00108 } 00109 00110 // init the stroke paramters 00111 ptr->style.color = SCB_DEV_COLOR_BLACK; 00112 ptr->style.layer = SCB_DEF_STROKE_LAYER; 00113 ptr->style.lineStyle = SCB_DEF_STROKE_LINESTYLE; 00114 ptr->style.penSize = SCB_DEF_STROKE_PENSIZE; 00115 00116 // init out bound rect. used to fast hit test 00117 ptr->rect.left = INT_MAX; 00118 ptr->rect.top = INT_MAX; 00119 ptr->rect.right = INT_MIN; 00120 ptr->rect.bottom = INT_MIN; 00121 00122 // init fast draw context 00123 scb_fast_draw_reset_context(); 00124 return ptr; 00125 }

| ScbStrokePtr scb_stroke_new_with_style | ( | ScbStrokeStylePtr | ptr | ) |
Definition at line 127 of file scbstroke.c.
00128 { 00129 SCB_RET_NULL_IF(NULL == pStyle, "Invalid pointer!"); 00130 00131 ScbStrokePtr ptr = g_new0(ScbStroke, 1); 00132 SCB_RET_NULL_IF(NULL == ptr, "Not enough memory for stroke!"); 00133 00134 // allocate points array 00135 if (!scb_points_new(&ptr->points, SCB_DEF_STROKE_POINTSIZE)) 00136 { 00137 // could not alloc memory for list 00138 g_free(ptr); 00139 return NULL; 00140 } 00141 00142 // init the stroke paramters 00143 ptr->style = *pStyle; 00144 00145 // init out bound rect. used to fast hit test 00146 ptr->rect.left = INT_MAX; 00147 ptr->rect.top = INT_MAX; 00148 ptr->rect.right = INT_MIN; 00149 ptr->rect.bottom = INT_MIN; 00150 00151 // init fast draw context 00152 scb_fast_draw_reset_context(); 00153 return ptr; 00154 }

| gboolean scb_stroke_point_hit_test | ( | ScbStrokePtr | stroke, | |
| ScbDevPointPtr | point, | |||
| const ScbHitTestCtxPtr | ctx | |||
| ) |
Definition at line 362 of file scbstroke.c.
00365 { 00366 SCB_RET_FALSE_IF(NULL == stroke || NULL == point || NULL == ctx, 00367 "Invalid pointer(s)!"); 00368 00369 // fast check 00370 ScbRect tmp; 00371 double ratio = 1.0; 00372 if (fabs(stroke->style.zoom - ctx->zoom) >= e) 00373 { 00374 ratio = stroke->style.zoom / ctx->zoom; 00375 } 00376 tmp.left = point->x * ratio - ctx->size; 00377 tmp.right = point->x * ratio + ctx->size; 00378 tmp.top = point->y * ratio - ctx->size; 00379 tmp.bottom = point->y * ratio + ctx->size; 00380 if (!scb_is_rect_intersect(&stroke->rect, &tmp)) 00381 { 00382 return FALSE; 00383 } 00384 00385 // check each point in stroke 00386 ScbRect src; 00387 int size = stroke->style.penSize; 00388 int len = stroke->points.points->len; 00389 ScbPointPtr pts = (ScbPointPtr)stroke->points.points->data; 00390 while (len) 00391 { 00392 src.left = pts->x - size; 00393 src.right = pts->x + size; 00394 src.top = pts->y - size; 00395 src.bottom = pts->y + size; 00396 if (scb_is_rect_intersect(&src, &tmp)) 00397 { 00398 #if (SCB_DEBUG_ON) 00399 SCB_TRACE("\nrect1: (%d %d %d %d)\nrect2: (%d %d %d %d)", 00400 src.left, src.top, src.right, src.bottom, 00401 tmp.left, tmp.top, tmp.right, tmp.bottom); 00402 #endif 00403 return TRUE; 00404 } 00405 ++pts; --len; 00406 } 00407 return FALSE; 00408 }

| gboolean scb_stroke_save | ( | ScbStrokePtr | stroke, | |
| ScbXmlPtr | ||||
| ) |
Definition at line 496 of file scbstroke.c.
00497 { 00498 // construct xpath 00499 char xPath[SCB_MAX_XML_PATH] = {0}; 00500 strncpy(xPath, ptr->xPath, SCB_MAX_XML_PATH); 00501 strncat(xPath, "/stroke", SCB_MAX_XML_PATH); 00502 snprintf(xPath, SCB_MAX_XML_PATH, "%s/stroke[%d]", ptr->xPath, ptr->index); 00503 // SCB_TRACE("xPath: %s", xPath); 00504 00505 // create node, construct data, from stroke data to string 00506 const int LINE_BYTES = 33; // 2147483647 2147483647 2147483647\n 00507 int count = scb_stroke_get_point_count(stroke); 00508 if (count) 00509 { 00510 int len = LINE_BYTES * count; 00511 char *buf = g_new0(char, len); 00512 if (NULL == buf) return FALSE; 00513 char *tmp = buf; 00514 ScbPointPtr point = (ScbPointPtr)stroke->points.points->data; 00515 int* ppressure = (int *)stroke->points.pressures->data; 00516 // write information into buf 00517 while (count > 0) 00518 { 00519 tmp += snprintf(tmp, LINE_BYTES, "%d %d %d\n", 00520 point->x, point->y, *ppressure); 00521 --count; ++point; ++ppressure; 00522 } 00523 ermXmlNewString(&ptr->handle, ptr->xPath, "stroke", buf); 00524 g_free(buf); 00525 } 00526 00527 // set attributes 00528 ermXmlSetAttributeString(&ptr->handle, xPath, "color", 00529 scb_dev_color_to_html_color(stroke->style.color), SCB_MAX_COLOR_LEN); 00530 ermXmlSetAttributeInt(&ptr->handle, xPath, "layer", stroke->style.layer); 00531 ermXmlSetAttributeInt(&ptr->handle, xPath, "penSize", stroke->style.penSize); 00532 ermXmlSetAttributeString(&ptr->handle, xPath, "linestyle", 00533 scb_line_style_to_str(stroke->style.lineStyle), SCB_MAX_XML_PATH); 00534 // zoom factor 00535 char tmp[20] = {0}; snprintf(tmp, 20, "%lf", stroke->style.zoom); 00536 ermXmlSetAttributeString(&ptr->handle, xPath, "zoom", 00537 tmp, SCB_MAX_XML_PATH); 00538 00539 return TRUE; 00540 }

| void scb_stroke_set_color | ( | ScbStrokePtr | stroke, | |
| const ScbDevColor | color | |||
| ) |
Definition at line 605 of file scbstroke.c.
00606 { 00607 SCB_RET_IF(NULL == stroke, "Invalid pointer!"); 00608 stroke->style.color = color; 00609 }
1.5.6