⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recognize.c

📁 添加系统调用。。。在LINUX下添加一个新的系统调用。在文件中添加自己的系统调用的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*cellwriter -- a character recognition input methodCopyright (C) 2007 Michael Levin <risujin@risujin.org>This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/#include "config.h"#include <stdlib.h>#include <string.h>#include <math.h>#include <gtk/gtk.h>#include "common.h"#include "recognize.h"/* preprocess.c */int prep_examined;void engine_prep(void);/*        Engines*/Engine engines[] = {        /* Preprocessor engine must run first */        { "Key-point distance", engine_prep, MAX_RANGE, TRUE, -1, 0, 0 },        /* Averaging engines */        { "Average distance", engine_average, MAX_RANGE, TRUE, -1, 0, 0 },        { "Average angle", NULL, MAX_RANGE, TRUE, 0, 0, 0 },#ifndef DISABLE_WORDFREQ        /* Word frequency engine */        { "Word context", engine_wordfreq, MAX_RANGE / 3, FALSE, -1, 0, 0 },#endif};static int engine_rating(const Sample *sample, int j)/* Get the processed rating for engine j on a sample */{        int value;        if (!engines[j].range || engines[j].max < 1)                return 0;        value = ((int)sample->ratings[j] - engines[j].average) *                engines[j].range / engines[j].max;        if (engines[j].scale >= 0)                value = value * engines[j].scale / ENGINE_SCALE;        return value;}/*        Sample chain wrapper*/typedef struct SampleLink {        Sample sample;        struct SampleLink *prev, *next;} SampleLink;static SampleLink *samplelink_root = NULL, *samplelink_iter = NULL;static int current = 1;static Sample *sample_new(void)/* Allocate a link in the sample linked list */{        SampleLink *link;        link = g_malloc0(sizeof (*link));        link->next = samplelink_root;        if (samplelink_root)                samplelink_root->prev = link;        samplelink_root = link;        return &link->sample;}void sampleiter_reset(void)/* Reset the sample linked list iterator */{        samplelink_iter = samplelink_root;}Sample *sampleiter_next(void)/* Get the next sample link from the sample linked list iterator */{        SampleLink *link;        if (!samplelink_iter)                return NULL;        link = samplelink_iter;        samplelink_iter = samplelink_iter->next;        return &link->sample;}int samples_loaded(void){        return samplelink_root != NULL;}/*        Samples*/int samples_max = 5, no_latin_alpha = FALSE;void clear_sample(Sample *sample)/* Free stroke data associated with a sample and reset its parameters */{        int i;        for (i = 0; i < sample->len; i++) {                stroke_free(sample->strokes[i]);                stroke_free(sample->roughs[i]);        }        memset(sample, 0, sizeof (*sample));}void copy_sample(Sample *dest, const Sample *src)/* Copy a sample, cloing its strokes, overwriting dest */{        int i;        *dest = *src;        for (i = 0; i < src->len; i++) {                dest->strokes[i] = stroke_clone(src->strokes[i], FALSE);                dest->roughs[i] = stroke_clone(src->roughs[i], FALSE);        }}static void process_gluable(const Sample *sample, int stroke_num)/* Calculates the lowest distance between the start or end of one stroke and any   other point on each other stroke in the sample */{        Point point;        Stroke *s1;        int i, start;        /* Dots cannot be glued */        s1 = sample->strokes[stroke_num];        memset(s1->gluable_start, -1, sizeof (s1->gluable_start));        memset(s1->gluable_end, -1, sizeof (s1->gluable_end));        if (s1->spread < DOT_SPREAD)                return;        start = TRUE;scan:        point = start ? s1->points[0] : s1->points[s1->len - 1];        for (i = 0; i < sample->len; i++) {                Vec2 v;                Stroke *s2;                float dist, min = GLUE_DIST;                int j;                char gluable;                s2 = sample->strokes[i];                if (i == stroke_num || s2->spread < DOT_SPREAD)                        continue;                /* Check the distance to the first point */                vec2_set(&v, s2->points[0].x - point.x,                         s2->points[0].y - point.y);                dist = vec2_mag(&v);                if (dist < min)                        min = dist;                /* Find the lowest distance from the glue point to any other                   point on the other stroke */                for (j = 0; j < s2->len - 1; j++) {        	        Vec2 l, w;        		double dist, mag, dot;                        /* Vector l is a unit vector from point j to j + 1 */        		vec2_set(&l, s2->points[j].x - s2->points[j + 1].x,        		         s2->points[j].y - s2->points[j + 1].y);                        mag = vec2_norm(&l, &l);        		/* Vector w is a vector from point j to our point */        		vec2_set(&w, s2->points[j].x - point.x,        		         s2->points[j].y - point.y);        		/* For points that are not in between a segment,        		   get the distance from the points themselves,        		   otherwise get the distance from the segment line */        		dot = vec2_dot(&l, &w);        		if (dot < 0. || dot > mag) {        		        vec2_set(&v, s2->points[j + 1].x - point.x,        		                 s2->points[j + 1].y - point.y);        		        dist = vec2_mag(&v);		        } else {                		dist = vec2_cross(&w, &l);                		if (dist < 0)                		        dist = -dist;		        }                        if (dist < min)                                min = dist;                }                gluable = min * GLUABLE_MAX / GLUE_DIST;                if (start)                        s1->gluable_start[i] = gluable;                else                        s1->gluable_end[i] = gluable;        }        if (start) {                start = FALSE;                goto scan;        }}void process_sample(Sample *sample)/* Generate cached properties of a sample */{        int i;        float distance;        if (sample->processed)                return;        sample->processed = TRUE;        /* Make sure all strokes have been processed first */        for (i = 0; i < sample->len; i++)                process_stroke(sample->strokes[i]);        /* Compute properties for each stroke */        vec2_set(&sample->center, 0., 0.);        for (i = 0, distance = 0.; i < sample->len; i++) {                Vec2 v;                Stroke *stroke;                float weight;                int points;                stroke = sample->strokes[i];                /* Add the stroke center to the center vector, weighted by                   length */                vec2_copy(&v, &stroke->center);                weight = stroke->spread < DOT_SPREAD ?                         DOT_SPREAD : stroke->distance;                vec2_scale(&v, &v, weight);                vec2_sum(&sample->center, &sample->center, &v);                distance += weight;                /* Get gluing distances */                process_gluable(sample, i);                /* Create a rough-sampled version */                points = stroke->distance / ROUGH_RESOLUTION + 0.5;                if (points < 4)                        points = 4;                sample->roughs[i] = sample_stroke(NULL, stroke, points, points);        }        vec2_scale(&sample->center, &sample->center, 1.f / distance);        sample->distance = distance;}void center_samples(Vec2 *ac_to_bc, Sample *a, Sample *b)/* Adjust for the difference between two sample centers */{        vec2_sub(ac_to_bc, &b->center, &a->center);}int char_disabled(int ch)/* Returns TRUE if a character is not renderable or is explicity disabled by   a setting (not counting disabled Unicode blocks) */{        return (no_latin_alpha && ch >= unicode_blocks[0].start &&                ch <= unicode_blocks[0].end && g_ascii_isalpha(ch)) ||               !g_unichar_isgraph(ch);}int sample_disqualified(const Sample *sample)/* Check disqualification conditions for a sample during recognition.   The preprocessor engine must run before any calls to this or   disqualification will not work. */{        if ((!ignore_stroke_num && sample->len != input->len) ||            !sample->enabled)                return 1;        if (sample->disqualified)                return 2;        if (char_disabled(sample->ch))                return 3;        return 0;}int sample_valid(const Sample *sample, int used)/* Check if this sample has changed since it was last referenced */{        if (!sample || !used)                return FALSE;        return sample->used == used;}static void sample_rating(Sample *sample)/* Get the composite processed rating on a sample */{        int i, rating;        if (!sample->ch || sample_disqualified(sample) ||            sample->penalty >= 1.f) {                sample->rating = RATING_MIN;                return;        }        for (i = 0, rating = 0; i < ENGINES; i++)                rating += engine_rating(sample, i);        rating *= 1.f - sample->penalty;        if (rating > RATING_MAX)                rating = RATING_MAX;        if (rating < RATING_MIN)                rating = RATING_MIN;        sample->rating = rating;}void update_enabled_samples(void)/* Run through the samples list and enable samples in enabled blocks */{        Sample *sample;        sampleiter_reset();        while ((sample = sampleiter_next())) {                UnicodeBlock *block;                sample->enabled = FALSE;                if (!sample->ch)                        continue;                block = unicode_blocks;                while (block->name) {                        if (sample->ch >= block->start &&                            sample->ch <= block->end) {                                sample->enabled = block->enabled;                                break;                        }                        block++;                }        }}void promote_sample(Sample *sample)/* Update usage counter for a sample */{        sample->used = current++;}void demote_sample(Sample *sample)/* Remove the sample from our set if we can */{        if (char_trained(sample->ch) > 1)                clear_sample(sample);        else                sample->used = 1;}Stroke *transform_stroke(Sample *src, Transform *tfm, int i)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -