Using textWidth(), redo Example 17-4 (the text “mirror”) to use a non-fixed-width font with proper character spacing.

example
Example
// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Exercise 17-9: Using textWidth(), redo Example 17-4 (the text "mirror") to use a 
// non-fixed-width font with proper character spacing.


import processing.video.*;

// Size of each cell in the grid, ratio of window size to video size
int videoScale = 16;
// Number of columns and rows in our system
int cols, rows;
// Variable to hold onto capture object
Capture video;

// A String and Font
String chars = "itwasadarkandstormynightthequickbrownfoxjumpedoverthelazydog";
PFont f;

void setup() {
  size(640, 480);
  //set up columns and rows
  cols = width/videoScale;
  rows = height/videoScale;
  video = new Capture(this,cols,rows,15);

  // Load the font
  f = createFont("Arial",18,true);
}

void draw(){ 
  // Read image from the camera
  if (video.available()) {
    video.read(); 
  }
  video.loadPixels();
  //image(video,0,0,width,height);

  background(0);

  // Use a variable to count through chars in String
  int charcount = 0;

  // Begin loop for rows
  for ( int j = 0; j < rows;j++) {
    // Begin loop for columns, instead of pixel by pixel now
    // we move with a variable floating point x,  based on character width
    float x = 0;
    while (x < width) {
      // Where are we, pixel-wise for y?
      int y = j*videoScale;
      // Where are we pixel-wise for x? Convert to int, scale down, and make sure we don't go offscreen 
      int pix = constrain((int) (x / videoScale),0,cols-1);

      // Looking up the appropriate color in the pixel array
      color c = video.pixels[pix+j*video.width]; 

      // Displaying an individual character from the String
      // Instead of a rectangle
      textFont(f);
      fill(c);
      char ch = chars.charAt(charcount);
      text(ch,x,y);
      // Go on to the next character, loop back to zero at end
      charcount = (charcount + 1) % chars.length();
      // Move x according to character's widt
      x += textWidth(ch);
    }
  }

}
  • Scott02127

    Where is exercise 17-8??? I am having issues with it, and there is nothing on this site

  • Scott02127

    Go it working! Don’t know if it is correct, but here is what I did for Exercise 17-8

    PFont f;
    String message = “A long long timenIn a galaxy far far away”;
    float y = 0;

    void setup(){
      size(600,600,P3D);
      f = createFont(“Arial”, 20*4, true);
    }

    void draw(){
      background(255);
      fill(0);
      textFont(f); // Set the font
      translate(width/2,height/2+y,y); //Translate to the center
      rotateX(radians(60)); // rotate by 60 degrees
      textAlign(CENTER);
      text(message,0,0);
      y–;
    }
     

  • Anonymous

    Great job!  A slight simplification:

      translate(width/2,height/2); //Translate to the center  rotateX(radians(60)); // rotate by 60 degrees  textAlign(CENTER);  text(message,0,y);  y–;

  • http://www.jingzhoustudio.net/ JZ

    I got this mirror project (exercise 17-9) to work. Then I want to upgrade it to an object oriented sketch. It is not working the way I wanted. I would appreciate it if you could point out what went wrong. Thanks.

    import processing.video.*;Capture video;int x, y, charcount, rows, cols;int videoScale = 16;PFont f;String myMessage = “the quick brown fox jumps over the lazy dog. “;Letter letters;void setup() {  size(640, 480);  smooth();  frameRate(30);  rows = height/videoScale;  // cols = width/videoScale; // my sketch didn’t use it  video = new Capture (this, width, rows, 30);  f = createFont(“Miso”, 18, true);  textFont(f);  letters = new Letter();}void draw() {  background(70, 15, 100);  if (video.available()) video.read();  video.loadPixels();  //image(video,0,0,width,height);  // Use a variable to count through chars in String  charcount=0;  // begin loop for rows  for (int j=0; j<rows; j++) {    // begin loop for columns    for (float x=0; x<width; x++) {      color c = video.pixels[(int) x+j*video.width]; // add (int) because x is a float      y = j*videoScale;      char myChar = myMessage.charAt(charcount);      letters.display(x, y, c, myChar);            charcount = (charcount+1) % myMessage.length();            letters.moveX(x, myChar);      println(myMessage.charAt(charcount));          }  }}class Letter {  // char messageLetter;  // float x, y; // x, y show its current location  Letter() {  }  void display(float x_, float y_, color colr, char messageLetter) {    fill(colr);    textAlign(LEFT);    text(messageLetter, x_, y_);      }  void moveX (float x_, char messageLetter) {    // Move x according to character's width    x_ += textWidth(messageLetter);  }}