scbstrokes.c

Go to the documentation of this file.
00001 /*
00002  * File Name: scbstrokes.c
00003  */
00004 
00005 /*
00006  * This file is part of liberscribble.
00007  *
00008  * liberscribble is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * liberscribble is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 
00028 #define _GNU_SOURCE
00029 
00030 //----------------------------------------------------------------------------
00031 // Include Files
00032 //----------------------------------------------------------------------------
00033 
00034 // system include files, between < >
00035 
00036 // ereader include files, between < >
00037 
00038 // local include files, between " "
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 // Type Declarations
00049 //----------------------------------------------------------------------------
00050 
00051 
00052 //----------------------------------------------------------------------------
00053 // Global Constants
00054 //----------------------------------------------------------------------------
00055 
00056 
00057 //----------------------------------------------------------------------------
00058 // Static Variables
00059 //----------------------------------------------------------------------------
00060 
00061 
00062 //============================================================================
00063 // Local Function Definitions
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 // Functions Implementation
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     // release all stroke
00087     g_list_foreach(strokes->strokes, _stroke_release, NULL);
00088 
00089     // now the pointers are wild pointers
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     // here, the list contains a empty item, so we need to decrease one
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             // move from one stroke list to the other
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             // move from one list to the other
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             // use reverse color
00221             // TODO. The WHITE color is not always correct.
00222             // We should the draw the erased part by background color in the future.
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 // Local Functions Implementation
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 }
Generated by  doxygen 1.6.2-20100208