00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define _GNU_SOURCE
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "scblog.h"
00040 #include "scbconfig.h"
00041 #include "scbstroke.h"
00042 #include "scbstrokes.h"
00043
00044 #define UNUSED(x) (void)(x)
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static void _stroke_release (gpointer data, gpointer user_data);
00067 static void _stroke_dump (gpointer data, gpointer user_data);
00068
00069
00070
00071
00072
00073
00074 gboolean erscribble_strokes_new(ScbStrokesPtr ptr)
00075 {
00076 ERSCRIBBLE_RET_FALSE_IF(NULL == ptr, "Invalid pointer!");
00077 ptr->strokes = 0;
00078 return TRUE;
00079 }
00080
00081
00082 void erscribble_strokes_free(ScbStrokesPtr strokes)
00083 {
00084 ERSCRIBBLE_RET_IF(NULL == strokes, "Attempt to release NULL pointer!");
00085
00086
00087 g_list_foreach(strokes->strokes, _stroke_release, NULL);
00088
00089
00090 g_list_free(strokes->strokes);
00091 strokes->strokes = NULL;
00092 }
00093
00094
00095 void erscribble_strokes_clear(ScbStrokesPtr strokes)
00096 {
00097 ERSCRIBBLE_RET_IF(NULL == strokes, "Attempt to release NULL pointer!");
00098
00099 g_list_free(strokes->strokes);
00100 strokes->strokes = NULL;
00101 }
00102
00103
00104 int erscribble_strokes_get_count(const ScbStrokesPtr strokes)
00105 {
00106 ERSCRIBBLE_RET_INT_IF(NULL == strokes, ERSCRIBBLE_INVALID_COUNT, "Invalid strokes pointer!");
00107
00108
00109 return g_list_length(strokes->strokes);
00110 }
00111
00112
00113 void erscribble_strokes_add_stroke(ScbStrokesPtr strokes,
00114 ScbStrokePtr stroke)
00115 {
00116 ERSCRIBBLE_RET_IF(NULL == strokes || NULL == stroke, "Invalid storkes or stroke pointer!");
00117 strokes->strokes = g_list_append(strokes->strokes, stroke);
00118 }
00119
00120
00121 void erscribble_strokes_add_strokes(ScbStrokesPtr dst,
00122 const ScbStrokesPtr src)
00123 {
00124 ERSCRIBBLE_RET_IF(NULL == dst || NULL == src, "Invalid pointer(s)!");
00125 dst->strokes = g_list_concat(dst->strokes, src->strokes);
00126 }
00127
00128
00129 ScbStrokePtr erscribble_strokes_detach_stroke(ScbStrokesPtr strokes,
00130 ScbStrokePtr stroke)
00131 {
00132 ERSCRIBBLE_RET_NULL_IF(NULL == strokes || NULL == stroke, "Invalid pointer!");
00133 strokes->strokes = g_list_remove(strokes->strokes, stroke);
00134 return stroke;
00135 }
00136
00137
00138 ScbStrokesPtr erscribble_strokes_point_hit_test(ScbStrokesPtr strokes,
00139 ScbDevPointPtr point,
00140 const ScbHitTestCtxPtr ctx)
00141 {
00142 ERSCRIBBLE_RET_NULL_IF(NULL == strokes, "Invalid strokes list pointer!");
00143
00144 ScbStrokesPtr result = NULL;
00145 ScbStrokePtr stroke = NULL;
00146 GList* ptr = g_list_first(strokes->strokes);
00147 while(ptr)
00148 {
00149 stroke = (ScbStrokePtr)ptr->data;
00150 if (stroke && erscribble_stroke_point_hit_test(stroke, point, ctx))
00151 {
00152 LOGPRINTF("point hit");
00153 if (NULL == result)
00154 {
00155 result = g_new0(ScbStrokes, 1);
00156 if (! erscribble_strokes_new(result))
00157 {
00158 return NULL;
00159 }
00160 }
00161
00162 erscribble_strokes_add_stroke(result, stroke);
00163 erscribble_strokes_detach_stroke(strokes, stroke);
00164 }
00165 ptr = g_list_next(ptr);
00166 }
00167 return result;
00168 }
00169
00170
00171 ScbStrokesPtr erscribble_strokes_line_hit_test(ScbStrokesPtr strokes,
00172 ScbDevPointPtr point1,
00173 ScbDevPointPtr point2,
00174 const ScbHitTestCtxPtr ctx)
00175 {
00176 ERSCRIBBLE_RET_NULL_IF(NULL == strokes, "Invalid strokes list pointer!");
00177
00178 ScbStrokesPtr result = NULL;
00179 ScbStrokePtr stroke = NULL;
00180 GList* ptr = g_list_first(strokes->strokes);
00181 while(ptr)
00182 {
00183 stroke = (ScbStrokePtr)ptr->data;
00184 if (stroke && erscribble_stroke_line_hit_test(stroke, point1, point2, ctx))
00185 {
00186 LOGPRINTF("line hit");
00187 if (NULL == result)
00188 {
00189 result = g_new0(ScbStrokes, 1);
00190 if (!erscribble_strokes_new(result))
00191 {
00192 return NULL;
00193 }
00194 }
00195
00196 erscribble_strokes_add_stroke(result, stroke);
00197 erscribble_strokes_detach_stroke(strokes, stroke);
00198 }
00199 ptr = g_list_next(ptr);
00200 }
00201 return result;
00202 }
00203
00204
00205 void erscribble_strokes_erase_driver_draw(ScbStrokesPtr strokes)
00206 {
00207 if (NULL == strokes)
00208 {
00209 return;
00210 }
00211
00212 GList *ptr = g_list_first(strokes->strokes);
00213 ScbStrokePtr stroke = NULL;
00214 while (ptr)
00215 {
00216 stroke = (ScbStrokePtr)ptr->data;
00217 if (stroke)
00218 {
00219 ScbDevColor old = stroke->attributes.color;
00220
00221
00222
00223 stroke->attributes.color = ERSCRIBBLE_DEV_COLOR_WHITE;
00224 erscribble_stroke_driver_draw(stroke);
00225 stroke->attributes.color = old;
00226 }
00227 ptr = g_list_next(ptr);
00228 }
00229 }
00230
00231
00232 gboolean erscribble_strokes_load(ScbStrokesPtr strokes, ScbStreamPtr stream, const int strokes_num)
00233 {
00234 ERSCRIBBLE_RET_FALSE_IF(NULL == strokes || NULL == stream, "Invalid strokes or stream!");
00235
00236 erscribble_strokes_clear(strokes);
00237
00238 int i = 0;
00239 for (; i < strokes_num; ++i)
00240 {
00241 ScbStrokePtr stroke = erscribble_stroke_new();
00242 if (erscribble_stroke_load(stroke, stream))
00243 {
00244 erscribble_strokes_add_stroke(strokes, stroke);
00245 }
00246 else
00247 {
00248 erscribble_stroke_free(stroke);
00249 return FALSE;
00250 }
00251 }
00252
00253 return TRUE;
00254 }
00255
00256
00257 gboolean erscribble_strokes_write_stream(ScbStrokesPtr strokes, ScbStreamPtr stream)
00258 {
00259 ERSCRIBBLE_RET_FALSE_IF(NULL == strokes || NULL == stream, "Invalid strokes or stream!");
00260
00261 ScbStrokePtr stroke = NULL;
00262 GList* item = g_list_first(strokes->strokes);
00263 while(item)
00264 {
00265 stroke = (ScbStrokePtr)item->data;
00266
00267 if (erscribble_stroke_write_stream(stroke, stream) == FALSE)
00268 {
00269 return FALSE;
00270 }
00271
00272 item = g_list_next(item);
00273 }
00274
00275 return TRUE;
00276 }
00277
00278
00279 void erscribble_strokes_dump(ScbStrokesPtr strokes)
00280 {
00281 if (strokes)
00282 {
00283 g_list_foreach(strokes->strokes, _stroke_dump, 0);
00284 }
00285 }
00286
00287
00288
00289
00290
00291
00292 static void _stroke_release(gpointer data, gpointer user_data)
00293 {
00294 UNUSED(user_data);
00295 if (data)
00296 {
00297 erscribble_stroke_free((ScbStrokePtr)data);
00298 }
00299 }
00300
00301
00302 static void _stroke_dump(gpointer data, gpointer user_data)
00303 {
00304 UNUSED(user_data);
00305 if (data)
00306 {
00307 erscribble_stroke_dump((ScbStrokePtr)data);
00308 }
00309 }