00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024 #define _GNU_SOURCE
00025
00026 #include <stdio.h>
00027 #include <string.h>
00028
00029 #include "scbconfig.h"
00030 #include "scblog.h"
00031 #include "scbpage.h"
00032 #include "scbtype.h"
00033
00034
00035
00036 void scb_page_id_from_int(ScbPageIdPtr ptr, const int number)
00037 {
00038 if (ptr)
00039 {
00040 snprintf(ptr->id, SCB_MAX_PAGEID_LEN, "%d", number);
00041 }
00042 }
00043
00044 void scb_page_id_from_str(ScbPageIdPtr ptr, const char *str)
00045 {
00046 if (ptr && str)
00047 {
00048 strncpy(ptr->id, str, SCB_MAX_PAGEID_LEN);
00049 }
00050 }
00051
00052
00053
00054 typedef struct _ScbEraseCtx
00055 {
00056 ScbDevPoint p1, p2;
00057 int count;
00058 }ScbEraseCtx;
00059 ScbEraseCtx _erase_ctx;
00060 static gboolean bEraseCtxInit = FALSE;
00061
00062
00063
00064 ScbPagePtr scb_page_new()
00065 {
00066 ScbPagePtr ptr = g_new0(ScbPage, 1);
00067 if (NULL == ptr)
00068 {
00069
00070 SCB_ERROR("Not enough memory for page!");
00071 return NULL;
00072 }
00073
00074
00075 if (!scb_strokes_new(&ptr->strokes))
00076 {
00077 g_free(ptr);
00078 return NULL;
00079 }
00080
00081 ptr->rect.left = SCB_DEF_PAGE_LEFT;
00082 ptr->rect.right = SCB_DEF_PAGE_RIGHT;
00083 ptr->rect.top = SCB_DEF_PAGE_TOP;
00084 ptr->rect.bottom = SCB_DEF_PAGE_BOTTOM;
00085
00086 return ptr;
00087 }
00088
00089
00090 void scb_page_free(ScbPagePtr ptr)
00091 {
00092 SCB_RET_IF(NULL == ptr, "Attempt to release NULL pointer!");
00093
00094 scb_strokes_free(&ptr->strokes);
00095 scb_strokes_free(&ptr->delStrokes);
00096 g_free(ptr);
00097 }
00098
00099
00100 void scb_page_set_id(ScbPagePtr page, ScbPageIdPtr id)
00101 {
00102 if (page && id)
00103 {
00104 strncpy(page->id.id, id->id, SCB_MAX_PAGEID_LEN);
00105 }
00106 }
00107
00108
00109
00110 void scb_page_clear(ScbPagePtr ptr)
00111 {
00112 SCB_RET_IF(NULL == ptr, "Attempt to take action on NULL pointer!");
00113 scb_strokes_empty(&ptr->strokes);
00114 scb_strokes_empty(&ptr->delStrokes);
00115 }
00116
00117
00118 int scb_page_get_stroke_count(ScbPagePtr ptr)
00119 {
00120 SCB_RET_INT_IF(NULL == ptr, SCB_INVALID_COUNT, "Invalid page pointer!");
00121 return scb_strokes_get_count(&ptr->strokes);
00122 }
00123
00124
00125 gboolean scb_page_add_stroke(ScbPagePtr page, ScbStrokePtr stroke)
00126 {
00127 SCB_RET_FALSE_IF(NULL == page || NULL == stroke, "Invalid pointer!");
00128 g_list_append(page->strokes.strokes, stroke);
00129 return TRUE;
00130 }
00131
00132
00133 ScbStrokesPtr scb_page_get_strokes(ScbPagePtr page)
00134 {
00135 SCB_RET_NULL_IF(NULL == page, "Attempt to access NULL pointer!");
00136 return &page->strokes;
00137 }
00138
00139 void scb_page_erase_fast_draw(ScbPagePtr page, ScbDevPointPtr point)
00140 {
00141 ScbHitTestCtx ctx; ctx.size = SCB_DEF_ERASE_SIZE;
00142 ScbStrokesPtr strokes = NULL;
00143 if (!bEraseCtxInit)
00144 {
00145 _erase_ctx.count = 0;
00146 bEraseCtxInit = TRUE;
00147 }
00148
00149 if (0 == _erase_ctx.count)
00150 {
00151 _erase_ctx.p1 = *point;
00152 _erase_ctx.count = 1;
00153 strokes = scb_strokes_point_hit_test(&page->strokes, point, &ctx);
00154 }
00155 else
00156 {
00157 if (_erase_ctx.count > 1)
00158 {
00159 _erase_ctx.p1 = _erase_ctx.p2;
00160 }
00161 _erase_ctx.p2 = *point;
00162 strokes = scb_strokes_line_hit_test(&page->strokes,
00163 &_erase_ctx.p1,
00164 &_erase_ctx.p2,
00165 &ctx);
00166 }
00167
00168
00169 if (strokes)
00170 {
00171 scb_strokes_erase_fast_draw(strokes);
00172 scb_strokes_add_strokes(&page->delStrokes, (const ScbStrokesPtr)&strokes);
00173 scb_strokes_detach(strokes);
00174 }
00175 }
00176
00177
00178 void scb_page_erase_fast_draw_done(ScbPagePtr page, ScbDevPointPtr point)
00179 {
00180 ScbStrokesPtr strokes = NULL;
00181 ScbHitTestCtx ctx; ctx.size = SCB_DEF_ERASE_SIZE;
00182 if (0 == _erase_ctx.count)
00183 {
00184 _erase_ctx.p1 = *point;
00185 _erase_ctx.count = 1;
00186 strokes = scb_strokes_point_hit_test(&page->strokes, point, &ctx);
00187 }
00188 else
00189 {
00190 if (_erase_ctx.count > 1)
00191 {
00192 _erase_ctx.p1 = _erase_ctx.p2;
00193 }
00194 _erase_ctx.p2 = *point;
00195 strokes = scb_strokes_line_hit_test(&page->strokes,
00196 &_erase_ctx.p1,
00197 &_erase_ctx.p2,
00198 &ctx);
00199 }
00200
00201
00202 if (strokes)
00203 {
00204 scb_strokes_erase_fast_draw(strokes);
00205 scb_strokes_add_strokes(&page->delStrokes, (const ScbStrokesPtr)&strokes);
00206 scb_strokes_detach(strokes);
00207 }
00208
00209
00210 _erase_ctx.count = 0;
00211 }
00212
00213 void scb_page_erase_init(ScbPageEraseCtxPtr ptr)
00214 {
00215 ptr->zoom = 1.0;
00216 ptr->bInit = FALSE;
00217 }
00218
00219 ScbStrokesPtr scb_page_erase_hit_test(ScbPagePtr page, ScbDevPointPtr point, ScbPageEraseCtxPtr eraCtx)
00220 {
00221 ScbStrokesPtr strokes = NULL;
00222 ScbHitTestCtx ctx;
00223 ctx.size = SCB_DEF_ERASE_SIZE;
00224 ctx.zoom = eraCtx->zoom;
00225 if (!eraCtx->bInit)
00226 {
00227 eraCtx->p1 = *point;
00228 eraCtx->bInit = TRUE;
00229 strokes = scb_strokes_point_hit_test(&page->strokes, point, &ctx);
00230 }
00231 else
00232 {
00233 eraCtx->p2 = eraCtx->p1;
00234 eraCtx->p1 = *point;
00235 strokes = scb_strokes_line_hit_test(&page->strokes,
00236 &eraCtx->p2,
00237 &eraCtx->p1,
00238 &ctx);
00239 }
00240
00241 return strokes;
00242 }
00243
00244
00245 gboolean scb_page_save(ScbPagePtr page, ScbXmlPtr ptr)
00246 {
00247
00248 SCB_RET_FALSE_IF(NULL == page || NULL == ptr, "Invalid page or xml pointer!");
00249
00250
00251 ScbXmlPtr self = scb_xml_clone(ptr);
00252 ermXmlNewString(&ptr->handle, self->xPath, "page", "");
00253 char * tmp = self->xPath + strnlen(self->xPath, SCB_MAX_XML_PATH);
00254 snprintf(tmp, SCB_MAX_XML_PATH, "/page[%d]", ptr->index);
00255
00256
00257 ermXmlSetAttributeString(&ptr->handle, self->xPath, "backgroundcolor",
00258 scb_color_to_html_color(&page->style.bgColor), SCB_MAX_COLOR_LEN);
00259 ermXmlSetAttributeString(&ptr->handle, self->xPath,
00260 "id", page->id.id, SCB_MAX_PAGEID_LEN);
00261 ermXmlNewInt(&ptr->handle, self->xPath,
00262 "orientation", page->style.orientation);
00263 ermXmlNewInt(&ptr->handle, self->xPath,
00264 "height", page->rect.bottom - page->rect.top);
00265 ermXmlNewInt(&ptr->handle, self->xPath,
00266 "width", page->rect.right - page->rect.left);
00267
00268
00269 gboolean bRet = scb_strokes_save(&page->strokes, self);
00270 scb_xml_free(self);
00271 return bRet;
00272 }
00273
00274
00275 gboolean scb_page_load(ScbPagePtr page, ScbXmlPtr ptr)
00276 {
00277
00278 SCB_RET_FALSE_IF(NULL == page || NULL == ptr, "Invalid page or xml pointer!");
00279
00280
00281 ScbXmlPtr self = scb_xml_clone(ptr);
00282 char * tmp = self->xPath + strnlen(self->xPath, SCB_MAX_XML_PATH);
00283 snprintf(tmp, SCB_MAX_XML_PATH, "/page[%d]", self->index);
00284 char xPath[SCB_MAX_XML_PATH] = {0};
00285 strncpy(xPath, self->xPath, SCB_MAX_XML_PATH);
00286 int len = strnlen(xPath, SCB_MAX_XML_PATH);
00287
00288 if (RET_ERR == ermXmlExist(&ptr->handle, xPath))
00289 {
00290
00291 return FALSE;
00292 }
00293
00294
00295 char color[SCB_MAX_COLOR_LEN] = {0};
00296 ermXmlGetAttributeString(&self->handle, self->xPath,
00297 "backgroundcolor", color, SCB_MAX_COLOR_LEN);
00298 scb_html_color_to_color(color, SCB_MAX_COLOR_LEN, &page->style.bgColor);
00299
00300
00301 ermXmlGetAttributeString(&ptr->handle, self->xPath,
00302 "id", page->id.id, SCB_MAX_PAGEID_LEN);
00303
00304
00305 strncat(xPath, "orientation", SCB_MAX_XML_PATH);
00306 ermXmlGetInt(&ptr->handle, xPath, &page->style.orientation);
00307
00308
00309 page->rect.left = page->rect.top = 0;
00310 int value = 0;
00311 xPath[len] = 0;
00312 strncat(xPath, "/height", SCB_MAX_XML_PATH);
00313 ermXmlGetInt(&ptr->handle, xPath, &value);
00314 page->rect.bottom = value;
00315
00316
00317 xPath[len] = 0;
00318 strncat(xPath, "/width", SCB_MAX_XML_PATH);
00319 ermXmlGetInt(&ptr->handle, xPath, &value);
00320 page->rect.right = value;
00321
00322
00323 gboolean bRet = scb_strokes_load(&page->strokes, self);
00324 scb_xml_free(self);
00325 return bRet;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 void scb_page_dump(ScbPagePtr ptr)
00389 {
00390 SCB_RET_IF(NULL == ptr, "Attempt to dump on NULL page pointer!");
00391
00392 SCB_DUMP("================= Page %s Information =================", ptr->id.id);
00393 SCB_DUMP("orientation %d", ptr->style.orientation);
00394 SCB_DUMP("rect (%d, %d) - (%d, %d)", ptr->rect.left, ptr->rect.top,
00395 ptr->rect.right, ptr->rect.bottom);
00396 scb_strokes_dump(&ptr->strokes);
00397 SCB_DUMP("==================== Page %s Done =====================", ptr->id.id);
00398 }