~ubuntu-branches/ubuntu/saucy/python-scipy/saucy

« back to all changes in this revision

Viewing changes to scipy/sandbox/xplt/src/play/win/plines.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * plines.c -- $Id: plines.c 685 2003-03-08 15:26:51Z travo $
 
3
 * p_lines for MS Windows
 
4
 *
 
5
 * Copyright (c) 1999.  See accompanying LEGAL file for details.
 
6
 */
 
7
 
 
8
#include "playw.h"
 
9
 
 
10
/* Following advantages of paths would be nice, BUT paths cost
 
11
 *   a factor of two or so in performance, so forget it:
 
12
 * Reasons to use paths for all lines and fills:
 
13
 * (1) Win9x join and cap styles only work for paths
 
14
 * (2) Other fill primitives use pen, requiring it to be set NULL
 
15
 *     affects prect.c, ellipse.c
 
16
 */
 
17
 
 
18
/* MS Windows unclear on what happens when begin and end points
 
19
 * of a line are identical, making the inconsistent claim that
 
20
 * the first point on a line is always included and the last point
 
21
 * on a line is always excluded
 
22
 * -- experimentally, the last point can be included by adding
 
23
 *    a single segment one pixel long to the end (last segment
 
24
 *    cannot be zero pixels long) -- Munro's Win95 box
 
25
 * -- but on Langer's WinNT box, last point *is* included,
 
26
 * the two boxes also differ in does_linetypes, so the hack here
 
27
 * uses that to distinguish -- I dont know what else to do... */
 
28
 
 
29
static int w_polyline_to(HDC dc, int type, int width, POINT *pxy, int n,
 
30
                         int closed);
 
31
static void w_final_pt(HDC dc, POINT *pxy);
 
32
static float w_hypot(float dx, float dy);
 
33
 
 
34
void
 
35
p_lines(p_win *w)
 
36
{
 
37
  int n = w_pt_count;
 
38
  HDC dc = w_getdc(w, 2);
 
39
  if (dc && n>0) {
 
40
    POINT *pxy = w_pt_list;
 
41
    if (n>1) {
 
42
      int closed = (pxy[0].x==pxy[n-1].x && pxy[0].y==pxy[n-1].y);
 
43
      if ((w->pen_type&7)==P_SOLID || w->s->does_linetypes) {
 
44
        /* NOTE: PolylineTo is MUCH slower than Polyline */
 
45
        Polyline(dc, pxy, n);
 
46
        if (!closed && !w->s->does_linetypes)
 
47
           MoveToEx(dc, pxy[n-1].x, pxy[n-1].y, 0),
 
48
             w_final_pt(dc, &pxy[n-2]);
 
49
      } else {
 
50
        MoveToEx(dc, pxy[0].x, pxy[0].y, 0);
 
51
        w_polyline_to(dc, w->pen_type&7, w->pen_width, &pxy[0], n-1, closed);
 
52
      }
 
53
    } else {
 
54
      MoveToEx(dc, pxy[0].x, pxy[0].y, 0);
 
55
      LineTo(dc, pxy[0].x+1, pxy[0].y);
 
56
    }
 
57
  }
 
58
}
 
59
 
 
60
void
 
61
p_segments(p_win *w)
 
62
{
 
63
  int n = w_pt_count / 2;
 
64
  HDC dc = w_getdc(w, 2);
 
65
  if (dc && n>0) {
 
66
    POINT *pxy = w_pt_list;
 
67
    while (n-- > 0) {
 
68
      MoveToEx(dc, pxy[0].x, pxy[0].y, 0);
 
69
      if (pxy[1].x!=pxy[0].x || pxy[1].y!=pxy[0].y) {
 
70
        if ((w->pen_type&7)==P_SOLID || w->s->does_linetypes) {
 
71
          LineTo(dc, pxy[1].x, pxy[1].y);
 
72
          if (!w->s->does_linetypes) w_final_pt(dc, pxy);
 
73
        } else {
 
74
          w_polyline_to(dc, w->pen_type&7, w->pen_width, &pxy[0], 1, 0);
 
75
        }
 
76
      } else {
 
77
        LineTo(dc, pxy[1].x+1, pxy[1].y);
 
78
      }
 
79
      pxy += 2;
 
80
    }
 
81
  }
 
82
}
 
83
 
 
84
void
 
85
p_dots(p_win *w)
 
86
{
 
87
  int n = w_pt_count;
 
88
  HDC dc = w_getdc(w, 0);
 
89
  if (dc) {
 
90
    POINT *pxy = w_pt_list;
 
91
    COLORREF color = w_color(w, w->color);
 
92
    while (n-- > 0) {
 
93
      SetPixelV(dc, pxy[0].x, pxy[0].y, color);
 
94
      pxy++;
 
95
    }
 
96
  }
 
97
}
 
