diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index d3878a8..0abf29e 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -4,6 +4,7 @@ #include "ofColor.h" #include "ofEvents.h" #include "ofGraphics.h" +#include "ofRectangle.h" #include "ofUtils.h" namespace ofxVariableLab { @@ -179,8 +180,7 @@ void GPUFontAtlasLayerCombo::draw(){ int currentProgram; glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - float cx = FLT_MAX; - float cy = FLT_MAX; + float superLineHeight = 0; if(font){ fontShaderProgram = fontShader->program; glUseProgram(fontShaderProgram); @@ -210,25 +210,135 @@ void GPUFontAtlasLayerCombo::draw(){ std::vector vertices; std::vector indices; - for(const auto & layer : layers){ - ofNode node; - node.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); - node.move(glm::vec3(layer->getProps().x, - layer->getProps().y, - 0)); - font->collectVerticesAndIndices(node, - layer->getVariationText(), - vertices, indices, - layer->getColor(), - true, - layer->getProps().fontSize_px); - } vertices.resize(totalCharacters * 4); indices.resize(totalCharacters * 6); + std::vector outerBoundingBoxes; + for(const auto & layer : layers){ + float lineHeight = font->getLineHeight(layer->getProps().fontSize_px); + float ascender = font->getAscender(layer->getProps().fontSize_px); + superLineHeight = lineHeight; + ofxGPUFont::Font::BoundingBox bb; + std::vector bbs; + float advanceY = 0; + font->collectBoundingBoxes(layer->getVariationText(), + bb, bbs, advanceY, + true, layer->getProps().fontSize_px); + ofNode momNode; + ofNode node; + node.setParent(momNode); + glm::vec4 transformOrigin; + switch(layer->getProps().transformOrigin){ + default: + case Layer::TransformOrigin::TOP_LEFT: { + node.move(glm::vec3(0, + ascender, + 0)); + momNode.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); + transformOrigin = glm::vec4(layer->getProps().x, + layer->getProps().y - ascender, + 0, 1); + momNode.move(transformOrigin); + break; + } + + case Layer::TransformOrigin::TOP_RIGHT: { + float moveX = bb.p1.x - bb.p0.x; + node.move(glm::vec3(-moveX, + ascender, + 0)); + momNode.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); + transformOrigin = glm::vec4(layer->getProps().x + moveX, + layer->getProps().y - ascender, + 0, 1); + momNode.move(transformOrigin); + break; + } + + case Layer::TransformOrigin::CENTER: { + float moveX = (bb.p2.x - bb.p0.x) * 0.5 + bb.p0.x; + float moveY = (bb.p2.y - bb.p0.y) * 0.5 - bb.p2.y; + node.move(glm::vec3(-moveX, + moveY, + 0)); + momNode.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); + transformOrigin = glm::vec4(layer->getProps().x + moveX, + layer->getProps().y - moveY, + 0, 1); + momNode.move(transformOrigin); + break; + } + + case Layer::TransformOrigin::BOTTOM_LEFT: { + float moveY = ascender - advanceY; + node.move(glm::vec3(0, + moveY, + 0)); + momNode.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); + transformOrigin = glm::vec4(layer->getProps().x, + layer->getProps().y - moveY, + 0, 1); + momNode.move(transformOrigin); + break; + } + + case Layer::TransformOrigin::BOTTOM_RIGHT: { + float moveY = ascender - (advanceY); + float moveX = (bb.p2.x - bb.p0.x); + node.move(glm::vec3(-moveX, + moveY, + 0)); + momNode.rotateDeg(layer->getProps().rotation, glm::vec3(0, 0, 1)); + transformOrigin = glm::vec4(layer->getProps().x + moveX, + layer->getProps().y - moveY, + 0, 1); + momNode.move(transformOrigin); + break; + } + + } + bb.multiply(node.getGlobalTransformMatrix()); + ofVboMesh mesh; + mesh.addVertices({bb.p0, bb.p1, bb.p2, bb.p3, + glm::vec4(layer->getProps().x, layer->getProps().y, 0, 1), + transformOrigin + }); + mesh.addColors({ + ofColor::red, + ofColor::red, + ofColor::red, + ofColor::red, + ofColor::white, + ofColor::green, + }); + outerBoundingBoxes.push_back(mesh); + + font->collectVerticesAndIndices(node, + bbs, + vertices, + indices, + layer->getColor(), + layer->getProps().fontSize_px); + + } + font->draw(vertices, indices); glUseProgram(currentProgram); + ofPushStyle(); + ofSetColor(ofColor::white); + for(const auto & b : outerBoundingBoxes){ + int i = 0; + for(const auto & v : b.getVertices()){ + ofSetColor(b.getColors()[i]); + ofDrawCircle(v, 4); + ofDrawBitmapString(ofToString(i), 0, 0); + i++; + } + b.drawVertices(); + } + ofFill(); + ofPopStyle(); } glDisable(GL_BLEND); @@ -236,6 +346,7 @@ void GPUFontAtlasLayerCombo::draw(){ ofDrawBitmapStringHighlight( "fps: " + ofToString(ofGetFrameRate()) + "\n" + "font: " + this->identifier.fontPath + "\n" + + "lineHEight: " + ofToString(superLineHeight) + "\n" , 20, 20); } diff --git a/src/Layer.h b/src/Layer.h index 8e2080f..638fda3 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -18,6 +18,13 @@ struct LayerSettings { class Layer { public: + enum TransformOrigin : int { + TOP_LEFT = 0, + TOP_RIGHT, + CENTER, + BOTTOM_LEFT, + BOTTOM_RIGHT + }; struct Props { float x = 200; float y = 200; @@ -29,6 +36,7 @@ class Layer { bool mirror_y = false; float mirror_y_distance = 0; float letterDelay = 0; + int transformOrigin = TransformOrigin::TOP_LEFT; std::vector fontVariations; string text = "abc"; string fontPath = "data/celines-fonts/Version-2-var.ttf";