/* * A demonstration of text processing in the form of a * speed-reading application, somewhat akin to Spritz. * * Author: Michael Goldwasser */ // contstants that can be tuned int WORDS_PER_MINUTE = 300; int FONTSIZE = 70; //String sourcefile = "http://www.gutenberg.org/cache/epub/2591/pg2591.txt"; int NUM_SAMPLES = 9; int num = int(1 + random(NUM_SAMPLES)); String sourcefile = "example" + num + ".txt"; // globals used to store text and progress String[] words; // will be loaded from file int cur=0; // index of current word boolean running = false; // global to help with font metric float interwordGap; float tickMarkX; // x-coordinate of tick mark for placing word float baseline; void setup() { noLoop(); // don't start drawing until window clicked frameRate(WORDS_PER_MINUTE/60.0); textSize(FONTSIZE); int windowWidth = int(15 * textWidth("M")); size(windowWidth, 3*FONTSIZE); background(255); strokeWeight(2); interwordGap = (textWidth("OOOOOOOOOO") - 10 * textWidth("O"))/9.0; tickMarkX = 0.33*width; baseline = 2*FONTSIZE - textDescent(); line(0, 0.1*FONTSIZE, width, 0.1*FONTSIZE); line(0, 2.9*FONTSIZE, width, 2.9*FONTSIZE); line(tickMarkX, 0.1*FONTSIZE, tickMarkX, 0.5*FONTSIZE); line(tickMarkX, 2.5*FONTSIZE, tickMarkX, 2.9*FONTSIZE); loadTextFile(sourcefile); renderWord("Click to Begin"); } // used to (re)start the rendering of the prose void mouseClicked() { if (words != null) { running = !running; loop(); if (cur >= words.length) { cur = 0; // start over } } } void draw() { if (running) { renderWord(words[cur]); cur++; if (cur == words.length) { running = false; noLoop(); } } } // Display a single word to be read void renderWord(String word) { noStroke(); fill(255); rect(0, 0.5*FONTSIZE, width, 2*FONTSIZE); // divide word into three portions (left, middle, right). int divide = getRedIndex(word.length()); String left = word.substring(0,divide); String middle = word.substring(divide, 1+divide); String right = word.substring(1+divide); // until the end textAlign(CENTER); fill(255,0,0); text(middle, tickMarkX, baseline); float pad = interwordGap + 0.5 * textWidth(middle); fill(0); textAlign(RIGHT); text(left, tickMarkX - pad, baseline); textAlign(LEFT); text(right, tickMarkX + pad, baseline); } // Open a text file and break its text into individual words, // as separated by spaces. Those words are loaded into the // global 'words' array. void loadTextFile(String filename) { String[] lines = loadStrings(filename); // first, let's count the total number of words in document int total = 0; for (int j=0; j < lines.length; j++) { total += splitTokens(lines[j]).length; } // Now let's resize global array of words and fill it words = new String[total]; int w=0; // index into words for (int j=0; j < lines.length; j++) { String[] pieces = splitTokens(lines[j]); for (int k=0; k < pieces.length; k++) { words[w] = pieces[k]; w++; } } } // Given a particular word length, return index of character that becomes red int getRedIndex(int length) { return (length + 2) / 4; // integer division }