98
 
 
99
static void
 
100
w_final_pt(HDC dc, POINT *pxy)
 
101
{
 
102
  /* Windows maddeningly wont draw final pixel on a polyline
 
103
   * -- this hack works pretty well onscreen, worse in metafiles */
 
104
  long dx = pxy[1].x - pxy[0].x;
 
105
  long dy = pxy[1].y - pxy[0].y;
 
106
  int ix = 1, iy = 0;
 
107
  if (dx < 0) {
 
108
    if (dy < 0) {
 
109
      ix = -((dy > dx) || (dx < 2*dy));
 
110
      iy = -((dx > dy) || (dy < 2*dx));
 
111
    } else {
 
112
      ix = -((dy < -dx) || (-dx > 2*dy));
 
113
      iy = ((-dx < dy) || (dy > -2*dx));
 
114
    }
 
115
  } else {
 
116
    if (dy < 0) {
 
117
      ix = ((-dy < dx) || (dx > -2*dy));
 
118
      iy = -((dx < -dy) || (-dy > 2*dx));
 
119
    } else if (dy > 0) {
 
120
      ix = ((dy < dx) || (dx > 2*dy));
 
121
      iy = ((dx < dy) || (dy > 2*dx));
 
122
    }
 
123
  }
 
124
  LineTo(dc, pxy[1].x+ix, pxy[1].y+iy);
 
125
}
 
126
 
 
127
static float dashed[] = { 5, 5 };
 
128
static float dotted[] = { 1, 3 };
 
129
static float dashdot[] = { 5, 2, 1, 2 };
 
130
static float dashdotdot[] = { 5, 2, 1, 2, 1, 2 };
 
131
static float *x_dash[] = { 0, dashed, dotted, dashdot, dashdotdot };
 
132
static int x_ndash[] = { 0, 2, 2, 4, 6 };
 
133
 
 
134
static int
 
135
w_polyline_to(HDC dc, int type, int width, POINT *pxy, int n, int closed)
 
136
{
 
137
  int ndash = x_ndash[type];
 
138
  int i, x, y, xmv=0, ymv=0;
 
139
  int moved = 0;
 
140
  float dash[6], len, dx, dy, d=0.0;
 
141
 
 
142
  for (i=0 ; i<ndash ; i++) {
 
143
    dash[i] = x_dash[type][i];
 
144
    if (width>1 && dash[i]>1) dash[i] *= width;
 
145
  }
 
146
 
 
147
  i = 0;
 
148
  while (n-- > 0) {
 
149
    x = pxy[0].x;
 
150
    y = pxy[0].y;
 
151
    pxy++;
 
152
    dx = (float)(pxy[0].x - x);
 
153
    dy = (float)(pxy[0].y - y);
 
154
    len = w_hypot(dx, dy);
 
155
    if (d+len > dash[i]) {
 
156
      float s = -d;
 
157
      float m = 1.0f/len;
 
158
      float f;
 
159
      int xx, yy;
 
160
      do {
 
161
        s += dash[i];
 
162
        f = (s+0.5f)*m;
 
163
        xx = x + (int)(f*dx);
 
164
        yy = y + (int)(f*dy);
 
165
        if (i&1) {
 
166
          xmv = xx, ymv = yy, moved = 1;
 
167
        } else {
 
168
          if (moved) MoveToEx(dc, xmv, ymv, 0), moved = 0;
 
169
          LineTo(dc, xx, yy);
 
170
        }
 
171
        if ((++i) == ndash) i = 0;
 
172
      } while (s+dash[i] < len);
 
173
      d = len - s;  /* 0 < d <= dash[i] */
 
174
    } else {
 
175
      d += len;
 
176
    }
 
177
    if (i&1) {
 
178
      xmv = pxy[0].x, ymv = pxy[0].y, moved = 1;
 
179
    } else {
 
180
      if (moved) MoveToEx(dc, xmv, ymv, 0), moved = 0;
 
181
      LineTo(dc, pxy[0].x, pxy[0].y);
 
182
    }
 
183
  }
 
184
  if (!moved && !closed) LineTo(dc, pxy[0].x+1, pxy[0].y);
 
185
  return 1;
 
186
}
 
187
 
 
188
static float
 
189
w_hypot(float dx, float dy)
 
190
{
 
191
  if (dx<0.0) dx = -dx;
 
192
  if (dy<0.0) dy = -dy;
 
193
  if (dy > dx) {
 
194
    float tmp = dy;
 
195
    dy = dx;
 
196
    dx = tmp;
 
197
  }
 
198
  /* biggest error is when dx==dy -- off by 6 percent */
 
199
  if (dx) dx += 0.5f*dy*dy/dx;
 
200
  return dx;
 
201
}