fix text alignment

This commit is contained in:
jrkb 2023-09-06 18:17:53 +02:00
parent 8952672e84
commit 20ad951c46

View file

@ -794,12 +794,9 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::Bou
float advanceY, float advanceY,
float textAlignment){ float textAlignment){
int n_wraps = 0;
std::vector <int> lineBreaks; std::vector <int> lineBreaks;
std::vector <int> goodCharacters;
int lastGoodCharacter = -1; int lastGoodCharacter = -1;
//textAlignment = ofMap(sin(ofGetElapsedTimef()), -1, 1, 0, 1); //textAlignment = ofMap(sin(ofGetElapsedTimef()), -1, 1, 0, 1);
std::vector <int> vis;
std::vector <int> wrapIndices; std::vector <int> wrapIndices;
{ // collect existing linebreaks, wrapindices and good characters { // collect existing linebreaks, wrapindices and good characters
@ -824,7 +821,6 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::Bou
vi++; vi++;
}else{ }else{
hasGoodCharacter = true; hasGoodCharacter = true;
goodCharacters.push_back(vi);
} }
} }
if(variationText[vi].charcode == '-'){ if(variationText[vi].charcode == '-'){
@ -838,15 +834,14 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::Bou
vi++; vi++;
} }
} }
int n_wraps = 0;
{ // add new linebreaks at wrapindices { // add new linebreaks at wrapindices
int i = 0; int i = 0;
float wrapWidth; float wrapWidth;
int lastBrokenWrapIndex = -1;
for(ofxGPUFont::Font::BoundingBox & bb : bbs){ for(ofxGPUFont::Font::BoundingBox & bb : bbs){
int wrapIndex = wrapIndices[i]; int wrapIndex = wrapIndices[i];
if(width > 0 && bb.p1.x > width){ if(width > 0 && bb.p1.x > width){
if(wrapIndex >= 0 && std::find(lineBreaks.begin(), lineBreaks.end(), wrapIndex - 1) == lineBreaks.end()){ if(wrapIndex >= 0 && std::find(lineBreaks.begin(), lineBreaks.end(), wrapIndex - 1) == lineBreaks.end()){
lastBrokenWrapIndex = wrapIndex;
wrapWidth = bbs[wrapIndex].p0.x; wrapWidth = bbs[wrapIndex].p0.x;
int nextLineBreak = INT_MAX; int nextLineBreak = INT_MAX;
for(int lb = 0; lb < lineBreaks.size(); lb++){ for(int lb = 0; lb < lineBreaks.size(); lb++){
@ -855,6 +850,7 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::Bou
break; break;
} }
} }
// TODO: should be possible without iterating bbs
for(int w = wrapIndex; w < bbs.size(); w++){ for(int w = wrapIndex; w < bbs.size(); w++){
if(w <= nextLineBreak){ if(w <= nextLineBreak){
bbs[w].p0.x -= wrapWidth; bbs[w].p0.x -= wrapWidth;
@ -875,24 +871,30 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::Bou
} }
} }
float maxX = -1 * FLT_MAX;
for(const auto & bb : bbs){
maxX = max(maxX, bb.p1.x);
}
if(textAlignment != 0){ if(textAlignment != 0){
if(lineBreaks.size() > 0){ if(lineBreaks.size() > 0){
lineBreaks.push_back(lastGoodCharacter); lineBreaks.push_back(lastGoodCharacter);
} }
//float w = width > 0 ? width : maxX; std::sort(lineBreaks.begin(), lineBreaks.end());
float w = maxX;
// following may seem overcomplicated, though:
// if width is set, we use width to shift text alignment
// if not, we calculate maximum x and use that
// the syntax makes it possible to only calculate
// when we need it
float w = width > 0 ? width :
std::accumulate(bbs.begin(),
bbs.end(),
-1 * FLT_MAX,
[](float a,
const ofxGPUFont::Font::BoundingBox & bb)
{
return max(a, bb.p1.x);
});
int startFromCharacter = 0; int startFromCharacter = 0;
for(int lineBreak : lineBreaks){ for(int lineBreak : lineBreaks){
ofxGPUFont::Font::BoundingBox & bbb = bbs[lineBreak]; 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; float shiftX = (w - bbb.p1.x) * textAlignment;
for(int i = startFromCharacter; i <= lineBreak; i++){ for(int i = startFromCharacter; i <= lineBreak; i++){
auto & bb = bbs[i]; auto & bb = bbs[i];