diff --git a/core/api.txt b/core/api.txt index 9dcb640d2..8efff357d 100644 --- a/core/api.txt +++ b/core/api.txt @@ -349,6 +349,11 @@ style(PStyle s) protected void backgroundFromCalc() protected void backgroundImpl() + public final int color(int gray) + public final int color(int gray, int alpha) + public final int color(int rgb, float alpha) + public final int color(int x, int y, int z) + public final float alpha(int what) public final float red(int what) public final float green(int what) @@ -360,6 +365,12 @@ style(PStyle s) public int lerpColor(int c1, int c2, float amt) static public int lerpColor(int c1, int c2, float amt, int mode) + public void beginRaw(PGraphics rawGraphics) + public void endRaw() + + static public void showWarning(String msg) + static public void showException(String msg) + public boolean displayable() public boolean dimensional() // better name for this? diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 694f0faa9..bdb01d5ee 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3764,230 +3764,6 @@ public class PGraphics extends PImage implements PConstants { - ////////////////////////////////////////////////////////////// - - // COLOR MODE - - - public void colorMode(int mode) { - colorMode(mode, colorModeX, colorModeY, colorModeZ, colorModeA); - } - - - public void colorMode(int mode, float max) { - colorMode(mode, max, max, max, max); - } - - - /** - * Set the colorMode and the maximum values for (r, g, b) - * or (h, s, b). - *

- * Note that this doesn't set the maximum for the alpha value, - * which might be confusing if for instance you switched to - *

