Mesh replaces Polygon
[org.ibex.core.git] / src / org / ibex / graphics / PixelBuffer.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the GNU General Public License version 2 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.graphics;
6 import org.ibex.util.*;
7
8 /**
9  *  <p>
10  *  A block of pixels which can be drawn on.
11  *  </p>
12  *
13  *  <p>
14  *  Implementations of the Platform class should return objects
15  *  supporting this interface from the _createPixelBuffer()
16  *  method. These implementations may choose to use off-screen video
17  *  ram for this purpose (for example, a Pixmap on X11).
18  *  </p>
19  */
20 public interface PixelBuffer {
21     public abstract void drawLine(int x1, int y1, int x2, int y2, int color);
22     public abstract void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
23     public abstract void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color);
24     public abstract void drawPicture(Picture p, Affine a, Mesh h);
25     public abstract void drawGlyph(Font.Glyph source, Affine a, Mesh h, int rgb, int bg);
26     public abstract void stroke(Mesh p, int color);
27     public abstract void fill(Mesh p, Paint paint);
28 }
29
30
31
32
33 /*
34     // FEATURE: we want floats (inter-pixel spacing) for antialiasing, but this hoses the fastpath line drawing... argh!
35     // draws a line of width <tt>w</tt>; note that the coordinates here are <i>post-transform</i> 
36     public void drawLine(int x1, int y1, int x2, int y2, int w, int color, boolean capped) {
37
38         if (y1 > y2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; }
39
40         if (x1 == x2) {
41             fillTrapezoid(x1 - w / 2, x2 + w / 2, y1 - (capped ? w / 2 : 0),
42                           x1 - w / 2, x2 + w / 2, y2 + (capped ? w / 2 : 0), color);
43             return;
44         }
45
46         // fastpath for single-pixel width lines
47         if (w == 1) {
48             float slope = (float)(y2 - y1) / (float)(x2 - x1);
49             int last_x = x1;
50             for(int y=y1; y<=y2; y++) {
51                 int new_x = (int)((float)(y - y1) / slope) + x1;
52                 if (slope >= 0) fillTrapezoid(last_x + 1, y != y2 ? new_x + 1 : new_x, y,
53                                               last_x + 1, y != y2 ? new_x + 1 : new_x, y + 1, color);
54                 else fillTrapezoid(y != y2 ? new_x : new_x + 1, last_x, y,
55                                    y != y2 ? new_x : new_x + 1, last_x, y + 1, color);
56                 last_x = new_x;
57             }
58             return;
59         }
60
61         // actually half-width
62         float width = (float)w / 2;
63         float phi = (float)Math.atan((y2 - y1) / (x2 - x1));
64         if (phi < 0.0) phi += (float)Math.PI * 2;
65         float theta = (float)Math.PI / 2 - phi;
66
67         // dx and dy are the x and y distance between each endpoint and the corner of the stroke
68         int dx = (int)(width * Math.cos(theta));
69         int dy = (int)(width * Math.sin(theta));
70
71         // slice is the longest possible length of a horizontal line across the stroke
72         int slice = (int)(2 * width / Math.cos(theta));
73
74         if (capped) {
75             x1 -= width * Math.cos(phi);
76             x2 += width * Math.cos(phi);
77             y1 -= width * Math.sin(phi);
78             y2 += width * Math.sin(phi);
79         }
80
81         fillTrapezoid(x1 + dx, x1 + dx, y1 - dy, x1 - dx, x1 - dx + slice, y1 + dy, color);           // top corner
82         fillTrapezoid(x2 + dx - slice, x2 + dx, y2 - dy, x2 - dx, x2 - dx, y2 + dy, color);           // bottom corner
83         fillTrapezoid(x1 - dx, x1 - dx + slice, y1 + dy, x2 + dx - slice, x2 + dx, y2 - dy, color);   // middle
84     }
85
86 }
87 */