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

📄 cellwidget.c

📁 添加系统调用。。。在LINUX下添加一个新的系统调用。在文件中添加自己的系统调用的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*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 "common.h"#include "recognize.h"#include "keys.h"#include <string.h>/* stroke.c */void smooth_stroke(Stroke *s);void simplify_stroke(Stroke *s);/* cellwidget.c */int cell_widget_scrollbar_width(void);static void start_timeout(void);static void show_context_menu(int button, int time);static void stop_drawing(void);/*        Cells*/#define ALTERNATES 5#define CELL_BASELINE (cell_height / 3)#define CELL_BORDER (cell_height / 12)#define KEY_WIDGET_COLS 4#define KEY_WIDGET_BORDER 6/* Msec of no mouse motion before a cell is finished */#define MOTION_TIMEOUT 500/* Cell flags */#define CELL_SHOW_INK   0x01#define CELL_DIRTY      0x02#define CELL_VERIFIED   0x04#define CELL_SHIFTED    0x08struct Cell {        Sample sample, *alts[ALTERNATES];        gunichar2 ch;        int alt_used[ALTERNATES];        char flags, alt_ratings[ALTERNATES];};/* Cell preferences */int cell_width = 40, cell_height = 70, cell_cols_pref = 12, cell_rows_pref = 4,    enable_cairo = TRUE, training = FALSE, train_on_input = TRUE,    right_to_left = FALSE, keyboard_enabled = TRUE, xinput_enabled = FALSE;/* Statistics */int corrections = 0, rewrites = 0, characters = 0, inputs = 0;/* Colors */GdkColor custom_active_color = RGB_TO_GDKCOLOR(255, 255, 255),         custom_inactive_color = RGB_TO_GDKCOLOR(212, 222, 226),         custom_ink_color = RGB_TO_GDKCOLOR(0, 0, 0),         custom_select_color = RGB_TO_GDKCOLOR(204, 0, 0);static GdkColor color_active, color_inactive, color_ink, color_select;static Cell *cells = NULL, *cells_saved = NULL;static GtkWidget *drawing_area = NULL, *training_menu, *scrollbar;static GdkPixmap *pixmap = NULL;static GdkGC *pixmap_gc = NULL;static GdkColor color_bg, color_bg_dark;static cairo_t *cairo = NULL;static PangoContext *pango = NULL;static PangoFontDescription *pango_font_desc = NULL;static KeyWidget *key_widget;static gunichar2 *history[HISTORY_MAX];static int cell_cols, cell_rows, cell_row_view = 0, current_cell = -1, old_cc,           cell_cols_saved, cell_rows_saved, cell_row_view_saved,           timeout_source,           drawing = FALSE, inserting = FALSE, eraser = FALSE, invalid = FALSE,           potential_insert = FALSE, potential_hold = FALSE, cross_out = FALSE,           show_keys = TRUE, is_clear = TRUE, keys_dirty = FALSE;static double cursor_x, cursor_y;static void cell_coords(int cell, int *px, int *py)/* Get the int position of a cell from its index */{        int cell_y, cell_x;        cell -= cell_row_view * cell_cols;        cell_y = cell / cell_cols;        cell_x = cell - cell_y * cell_cols;        *px = (!right_to_left ? cell_x * cell_width :                                (cell_cols - cell_x - 1) * cell_width) + 1;        *py = cell_y * cell_height + 1;}static void set_pen_color(Sample *sample, int cell)/* Selects the pen color depending on if the sample being drawn is the input   or the template sample */{        if (sample == input || sample == &cells[cell].sample)                cairo_set_source_gdk_color(cairo, &color_ink, 1.);        else                cairo_set_source_gdk_color(cairo, &color_select, 1.);}static void render_point(Sample *sample, int cell, int stroke, Vec2 *offset)/* Draw a single point stroke */{        double x, y, radius;        int cx, cy;        if (!pixmap || stroke < 0 || !sample || stroke >= sample->len ||            sample->strokes[stroke]->len < 1)                return;        /* Apply offset */        x = sample->strokes[stroke]->points[0].x;        y = sample->strokes[stroke]->points[0].y;        if (offset) {                x += offset->x;                y += offset->y;        }        /* Unscale coordinates */        cell_coords(cell, &cx, &cy);        x = cx + cell_width / 2 + x * cell_height / SCALE;        y = cy + cell_height / 2 + y * cell_height / SCALE;        /* Draw a dot with cairo */        cairo_new_path(cairo);        radius = cell_height / 33.;        cairo_arc(cairo, x, y, radius > 1. ? radius : 1., 0., 2 * M_PI);        set_pen_color(sample, cell);        cairo_fill(cairo);        gtk_widget_queue_draw_area(drawing_area, x - radius - 0.5,                                   y - radius - 0.5, radius * 2 + 0.5,                                   radius * 2 + 0.5);}static void render_segment(Sample *sample, int cell, int stroke, int seg,                           Vec2 *offset)/* Draw a segment of the stroke   FIXME since the segments are not properly connected according to Cairo,         there is a bit of missing value at the segment connection points */{        double pen_width, x1, x2, y1, y2;        int xmin, xmax, ymin, ymax, cx, cy, pen_range;        if (!cairo || stroke < 0 || !sample || stroke >= sample->len ||            seg < 0 || seg >= sample->strokes[stroke]->len - 1)                return;        x1 = sample->strokes[stroke]->points[seg].x;        x2 = sample->strokes[stroke]->points[seg + 1].x;        y1 = sample->strokes[stroke]->points[seg].y;        y2 = sample->strokes[stroke]->points[seg + 1].y;        /* Apply offset */        if (offset) {                x1 += offset->x;                y1 += offset->y;                x2 += offset->x;                y2 += offset->y;        }        /* Unscale coordinates */        cell_coords(cell, &cx, &cy);        x1 = cx + cell_width / 2 + x1 * cell_height / SCALE;        x2 = cx + cell_width / 2 + x2 * cell_height / SCALE;        y1 = cy + cell_height / 2 + y1 * cell_height / SCALE;        y2 = cy + cell_height / 2 + y2 * cell_height / SCALE;        /* Find minimum and maximum x and y */        if (x1 > x2) {                xmax = x1 + 0.9999;                xmin = x2;        } else {                xmin = x1;                xmax = x2 + 0.9999;        }        if (y1 > y2) {                ymax = y1 + 0.9999;                ymin = y2;        } else {                ymin = y1;                ymax = y2 + 0.9999;        }        /* Draw the new segment using Cairo */        cairo_new_path(cairo);        cairo_move_to(cairo, x1, y1);        cairo_line_to(cairo, x2, y2);        set_pen_color(sample, cell);        pen_width = cell_height / 33.;        if (pen_width < 1.)                pen_width = 1.;        cairo_set_line_width(cairo, pen_width);        cairo_stroke(cairo);        /* Dirty only the new segment */        pen_range = 2 * pen_width + 0.9999;        gtk_widget_queue_draw_area(drawing_area, xmin - pen_range,                                   ymin - pen_range,                                   xmax - xmin + pen_range + 1,                                   ymax - ymin + pen_range + 1);}static void render_sample(Sample *sample, int cell)/* Render the ink from a sample in a cell */{        Vec2 sc_to_ic;        int i, j;        if (!sample)                return;        /* Center stored samples on input */        if (sample != &cells[cell].sample)                center_samples(&sc_to_ic, sample, &cells[cell].sample);        else                vec2_set(&sc_to_ic, 0., 0.);        for (i = 0; i < sample->len; i++)                if (sample->strokes[i]->len <= 1 ||                    sample->strokes[i]->spread < DOT_SPREAD)                        render_point(sample, cell, i, &sc_to_ic);                else                        for (j = 0; j < sample->strokes[i]->len - 1; j++)                                render_segment(sample, cell, i, j, &sc_to_ic);}static int cell_offscreen(int cell){        int rows, cols;        cols = cell_cols;        if (show_keys)                cols -= KEY_WIDGET_COLS;        rows = cell_rows < cell_rows_pref ? cell_rows : cell_rows_pref;        return cell < cell_row_view * cols ||               cell >= (cell_row_view + rows) * cols;}static void dirty_cell(int cell){        if (!cell_offscreen(cell))                cells[cell].flags |= CELL_DIRTY;}static void dirty_all(void){        int i, rows;        rows = cell_row_view + cell_rows_pref > cell_rows ?               cell_rows : cell_row_view + cell_rows_pref;        for (i = cell_cols * cell_row_view; i < rows * cell_cols; i++)                cells[i].flags |= CELL_DIRTY;}static void render_cell(int i){        cairo_pattern_t *pattern;        GdkColor color, *base_color;        Cell *pc;        int x, y, active, cols, samples = 0;        if (!cairo || !pixmap || !pixmap_gc || cell_offscreen(i))                return;        pc = cells + i;        cell_coords(i, &x, &y);        if (training) {                samples = char_trained(pc->ch);                active = pc->ch && (samples > 0 ||                                    (current_cell == i && input &&                                     !invalid && input->len));        } else                active = pc->ch || (current_cell == i && !inserting &&                                    !invalid && input && input->len);        base_color = active ? &color_active : &color_inactive;        /* Fill above baseline */        gdk_gc_set_rgb_fg_color(pixmap_gc, base_color);        gdk_draw_rectangle(pixmap, pixmap_gc, TRUE, x, y, cell_width,                                cell_height - CELL_BASELINE);        /* Fill baseline */        highlight_gdk_color(base_color, &color, 0.1);        gdk_gc_set_rgb_fg_color(pixmap_gc, &color);        gdk_draw_rectangle(pixmap, pixmap_gc, TRUE, x, y + cell_height -                           CELL_BASELINE, cell_width, CELL_BASELINE);        /* Cairo clip region */        cairo_reset_clip(cairo);        cairo_rectangle(cairo, x, y, cell_width, cell_height);        cairo_clip(cairo);        /* Separator line */        cols = cell_cols;        if (show_keys)                cols -= KEY_WIDGET_COLS;        if ((!right_to_left && i % cell_cols) ||            (right_to_left && i % cell_cols != cols - 1)) {                highlight_gdk_color(base_color, &color, 0.5);                pattern = cairo_pattern_create_linear(x, y, x, y + cell_height);                cairo_pattern_add_gdk_color_stop(pattern, 0.0, &color, 0.);                cairo_pattern_add_gdk_color_stop(pattern, 0.5, &color, 1.);                cairo_pattern_add_gdk_color_stop(pattern, 1.0, &color, 0.);                cairo_set_source(cairo, pattern);                cairo_set_line_width(cairo, 0.5);                cairo_move_to(cairo, x + 0.5, y);                cairo_line_to(cairo, x + 0.5, y + cell_height - 1);                cairo_stroke(cairo);                cairo_pattern_destroy(pattern);        }        /* Draw ink if shown */        if ((cells[i].ch && cells[i].flags & CELL_SHOW_INK) ||            (current_cell == i && input && input->len)) {                int j;                render_sample(&cells[i].sample, i);                if (cells[i].ch)                        for (j = 0; j < ALTERNATES && cells[i].alts[j]; j++)                                if (sample_valid(cells[i].alts[j],                                                 cells[i].alt_used[j]) &&                                    cells[i].alts[j]->ch == cells[i].ch) {                                        render_sample(cells[i].alts[j], i);                                        break;                                }        }        /* Draw letter if recognized or training */        else if (pc->ch && (current_cell != i || !input || !input->len)) {                PangoLayout *layout;                PangoRectangle ink_ext, log_ext;                char string[6] = { 0, 0, 0, 0, 0, 0 };                /* Training color is determined by how well a character is                   trained */                if (training) {                        if (samples)                                highlight_gdk_color(&color_ink, &color,                                                    0.5 - ((double)samples) /                                                    samples_max / 2.);                        else                                highlight_gdk_color(&color_inactive,                                                    &color, 0.2);                }                /* Use ink color unless this is a questionable match */                else {                        color = color_ink;                        if (!(pc->flags & CELL_VERIFIED) && pc->alts[0] &&                            pc->alts[1] && pc->ch == pc->alts[0]->ch &&                            pc->alt_ratings[0] - pc->alt_ratings[1] <= 10)                                color = color_select;                }                cairo_set_source_gdk_color(cairo, &color, 1.);                layout = pango_layout_new(pango);                cairo_move_to(cairo, x, y);                g_unichar_to_utf8(pc->ch, string);                pango_layout_set_text(layout, string, 6);                pango_layout_set_font_description(layout, pango_font_desc);                pango_layout_get_pixel_extents(layout, &ink_ext, &log_ext);                cairo_rel_move_to(cairo,                                  cell_width / 2 - log_ext.width / 2, 2);                pango_cairo_show_layout(cairo, layout);

⌨️ 快捷键说明

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