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

📄 polygon.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
    } while (cur_index != max_index);    for (i = 0; i < nr_hlines; i++) {        cb (context, hlines [i].x1, hlines [i].x2, i + min_point_y);    }    /* Release the line list's memory and we're successfully done */    free (hlines);    return TRUE;}/* _fill_edge_structure: *  Polygon helper function: initialises an edge structure for the 2d *  rasteriser. */void _fill_edge_structure (POLYGON_EDGE *edge, const int *i1, const int *i2){    if (i2[1] < i1[1]) {        const int *it;        it = i1;        i1 = i2;        i2 = it;    }    edge->top = i1[1];    edge->bottom = i2[1] - 1;    edge->dx = ((i2[0] - i1[0]) << POLYGON_FIX_SHIFT) / (i2[1] - i1[1]);    edge->x = (i1[0] << POLYGON_FIX_SHIFT) + (1<<(POLYGON_FIX_SHIFT-1)) - 1;    edge->prev = NULL;    edge->next = NULL;    if (edge->dx < 0)        edge->x += MIN(edge->dx+(1<<POLYGON_FIX_SHIFT), 0);    edge->w = MAX(ABS(edge->dx)-(1<<POLYGON_FIX_SHIFT), 0);}/* _add_edge: *  Adds an edge structure to a linked list, returning the new head pointer. */POLYGON_EDGE *_add_edge (POLYGON_EDGE *list, POLYGON_EDGE *edge, int sort_by_x){    POLYGON_EDGE *pos = list;    POLYGON_EDGE *prev = NULL;    if (sort_by_x) {        while ((pos) && ((pos->x + (pos->w + pos->dx) / 2) <                        (edge->x + (edge->w + edge->dx) / 2))) {            prev = pos;            pos = pos->next;        }    }    else {        while ((pos) && (pos->top < edge->top)) {            prev = pos;            pos = pos->next;        }    }    edge->next = pos;    edge->prev = prev;    if (pos)        pos->prev = edge;    if (prev) {        prev->next = edge;        return list;    }    else        return edge;}/* _remove_edge: *  Removes an edge structure from a list, returning the new head pointer. */POLYGON_EDGE *_remove_edge(POLYGON_EDGE *list, POLYGON_EDGE *edge){    if (edge->next)         edge->next->prev = edge->prev;    if (edge->prev) {        edge->prev->next = edge->next;        return list;    }    else        return edge->next;}/* General polygon generator */BOOL GUIAPI PolygonGenerator (void* context, const POINT* pts, int vertices, CB_POLYGON cb){    int c;    int top = INT_MAX;    int bottom = INT_MIN;    const int *i1, *i2;    void* _scratch_mem;    const int* points = (int*) pts;    POLYGON_EDGE *edge, *next_edge;    POLYGON_EDGE *active_edges = NULL;    POLYGON_EDGE *inactive_edges = NULL;    /* allocate some space and fill the edge table */    _scratch_mem = malloc (sizeof(POLYGON_EDGE) * vertices);    if (!(edge = (POLYGON_EDGE *)_scratch_mem))        return FALSE;    i1 = points;    i2 = points + (vertices-1) * 2;    for (c=0; c<vertices; c++) {        if (i1[1] != i2[1]) {            _fill_edge_structure (edge, i1, i2);            if (edge->bottom >= edge->top) {                if (edge->top < top)                    top = edge->top;                if (edge->bottom > bottom)                    bottom = edge->bottom;                inactive_edges = _add_edge(inactive_edges, edge, FALSE);                edge++;            }        }        i2 = i1;        i1 += 2;    }    /* for each scanline in the polygon... */    for (c=top; c<=bottom; c++) {        /* check for newly active edges */        edge = inactive_edges;        while ((edge) && (edge->top == c)) {            next_edge = edge->next;            inactive_edges = _remove_edge(inactive_edges, edge);            active_edges = _add_edge(active_edges, edge, TRUE);            edge = next_edge;        }        /* draw horizontal line segments */        edge = active_edges;        while ((edge) && (edge->next)) {            int x1 = edge->x>>POLYGON_FIX_SHIFT;            int x2 = ((edge->next->x+edge->next->w)>>POLYGON_FIX_SHIFT);            cb (context, x1, x2, c);             edge = edge->next->next;        }        /* update edges, sorting and removing dead ones */        edge = active_edges;        while (edge) {            next_edge = edge->next;            if (c >= edge->bottom) {                active_edges = _remove_edge(active_edges, edge);            }            else {                edge->x += edge->dx;                while ((edge->prev) &&                         (edge->x+edge->w/2 < edge->prev->x+edge->prev->w/2)) {                    if (edge->next)                        edge->next->prev = edge->prev;                    edge->prev->next = edge->next;                    edge->next = edge->prev;                    edge->prev = edge->prev->prev;                    edge->next->prev = edge;                    if (edge->prev)                        edge->prev->next = edge;                    else                        active_edges = edge;                }            }            edge = next_edge;        }    }    free (_scratch_mem);    return TRUE;}static POINT* convert_vertices (PDC pdc, const POINT* pts, int vertices, RECT* rcOutput){    int i;    POINT* points;    if (vertices < 3) return NULL;    if (!(points = malloc (sizeof (POINT) * vertices))) {        return NULL;    }    /* Transfer logical to device to screen and find rcOutput here. */    points [0] = pts [0];    coor_LP2SP (pdc, &points [0].x, &points [0].y);    rcOutput->left = rcOutput->right = points [0].x;    rcOutput->top = rcOutput->bottom = points [0].y;    for (i = 1; i < vertices; i++) {        points [i] = pts [i];        coor_LP2SP (pdc, &points [i].x, &points [i].y);        if (points [i].x < rcOutput->left) {            rcOutput->left = points [i].x;        }        else if (points [i].x > rcOutput->right) {            rcOutput->right = points [i].x;        }        if (points [i].y < rcOutput->top) {            rcOutput->top = points [i].y;        }        else if (points [i].y > rcOutput->bottom) {            rcOutput->bottom = points [i].y;        }    }    return points;}BOOL GUIAPI FillPolygon (HDC hdc, const POINT* pts, int vertices){    PDC pdc;    RECT rc_tmp;    POINT* points;    BOOL is_mv;    if (vertices < 3) return FALSE;    if (!(pdc = check_ecrgn (hdc)))        return TRUE;    is_mv = PolygonIsMonotoneVertical (pts, vertices);    if (!(points = convert_vertices (pdc, pts, vertices, &pdc->rc_output)))        return FALSE;    pdc->cur_pixel = pdc->brushcolor;    pdc->cur_ban = NULL;    rc_tmp = pdc->rc_output;    pdc->rc_output.right ++;    pdc->rc_output.bottom ++;    ENTER_DRAWING (pdc);    if (rc_tmp.left == rc_tmp.right) {        _dc_draw_vline_clip (pdc, rc_tmp.top, rc_tmp.bottom, rc_tmp.left);    }    else if (rc_tmp.top == rc_tmp.bottom) {        _dc_draw_hline_clip (pdc, rc_tmp.left, rc_tmp.right, rc_tmp.top);    }    else {        if (is_mv)            MonotoneVerticalPolygonGenerator (pdc, points, vertices, _dc_draw_hline_clip);        else            PolygonGenerator (pdc, points, vertices, _dc_draw_hline_clip);    }    LEAVE_DRAWING (pdc);    UNLOCK_GCRINFO (pdc);    free (points);    return TRUE;}

⌨️ 快捷键说明

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