diff --git a/app/PdeBase.java b/app/PdeBase.java index 91dfb688a..87da07863 100644 --- a/app/PdeBase.java +++ b/app/PdeBase.java @@ -45,7 +45,7 @@ import com.ice.jni.registry.*; * files and images, etc) that comes from that. */ public class PdeBase { - static final String VERSION = "0079 Alpha"; + static final String VERSION = "0080 Alpha"; static String openedAtStartup; diff --git a/app/PdeSketch.java b/app/PdeSketch.java index eb7666ffd..750a52cfe 100644 --- a/app/PdeSketch.java +++ b/app/PdeSketch.java @@ -1495,13 +1495,52 @@ public class PdeSketch { } } // else no size() command found - // handle this in editor instead, rare or nonexistant - //} catch (MalformedPatternException e) { - //PdeBase.showWarning("Internal Problem", - // "An internal error occurred while trying\n" + - // "to export the sketch. Please report this.", e); - //return false; - //} + /* + // try to get / ** blah * / stuff + // the plus gets / ***** and **** / if that's what they used + matcher = new Perl5Matcher(); + compiler = new Perl5Compiler(); + String description = ""; + //pattern = compiler.compile("\\/\\*\\*+(.*)\\*\\/"); + pattern = compiler.compile("\\/\\*\\*+(.+)"); + //pattern = compiler.compile("\\/\\*\\*+(.*)\\*+\\/"); + System.out.println("this compiled"); + input = new PatternMatcherInput(" " + code[0].program); + if (matcher.contains(input, pattern)) { + MatchResult result = matcher.getMatch(); + System.out.println("contains " + result.group(0)); + String stuff = result.group(1).toString(); + String lines[] = PApplet.split(stuff, '\n'); + PApplet.printarr(lines); + } + */ + StringBuffer dbuffer = new StringBuffer(); + String lines[] = PApplet.split(code[0].program, '\n'); + for (int i = 0; i < lines.length; i++) { + if (lines[i].trim().startsWith("/**")) { // this is our comment + // some smartass put the whole thing on the same line + //if (lines[j].indexOf("*/") != -1) break; + + for (int j = i+1; j < lines.length; j++) { + if (lines[j].trim().endsWith("*/")) { + // remove the */ from the end, and any extra *s + // in case there's also content on this line + // nah, don't bother.. make them use the three lines + break; + } + + int offset = 0; + while ((offset < lines[j].length()) && + ((lines[j].charAt(offset) == '*') || + (lines[j].charAt(offset) == ' '))) { + offset++; + } + // insert the return into the html to help w/ line breaks + dbuffer.append(lines[j].substring(offset) + "\n"); + } + } + } + String description = dbuffer.toString(); StringBuffer sources = new StringBuffer(); for (int i = 0; i < codeCount; i++) { @@ -1514,6 +1553,7 @@ public class PdeSketch { PrintStream ps = new PrintStream(fos); // @@sketch@@, @@width@@, @@height@@, @@archive@@, @@source@@ + // and now @@description@@ InputStream is = null; // if there is an applet.html file in the sketch folder, use that @@ -1551,6 +1591,10 @@ public class PdeSketch { sb.replace(index, index + "@@height@@".length(), String.valueOf(high)); } + while ((index = sb.indexOf("@@description@@")) != -1) { + sb.replace(index, index + "@@description@@".length(), + description); + } line = sb.toString(); } ps.println(line); diff --git a/build/howto.txt b/build/howto.txt index a57a8cce0..71c9bbc99 100755 --- a/build/howto.txt +++ b/build/howto.txt @@ -11,27 +11,30 @@ HOW TO BUILD PROCESSING ON YOUR FAVORITE PLATFORM linux users can hop ahead to step 2. ** of the packages, begin with the defaults, and add: -cvs - used for version control -gzip - probably installed by default, just make sure -perl - use this version, activestate or other distros have trouble -tar, unzip, zip - for created archives -textutils - i think this is included in the defaults, but make sure -** these aren't required initially, but useful: -openssh (command line ssh client) -nano (handy/simple text editor) ++ gcc-mingw - used to build processing.exe + (this will also pull in gcc-core) -** and be sure to select the option for 'unix line endings'. ++ cvs - used for version control -** other notes ++ perl - use this version, activestate or other distros have trouble + ++ unzip, zip - for dealing with archives -the installer is sometimes a little flakey, so it may take more than -one try to get everything in there. you can also run the installer -again to add new applications, so you might try just installing the -base stuff, and then come back to install the other bits. ++ included in the defaults, but make sure: + coreutils (or textutils), gzip, tar -it's also useful to run the installer (grab a new one from the site, -since it changes) every few months to keep things fresh. ++ not required but useful: + openssh - command line ssh client + nano - handy/simple text editor + +** and be sure to leave the option selected for 'unix line endings' + +the cygwin installer is sometimes a little flakey, so it may take more +than one try to get everything in there. in fact, it's often best to +run the installer once, and let it install all its defaults, then run +it again, and select the items above. it's also useful to run the +installer every few months to keep things fresh. 2. GRAB THE CODE FROM SOURCEFORGE diff --git a/core/PApplet.java b/core/PApplet.java index 70a84e645..39942eba4 100644 --- a/core/PApplet.java +++ b/core/PApplet.java @@ -85,10 +85,11 @@ public class PApplet extends Applet protected int emouseX, emouseY; /** - * used to set pmouseX/Y to mouseX/Y the first time mouseX/Y are used, - * otherwise pmouseX/Y are always zero, causing a nasty jump. just using - * (frameCount == 0) won't work since mouseXxxxx() may not be called - * until a couple frames into things. + * Used to set pmouseX/Y to mouseX/Y the first time mouseX/Y are used, + * otherwise pmouseX/Y are always zero, causing a nasty jump. + *
+ * Just using (frameCount == 0) won't work since mouseXxxxx() + * may not be called until a couple frames into things. */ public boolean firstMouse; @@ -96,14 +97,17 @@ public class PApplet extends Applet public MouseEvent mouseEvent; /** - * Last key pressed. If it's a coded key - * (arrows or ctrl/shift/alt, this will be set to 0xffff or 65535). + * Last key pressed. + *
+ * If it's a coded key (arrows or ctrl/shift/alt, + * this will be set to 0xffff or 65535). */ public char key; /** - * If the key is a coded key, i.e. up/down/ctrl/shift/alt - * the 'key' comes through as 0xffff (65535) + * If the key is a coded key such as UP/DOWN/CTRL/SHIFT/ALT, + * the 'key' comes through as 0xffff (65535) and keyCode will + * contain the proper value. */ public int keyCode; @@ -116,8 +120,10 @@ public class PApplet extends Applet public boolean focused = false; /** - * Is the applet online or not? This can be used to test how the - * applet should behave since online situations are different. + * true if the applet is online. + *
+ * This can be used to test how the applet should behave + * since online situations are different (no file writing, etc). */ public boolean online = false; @@ -347,7 +353,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// public class RegisteredMethods { @@ -451,7 +457,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// public void setup() { @@ -504,7 +510,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// public void size(int iwidth, int iheight) { @@ -791,7 +797,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// MouseEvent mouseEventQueue[] = new MouseEvent[10]; @@ -959,7 +965,7 @@ public class PApplet extends Applet public void mouseMoved() { } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// KeyEvent keyEventQueue[] = new KeyEvent[10]; @@ -1097,7 +1103,7 @@ public class PApplet extends Applet public void keyTyped() { } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// // i am focused man, and i'm not afraid of death. // and i'm going all out. i circle the vultures in a van @@ -1120,7 +1126,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// // getting the time @@ -1170,7 +1176,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// // controlling time and playing god @@ -1216,7 +1222,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// /** @@ -1287,7 +1293,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// /** @@ -1329,11 +1335,22 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// // SCREEN GRABASS + /** + * This version of save() is an override of PImage.save(), + * rather than calling g.save(). This version properly saves + * the image to the applet folder (whereas save doesn't know + * where to put things) + */ + public void save(String filename) { + g.save(savePath(filename)); + } + + /** * grab an image of what's currently in the drawing area. * best used just before endFrame() at the end of your loop(). @@ -1388,9 +1405,12 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ - // CURSOR, base code contributed by amit pitaru + ////////////////////////////////////////////////////////////// + + // CURSOR + + // based on code contributed by amit pitaru and jonathan feinberg int cursor_type = ARROW; // cursor type @@ -1418,10 +1438,8 @@ public class PApplet extends Applet public void cursor(PImage image, int hotspotX, int hotspotY) { //if (!isOneTwoOrBetter()) { if (JDK_VERSION < 1.2) { - System.err.println("cursor() error: Java 1.2 or higher is " + - "required to set cursors"); - System.err.println(" (You're using version " + - JDK_VERSION_STRING + ")"); + System.err.println("Java 1.2 or higher is required to use cursor()"); + System.err.println("(You're using version " + JDK_VERSION_STRING + ")"); return; } @@ -1449,7 +1467,7 @@ public class PApplet extends Applet cursor_visible = true; } catch (NoSuchMethodError e) { - System.out.println("cursor() is not available on " + + System.err.println("cursor() is not available on " + nf((float)JDK_VERSION, 1, 1)); } catch (IndexOutOfBoundsException e) { System.err.println("cursor() error: the hotspot " + hotspot + @@ -1494,7 +1512,7 @@ public class PApplet extends Applet } - // ------------------------------------------------------------ + ////////////////////////////////////////////////////////////// static public void print(byte what) { @@ -1805,8 +1823,10 @@ public class PApplet extends Applet Random internalRandom; /** - * Return a random number in the range [0, howbig) - * (0 is inclusive, non-inclusive of howbig) + * Return a random number in the range [0, howbig). + *
+ * The number returned will range from zero up to + * (but not including) 'howbig'. */ public final float random(float howbig) { // for some reason (rounding error?) Math.random() * 3 @@ -1829,8 +1849,11 @@ public class PApplet extends Applet /** - * Return a random number in the range [howsmall, howbig) - * (inclusive of howsmall, non-inclusive of howbig) + * Return a random number in the range [howsmall, howbig). + *
+ * The number returned will range from 'howsmall' up to + * (but not including 'howbig'. + *
* If howsmall is >= howbig, howsmall will be returned, * meaning that random(5, 5) will return 5 (useful) * and random(7, 4) will return 7 (not useful.. better idea?) @@ -1884,22 +1907,23 @@ public class PApplet extends Applet /** - * Computes the Perlin noise function value at the point (x, y, z). - * - * @param x x coordinate - * @param y y coordinate - * @param z z coordinate - * @return the noise function value at (x, y, z) + * Computes the Perlin noise function value at point x. */ public float noise(float x) { // is this legit? it's a dumb way to do it (but repair it later) return noise(x, 0f, 0f); } + /** + * Computes the Perlin noise function value at the point x, y. + */ public float noise(float x, float y) { return noise(x, y, 0f); } + /** + * Computes the Perlin noise function value at x, y, z. + */ public float noise(float x, float y, float z) { if (perlin == null) { if (perlinRandom == null) { @@ -2310,7 +2334,7 @@ public class PApplet extends Applet * I want to print lines to a file. Why am I always explaining myself? * It's the JavaSoft API engineers who need to explain themselves. */ - public PrintWriter writer(OutputStream output) { + static public PrintWriter writer(OutputStream output) { //try { OutputStreamWriter osw = new OutputStreamWriter(output); return new PrintWriter(osw); @@ -2502,7 +2526,7 @@ public class PApplet extends Applet /** * Saves bytes to a specific File location specified by the user. */ - public void saveBytes(File file, byte buffer[]) { + static public void saveBytes(File file, byte buffer[]) { try { String filename = file.getAbsolutePath(); createPath(filename); @@ -2519,15 +2543,15 @@ public class PApplet extends Applet /** * Spews a buffer of bytes to an OutputStream. */ - public void saveBytes(OutputStream output, byte buffer[]) { + static public void saveBytes(OutputStream output, byte buffer[]) { try { //BufferedOutputStream bos = new BufferedOutputStream(output); output.write(buffer); output.flush(); } catch (IOException e) { - System.err.println("error while saving bytes"); e.printStackTrace(); + throw new RuntimeException("Couldn't save bytes"); } } @@ -2541,13 +2565,13 @@ public class PApplet extends Applet fos.close(); } catch (IOException e) { - System.err.println("error while saving strings"); e.printStackTrace(); + throw new RuntimeException("saveStrings() failed: " + e.getMessage()); } } - public void saveStrings(File file, String strings[]) { + static public void saveStrings(File file, String strings[]) { try { String location = file.getAbsolutePath(); createPath(location); @@ -2561,7 +2585,8 @@ public class PApplet extends Applet } } - public void saveStrings(OutputStream output, String strings[]) { + + static public void saveStrings(OutputStream output, String strings[]) { PrintWriter writer = new PrintWriter(new OutputStreamWriter(output)); for (int i = 0; i < strings.length; i++) { @@ -3326,6 +3351,7 @@ public class PApplet extends Applet } + ////////////////////////////////////////////////////////////// // CASTING FUNCTIONS, INSERTED BY PREPROC @@ -4522,28 +4548,24 @@ v PApplet.this.stop(); } + public void set(int x1, int y1, PImage image) { + if (recorder != null) recorder.set(x1, y1, image); + g.set(x1, y1, image); + } + + public void mask(int alpha[]) { if (recorder != null) recorder.mask(alpha); g.mask(alpha); } - static public void mask(PImage image, int alpha[]) { - PGraphics.mask(image, alpha); - } - - public void mask(PImage alpha) { if (recorder != null) recorder.mask(alpha); g.mask(alpha); } - static public void mask(PImage image, PImage alpha) { - PGraphics.mask(image, alpha); - } - - public void filter(int kind) { if (recorder != null) recorder.filter(kind); g.filter(kind); @@ -4556,12 +4578,6 @@ v PApplet.this.stop(); } - public void copy(PImage src, int dx, int dy) { - if (recorder != null) recorder.copy(src, dx, dy); - g.copy(src, dx, dy); - } - - public void copy(int sx1, int sy1, int sx2, int sy2, int dx1, int dy1, int dx2, int dy2) { if (recorder != null) recorder.copy(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); @@ -4610,15 +4626,15 @@ v PApplet.this.stop(); } - static public boolean saveHeaderTIF(OutputStream output, + static public boolean saveHeaderTIFF(OutputStream output, int width, int height) { - return PGraphics.saveHeaderTIF(output, width, height); + return PGraphics.saveHeaderTIFF(output, width, height); } - static public boolean saveTIF(OutputStream output, int pixels[], - int width, int height) { - return PGraphics.saveTIF(output, pixels, width, height); + static public boolean saveTIFF(OutputStream output, int pixels[], + int width, int height) { + return PGraphics.saveTIFF(output, pixels, width, height); } @@ -4634,12 +4650,6 @@ v PApplet.this.stop(); } - public void save(String filename) { - if (recorder != null) recorder.save(filename); - g.save(filename); - } - - public void hint(int which) { if (recorder != null) recorder.hint(which); g.hint(which); @@ -4960,15 +4970,15 @@ v PApplet.this.stop(); } - public void textMode(int mode) { - if (recorder != null) recorder.textMode(mode); - g.textMode(mode); + public void textAlign(int align) { + if (recorder != null) recorder.textAlign(align); + g.textAlign(align); } - public void textSpace(int space) { - if (recorder != null) recorder.textSpace(space); - g.textSpace(space); + public void textMode(int space) { + if (recorder != null) recorder.textMode(space); + g.textMode(space); } diff --git a/core/PConstants.java b/core/PConstants.java index 14c5f024f..bef190b4c 100644 --- a/core/PConstants.java +++ b/core/PConstants.java @@ -83,13 +83,12 @@ public interface PConstants { // filter/convert types - static final int BLUR = 12; - //static final int EDGES = 15; // removed - static final int GRAY = 11; + static final int BLUR = 11; + static final int GRAY = 12; static final int INVERT = 13; - static final int POSTERIZE = 14; - static final int THRESHOLD = 10; - // RGB is also a filter option + static final int OPAQUE = 14; + static final int POSTERIZE = 15; + static final int THRESHOLD = 16; // blend mode keyword definitions @@ -171,27 +170,18 @@ public interface PConstants { // uv texture orientation modes - static final int NORMAL_SPACE = 0; // 0..1 - static final int IMAGE_SPACE = 1; - - - // hrmm, can i avoid these? - - //static final int DEFAULT_SIZE = Float.NaN; - //static final int DEFAULT_LEADING = Float.NaN; + static final int NORMALIZED = 1; //_SPACE = 0; // 0..1 + static final int IMAGE = 2; // text placement modes - static final int SCREEN_SPACE = 2; - static final int OBJECT_SPACE = 3; + //static final int SCREEN = 4; // var SCREEN exists elsewhere + static final int OBJECT = 3; // text alignment modes - - static final int ALIGN_LEFT = 0; - static final int ALIGN_CENTER = 1; - static final int ALIGN_RIGHT = 2; + // are inherited from LEFT, CENTER, RIGHT // stroke modes diff --git a/core/PFont.java b/core/PFont.java index 1bf07e127..0fe9b23c2 100644 --- a/core/PFont.java +++ b/core/PFont.java @@ -31,44 +31,51 @@ import java.lang.reflect.*; import java.util.*; -/* - awful ascii (non)art for how this works - | - | height is the full used height of the image - | - | ..XX.. } - | ..XX.. } - | ...... } - | XXXX.. } topExtent (top y is baseline - topExtent) - | ..XX.. } - | ..XX.. } dotted areas are where the image data - | ..XX.. } is actually located for the character - +---XXXXXX---- } (it extends to the right & down for pow of 2 textures) - | - ^^^^ leftExtent (amount to move over before drawing the image - - ^^^^^^^^^^^^^^ setWidth (width displaced by char) -*/ - +/** + * Grayscale bitmap font class used by Processing. + *
+ * Awful (and by that, I mean awesome) ascii (non)art for how this works: + * + *
+ * | + * | height is the full used height of the image + * | + * | ..XX.. } + * | ..XX.. } + * | ...... } + * | XXXX.. } topExtent (top y is baseline - topExtent) + * | ..XX.. } + * | ..XX.. } dotted areas are where the image data + * | ..XX.. } is actually located for the character + * +---XXXXXX---- } (it extends to the right and down + * | for power of two texture sizes) + * ^^^^ leftExtent (amount to move over before drawing the image + * + * ^^^^^^^^^^^^^^ setWidth (width displaced by char) + *+ */ public class PFont implements PConstants { - //int firstChar = 33; // always public int charCount; public PImage images[]; - // image width, a power of 2 - // note! these will always be the same - public int twidth, theight; - // float versions of the above - //float twidthf, theightf; + /** "natural" size of the font (most often 48) */ + public int size; - // formerly iwidthf, iheightf.. but that's wrong - // actually should be mbox, the font size - float fwidth, fheight; + /** next power of 2 over the max image size (usually 64) */ + public int mbox2; - // mbox is just the font size (i.e. 48 for most vlw fonts) - public int mbox2; // next power of 2 over the max image size - public int mbox; // actual "font size" of source font + /** floating point width (convenience) */ + protected float fwidth; + + /** floating point width (convenience) */ + protected float fheight; + + /** texture width, same as mbox2, but reserved for future use */ + public int twidth; + + /** texture height, same as mbox2, but reserved for future use */ + public int theight; public int value[]; // char code public int height[]; // height of the bitmap data @@ -80,22 +87,14 @@ public class PFont implements PConstants { public int ascent; public int descent; - // scaling, for convenience - //public float size; - //public float leading; - //public int align; - //public int space; - int ascii[]; // quick lookup for the ascii chars - //boolean cached; // shared by the text() functions to avoid incessant allocation of memory protected char textBuffer[] = new char[8 * 1024]; protected char widthBuffer[] = new char[8 * 1024]; - //public PGraphics parent; - public PFont() { } // for PFontAI subclass and font builder + public PFont() { } // for subclasses public PFont(InputStream input) throws IOException { @@ -108,29 +107,29 @@ public class PFont implements PConstants { int numBits = is.readInt(); // this was formerly ignored, now it's the actual font size - mbox = is.readInt(); + //mbox = is.readInt(); + size = is.readInt(); // this was formerly mboxY, the one that was used // this will make new fonts downward compatible + //mbox2 = is.readInt(); mbox2 = is.readInt(); - fwidth = mbox; - fheight = mbox; + fwidth = size; //mbox; + fheight = size; //mbox; // size for image ("texture") is next power of 2 // over the font size. for most vlw fonts, the size is 48 // so the next power of 2 is 64. // double-check to make sure that mbox2 is a power of 2 // there was a bug in the old font generator that broke this + //mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2))); mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2))); // size for the texture is stored in the font - twidth = theight = mbox2; + twidth = theight = mbox2; //mbox2; ascent = is.readInt(); // formerly baseHt (zero/ignored) descent = is.readInt(); // formerly ignored struct padding - //System.out.println("found mbox = " + mbox); - //System.out.println("found ascent/descent = " + ascent + " " + descent); - // allocate enough space for the character info value = new int[charCount]; height = new int[charCount]; @@ -200,23 +199,19 @@ public class PFont implements PConstants { } //System.out.println(); } - //resetSize(); - //space = OBJECT_SPACE; - //align = ALIGN_LEFT; } - //static boolean isSpace(int c) { - //return (Character.isWhitespace((char) c) || - // (c == '\u00A0') || (c == '\u2007') || (c == '\u202F')); - //} - + /** + * Write this PFont to an OutputStream. It is assumed that the + * calling class will handle closing the stream when finished. + */ public void write(OutputStream output) throws IOException { DataOutputStream os = new DataOutputStream(output); os.writeInt(charCount); os.writeInt(8); // numBits - os.writeInt(mbox); // formerly mboxX (was 64, now 48) + os.writeInt(size); // formerly mboxX (was 64, now 48) os.writeInt(mbox2); // formerly mboxY (was 64, still 64) os.writeInt(ascent); // formerly baseHt (was ignored) os.writeInt(descent); // formerly struct padding for c version @@ -232,18 +227,14 @@ public class PFont implements PConstants { } for (int i = 0; i < charCount; i++) { - //int bitmapSize = height[i] * width[i]; - //byte bitmap[] = new byte[bitmapSize]; - for (int y = 0; y < height[i]; y++) { for (int x = 0; x < width[i]; x++) { - //os.write(images[i].pixels[y * width[i] + x] & 0xff); os.write(images[i].pixels[y * mbox2 + x] & 0xff); } } } os.flush(); - os.close(); // can/should i do this? + //os.close(); // can/should i do this? } @@ -256,10 +247,6 @@ public class PFont implements PConstants { // if there are somehow zero chars in the lookup if (value.length == 0) return -1; - // these chars required in all fonts - //if ((c >= 33) && (c <= 126)) { - //return c - 33; - //} // quicker lookup for the ascii fellers if (c < 128) return ascii[c]; @@ -268,11 +255,7 @@ public class PFont implements PConstants { } - // whups, this used the p5 charset rather than what was inside the font - // meaning that old fonts would crash.. fixed for 0069 - protected int index_hunt(int c, int start, int stop) { - //System.err.println("checking between " + start + " and " + stop); int pivot = (start + stop) / 2; // if this is the char, then return it @@ -290,62 +273,21 @@ public class PFont implements PConstants { } - /* - public void space(int which) { - this.space = which; - if (space == SCREEN_SPACE) { - resetSize(); - //resetLeading(); - } - } - - - public void align(int which) { - this.align = which; - } - */ - - /** * Currently un-implemented for .vlw fonts, * but honored for layout in case subclasses use it. */ public float kern(char a, char b) { - return 0; // * size, but since zero.. + return 0; } - /* - public void resetSize() { - //size = 12; - size = mbox; // default size for the font - resetLeading(); // has to happen with the resize - } - - - public void size(float isize) { - size = isize; - } - - - public void resetLeading() { - // by trial & error, this seems close to illustrator - leading = (ascent() + descent()) * 1.275f; - } - - - public void leading(float ileading) { - leading = ileading; - } - */ - - /** * Returns the ascent of this font from the baseline. * The value is based on a font of size 1. */ public float ascent() { - return ((float)ascent / fheight); // * size; + return ((float)ascent / fheight); } @@ -354,7 +296,7 @@ public class PFont implements PConstants { * The value is based on a font size of 1. */ public float descent() { - return ((float)descent / fheight); // * size; + return ((float)descent / fheight); } @@ -367,8 +309,7 @@ public class PFont implements PConstants { int cc = index(c); if (cc == -1) return 0; - //return ((float)setWidth[cc] / fwidth) * size; - return ((float)setWidth[cc] / fwidth); // * size; + return ((float)setWidth[cc] / fwidth); } @@ -384,7 +325,6 @@ public class PFont implements PConstants { str.getChars(0, length, widthBuffer, 0); float wide = 0; - //float pwide = 0; int index = 0; int start = 0; @@ -395,7 +335,6 @@ public class PFont implements PConstants { } index++; } - //System.out.println(start + " " + length + " " + index); if (start < length) { wide = Math.max(wide, calcWidth(widthBuffer, start, index)); } @@ -420,11 +359,14 @@ public class PFont implements PConstants { } + /** + * Draw a character at an x, y, z position. + */ public void text(char c, float x, float y, float z, PGraphics parent) { - if (parent.textMode == ALIGN_CENTER) { + if (parent.textAlign == CENTER) { x -= parent.textSize * width(c) / 2f; - } else if (parent.textMode == ALIGN_RIGHT) { + } else if (parent.textAlign == RIGHT) { x -= parent.textSize * width(c); } @@ -433,28 +375,15 @@ public class PFont implements PConstants { /** - * Draw a character at an x, y, z position. + * Internal function to draw a character at an x, y, z position. + * This version is called after the textM */ protected void textImpl(char c, float x, float y, float z, PGraphics parent) { - //if (!valid) return; - //if (!exists(c)) return; - - // eventually replace this with a table - // to convert the > 127 coded chars - //int glyph = c - 33; int glyph = index(c); if (glyph == -1) return; - /* - if (!cached) { - // cache on first run, to ensure a graphics context exists - parent.cache(images); - cached = true; - } - */ - - if (parent.textSpace == OBJECT_SPACE) { + if (parent.textMode == OBJECT) { float high = (float) height[glyph] / fheight; float bwidth = (float) width[glyph] / fwidth; float lextent = (float) leftExtent[glyph] / fwidth; @@ -465,8 +394,6 @@ public class PFont implements PConstants { float x2 = x1 + bwidth * parent.textSize; float y2 = y1 + high * parent.textSize; - //parent.rectImpl(x1, y1, x2, y2); - boolean savedTint = parent.tint; int savedTintColor = parent.tintColor; float savedTintR = parent.tintR; @@ -495,43 +422,7 @@ public class PFont implements PConstants { parent.tintA = savedTintA; parent.tintAlpha = savedTintAlpha; - /* - // this code was moved here (instead of using parent.image) - // because now images use tint() for their coloring, which - // internally is kind of a hack because it temporarily sets - // the fill color to the tint values when drawing text. - // rather than doubling up the hack with this hack, the code - // is just included here instead. - - //int savedTextureMode = parent.textureMode; - boolean savedStroke = parent.stroke; - - //parent.textureMode = IMAGE_SPACE; - //parent.drawing_text = true; - parent.stroke = false; - - //System.out.println(x1 + " " + y1 + " " + x2 + " " + y2); - - parent.beginShape(QUADS); - parent.texture(images[glyph]); - parent.vertex(x1, y1, z, 0, 0); - parent.vertex(x1, y2, z, 0, height[glyph]); - parent.vertex(x2, y2, z, width[glyph], height[glyph]); - parent.vertex(x2, y1, z, width[glyph], 0); - //parent.vertex(x1, y1, z); - //parent.vertex(x1, y2, z); - //parent.vertex(x2, y2, z); - //parent.vertex(x2, y1, z); - parent.endShape(); - - //parent.textureMode = savedTextureMode; - //parent.drawing_text = false; - parent.stroke = savedStroke; - */ - - } else { // SCREEN_SPACE - //parent.loadPixels(); - + } else { // textMode SCREEN int xx = (int) x + leftExtent[glyph];; int yy = (int) y - topExtent[glyph]; @@ -546,17 +437,14 @@ public class PFont implements PConstants { if (xx < 0) { x0 -= xx; w0 += xx; - //System.out.println("x " + xx + " " + x0 + " " + w0); xx = 0; } if (yy < 0) { y0 -= yy; h0 += yy; - //System.out.println("y " + yy + " " + y0 + " " + h0); yy = 0; } if (xx + w0 > parent.width) { - //System.out.println("wide " + x0 + " " + w0); w0 -= ((xx + w0) - parent.width); } if (yy + h0 > parent.height) { @@ -585,7 +473,6 @@ public class PFont implements PConstants { (( a1 * fb + a2 * ( p2 & 0xff)) >> 8)); } } - //parent.updatePixels(); } } @@ -621,20 +508,16 @@ public class PFont implements PConstants { protected void textLine(int start, int stop, float x, float y, float z, PGraphics parent) { - //float startX = x; - //int index = 0; - //char previous = 0; - - if (parent.textMode == ALIGN_CENTER) { + if (parent.textAlign == CENTER) { x -= parent.textSize * calcWidth(textBuffer, start, stop) / 2f; - } else if (parent.textMode == ALIGN_RIGHT) { + } else if (parent.textAlign == RIGHT) { x -= parent.textSize * calcWidth(textBuffer, start, stop); } for (int index = start; index < stop; index++) { textImpl(textBuffer[index], x, y, z, parent); - x += parent.textSize * width(textBuffer[index]); + x += parent.textSize *width(textBuffer[index]); } } @@ -652,23 +535,22 @@ public class PFont implements PConstants { * Draw text in a box that is constrained to a particular size. * The parent PApplet will have converted the coords based on * the current rectMode(). - * + *
* Note that the x,y coords of the start of the box * will align with the *ascent* of the text, not the baseline, * as is the case for the other text() functions. */ public void text(String str, float boxX1, float boxY1, float boxX2, float boxY2, float boxZ, PGraphics parent) { - float spaceWidth = width(' '); + float spaceWidth = width(' ') * parent.textSize; float runningX = boxX1; float currentY = boxY1; float boxWidth = boxX2 - boxX1; - //float right = x + w; float lineX = boxX1; - if (parent.textMode == ALIGN_CENTER) { + if (parent.textAlign == CENTER) { lineX = lineX + boxWidth/2f; - } else if (parent.textMode == ALIGN_RIGHT) { + } else if (parent.textAlign == RIGHT) { lineX = boxX2; } @@ -688,8 +570,7 @@ public class PFont implements PConstants { int lineStart = 0; int index = 0; while (index < length) { - if ((textBuffer[index] == ' ') || - (index == length-1)) { + if ((textBuffer[index] == ' ') || (index == length-1)) { // boundary of a word float wordWidth = parent.textSize * calcWidth(textBuffer, wordStart, index); @@ -752,10 +633,7 @@ public class PFont implements PConstants { } index++; } - if ((lineStart < length) && - (lineStart != index)) { // if line is not empty - //System.out.println("line not empty " + - // new String(textBuffer, lineStart, index)); + if ((lineStart < length) && (lineStart != index)) { textLine(lineStart, index, lineX, currentY, boxZ, parent); } } @@ -825,8 +703,8 @@ public class PFont implements PConstants { * Create a new .vlw font on the fly. See documentation with * the later version of this constructor. */ - public PFont(String name, int size) { - this(new Font(name, Font.PLAIN, size), false, true); + public PFont(String name, int fontsize) { + this(new Font(name, Font.PLAIN, fontsize), false, true); } @@ -834,8 +712,8 @@ public class PFont implements PConstants { * Create a new .vlw font on the fly. See documentation with * the later version of this constructor. */ - public PFont(String name, int size, boolean smooth) { - this(new Font(name, Font.PLAIN, size), false, smooth); + public PFont(String name, int fontsize, boolean smooth) { + this(new Font(name, Font.PLAIN, fontsize), false, smooth); } @@ -843,16 +721,21 @@ public class PFont implements PConstants { * Use reflection to create a new .vlw font on the fly. * This only works with Java 1.3 and higher. * - * @param Font the font object to create from + * @param font the font object to create from * @param all true to include all available characters in the font * @param smooth true to enable smoothing/anti-aliasing */ public PFont(Font font, boolean all, boolean smooth) { + if (PApplet.JDK_VERSION < 1.3) { + throw new RuntimeException("Can only create fonts with " + + "Java 1.3 or higher"); + } + try { this.charCount = all ? 65536 : charset.length; - this.mbox = font.getSize(); + this.size = font.getSize(); - fwidth = fheight = mbox; + fwidth = fheight = size; PImage bitmaps[] = new PImage[charCount]; @@ -867,7 +750,7 @@ public class PFont implements PConstants { ascii = new int[128]; for (int i = 0; i < 128; i++) ascii[i] = -1; - int mbox3 = mbox * 3; + int mbox3 = size * 3; /* BufferedImage playground = @@ -982,7 +865,7 @@ public class PFont implements PConstants { g.setColor(Color.white); g.fillRect(0, 0, mbox3, mbox3); g.setColor(Color.black); - g.drawString(String.valueOf(c), mbox, mbox * 2); + g.drawString(String.valueOf(c), size, size * 2); // grabs copy of the current data.. so no updates (do each time) /* @@ -1045,11 +928,11 @@ public class PFont implements PConstants { if (c < 128) ascii[c] = index; // offset from vertical location of baseline - // of where the char was drawn (mbox*2) - topExtent[index] = mbox*2 - minY; + // of where the char was drawn (size*2) + topExtent[index] = size*2 - minY; // offset from left of where coord was drawn - leftExtent[index] = minX - mbox; + leftExtent[index] = minX - size; if (c == 'd') { ascent = topExtent[index]; @@ -1112,7 +995,7 @@ public class PFont implements PConstants { } catch (Exception e) { // catch-all for reflection stuff e.printStackTrace(); - return; + throw new RuntimeException(e.getMessage()); } } } diff --git a/core/PGraphics.java b/core/PGraphics.java index 2ffc1dfbd..23845af9c 100644 --- a/core/PGraphics.java +++ b/core/PGraphics.java @@ -81,37 +81,51 @@ public class PGraphics extends PImage implements PConstants { /** True if colorMode(RGB, 255) */ boolean colorRgb255; - /** True if tint() is enabled, read-only */ + // ........................................................ + + /** true if tint() is enabled (read-only) */ public boolean tint; - /** Tint that was last set, read-only */ + /** tint that was last set (read-only) */ public int tintColor; - /** True if the tint has an alpha value */ boolean tintAlpha; + float tintR, tintG, tintB, tintA; + int tintRi, tintGi, tintBi, tintAi; - public float tintR, tintG, tintB, tintA; - public int tintRi, tintGi, tintBi, tintAi; + // ........................................................ - // fill color + /** true if fill() is enabled, (read-only) */ public boolean fill; - public int fillColor; - public boolean fillAlpha; - public float fillR, fillG, fillB, fillA; - public int fillRi, fillGi, fillBi, fillAi; - // stroke color + /** fill that was last set (read-only) */ + public int fillColor; + + boolean fillAlpha; + float fillR, fillG, fillB, fillA; + int fillRi, fillGi, fillBi, fillAi; + + // ........................................................ + + /** true if stroke() is enabled, (read-only) */ public boolean stroke; - boolean strokeAlpha; - public float strokeR, strokeG, strokeB, strokeA; - public int strokeRi, strokeGi, strokeBi, strokeAi; + + /** stroke that was last set (read-only) */ public int strokeColor; - //public boolean background; - /** Last background color that was set */ + boolean strokeAlpha; + float strokeR, strokeG, strokeB, strokeA; + int strokeRi, strokeGi, strokeBi, strokeAi; + + // ........................................................ + + /** Last background color that was set, zero if an image */ public int backgroundColor; - public float backgroundR, backgroundG, backgroundB; - public int backgroundRi, backgroundGi, backgroundBi; + + float backgroundR, backgroundG, backgroundB; + int backgroundRi, backgroundGi, backgroundBi; + + // ........................................................ // internal color for setting/calculating float calcR, calcG, calcB, calcA; @@ -124,24 +138,15 @@ public class PGraphics extends PImage implements PConstants { /** Result of the last conversion to HSB */ float cacheHsbValue[] = new float[3]; // inits to zero - /** True if depth() is enabled, read-only */ - //public boolean depth; + // ........................................................ - /** - * Internal values for enabling/disabling 2D or 0D optimizations. - * These are normally turned on, but will be shut off for OpenGL. - * Also, users may want to disable them if they're causing trouble. - */ - //public boolean optimize0 = true; - //public boolean optimize2 = true; - - /** Set by strokeWeight(), read-only */ + /** Last value set by strokeWeight() (read-only) */ public float strokeWeight; - /** Set by strokeJoin(), read-only */ + /** Set by strokeJoin() (read-only) */ public int strokeJoin; - /** Set by strokeCap(), read-only */ + /** Set by strokeCap() (read-only) */ public int strokeCap; // ........................................................ @@ -220,8 +225,6 @@ public class PGraphics extends PImage implements PConstants { static final int DEFAULT_SPLINE_VERTICES = 128; protected float splineVertices[][]; protected int splineVertexCount; - //boolean spline_vertices_flat; - // ........................................................ @@ -246,20 +249,27 @@ public class PGraphics extends PImage implements PConstants { } } - // ........................................................ - + /** The current rect mode (read-only) */ public int rectMode; - public int ellipseMode; - //public int arcMode; - //int text_mode; - //int text_space; + /** The current ellipse mode (read-only) */ + public int ellipseMode; + + /** The current text font (read-only) */ public PFont textFont; - public int textMode; // alignment - public int textSpace; + + /** The current text align (read-only) */ + public int textAlign; + + /** The current text mode (read-only) */ + public int textMode; + + /** The current text size (read-only) */ public float textSize; + + /** The current text leading (read-only) */ public float textLeading; @@ -402,10 +412,8 @@ public class PGraphics extends PImage implements PConstants { textFont = null; textSize = 12; textLeading = 14; - textMode = ALIGN_LEFT; - textSpace = OBJECT_SPACE; - //text_mode = ALIGN_LEFT; - //text_space = OBJECT_SPACE; + textAlign = LEFT; + textMode = OBJECT; } @@ -1461,19 +1469,24 @@ public class PGraphics extends PImage implements PConstants { // TEXT/FONTS + /** + * Useful function to set the font and size at the same time. + */ public void textFont(PFont which, float size) { textFont(which); textSize(size); } + /** + * Sets the current font. The font's size will be the "natural" + * size of this font (the size that was set when using "Create Font"). + * The leading will also be reset. + */ public void textFont(PFont which) { if (which != null) { textFont = which; - - if (textSpace == SCREEN_SPACE) { - textSize(textFont.mbox); - } + textSize(textFont.size); } else { throw new RuntimeException("a null PFont was passed to textFont()"); @@ -1486,10 +1499,10 @@ public class PGraphics extends PImage implements PConstants { */ public void textSize(float size) { if (textFont != null) { - if ((textSpace == SCREEN_SPACE) && - (size != textFont.mbox)) { + if ((textMode == SCREEN) && + (size != textFont.size)) { throw new RuntimeException("can't use textSize() with " + - "textSpace(SCREEN_SPACE)"); + "textMode(SCREEN)"); } textSize = size; textLeading = textSize * @@ -1502,12 +1515,9 @@ public class PGraphics extends PImage implements PConstants { } - //protected void textLeadingReset() { - //textLeading = textSize * - // ((textFont.ascent() + textFont.descent()) * 1.275f); - //} - - + /** + * Set the text leading to a specific value. + */ public void textLeading(float leading) { textLeading = leading; /* @@ -1521,31 +1531,23 @@ public class PGraphics extends PImage implements PConstants { } - public void textMode(int mode) { - textMode = mode; - /* - if (textFont != null) { - textFont.align(mode); - - } else { - throw new RuntimeException("use textFont() before textMode()"); - } - */ + public void textAlign(int align) { + textAlign = align; } - public void textSpace(int space) { + public void textMode(int space) { if (textFont != null) { - textSpace = space; + textMode = space; // reset the font to its natural size // (helps with width calculations and all that) - if (textSpace == SCREEN_SPACE) { - textSize(textFont.mbox); + if (textMode == SCREEN) { + textSize(textFont.size); } } else { - throw new RuntimeException("use textFont() before textSpace()"); + throw new RuntimeException("use textFont() before textMode()"); } } @@ -1596,9 +1598,9 @@ public class PGraphics extends PImage implements PConstants { public void text(char c, float x, float y) { if (textFont != null) { - if (textSpace == SCREEN_SPACE) loadPixels(); + if (textMode == SCREEN) loadPixels(); textFont.text(c, x, y, this); - if (textSpace == SCREEN_SPACE) updatePixels(); + if (textMode == SCREEN) updatePixels(); } else { throw new RuntimeException("use textFont() before text()"); @@ -1612,17 +1614,17 @@ public class PGraphics extends PImage implements PConstants { * ignored. */ public void text(char c, float x, float y, float z) { - if ((z != 0) && (textSpace == SCREEN_SPACE)) { - String msg = "textSpace(SCREEN_SPACE) cannot have a z coordinate"; + if ((z != 0) && (textMode == SCREEN)) { + String msg = "textMode(SCREEN) cannot have a z coordinate"; throw new RuntimeException(msg); } // this just has to pass through.. if z is not zero when // drawing to non-depth(), the PFont will have to throw an error. if (textFont != null) { - if (textSpace == SCREEN_SPACE) loadPixels(); + if (textMode == SCREEN) loadPixels(); textFont.text(c, x, y, z, this); - if (textSpace == SCREEN_SPACE) updatePixels(); + if (textMode == SCREEN) updatePixels(); } else { throw new RuntimeException("use textFont() before text()"); @@ -1634,9 +1636,9 @@ public class PGraphics extends PImage implements PConstants { public void text(String s, float x, float y) { if (textFont != null) { - if (textSpace == SCREEN_SPACE) loadPixels(); + if (textMode == SCREEN) loadPixels(); textFont.text(s, x, y, this); - if (textSpace == SCREEN_SPACE) updatePixels(); + if (textMode == SCREEN) updatePixels(); } else { throw new RuntimeException("use textFont() before text()"); } @@ -1644,17 +1646,17 @@ public class PGraphics extends PImage implements PConstants { public void text(String s, float x, float y, float z) { - if ((z != 0) && (textSpace == SCREEN_SPACE)) { - String msg = "textSpace(SCREEN_SPACE) cannot have a z coordinate"; + if ((z != 0) && (textMode == SCREEN)) { + String msg = "textMode(SCREEN) cannot have a z coordinate"; throw new RuntimeException(msg); } // this just has to pass through.. if z is not zero when // drawing to non-depth(), the PFont will have to throw an error. if (textFont != null) { - if (textSpace == SCREEN_SPACE) loadPixels(); + if (textMode == SCREEN) loadPixels(); textFont.text(s, x, y, z, this); - if (textSpace == SCREEN_SPACE) updatePixels(); + if (textMode == SCREEN) updatePixels(); } else { throw new RuntimeException("use textFont() before text()"); @@ -1706,9 +1708,9 @@ public class PGraphics extends PImage implements PConstants { if (y2 < y1) { float temp = y1; y1 = y2; y2 = temp; } - if (textSpace == SCREEN_SPACE) loadPixels(); + if (textMode == SCREEN) loadPixels(); textFont.text(s, x1, y1, x2, y2, this); - if (textSpace == SCREEN_SPACE) updatePixels(); + if (textMode == SCREEN) updatePixels(); } else { throw new RuntimeException("use textFont() before text()"); @@ -2512,6 +2514,9 @@ public class PGraphics extends PImage implements PConstants { throw new RuntimeException("background images should be RGB or ARGB"); } + // zero this out since it's an image + backgroundColor = 0; + // blit image to the screen System.arraycopy(image.pixels, 0, pixels, 0, pixels.length); } @@ -2696,77 +2701,6 @@ public class PGraphics extends PImage implements PConstants { } - /* - public final static int _blend(int p1, int p2, int a2) { - // scale alpha by alpha of incoming pixel - a2 = (a2 * (p2 >>> 24)) >> 8; - - int a1 = a2 ^ 0xff; - int r = (a1 * ((p1 >> 16) & 0xff) + a2 * ((p2 >> 16) & 0xff)) & 0xff00; - int g = (a1 * ((p1 >> 8) & 0xff) + a2 * ((p2 >> 8) & 0xff)) & 0xff00; - int b = (a1 * ( p1 & 0xff) + a2 * ( p2 & 0xff)) >> 8; - - return 0xff000000 | (r << 8) | g | b; - } - */ - - - ////////////////////////////////////////////////////////////// - - // MATH - - // these are *only* the functions used internally - // the real math functions are inside PApplet - - // these have been made private so as not to conflict - // with the versions found in PApplet when fxn importing happens - // also might be faster that way. hmm. - - - //private final float mag(float a, float b) { - //return (float)Math.sqrt(a*a + b*b); - //} - - //private final float mag(float a, float b, float c) { - //return (float)Math.sqrt(a*a + b*b + c*c); - //} - - //private final float max(float a, float b) { - //return (a > b) ? a : b; - //} - - //private final float max(float a, float b, float c) { - //return Math.max(a, Math.max(b, c)); - //} - - //private final float sq(float a) { - //return a*a; - //} - - //private final float sqrt(float a) { - //return (float)Math.sqrt(a); - //} - - //private final float abs(float a) { - //return (a < 0) ? -a : a; - //} - - //private final float sin(float angle) { - //if (angleMode == DEGREES) angle *= DEG_TO_RAD; - //return (float)Math.sin(angle); - //} - - //private final float cos(float angle) { - //if (angleMode == DEGREES) angle *= DEG_TO_RAD; - //return (float)Math.cos(angle); - //} - - //private final float tan(float angle) { - //if (angleMode == DEGREES) angle *= DEG_TO_RAD; - //return (float)Math.tan(angle); - //} - - ////////////////////////////////////////////////////////////// @@ -2789,26 +2723,26 @@ public class PGraphics extends PImage implements PConstants { } } - //class Shape extends Path { - //} - ////////////////////////////////////////////////////////////// /** - * Cannot be used on PGraphics, use get(0, 0, width, height) first, - * and then mask() the image that's returned. The problem is that the - * results are too complicated across different implementations, - * and this implementation represents only a minimal speedup versus - * the amount of confusion it creates. + * Use with caution on PGraphics. This should not be used with + * the base PGraphics that's tied to a PApplet, but it can be used + * with user-created PGraphics objects that are drawn to the screen. */ public void mask(int alpha[]) { // ignore - throw new RuntimeException("mask() cannot be used on PGraphics"); + super.mask(alpha); } + /** + * Use with caution on PGraphics. This should not be used with + * the base PGraphics that's tied to a PApplet, but it can be used + * with user-created PGraphics objects that are drawn to the screen. + */ public void mask(PImage alpha) { // ignore - throw new RuntimeException("mask() cannot be used on PGraphics"); + super.mask(alpha); } } diff --git a/core/PGraphics2.java b/core/PGraphics2.java index a347c4a02..f25bff300 100644 --- a/core/PGraphics2.java +++ b/core/PGraphics2.java @@ -998,10 +998,11 @@ public class PGraphics2 extends PGraphics { // blit image to the screen //g2.drawImage((BufferedImage) image.cache, 0, 0, null); //graphics.drawImage((BufferedImage) image.cache, 0, 0, null); - push(); - resetMatrix(); - imageImpl(image, 0, 0, width, height, 0, 0, width, height); - pop(); + set(0, 0, image); + //push(); + //resetMatrix(); + //imageImpl(image, 0, 0, width, height, 0, 0, width, height); + //pop(); } @@ -1064,6 +1065,7 @@ public class PGraphics2 extends PGraphics { public int get(int x, int y) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0; return ((BufferedImage) image).getRGB(x, y); } @@ -1115,10 +1117,22 @@ public class PGraphics2 extends PGraphics { public void set(int x, int y, int argb) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return; ((BufferedImage) image).setRGB(x, y, argb); } + public void set(int dx, int dy, PImage src) { + push(); + imageImpl(src, 0, 0, width, height, 0, 0, width, height); + resetMatrix(); + pop(); + //loadPixels(); + //super.set(dx, dy, src); + //updatePixels(); + } + + ////////////////////////////////////////////////////////////// @@ -1139,13 +1153,6 @@ public class PGraphics2 extends PGraphics { ////////////////////////////////////////////////////////////// - public void copy(PImage src, int dx, int dy) { - loadPixels(); - super.copy(src, dx, dy); - updatePixels(); - } - - public void copy(PImage src, int sx1, int sy1, int sx2, int sy2, int dx1, int dy1, int dx2, int dy2) { loadPixels(); diff --git a/core/PGraphics3.java b/core/PGraphics3.java index 543adba68..929edc1f0 100644 --- a/core/PGraphics3.java +++ b/core/PGraphics3.java @@ -128,8 +128,8 @@ public class PGraphics3 extends PGraphics { // ........................................................ /** - * IMAGE_SPACE or NORMAL_SPACE, though this should probably - * be called textureSpace().. hrm + * IMAGE or NORMALIZED, though this should probably + * be called textureSpace(). */ public int textureMode; @@ -311,7 +311,7 @@ public class PGraphics3 extends PGraphics { //System.out.println("PGraphics3.defaults()"); // easiest for beginners - textureMode(IMAGE_SPACE); + textureMode(IMAGE); // better to leave this turned off by default noLights(); @@ -500,7 +500,7 @@ public class PGraphics3 extends PGraphics { // "after beginShape() and before vertex()"); //return; } - if (textureMode == IMAGE_SPACE) { + if (textureMode == IMAGE) { u /= (float) textureImage.width; v /= (float) textureImage.height; } @@ -1949,7 +1949,7 @@ public class PGraphics3 extends PGraphics { stroke = false; fill = true; - textureMode = IMAGE_SPACE; + textureMode = IMAGE; float savedFillR = fillR; float savedFillG = fillG; diff --git a/core/PImage.java b/core/PImage.java index 195c9ca07..d9770f88b 100644 --- a/core/PImage.java +++ b/core/PImage.java @@ -34,6 +34,8 @@ import java.io.*; /** + * image class developed by toxi and fry. + * *
[fry 0407XX]
* - get() on RGB images sets the high bits to opaque
* - modification of naming for functions
@@ -110,6 +112,12 @@ public class PImage implements PConstants, Cloneable {
static final int PREC_ALPHA_SHIFT = 24-PRECISIONB;
static final int PREC_RED_SHIFT = 16-PRECISIONB;
+ // internal kernel stuff for the gaussian blur filter
+ int blurRadius;
+ int blurKernelSize;
+ int[] blurKernel;
+ int[][] blurMult;
+
//////////////////////////////////////////////////////////////
@@ -361,15 +369,37 @@ public class PImage implements PConstants, Cloneable {
/**
- * Returns a "color" type (a packed 32 bit int with the color.
+ * Returns an ARGB "color" type (a packed 32 bit int with the color.
+ * If the coordinate is outside the image, zero is returned
+ * (black, but completely transparent).
+ *
* If the image is in RGB format (i.e. on a PVideo object),
- * the value will get its high bits set, because of the likely
- * case that they haven't been already.
+ * the value will get its high bits set, just to avoid cases where
+ * they haven't been set already.
+ *
+ * If the image is in ALPHA format, this returns a white color
+ * that has its alpha value set.
+ *
+ * This function is included primarily for beginners. It is quite
+ * slow because it has to check to see if the x, y that was provided
+ * is inside the bounds, and then has to check to see what image
+ * type it is. If you want things to be more efficient, access the
+ * pixels[] array directly.
*/
public int get(int x, int y) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0;
- return (format == RGB) ?
- (pixels[y*width + x] | 0xff000000) : pixels[y*width + x];
+
+ switch (format) {
+ case RGB:
+ return pixels[y*width + x] | 0xff000000;
+
+ case ARGB:
+ return pixels[y*width + x];
+
+ case ALPHA:
+ return (pixels[y*width + x] << 24) | 0xffffff;
+ }
+ return 0;
}
@@ -423,12 +453,105 @@ public class PImage implements PConstants, Cloneable {
}
+ /**
+ * Silently ignores if the coordinate is outside the image.
+ */
public void set(int x, int y, int c) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return;
pixels[y*width + x] = c;
}
+ /*
+ // properly debugged version from copy()
+ // in case the below one doesn't work
+
+ public void set(int dx, int dy, PImage src) {
+ // source
+ int sx = 0;
+ int sy = 0;
+ int sw = src.width;
+ int sh = src.height;
+
+ // target
+ int tx = dx; // < 0 ? 0 : x;
+ int ty = dy; // < 0 ? 0 : y;
+ int tw = width;
+ int th = height;
+
+ if (tx < 0) { // say if target x were -3
+ sx -= tx; // source x -(-3) (or add 3)
+ sw += tx; // source width -3
+ tw += tx; // target width -3
+ tx = 0; // target x is zero (upper corner)
+ }
+ if (ty < 0) {
+ sy -= ty;
+ sh += ty;
+ th += ty;
+ ty = 0;
+ }
+ if (tx + tw > width) {
+ int extra = (tx + tw) - width;
+ sw -= extra;
+ tw -= extra;
+ }
+ if (ty + th > height) {
+ int extra = (ty + th) - height;
+ sh -= extra;
+ sw -= extra;
+ }
+
+ for (int row = sy; row < sy + sh; row++) {
+ System.arraycopy(src.pixels, row*src.width + sx,
+ pixels, (dy+row)*width + tx, sw);
+ }
+ }
+ */
+
+
+ public void set(int x1, int y1, PImage image) {
+ int x2 = x1 + image.width;
+ int y2 = y1 + image.height;
+
+ // off to the top and/or left
+ if ((x2 < 0) || (y2 < 0)) return;
+
+ int ix1 = 0;
+ int iy1 = 0;
+ int ix2 = image.width;
+ int iy2 = image.height;
+
+ if (x1 < 0) { // off left edge
+ ix1 += -x1;
+ x1 = 0;
+ }
+ if (y1 < 0) { // off top edge
+ iy1 += - y1;
+ y1 = 0;
+ }
+ if (x2 >= width) { // off right edge
+ ix2 -= x2 - width;
+ x2 = width;
+ }
+ if (y2 >= height) { // off bottom edge
+ iy2 -= y2 - height;
+ y2 = height;
+ }
+
+ int src = iy1*image.width + ix1;
+ int dest = y1*width + x1;
+ int len = x2 - x1;
+
+ for (int y = y1; y < y2; y++) {
+ //for (int x = x1; x < x2; x++) {
+ System.arraycopy(image.pixels, src, pixels, dest, len);
+ src += len;
+ dest += len;
+ }
+ }
+
+
//////////////////////////////////////////////////////////////
@@ -436,39 +559,28 @@ public class PImage implements PConstants, Cloneable {
/**
- * Set alpha channel for an image.
+ * Set alpha channel for an image. Black colors in the source
+ * image will make the destination image completely transparent,
+ * and white will make things fully opaque. Gray values will
+ * be in-between steps.
+ *
+ * Strictly speaking the "blue" value from the source image is
+ * used as the alpha color. For a fully grayscale image, this
+ * is correct, but for a color image it's not 100% accurate.
+ * For a more accurate conversion, first use filter(GRAY)
+ * which will make the image into a "correct" grayscake by
+ * performing a proper luminance-based conversion.
*/
public void mask(int alpha[]) {
- mask(this, alpha);
- }
-
-
- /**
- * Set alpha channel for an image.
- */
- static public void mask(PImage image, int alpha[]) {
// don't execute if mask image is different size
- if (alpha.length != image.pixels.length) {
+ if (alpha.length != pixels.length) {
throw new RuntimeException("The PImage used with mask() must be " +
"the same size as the applet.");
}
- for (int i = 0; i < image.pixels.length; i++) {
- image.pixels[i] =
- ((alpha[i] & 0xff) << 24) |
- (image.pixels[i] & 0xffffff);
+ for (int i = 0; i < pixels.length; i++) {
+ pixels[i] = ((alpha[i] & 0xff) << 24) | (pixels[i] & 0xffffff);
}
- /*
- if (highbits) { // grab alpha from the high 8 bits (ARGB style)
- for (int i = 0; i < pixels.length; i++) {
- pixels[i] = pixels[i] & 0xffffff | (alpha[i] & 0xff000000);
- }
- } else { // alpha is in the low bits (ALPHA style)
- for (int i = 0; i < pixels.length; i++) {
- pixels[i] = pixels[i] & 0xffffff | ((alpha[i] & 0xff) << 24);
- }
- }
- */
- image.format = ARGB;
+ format = ARGB;
}
@@ -480,20 +592,14 @@ public class PImage implements PConstants, Cloneable {
}
- static public void mask(PImage image, PImage alpha) {
- mask(image, alpha.pixels);
- }
-
-
/**
* Method to apply a variety of basic filters to this image.
*
*
*