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){
|
if(layer->getProps().width > 0){
|
||||||
int n_wraps = wrapBoundingBoxes(bbs,
|
int n_wraps = wrapBoundingBoxes(bbs,
|
||||||
layer->getVariationText(),
|
layer->getVariationText(),
|
||||||
|
const_cast <std::vector <ofxGPUFont::GlyphAppearance> &>(layer->getVariationTextAppearance()), // TODO: REMOVE
|
||||||
layer->getProps().width,
|
layer->getProps().width,
|
||||||
lineHeight);
|
lineHeight);
|
||||||
float min_x = FLT_MAX;
|
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;
|
float lineHeight = font->getLineHeight(layer->getProps().fontSize_px) * layer->getProps().lineHeight;
|
||||||
int n_wraps = wrapBoundingBoxes(bbs,
|
int n_wraps = wrapBoundingBoxes(bbs,
|
||||||
layer->getVariationText(),
|
layer->getVariationText(),
|
||||||
|
const_cast <std::vector <ofxGPUFont::GlyphAppearance> &>(layer->getVariationTextAppearance()), // TODO: REMOVE
|
||||||
layer->getProps().width,
|
layer->getProps().width,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
layer->getProps().textAlignment);
|
layer->getProps().textAlignment);
|
||||||
|
@ -787,86 +789,110 @@ void GPUFontAtlasLayerCombo::getAndApplyTransformOrigin(glm::vec4 & transformOri
|
||||||
}
|
}
|
||||||
int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
||||||
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
||||||
|
std::vector <ofxGPUFont::GlyphAppearance> & variationTextAppearance,
|
||||||
int width,
|
int width,
|
||||||
float advanceY,
|
float advanceY,
|
||||||
float textAlignment){
|
float textAlignment){
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int vi = 0;
|
|
||||||
int wrapIndex = -1;
|
|
||||||
int n_wraps = 0;
|
int n_wraps = 0;
|
||||||
float collectedWrapWidth = 0;
|
|
||||||
std::vector <int> lineBreaks;
|
std::vector <int> lineBreaks;
|
||||||
std::vector <int> goodCharacters;
|
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;
|
||||||
|
|
||||||
float maxX = 0;
|
{ // collect existing linebreaks, wrapindices and good characters
|
||||||
for(ofxGPUFont::Font::BoundingBox & bb : bbs){
|
int vi = 0;
|
||||||
// good character means it's a drawable character
|
int wrapIndex = -1;
|
||||||
bool hasGoodCharacter = false;
|
for(int i = 0; i < bbs.size(); i++){
|
||||||
while(!hasGoodCharacter && vi < variationText.size()){
|
// good character means it's a drawable character
|
||||||
if(variationText[vi].charcode == '\0'
|
bool hasGoodCharacter = false;
|
||||||
|| variationText[vi].charcode == '\r'
|
while(!hasGoodCharacter && vi < variationText.size()){
|
||||||
|| variationText[vi].charcode == '\n'){
|
if(variationText[vi].charcode == '\0'
|
||||||
if(variationText[vi].charcode == '\n'){
|
|| variationText[vi].charcode == '\r'
|
||||||
if(lastGoodCharacter >= 0){
|
|| variationText[vi].charcode == '\n'){
|
||||||
lineBreaks.push_back(lastGoodCharacter);
|
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;
|
if(variationText[vi].charcode == '-'){
|
||||||
vi++;
|
|
||||||
}else if(variationText[vi].charcode == ' '){ // TODO: any whitespace
|
|
||||||
wrapIndex = i;
|
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(hasGoodCharacter){
|
||||||
if(wrapIndex >= 0){
|
lastGoodCharacter = i;
|
||||||
float wrapWidth = bbs[wrapIndex].p0.x;
|
}
|
||||||
for(int w = wrapIndex; w < bbs.size(); w++){
|
wrapIndices.push_back(wrapIndex);
|
||||||
bbs[w].p0.x -= wrapWidth;
|
vi++;
|
||||||
bbs[w].p1.x -= wrapWidth;
|
}
|
||||||
bbs[w].p2.x -= wrapWidth;
|
}
|
||||||
bbs[w].p3.x -= wrapWidth;
|
{ // add new linebreaks at wrapindices
|
||||||
bbs[w].p0.y += advanceY;
|
int i = 0;
|
||||||
bbs[w].p1.y += advanceY;
|
float wrapWidth;
|
||||||
bbs[w].p2.y += advanceY;
|
int lastBrokenWrapIndex = -1;
|
||||||
bbs[w].p3.y += advanceY;
|
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);
|
float maxX = -1 * FLT_MAX;
|
||||||
|
for(const auto & bb : bbs){
|
||||||
if(hasGoodCharacter){
|
maxX = max(maxX, bb.p1.x);
|
||||||
lastGoodCharacter = i;
|
|
||||||
}
|
|
||||||
vi++;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
//float w = width > 0 ? width : maxX;
|
||||||
|
float w = maxX;
|
||||||
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];
|
||||||
|
|
|
@ -91,6 +91,7 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
||||||
private:
|
private:
|
||||||
int wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
int wrapBoundingBoxes(std::vector <ofxGPUFont::Font::BoundingBox> & bbs,
|
||||||
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
const std::vector <ofxGPUFont::GlyphIdentity> & _variationText,
|
||||||
|
std::vector <ofxGPUFont::GlyphAppearance> & variationTextAppearance,
|
||||||
int width,
|
int width,
|
||||||
float advanceY,
|
float advanceY,
|
||||||
float textAlignment = 0);
|
float textAlignment = 0);
|
||||||
|
|
Loading…
Reference in a new issue