//(c): Matti Katila package org.fenfire.modules.pp.lava; import org.nongnu.libvob.*; import org.nongnu.libvob.gl.*; import org.nongnu.libvob.util.ColorUtil; import java.awt.*; import java.util.Random; /** A vob which is a rectangular background and frame. * Draws a filled (possibly with several colors) background rectangle, * surrounded by a rectangle of the current foreground color. */ public class UniquePaperVob extends AbstractVob { public static final String rcsid = "$Id: UniquePaperVob.java,v 1.1 2003/05/14 12:32:53 mudyc Exp $"; public static boolean dbg = false; private static void pa(String s) { System.out.println("UniquePaperVob::"+s); } private Random rand; private final long seed; public UniquePaperVob(Object uniqId) { this.seed = uniqId.hashCode(); } public void render(Graphics g, boolean fast, Vob.RenderInfo info1, Vob.RenderInfo info2) { rand = new Random(seed); Shape oldClip = g.getClip(); Color oldfg = g.getColor(); Rectangle rect = new Rectangle(); Rectangle geom = new Rectangle(); info1.getExtRect(rect); g.setClip(rect.x, rect.y, rect.width, rect.height); int mx = rect.x, my=rect.y, mw = rect.width, mh = rect.height; if (mw < 10 || mh < 10) return; info2.getExtRect(geom); int panx = geom.width, pany = geom.height; if (dbg) pa("mx: "+mx+", gx: "+geom.x+", panx: "+panx+", pany: "+pany); float zoom = ((float)(geom.x))/100000; int gx = geom.x; // Make SEEPRA! ;) float k = rand.nextFloat() * 2 -1; float j = (float)Math.cos(k - Math.PI/2); float ratio = rand.nextFloat()*0.7f + 1.5f; Color c1 = getUniqColor(); Color c2 = getUniqColor(); float a =(float) Math.PI * rand.nextFloat(); if ( Math.abs(rand.nextInt())%4 != 0) { float linew = mw/((Math.abs(rand.nextInt())%5) + 3); float begin_x = -1; float begin_y = -1; float f; if (a > Math.PI/4 && a <= Math.PI *3f/4) { // verticals.. f = mx + mw/2 + panx*zoom; // >> if too far we have to be at least mw away from mx. while ( f < mx - 2*mw) { f += Math.abs( ((ratio * linew)/j)*zoom ); f += Math.abs( (((1-ratio) * linew)/j)*zoom ); } // add y component f += (pany*zoom)/(float)Math.tan(a); if (a < Math.PI/2) f += (mh/2)/(float)Math.tan(a); else f -= (mh/2)/(float)Math.tan(a); // << if too near while( f > mx-2*mw ) { f -= Math.abs( ((ratio * linew)/j)*zoom ); f -= Math.abs( (((1-ratio) * linew)/j)*zoom ); } begin_x = f; } else { j = (float)Math.sin(k - Math.PI/2); // horizontals.. f = my + mh/2 + pany*zoom; // >> if too far we have to be at least mw away from my. while ( f < my - 2*mh) { f += Math.abs( ((ratio * linew)/j)*zoom ); f += Math.abs( (((1-ratio) * linew)/j)*zoom ); } // add x component f -= (panx*zoom)*(float)Math.tan(a); if (a < Math.PI/4) f += (mw/2)*(float)Math.tan(a); else f -= (mw/2)*(float)Math.tan(a); // << if too near while( f > my-2*mh ) { f -= Math.abs( ((ratio * linew)/j)*zoom ); f -= Math.abs( (((1-ratio) * linew)/j)*zoom ); } begin_y = f; } boolean black = true; float end_x = mx + mw + Math.abs(mh/(float)Math.tan(a)); float end_y = my + mh + Math.abs(mw*(float)Math.tan(a)); int[] x = new int[4]; int[] y = new int[4]; if (a > Math.PI/4 && a <= Math.PI *3f/4) { if (begin_x > end_x) throw new Error("UniquePaperVob::begin_x > end_x!"); while (begin_x < end_x) { x[0] = (int)begin_x; y[0] = (my+mh); x[1] = (int)( begin_x + mh/Math.tan(a) ); y[1] = my; if (black) begin_x += Math.abs(zoom* (ratio * linew)/j); else begin_x += Math.abs(zoom* ((1-ratio) * linew)/j); black = !black; x[2] = (int)( begin_x + mh/Math.tan(a)); y[2] = my; x[3] = (int)(begin_x); y[3] = my+mh; if (black) g.setColor(c1); else g.setColor(c2); g.fillPolygon(x,y,4); } } else { if (begin_y > end_y) throw new Error("UniquePaperVob::begin_y > end_y!"); while (begin_y < end_y) { y[0] = (int)begin_y; x[0] = mx; y[1] = (int)( begin_y + mw * Math.tan(a)); x[1] = mx+mw; if (black) begin_y += Math.abs(zoom* (ratio * linew)/j); else begin_y += Math.abs(zoom* ((1-ratio) * linew)/j); black = !black; y[2] = (int)( begin_y + mw * Math.tan(a)); x[2] = mx+mw; y[3] = (int)(begin_y); x[3] = mx; if (black) g.setColor(c1); else g.setColor(c2); g.fillPolygon(x,y,4); } } } else { g.setColor(c1); g.fillRect(mx, my, mw, mh); } if (dbg) { int x = mx + mw/2 - (int)((mw*zoom)/4) + (int)(panx * zoom), y = my + mh/2 - (int)((mh*zoom)/4) + (int)(pany * zoom), w = (int) ((float)mw*zoom)/2, h = (int) ((float)mh*zoom)/2; g.setColor(Color.gray); g.fillRect(x, y, w, h); } g.setColor(oldfg); g.setClip(oldClip); } private Color getUniqColor() { float brigh = .8f; return Color.getHSBColor(rand.nextFloat(), .7f + (rand.nextFloat()*2-1)/8, brigh); } public int putGL(VobScene vs, int coordsys1) { throw new Error("Use libpaper with OpenGL instead of UniquePaperVob"); } }