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 }