fix wrapping
text alignment still broken
This commit is contained in:
parent
1f5b02e947
commit
8952672e84
2 changed files with 79 additions and 52 deletions
|
@ -243,6 +243,7 @@ void GPUFontAtlasLayerCombo::draw(int width, int height){
|
|||
if(layer->getProps().width > 0){
|
||||
int n_wraps = wrapBoundingBoxes(bbs,
|
||||
layer->getVariationText(),
|
||||
const_cast <std::vector <ofxGPUFont::GlyphAppearance> &>(layer->getVariationTextAppearance()), // TODO: REMOVE
|
||||
layer->getProps().width,
|
||||
lineHeight);
|
||||
float min_x = FLT_MAX;
|
||||
|
@ -515,6 +516,7 @@ void GPUFontAtlasLayerCombo::draw(int width,
|
|||
float lineHeight = font->getLineHeight(layer->getProps().fontSize_px) * layer->getProps().lineHeight;
|
||||
int n_wraps = wrapBoundingBoxes(bbs,
|
||||
layer->getVariationText(),
|
||||
const_cast <std::vector <ofxGPUFont::GlyphAppearance> &>(layer->getVariationTextAppearance()), // TODO: REMOVE
|
||||
layer->getProps().width,
|
||||
lineHeight,
|
||||
layer->getProps().textAlignment);
|
||||
|
@ -787,86 +789,110 @@ void GPUFontAtlasLayerCombo::getAndApplyTransformOrigin(glm::vec4 & transformOri
|
|||
}
|
||||
int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
||||
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
||||
std::vector <ofxGPUFont::GlyphAppearance> & variationTextAppearance,
|
||||
int width,
|
||||
float advanceY,
|
||||
float textAlignment){
|
||||
|
||||
int i = 0;
|
||||
int vi = 0;
|
||||
int wrapIndex = -1;
|
||||
int n_wraps = 0;
|
||||
float collectedWrapWidth = 0;
|
||||
std::vector <int> lineBreaks;
|
||||
std::vector <int> goodCharacters;
|
||||
int lastGoodCharacter = -1;
|
||||
//textAlignment = ofMap(sin(ofGetElapsedTimef()), -1, 1, 0, 1);
|
||||
std::vector <int> vis;
|
||||
std::vector <int> wrapIndices;
|
||||
|
||||
float maxX = 0;
|
||||
for(ofxGPUFont::Font::BoundingBox & bb : bbs){
|
||||
// good character means it's a drawable character
|
||||
bool hasGoodCharacter = false;
|
||||
while(!hasGoodCharacter && vi < variationText.size()){
|
||||
if(variationText[vi].charcode == '\0'
|
||||
|| variationText[vi].charcode == '\r'
|
||||
|| variationText[vi].charcode == '\n'){
|
||||
if(variationText[vi].charcode == '\n'){
|
||||
if(lastGoodCharacter >= 0){
|
||||
lineBreaks.push_back(lastGoodCharacter);
|
||||
{ // collect existing linebreaks, wrapindices and good characters
|
||||
int vi = 0;
|
||||
int wrapIndex = -1;
|
||||
for(int i = 0; i < bbs.size(); i++){
|
||||
// good character means it's a drawable character
|
||||
bool hasGoodCharacter = false;
|
||||
while(!hasGoodCharacter && vi < variationText.size()){
|
||||
if(variationText[vi].charcode == '\0'
|
||||
|| variationText[vi].charcode == '\r'
|
||||
|| variationText[vi].charcode == '\n'){
|
||||
if(variationText[vi].charcode == '\n'){
|
||||
if(lastGoodCharacter >= 0){
|
||||
lineBreaks.push_back(lastGoodCharacter);
|
||||
}
|
||||
}
|
||||
wrapIndex = -1;
|
||||
vi++;
|
||||
}else if(variationText[vi].charcode == ' '){ // TODO: any whitespace
|
||||
wrapIndex = i;
|
||||
vi++;
|
||||
}else{
|
||||
hasGoodCharacter = true;
|
||||
goodCharacters.push_back(vi);
|
||||
}
|
||||
wrapIndex = -1;
|
||||
collectedWrapWidth = 0;
|
||||
vi++;
|
||||
}else if(variationText[vi].charcode == ' '){ // TODO: any whitespace
|
||||
}
|
||||
if(variationText[vi].charcode == '-'){
|
||||
wrapIndex = i;
|
||||
vi++;
|
||||
}else{
|
||||
hasGoodCharacter = true;
|
||||
goodCharacters.push_back(i);
|
||||
}
|
||||
}
|
||||
if(variationText[vi].charcode == '-'){
|
||||
wrapIndex = i;
|
||||
}
|
||||
const float insideWidth = bb.p1.x - collectedWrapWidth;
|
||||
bool overhang = (insideWidth / float(width)) > (n_wraps + 1);
|
||||
|
||||
if(width > 0 && insideWidth > width){
|
||||
if(wrapIndex >= 0){
|
||||
float wrapWidth = bbs[wrapIndex].p0.x;
|
||||
for(int w = wrapIndex; w < bbs.size(); w++){
|
||||
bbs[w].p0.x -= wrapWidth;
|
||||
bbs[w].p1.x -= wrapWidth;
|
||||
bbs[w].p2.x -= wrapWidth;
|
||||
bbs[w].p3.x -= wrapWidth;
|
||||
bbs[w].p0.y += advanceY;
|
||||
bbs[w].p1.y += advanceY;
|
||||
bbs[w].p2.y += advanceY;
|
||||
bbs[w].p3.y += advanceY;
|
||||
if(hasGoodCharacter){
|
||||
lastGoodCharacter = i;
|
||||
}
|
||||
wrapIndices.push_back(wrapIndex);
|
||||
vi++;
|
||||
}
|
||||
}
|
||||
{ // add new linebreaks at wrapindices
|
||||
int i = 0;
|
||||
float wrapWidth;
|
||||
int lastBrokenWrapIndex = -1;
|
||||
for(ofxGPUFont::Font::BoundingBox & bb : bbs){
|
||||
int wrapIndex = wrapIndices[i];
|
||||
if(width > 0 && bb.p1.x > width){
|
||||
if(wrapIndex >= 0 && std::find(lineBreaks.begin(), lineBreaks.end(), wrapIndex - 1) == lineBreaks.end()){
|
||||
lastBrokenWrapIndex = wrapIndex;
|
||||
wrapWidth = bbs[wrapIndex].p0.x;
|
||||
int nextLineBreak = INT_MAX;
|
||||
for(int lb = 0; lb < lineBreaks.size(); lb++){
|
||||
if(lineBreaks[lb] >= i){
|
||||
nextLineBreak = lineBreaks[lb];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int w = wrapIndex; w < bbs.size(); w++){
|
||||
if(w <= nextLineBreak){
|
||||
bbs[w].p0.x -= wrapWidth;
|
||||
bbs[w].p1.x -= wrapWidth;
|
||||
bbs[w].p2.x -= wrapWidth;
|
||||
bbs[w].p3.x -= wrapWidth;
|
||||
}
|
||||
bbs[w].p0.y += advanceY;
|
||||
bbs[w].p1.y += advanceY;
|
||||
bbs[w].p2.y += advanceY;
|
||||
bbs[w].p3.y += advanceY;
|
||||
}
|
||||
n_wraps++;
|
||||
lineBreaks.push_back(wrapIndex - 1);
|
||||
}
|
||||
n_wraps++;
|
||||
lineBreaks.push_back(wrapIndex - 1);
|
||||
wrapIndex = -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
maxX = max(maxX, bbs[i].p1.x);
|
||||
|
||||
if(hasGoodCharacter){
|
||||
lastGoodCharacter = i;
|
||||
}
|
||||
vi++;
|
||||
i++;
|
||||
float maxX = -1 * FLT_MAX;
|
||||
for(const auto & bb : bbs){
|
||||
maxX = max(maxX, bb.p1.x);
|
||||
}
|
||||
|
||||
if(textAlignment != 0){
|
||||
if(lineBreaks.size() > 0){
|
||||
lineBreaks.push_back(lastGoodCharacter);
|
||||
}
|
||||
float w = width; // > 0 ? width : maxX;
|
||||
//float w = width > 0 ? width : maxX;
|
||||
float w = maxX;
|
||||
int startFromCharacter = 0;
|
||||
for(int lineBreak : lineBreaks){
|
||||
ofxGPUFont::Font::BoundingBox & bbb = bbs[lineBreak];
|
||||
int vi = vis[lineBreak];
|
||||
int vi2 = vis[startFromCharacter];
|
||||
variationTextAppearance[vi].color[0] = 1.0;
|
||||
variationTextAppearance[vi2].color[1] = 1.0;
|
||||
float shiftX = (w - bbb.p1.x) * textAlignment;
|
||||
for(int i = startFromCharacter; i <= lineBreak; i++){
|
||||
auto & bb = bbs[i];
|
||||
|
|
|
@ -91,6 +91,7 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
|||
private:
|
||||
int wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
||||
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
||||
std::vector <ofxGPUFont::GlyphAppearance> & variationTextAppearance,
|
||||
int width,
|
||||
float advanceY,
|
||||
float textAlignment = 0);
|
||||
|
|
Loading…
Reference in a new issue