We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I made a small mark up language here:
<
and after >
, but never inside <
and >
.you can use
<Bold> glamorous </Bold>
<Italic> surprising </Italic>
<Col255,0,0> anyone </Col> : all colors with 3 parameters, no spaces inside `<>`
Hope this helps.
Best, Chrisir ;-)
Keywords: bricklaying, markup, mark up language, formatting text
//===========================================================================
// FINAL FIELDS:
final int Y_OFFSET=100;
final int TEXT_SIZE=14;
final int fontSituationNormal=0;
final int fontSituationBold=1;
final int fontSituationItalic=2;
//===========================================================================
// GLOBAL VARIABLES:
int fontSituation = fontSituationNormal;
PFont fontNormal, fontBold, fontItalic;
String [] poem = new String[15];
//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:
void setup() {
size(1500, 600);
// printArray(PFont.list());
fontNormal = createFont("Arial", TEXT_SIZE);
fontBold = createFont("Arial Bold", TEXT_SIZE);
fontItalic = createFont("Arial Italic", TEXT_SIZE);
textFont(fontNormal);
rectMode(CENTER);
fill(255);
strokeWeight(2);
textSize(TEXT_SIZE);
poem[0]="i love you much <Bold> glamorous </Bold> darling ";
poem[1]="i love you much <Italic> surprising </Italic> darling ";
poem[2]="more than <Col255,0,0> anyone </Col> on the earth and i";
poem[3]="like you better than everything in the sky";
poem[4]="-sunlight and singing welcome your coming";
poem[5]="although winter may be everywhere";
poem[6]="with such a silence and such a darkness";
poem[7]="noone can <Col255,0,255> quite begin to guess";
poem[8]="(except my life)the true time of year-";
poem[9]="and if what calls itself a </Col> world should have";
poem[10]="the luck to hear such singing (or glimpse such";
poem[11]="sunlight as will leap higher than high";
poem[12]="through gayer than gayest someone's heart at your each";
poem[13]="nearness) <Col0,0,255> everyone certainly </Col> would (my";
poem[14]="most beautiful darling) believe in nothing but love.";
}
void draw() {
background(0);
showRawData();
}
//===========================================================================
// PROCESSING DEFAULT INPUT FUNCTIONS:
void keyPressed() {
if (key==' ')
{
}
}//func
//===========================================================================
// OTHER FUNCTIONS:
void showRawData() {
String textAdd;
int textWidthBold=0;
fill(255); // white is default
// for all lines in the poem
for (int i=0; i<poem.length; i++) {
String[] line1 = split (poem[i], " ");
textAdd="";
textWidthBold=0;
// for all words in the poem
for (int i2=0; i2<line1.length; i2++) {
// println(line1[i2]);
// Is it mark up entry?
if ( startOfMarkUp(line1[i2]) ) {
// Yes.
analyzeMarkUpEntry(line1[i2]);
//
}//if mark up entry
// -----------------
else {
// normal word
// the x-value is a little tricky here since bold is wider than normal (or italic)
// textWidth() calculates with current font.
// This won't work in all situations.
textFont(fontNormal);
float textWidthResult=textWidth(textAdd)+textWidthBold;
restoreFont();
text(line1[i2], float(300)+ textWidthResult, Y_OFFSET + i*2*TEXT_SIZE);
if (fontSituation==fontSituationBold)
textWidthBold=6;
textAdd+=line1[i2]+" ";
}//else
}//for
}//for
//
}
// ------------------------------------------
void analyzeMarkUpEntry( String str ) {
// Is it an ending sign?
if ( startOfEndingMarkUp(str)) {
// it is an ending mark up like </...>, e.g. </Bold>
if (isEndingColor(str)) {
fill(255); // white is default
} else if (isEndingBold(str)) {
textFont(fontNormal);
fontSituation=fontSituationNormal;
} else if (isEndingItalic(str)) {
textFont(fontNormal);
fontSituation=fontSituationNormal;
} else {
println ("unknown ending sign: "
+ str);
exit();
}
} else {
// it's a starting mark up like <Bold>
if (isStartingColor(str)) {
// set color is handled in function isStartingColor
} else if (isStartingBold(str)) {
fontSituation=fontSituationBold;
} else if (isStartingItalic(str)) {
fontSituation=fontSituationItalic;
} else {
println ("unknown starting sign: "
+ str);
exit();
}
} //else
}//func
//--------------------------------------------
boolean startOfMarkUp(String str) {
if (str.trim().length()<=0)
return false;
if (str.trim().charAt(0)=='<')
return true;
return false;
}
boolean startOfEndingMarkUp(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().charAt(0)=='<' &&
str.trim().charAt(1)=='/')
return true;
return false;
}
//------------------------------
boolean isEndingColor(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().equals("</Col>"))
return true;
return false;
}
boolean isEndingBold(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().equals("</Bold>"))
return true;
return false;
}
boolean isEndingItalic(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().equals("</Italic>"))
return true;
return false;
}
// ----------------------------------------------
boolean isStartingColor(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().contains("<Col")) {
str=str.trim();
str=str.replace("<Col", "");
str=str.replace(">", "");
String[] colorValues = split(str, ",");
if (colorValues.length==3)
fill(int(colorValues[0]),
int(colorValues[1]),
int(colorValues[2]));
return true;
}
return false;
}
boolean isStartingBold(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().equals("<Bold>"))
return true;
return false;
}
boolean isStartingItalic(String str) {
if (str.trim().length()<=2)
return false;
if (str.trim().equals("<Italic>"))
return true;
return false;
}
//------------------------------
void restoreFont() {
switch(fontSituation) {
case fontSituationBold:
textFont(fontBold);
break;
case fontSituationItalic:
textFont(fontItalic);
break;
case fontSituationNormal:
textFont(fontNormal);
break;
}//switch
}
//
Also, just to clarify, the second picture I provided doesn't actually use kerning (space between individual letters) -- it expands the space between words but leaves letter spacing alone. So for the you would need to chunk by words and measure their while packing each line, then space them across the line.
For previous related discussions of bolded words or colored words (which also require chunking text by word before layout) search the forum for 'bricklaying':
Possibly relevant if you decided to build your own clickable multiline text output area from the ground up: bricklaying text layout algorithm discussion:
In your case you might be tracking this for each character rather than each word in order to interpret clicks into cursor insert positions.
How would you do to write bold text
BUT:
If you want to treat any part of a text string differently, you can simulate this by breaking your one call to text()
up into multiple text()
calls using the bricklaying method recently discussed in another thread: https://forum.processing.org/two/discussion/comment/80759/#Comment_80759
So, you print your words or phrases one at a time, and when you get to that word or phrase you want to be bold, you either change the font to a bold version of the font or you do pseudo-bold -- for example by drawing the word several times with 1px offsets.
is it possible to know what is the current font being used by Processing?
The easiest way is to set the font explicitly at the start of your sketch -- then you know what font it is. See the Typography tutorial for details, which also explains how to find the list of currently available fonts for loading: https://processing.org/tutorials/typography/
@jabobob -- right, that's why I described text wrap through bricklaying. That should solve your problem. I've updated my description above to simplify it, so that you aren't dynamically searching for wrap points -- instead you are printing each word with a separate call to text()
.
Your example screenshot includes dynamic in-word hyphenation. Implementing rules for acceptable hyphenation is going to be a bit tricky -- you might want to add it after everything else works.
@jabobob -- The left margin problem means that you can't allow line wrapping, ever. Instead you probably need to implement text wrapping for single-line text()
blocks using a bricklaying algorithm with partial-bricks.
For example:
Edit: simplified this for clarity
This should with text of any length, although the checking method is really inefficient if all your text is paragraph length -- in that case you might want to pre-chunk your text or do a better pre-approximation of line length.
Or, to make all of this much much less fiddly, use a fixed-distance font.