// Copyright 2000-2005 the Contributors, as shown in the revision logs. // Licensed under the GNU General Public License version 2 ("the License"). // You may not use this file except in compliance with the License. package org.ibex.graphics; import org.ibex.util.*; /** *

* A block of pixels which can be drawn on. *

* *

* Implementations of the Platform class should return objects * supporting this interface from the _createPixelBuffer() * method. These implementations may choose to use off-screen video * ram for this purpose (for example, a Pixmap on X11). *

*/ public interface PixelBuffer { public abstract void drawLine(int x1, int y1, int x2, int y2, int color); public abstract void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color); public abstract void drawPicture(Picture p, Affine a, Mesh h); public abstract void drawGlyph(Font.Glyph source, Affine a, Mesh h, int rgb, int bg); //public abstract void stroke(Mesh p, int color); //public abstract void fill(Mesh p, Paint paint); } /* // FEATURE: we want floats (inter-pixel spacing) for antialiasing, but this hoses the fastpath line drawing... argh! // draws a line of width w; note that the coordinates here are post-transform public void drawLine(int x1, int y1, int x2, int y2, int w, int color, boolean capped) { if (y1 > y2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } if (x1 == x2) { fillTrapezoid(x1 - w / 2, x2 + w / 2, y1 - (capped ? w / 2 : 0), x1 - w / 2, x2 + w / 2, y2 + (capped ? w / 2 : 0), color); return; } // fastpath for single-pixel width lines if (w == 1) { float slope = (float)(y2 - y1) / (float)(x2 - x1); int last_x = x1; for(int y=y1; y<=y2; y++) { int new_x = (int)((float)(y - y1) / slope) + x1; if (slope >= 0) fillTrapezoid(last_x + 1, y != y2 ? new_x + 1 : new_x, y, last_x + 1, y != y2 ? new_x + 1 : new_x, y + 1, color); else fillTrapezoid(y != y2 ? new_x : new_x + 1, last_x, y, y != y2 ? new_x : new_x + 1, last_x, y + 1, color); last_x = new_x; } return; } // actually half-width float width = (float)w / 2; float phi = (float)Math.atan((y2 - y1) / (x2 - x1)); if (phi < 0.0) phi += (float)Math.PI * 2; float theta = (float)Math.PI / 2 - phi; // dx and dy are the x and y distance between each endpoint and the corner of the stroke int dx = (int)(width * Math.cos(theta)); int dy = (int)(width * Math.sin(theta)); // slice is the longest possible length of a horizontal line across the stroke int slice = (int)(2 * width / Math.cos(theta)); if (capped) { x1 -= width * Math.cos(phi); x2 += width * Math.cos(phi); y1 -= width * Math.sin(phi); y2 += width * Math.sin(phi); } fillTrapezoid(x1 + dx, x1 + dx, y1 - dy, x1 - dx, x1 - dx + slice, y1 + dy, color); // top corner fillTrapezoid(x2 + dx - slice, x2 + dx, y2 - dy, x2 - dx, x2 - dx, y2 + dy, color); // bottom corner fillTrapezoid(x1 - dx, x1 - dx + slice, y1 + dy, x2 + dx - slice, x2 + dx, y2 - dy, color); // middle } } */