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

📄 line.c

📁 ARM9-2410教学实验系统下Linux下minigui程序
💻 C
字号:
/*** $Id: line.c,v 1.31 2003/09/04 06:02:53 weiym Exp $**** line.c: drawing of line, rectangle, and spline.**** Copyright (C) 2003 Feynman Software** Copyright (C) 2001 ~ 2002 Wei Yongming.****      Spline drawing algorithm comes from Allegro by **      Shawn Hargreaves and others.**      So thank them for their great work and good copyright statement.****      "Allegro is a gift-software"**** Current maintainer: Wei Yongming.**** Create date: 2001/10/12, derived from original draw.c*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of 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 of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//*** TODO:*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "ctrlclass.h"#include "dc.h"#include "memops.h"#include "pixel_ops.h"#include "cursor.h"void GUIAPI MoveTo (HDC hdc, int x, int y){    PDC pdc;    pdc = dc_HDC2PDC(hdc);    pdc->CurPenPos.x = x;    pdc->CurPenPos.y = y;}void GUIAPI LineTo (HDC hdc, int x, int y){    PCLIPRECT cliprect;    PDC pdc;    int startx, starty;    pdc = dc_HDC2PDC(hdc);    startx = pdc->CurPenPos.x;    starty = pdc->CurPenPos.y;    /* Move the current pen pos. */    pdc->CurPenPos.x = x;    pdc->CurPenPos.y = y;    if (!(pdc = check_ecrgn (hdc)))        return;    /* Transfer logical to device to screen here. */    coor_LP2SP(pdc, &x, &y);    coor_LP2SP(pdc, &startx, &starty);    pdc->cur_pixel = pdc->pencolor;    pdc->cur_ban = NULL;    pdc->step = 1;    if (startx == x && starty == y) {        _set_pixel_helper (pdc, x, y);        goto ret;    }    SetRect (&pdc->rc_output, startx, starty, x, y);    NormalizeRect (&pdc->rc_output);    InflateRect (&pdc->rc_output, 1, 1);    ENTER_DRAWING (pdc);    if (starty == y) { /* a horizontal line */        _dc_draw_hline_clip (pdc, startx, x, y);    }    else if (startx == x) { /* a vertical line */        _dc_draw_vline_clip (pdc, starty, y, x);    }    else {        RECT eff_rc;        cliprect = pdc->ecrgn.head;        while (cliprect) {            if (IntersectRect (&eff_rc, &pdc->rc_output, &cliprect->rc)) {                int x0 = startx, y0 = starty, x1 = x, y1 = y;                 if (LineClipper (&eff_rc, &x0, &y0, &x1, &y1)) {                    pdc->move_to (pdc, x0, y0);                    LineGenerator (pdc, x0, y0, x1, y1, _dc_set_pixel_noclip);                }            }            cliprect = cliprect->next;        }    }    LEAVE_DRAWING (pdc);ret:    UNLOCK_GCRINFO (pdc);}void GUIAPI PolylineTo (HDC hdc, const POINT* point, int poinum){    int i;    MoveTo (hdc, point[0].x, point[0].y);    for (i = 1; i < poinum; i++)        LineTo (hdc, point[i].x, point[i].y);}void GUIAPI Rectangle (HDC hdc, int x0, int y0, int x1, int y1){    PDC pdc;    if (!(pdc = check_ecrgn (hdc)))        return;    /* Transfer logical to device to screen here. */    coor_LP2SP (pdc, &x0, &y0);     coor_LP2SP (pdc, &x1, &y1);     SetRect (&pdc->rc_output, x0, y0, x1, y1);    NormalizeRect (&pdc->rc_output);    x0 = pdc->rc_output.left; y0 = pdc->rc_output.top;    x1 = pdc->rc_output.right; y1 = pdc->rc_output.bottom;    pdc->rc_output.right ++;    pdc->rc_output.bottom ++;    pdc->cur_pixel = pdc->pencolor;    pdc->cur_ban = NULL;    pdc->step = 1;    if (x0 == x1 && y0 == y1) {        _set_pixel_helper (pdc, x0, y0);        goto ret;    }    ENTER_DRAWING (pdc);    _dc_draw_hline_clip (pdc, x0, x1, y0);    if (y0 != y1)        _dc_draw_hline_clip (pdc, x0, x1, y1);    _dc_draw_vline_clip (pdc, y0, y1, x0);    if (x0 != x1)        _dc_draw_vline_clip (pdc, y0, y1, x1);    LEAVE_DRAWING (pdc);ret:    UNLOCK_GCRINFO (pdc);}void GUIAPI FocusRect (HDC hdc, int x0, int y0, int x1, int y1){    PDC pdc;    int oldrop;    if (!(pdc = check_ecrgn (hdc)))        return;    /* Transfer logical to device to screen here. */    coor_LP2SP (pdc, &x0, &y0);     coor_LP2SP (pdc, &x1, &y1);     SetRect (&pdc->rc_output, x0, y0, x1, y1);    NormalizeRect (&pdc->rc_output);    x0 = pdc->rc_output.left; y0 = pdc->rc_output.top;    x1 = pdc->rc_output.right; y1 = pdc->rc_output.bottom;    pdc->rc_output.right ++;    pdc->rc_output.bottom ++;    pdc->cur_pixel = pdc->pencolor;    pdc->cur_ban = NULL;    pdc->step = 2;    oldrop = SetRasterOperation (hdc, ROP_XOR);    if (x0 == x1 && y0 == y1) {        _set_pixel_helper (pdc, x0, y0);        goto ret;    }    ENTER_DRAWING (pdc);    _dc_draw_hline_clip (pdc, x0, x1, y0);    if (y0 != y1)        _dc_draw_hline_clip (pdc, x0, x1, y1);    _dc_draw_vline_clip (pdc, y0, y1, x0);    if (x0 != x1)        _dc_draw_vline_clip (pdc, y0, y1, x1);    LEAVE_DRAWING (pdc);    SetRasterOperation (hdc, oldrop);ret:    UNLOCK_GCRINFO (pdc);}void GUIAPI DrawHVDotLine (HDC hdc, int x, int y, int w_h, BOOL H_V){    PDC pdc;    if (w_h < 1)        return;    if (!(pdc = check_ecrgn (hdc)))        return;    coor_LP2SP (pdc, &x, &y);     if (w_h == 1) {        if ((H_V && !(x % 2)) || (!H_V && !(y % 2))) {            _set_pixel_helper (pdc, x, y);        }        goto ret;    }    if (H_V) {        SetRect (&pdc->rc_output, x, y, x + w_h + 1, y + 2);    }    else {        SetRect (&pdc->rc_output, x, y, x + 2, y + w_h + 1);    }    pdc->cur_pixel = pdc->pencolor;    pdc->cur_ban = NULL;    pdc->step = 2;    ENTER_DRAWING (pdc);    if (H_V)        _dc_draw_hline_clip (pdc, x, x + w_h, y);    else        _dc_draw_vline_clip (pdc, y, y + w_h, x);    LEAVE_DRAWING (pdc);ret:    UNLOCK_GCRINFO (pdc);}void calc_spline (const POINT* points, int npts, int *out_x, int *out_y){   /* Derivatives of x(t) and y(t). */   double x, dx, ddx, dddx;   double y, dy, ddy, dddy;   int i;   /* Temp variables used in the setup. */   double dt, dt2, dt3;   double xdt2_term, xdt3_term;   double ydt2_term, ydt3_term;   dt = 1.0 / (npts-1);   dt2 = (dt * dt);   dt3 = (dt2 * dt);   /* x coordinates. */   xdt2_term = 3 * (points[2].x - 2*points[1].x + points[0].x);   xdt3_term = points[3].x + 3 * (-points[2].x + points[1].x) - points[0].x;   xdt2_term = dt2 * xdt2_term;   xdt3_term = dt3 * xdt3_term;   dddx = 6*xdt3_term;   ddx = -6*xdt3_term + 2*xdt2_term;   dx = xdt3_term - xdt2_term + 3 * dt * (points[1].x - points[0].x);   x = points[0].x;   out_x[0] = points[0].x;   x += .5;   for(i=1; i<npts; i++){      ddx += dddx;      dx += ddx;      x += dx;      out_x[i] = (int)x;   }   /* y coordinates. */   ydt2_term = 3 * (points[2].y - 2*points[1].y + points[0].y);   ydt3_term = points[3].y + 3 * (-points[2].y + points[1].y) - points[0].y;   ydt2_term = dt2 * ydt2_term;   ydt3_term = dt3 * ydt3_term;   dddy = 6*ydt3_term;   ddy = -6*ydt3_term + 2*ydt2_term;   dy = ydt3_term - ydt2_term + dt * 3 * (points[1].y - points[0].y);   y = points[0].y;   out_y[0] = points[0].y;   y += .5;   for(i=1; i<npts; i++){      ddy += dddy;      dy += ddy;      y += dy;      out_y[i] = (int)y;   }}/*  * SplineTo: Draws a bezier spline. */void GUIAPI SplineTo (HDC hdc, const POINT* points){   #define MAX_POINTS   64   int i;   int num_points;   int xpts[MAX_POINTS], ypts[MAX_POINTS];   gal_pixel pen_color = GetPenColor (hdc);   /* Calculate the number of points to draw. We want to draw as few as      possible without loosing image quality. This algorithm is rather      random; I have no motivation for it at all except that it seems to work      quite well. The length of the spline is approximated by the sum of      distances from first to second to third to last point. The number of      points to draw is then the square root of this distance. I first tried      to make the number of points proportional to this distance without      taking the square root of it, but then short splines kind of had too      few points and long splines had too many. Since sqrt() increases more      for small input than for large, it seems in a way logical to use it,      but I don't precisely have any mathematical proof for it. So if someone      has a better idea of how this could be done, don't hesitate to let us      know...   */   #undef DIST   #define DIST(x, y) (sqrt((x) * (x) + (y) * (y)))   num_points = (int)(sqrt(DIST(points[1].x-points[0].x, points[1].y-points[0].y) +                           DIST(points[2].x-points[1].x, points[2].y-points[1].y) +                           DIST(points[3].x-points[2].x, points[3].y-points[2].y)) * 1.2);   if (num_points > MAX_POINTS)      num_points = MAX_POINTS;   calc_spline (points, num_points, xpts, ypts);   MoveTo (hdc, xpts[0], ypts[0]);   for (i = 1; i < num_points; i++) {      LineTo (hdc, xpts[i], ypts[i]);      if (GetRasterOperation (hdc) == ROP_XOR)            SetPixel (hdc, xpts[i], ypts[i], pen_color);   }}

⌨️ 快捷键说明

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