boolean delayingIt = true;
int amountToShow = 0;
String enterMsg = "ENTER TEXT HERE";
String myText = "\"THE TIME HAS COME,\"\n    THE WALRUS SAID\n        \"TO SPEAK OF\n             MANIC  THINGS,\n OF SHOTS AND SHOUTS,\n  AND SEALING DOOMS\n     OF COMMONERS\n              AND KINGS.\"\n                                 --THURBER";
String imgName = "bush.jpg";
BFont font;// = null;loadFont("Futura-Bold.vlw.gz");

void setup(){
  size(400,250);
  font = loadFont("Futura-Bold.vlw.gz");
  textFont(font,44);
}

void loop(){
  if(delayingIt){amountToShow = endOfNextWord(amountToShow);}
  doImage();
}

void keyPressed(){
  int k = key;
  //println(k);
  if(myText.equals(enterMsg)){
    myText = "";
  }

  if(k == 8){
    if(myText.length() > 0){
      myText = myText.substring(0,myText.length()-1);
    }
  } else {
    myText += char(k);
  }

}

void doImage(){
  background(255);
  fill(0);
  String s;
  if(delayingIt) {
    s = myText.substring(0,amountToShow);
  } else {
    s = myText;
  }
  //draw the text for use as mask
  smooshText(s, 0, 27, 2);
  //show image after loading it through mask
  image(loadImageWithMask(imgName),0,0);
}

void smooshText(String s, int left, int lineheight, int squishfactor){
  int currenty = lineheight;
  int currentx = left;
  for(int i = 0; i < s.length(); i++){
    if((int)s.charAt(i) == 10){
      currenty += lineheight;
      currentx = left;
    } else {
      text(s.charAt(i),currentx,currenty);
      float advwidth = font.width(s.charAt(i));
      if(s.charAt(i) == ' ') advwidth *= .75;
      currentx += advwidth - squishfactor;
    }
  }
}

BImage loadImageWithMask(String filename){
  BImage img = loadImage(filename);
  for(int y = 0; y < img.height; y++){
    for(int x = 0; x < img.width; x++){
      int pixelOffset = x+(y * img.width);
      int colorMask = get(x,y);
      int colorImage = img.pixels[pixelOffset];
      img.pixels[pixelOffset] = color(
      getNewColor(getRed(colorImage),getRed(colorMask)),
      getNewColor(getGreen(colorImage),getGreen(colorMask)),
      getNewColor(getBlue(colorImage),getBlue(colorMask))  );
    }
  }
  return img;
}
int getNewColor(int valImage, int valMask){
  if(valMask > 250) return 255;
  return  valImage ;
}

void mousePressed(){
  myText = enterMsg;
  boolean delayingIt = false;
}

int endOfNextWord(int start){
  if(start < myText.length() - 40){
    return start +1;
  } else {
    return myText.length();
  }
//code to do one word at a time
  /*int ptr = start;
  ptr++;
  while(ptr < myText.length() && (myText.charAt(ptr) != ' ' && myText.charAt(ptr) != '\n')){
    ptr++;
  }
  while(ptr < myText.length() && (myText.charAt(ptr) == ' ' || myText.charAt(ptr) == '\n')){
    ptr++;
  }
  if(ptr > myText.length()) ptr = myText.length();

  return ptr;*/
}

int getAlpha(color c) {
  return mask8bits(c,24);
}
int getRed(color c) {
  return mask8bits(c,16);
}
int getGreen(color c) {
  return mask8bits(c,8);
}
int getBlue(color c) {
  return mask8bits(c,0);
}
int mask8bits(int c, int bits2shift){
  int mask = 255;
  mask = mask << bits2shift;
  int val = c & mask;
  val = val >> bits2shift;
  return val;
}