OSDN Git Service

added support for extra filters
authorevgeny <evgeny@users.sourceforge.jp>
Mon, 23 May 2011 16:00:04 +0000 (20:00 +0400)
committerevgeny <evgeny@users.sourceforge.jp>
Mon, 23 May 2011 16:00:04 +0000 (20:00 +0400)
new file:   src/recognize_extra.c
new file:   src/recognize_extra.h
modified:   src/Makefile.am
modified:   src/Makefile.in
modified:   src/recognize_kanji.c
modified:   src/recognize_stroke.c
modified:   src/recognize_stroke.h

src/recognize_extra.c [new file with mode: 0644]
src/recognize_extra.h [new file with mode: 0644]

diff --git a/src/recognize_extra.c b/src/recognize_extra.c
new file mode 100644 (file)
index 0000000..8b8b743
--- /dev/null
@@ -0,0 +1,163 @@
+
+#include "defs.h"
+
+#include "recognize_extra.h"
+
+static gint eval_filter(GList *s, gunichar2 arg)
+{
+    GdkPoint *p0 = (GdkPoint*)g_list_first(s)->data;
+    GdkPoint *pn = (GdkPoint*)g_list_last(s)->data;
+    switch( arg )
+    {
+       case 'x':
+           return p0->x;
+       case 'y':
+           return p0->y;
+       case 'i':
+           return pn->x;
+       case 'j':
+           return pn->y;
+       case 'a':
+           return ((p0->x + pn->x) >> 1);
+       case 'b':
+           return ((p0->y + pn->y) >> 1);
+       case 'l':
+           {
+               int dx = p0->x - pn->x;
+               int dy = p0->y - pn->y;
+               return abs(dx) + abs(dy);
+           }
+    }
+    return 0;
+}
+
+static void get_sz(GList *strokes, gint *sz)
+{
+    int xmin, ymin, xmax, ymax;
+    GdkPoint *pt = (GdkPoint*)(((GList*)strokes->data)->data);
+    xmin = xmax = pt->x;
+    ymin = ymax = pt->y;
+    GList *s, *s1;
+    for(s = g_list_first(strokes); s; s = g_list_next(s)) 
+    {
+       for(s1 = (GList*)s->data; s1; s1 = g_list_next(s1))
+       {
+           pt = (GdkPoint*)s1->data;
+           if(pt->x < xmin)
+               xmin = pt->x;
+           if(pt->y < ymin)
+               ymin = pt->y;
+           if(pt->x > xmax)
+               xmax = pt->x;
+           if(pt->y > ymax)
+               ymax = pt->y;
+       }
+    }
+    gint w = xmax - xmin, h = ymax - ymin;
+    *sz = (w > h) ? w : h;
+}
+
+gint pass_extra_filters(GList *strokes, gunichar2 *entry)
+{
+    gunichar2 arg[2], fn, c;
+    gint stroke[2];
+    gint sc, val[2];
+    gint index = 0;
+    gboolean must = False;
+    gint score = 0;
+
+    arg[0] = arg[1] = 0;
+    stroke[0] = stroke[1] = 0;
+
+    /* Simple parser for Filter strings. assumes a1-b1 structure,
+     * where a and b can be any single alphabetic cmd char, the 
+     * numbers can be multiple digit, and b1 can optionally be 
+     * followed by '!' to insist on the filter passing.  There can
+     * be multiple filters but they have to be separated by '!' or
+     * space(s).  The filter string is terminated by a null byte
+     * or an 8-bit char, the beginning of the next entry.  
+     * Leading spaces and trailing spaces are ignored. -rwells, 970722.
+     */
+
+    for(c = *entry; True; entry++, c = *entry )
+    {
+       switch( c )
+       {
+           case 'x': 
+           case 'y':
+           case 'i':
+           case 'j':
+           case 'a':
+           case 'b':
+           case 'l':
+               arg[index] = c;
+               break;
+
+           case '0':
+           case '1':
+           case '2':
+           case '3':
+           case '4':
+           case '5':
+           case '6':
+           case '7':
+           case '8':
+           case '9':
+               stroke[index] = stroke[index] * 10 + (c - '0');
+               break;
+
+           case '-':
+           case '<':
+           case '=':
+               fn = c;
+               index = 1;
+               break;
+
+           case '!':
+               must = True;
+
+           case ' ':
+           default:
+               if(index == 1) // second argument
+               {
+                   gint n = g_list_length(strokes);
+                   if((n > stroke[0]) || (n > stroke[1]))
+                   {
+                       val[0] = eval_filter(g_list_nth_data(strokes, stroke[0] - 1), arg[0]);
+                       val[1] = eval_filter(g_list_nth_data(strokes, stroke[1] - 1), arg[1]);
+                       gint sz;
+                       get_sz(strokes, &sz);
+                       if(fn == '-')
+                       {
+                           sc = ((val[0] - val[1]) < 0) ? 1 : -1;
+                           if(must) sc *= 2;
+                           score += sc;
+                       }
+                       else if(fn == '=')
+                       {
+                           sc = ((val[0] - val[1]) > sz/4) ? 1 : -1;
+                           if(must) sc *= 2;
+                           score += sc;
+                       }
+                       else if(fn == '<')
+                       {
+                           sc = (abs(val[1] - val[0]) > sz/2) ? 1 : -1;
+                           if(must) sc *= 2;
+                           score += sc;
+                       }
+                   }
+
+                   // reset
+                   index = 0;
+                   must = False;
+                   arg[0] = arg[1] = 0;
+                   stroke[0] = stroke[1] = 0;
+               }
+
+               if( c == '\r' || c == '\0' )
+                   return score;
+       }
+    }
+    return score;
+}
+
diff --git a/src/recognize_extra.h b/src/recognize_extra.h
new file mode 100644 (file)
index 0000000..2b92308
--- /dev/null
@@ -0,0 +1,7 @@
+
+#ifndef __KP_RECOGNIZE_EXTRA__
+#define __KP_RECOGNIZE_EXTRA__
+
+gint pass_extra_filters(GList *strokes, gunichar2 *filter);
+
+#endif