colorMode(HSB, 360, 100, 100);
- * because the alpha values were still between 0 and 255. - */ - public void colorMode(int mode, float maxX, float maxY, float maxZ) { - colorMode(mode, maxX, maxY, maxZ, colorModeA); - } - - - public void colorMode(int mode, - float maxX, float maxY, float maxZ, float maxA) { - colorMode = mode; - - colorModeX = maxX; // still needs to be set for hsb - colorModeY = maxY; - colorModeZ = maxZ; - colorModeA = maxA; - - // if color max values are all 1, then no need to scale - colorModeScale = - ((maxA != 1) || (maxX != maxY) || (maxY != maxZ) || (maxZ != maxA)); - - // if color is rgb/0..255 this will make it easier for the - // red() green() etc functions - colorModeDefault = (colorMode == RGB) && - (colorModeA == 255) && (colorModeX == 255) && - (colorModeY == 255) && (colorModeZ == 255); - } - - - - ////////////////////////////////////////////////////////////// - - // COLOR CALCULATIONS - - // Given input values for coloring, these functions will fill the calcXxxx - // variables with values that have been properly filtered through the - // current colorMode settings. - - // Renderers that need to subclass any drawing properties such as fill or - // stroke will usally want to override methods like fillFromCalc (or the - // same for stroke, ambient, etc.) That way the color calcuations are - // covered by this based PGraphics class, leaving only a single function - // to override/implement in the subclass. - - - /** - * Set the fill to either a grayscale value or an ARGB int. - *

- * The problem with this code is that it has to detect between these two - * situations automatically. This is done by checking to see if the high bits - * (the alpha for 0xAA000000) is set, and if not, whether the color value - * that follows is less than colorModeX (first param passed to colorMode). - *

- * This auto-detect would break in the following situation: - *

size(256, 256);
-   * for (int i = 0; i < 256; i++) {
-   *   color c = color(0, 0, 0, i);
-   *   stroke(c);
-   *   line(i, 0, i, 256);
-   * }
- * ...on the first time through the loop, where (i == 0), since the color - * itself is zero (black) then it would appear indistinguishable from code - * that reads "fill(0)". The solution is to use the four parameter versions - * of stroke or fill to more directly specify the desired result. - */ - protected void colorCalc(int rgb) { - if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { - colorCalc((float) rgb); - - } else { - colorCalcARGB(rgb, colorModeA); - } - } - - - protected void colorCalc(int rgb, float alpha) { - if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above - colorCalc((float) rgb, alpha); - - } else { - colorCalcARGB(rgb, alpha); - } - } - - - protected void colorCalc(float gray) { - colorCalc(gray, colorModeA); - } - - - protected void colorCalc(float gray, float alpha) { - if (gray > colorModeX) gray = colorModeX; - if (alpha > colorModeA) alpha = colorModeA; - - if (gray < 0) gray = 0; - if (alpha < 0) alpha = 0; - - calcR = colorModeScale ? (gray / colorModeX) : gray; - calcG = calcR; - calcB = calcR; - calcA = colorModeScale ? (alpha / colorModeA) : alpha; - - calcRi = (int)(calcR*255); calcGi = (int)(calcG*255); - calcBi = (int)(calcB*255); calcAi = (int)(calcA*255); - calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; - calcAlpha = (calcAi != 255); - } - - - protected void colorCalc(float x, float y, float z) { - colorCalc(x, y, z, colorModeA); - } - - - protected void colorCalc(float x, float y, float z, float a) { - if (x > colorModeX) x = colorModeX; - if (y > colorModeY) y = colorModeY; - if (z > colorModeZ) z = colorModeZ; - if (a > colorModeA) a = colorModeA; - - if (x < 0) x = 0; - if (y < 0) y = 0; - if (z < 0) z = 0; - if (a < 0) a = 0; - - switch (colorMode) { - case RGB: - if (colorModeScale) { - calcR = x / colorModeX; - calcG = y / colorModeY; - calcB = z / colorModeZ; - calcA = a / colorModeA; - } else { - calcR = x; calcG = y; calcB = z; calcA = a; - } - break; - - case HSB: - x /= colorModeX; // h - y /= colorModeY; // s - z /= colorModeZ; // b - - calcA = colorModeScale ? (a/colorModeA) : a; - - if (y == 0) { // saturation == 0 - calcR = calcG = calcB = z; - - } else { - float which = (x - (int)x) * 6.0f; - float f = which - (int)which; - float p = z * (1.0f - y); - float q = z * (1.0f - y * f); - float t = z * (1.0f - (y * (1.0f - f))); - - switch ((int)which) { - case 0: calcR = z; calcG = t; calcB = p; break; - case 1: calcR = q; calcG = z; calcB = p; break; - case 2: calcR = p; calcG = z; calcB = t; break; - case 3: calcR = p; calcG = q; calcB = z; break; - case 4: calcR = t; calcG = p; calcB = z; break; - case 5: calcR = z; calcG = p; calcB = q; break; - } - } - break; - } - calcRi = (int)(255*calcR); calcGi = (int)(255*calcG); - calcBi = (int)(255*calcB); calcAi = (int)(255*calcA); - calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; - calcAlpha = (calcAi != 255); - } - - - /** - * Unpacks AARRGGBB color for direct use with colorCalc. - *

- * Handled here with its own function since this is indepenent - * of the color mode. - *

- * Strangely the old version of this code ignored the alpha - * value. not sure if that was a bug or what. - *

- * Note, no need for a bounds check since it's a 32 bit number. - */ - protected void colorCalcARGB(int argb, float alpha) { - if (alpha == colorModeA) { - calcAi = (argb >> 24) & 0xff; - calcColor = argb; - } else { - calcAi = (int) (((argb >> 24) & 0xff) * (alpha / colorModeA)); - calcColor = (calcAi << 24) | (argb & 0xFFFFFF); - } - calcRi = (argb >> 16) & 0xff; - calcGi = (argb >> 8) & 0xff; - calcBi = argb & 0xff; - calcA = (float)calcAi / 255.0f; - calcR = (float)calcRi / 255.0f; - calcG = (float)calcGi / 255.0f; - calcB = (float)calcBi / 255.0f; - calcAlpha = (calcAi != 255); - } - - - ////////////////////////////////////////////////////////////// // STROKE CAP/JOIN/WEIGHT @@ -4632,11 +4408,239 @@ public class PGraphics extends PImage implements PConstants { ////////////////////////////////////////////////////////////// - // COLOR MANIPULATION + // COLOR MODE - // these functions are really slow, but easy to use - // if folks are advanced enough to want something faster, - // they can write it themselves (not difficult) + + public void colorMode(int mode) { + colorMode(mode, colorModeX, colorModeY, colorModeZ, colorModeA); + } + + + public void colorMode(int mode, float max) { + colorMode(mode, max, max, max, max); + } + + + /** + * Set the colorMode and the maximum values for (r, g, b) + * or (h, s, b). + *

+ * Note that this doesn't set the maximum for the alpha value, + * which might be confusing if for instance you switched to + *

colorMode(HSB, 360, 100, 100);
+ * because the alpha values were still between 0 and 255. + */ + public void colorMode(int mode, float maxX, float maxY, float maxZ) { + colorMode(mode, maxX, maxY, maxZ, colorModeA); + } + + + public void colorMode(int mode, + float maxX, float maxY, float maxZ, float maxA) { + colorMode = mode; + + colorModeX = maxX; // still needs to be set for hsb + colorModeY = maxY; + colorModeZ = maxZ; + colorModeA = maxA; + + // if color max values are all 1, then no need to scale + colorModeScale = + ((maxA != 1) || (maxX != maxY) || (maxY != maxZ) || (maxZ != maxA)); + + // if color is rgb/0..255 this will make it easier for the + // red() green() etc functions + colorModeDefault = (colorMode == RGB) && + (colorModeA == 255) && (colorModeX == 255) && + (colorModeY == 255) && (colorModeZ == 255); + } + + + + ////////////////////////////////////////////////////////////// + + // COLOR CALCULATIONS + + // Given input values for coloring, these functions will fill the calcXxxx + // variables with values that have been properly filtered through the + // current colorMode settings. + + // Renderers that need to subclass any drawing properties such as fill or + // stroke will usally want to override methods like fillFromCalc (or the + // same for stroke, ambient, etc.) That way the color calcuations are + // covered by this based PGraphics class, leaving only a single function + // to override/implement in the subclass. + + + /** + * Set the fill to either a grayscale value or an ARGB int. + *

+ * The problem with this code is that it has to detect between these two + * situations automatically. This is done by checking to see if the high bits + * (the alpha for 0xAA000000) is set, and if not, whether the color value + * that follows is less than colorModeX (first param passed to colorMode). + *

+ * This auto-detect would break in the following situation: + *

size(256, 256);
+   * for (int i = 0; i < 256; i++) {
+   *   color c = color(0, 0, 0, i);
+   *   stroke(c);
+   *   line(i, 0, i, 256);
+   * }
+ * ...on the first time through the loop, where (i == 0), since the color + * itself is zero (black) then it would appear indistinguishable from code + * that reads "fill(0)". The solution is to use the four parameter versions + * of stroke or fill to more directly specify the desired result. + */ + protected void colorCalc(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + colorCalc((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + } + } + + + protected void colorCalc(int rgb, float alpha) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + colorCalc((float) rgb, alpha); + + } else { + colorCalcARGB(rgb, alpha); + } + } + + + protected void colorCalc(float gray) { + colorCalc(gray, colorModeA); + } + + + protected void colorCalc(float gray, float alpha) { + if (gray > colorModeX) gray = colorModeX; + if (alpha > colorModeA) alpha = colorModeA; + + if (gray < 0) gray = 0; + if (alpha < 0) alpha = 0; + + calcR = colorModeScale ? (gray / colorModeX) : gray; + calcG = calcR; + calcB = calcR; + calcA = colorModeScale ? (alpha / colorModeA) : alpha; + + calcRi = (int)(calcR*255); calcGi = (int)(calcG*255); + calcBi = (int)(calcB*255); calcAi = (int)(calcA*255); + calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; + calcAlpha = (calcAi != 255); + } + + + protected void colorCalc(float x, float y, float z) { + colorCalc(x, y, z, colorModeA); + } + + + protected void colorCalc(float x, float y, float z, float a) { + if (x > colorModeX) x = colorModeX; + if (y > colorModeY) y = colorModeY; + if (z > colorModeZ) z = colorModeZ; + if (a > colorModeA) a = colorModeA; + + if (x < 0) x = 0; + if (y < 0) y = 0; + if (z < 0) z = 0; + if (a < 0) a = 0; + + switch (colorMode) { + case RGB: + if (colorModeScale) { + calcR = x / colorModeX; + calcG = y / colorModeY; + calcB = z / colorModeZ; + calcA = a / colorModeA; + } else { + calcR = x; calcG = y; calcB = z; calcA = a; + } + break; + + case HSB: + x /= colorModeX; // h + y /= colorModeY; // s + z /= colorModeZ; // b + + calcA = colorModeScale ? (a/colorModeA) : a; + + if (y == 0) { // saturation == 0 + calcR = calcG = calcB = z; + + } else { + float which = (x - (int)x) * 6.0f; + float f = which - (int)which; + float p = z * (1.0f - y); + float q = z * (1.0f - y * f); + float t = z * (1.0f - (y * (1.0f - f))); + + switch ((int)which) { + case 0: calcR = z; calcG = t; calcB = p; break; + case 1: calcR = q; calcG = z; calcB = p; break; + case 2: calcR = p; calcG = z; calcB = t; break; + case 3: calcR = p; calcG = q; calcB = z; break; + case 4: calcR = t; calcG = p; calcB = z; break; + case 5: calcR = z; calcG = p; calcB = q; break; + } + } + break; + } + calcRi = (int)(255*calcR); calcGi = (int)(255*calcG); + calcBi = (int)(255*calcB); calcAi = (int)(255*calcA); + calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; + calcAlpha = (calcAi != 255); + } + + + /** + * Unpacks AARRGGBB color for direct use with colorCalc. + *

+ * Handled here with its own function since this is indepenent + * of the color mode. + *

+ * Strangely the old version of this code ignored the alpha + * value. not sure if that was a bug or what. + *

+ * Note, no need for a bounds check since it's a 32 bit number. + */ + protected void colorCalcARGB(int argb, float alpha) { + if (alpha == colorModeA) { + calcAi = (argb >> 24) & 0xff; + calcColor = argb; + } else { + calcAi = (int) (((argb >> 24) & 0xff) * (alpha / colorModeA)); + calcColor = (calcAi << 24) | (argb & 0xFFFFFF); + } + calcRi = (argb >> 16) & 0xff; + calcGi = (argb >> 8) & 0xff; + calcBi = argb & 0xff; + calcA = (float)calcAi / 255.0f; + calcR = (float)calcRi / 255.0f; + calcG = (float)calcGi / 255.0f; + calcB = (float)calcBi / 255.0f; + calcAlpha = (calcAi != 255); + } + + + + ////////////////////////////////////////////////////////////// + + // COLOR DATATYPE STUFFING + + // The 'color' primitive type in Processing syntax is in fact a 32-bit int. + // These functions handle stuffing color values into a 32-bit cage based + // on the current colorMode settings. + + // These functions are really slow (because they take the current colorMode + // into account), but they're easy to use. Advanced users can write their + // own bit shifting operations to setup 'color' data types. public final int color(int gray) { // ignore @@ -4654,6 +4658,7 @@ public class PGraphics extends PImage implements PConstants { return calcColor; } + public final int color(float gray) { // ignore colorCalc(gray); return calcColor; @@ -4675,6 +4680,7 @@ public class PGraphics extends PImage implements PConstants { return calcColor; } + /** * @param rgb can be packed ARGB or a gray in this case */ @@ -4687,6 +4693,7 @@ public class PGraphics extends PImage implements PConstants { return calcColor; } + public final int color(float gray, float alpha) { // ignore colorCalc(gray, alpha); return calcColor; @@ -4706,6 +4713,7 @@ public class PGraphics extends PImage implements PConstants { return calcColor; } + public final int color(float x, float y, float z) { // ignore colorCalc(x, y, z); return calcColor; @@ -4726,11 +4734,20 @@ public class PGraphics extends PImage implements PConstants { return calcColor; } + public final int color(float x, float y, float z, float a) { // ignore colorCalc(x, y, z, a); return calcColor; } + + + ////////////////////////////////////////////////////////////// + + // COLOR DATATYPE EXTRACTION + + // Vee have veys of making the colors talk. + public final float alpha(int what) { float c = (what >> 24) & 0xff; @@ -4738,18 +4755,21 @@ public class PGraphics extends PImage implements PConstants { return (c / 255.0f) * colorModeA; } + public final float red(int what) { float c = (what >> 16) & 0xff; if (colorModeDefault) return c; return (c / 255.0f) * colorModeX; } + public final float green(int what) { float c = (what >> 8) & 0xff; if (colorModeDefault) return c; return (c / 255.0f) * colorModeY; } + public final float blue(int what) { float c = (what) & 0xff; if (colorModeDefault) return c; @@ -4766,6 +4786,7 @@ public class PGraphics extends PImage implements PConstants { return cacheHsbValue[0] * colorModeX; } + public final float saturation(int what) { if (what != cacheHsbKey) { Color.RGBtoHSB((what >> 16) & 0xff, (what >> 8) & 0xff, @@ -4775,6 +4796,7 @@ public class PGraphics extends PImage implements PConstants { return cacheHsbValue[1] * colorModeY; } + public final float brightness(int what) { if (what != cacheHsbKey) { Color.RGBtoHSB((what >> 16) & 0xff, (what >> 8) & 0xff, @@ -4785,6 +4807,14 @@ public class PGraphics extends PImage implements PConstants { } + + ////////////////////////////////////////////////////////////// + + // COLOR DATATYPE INTERPOLATION + + // Against our better judgement. + + /** * Interpolate between two colors, using the current color mode. */ @@ -4864,32 +4894,12 @@ public class PGraphics extends PImage implements PConstants { return 0; } + ////////////////////////////////////////////////////////////// - - /** - * 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 - 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 - super.mask(alpha); - } - - - ////////////////////////////////////////////////////////////// - + // BEGINRAW/ENDRAW + /** * Record individual lines and triangles by echoing them to another renderer.