void TTF_TextBox(const drawTextCommand_t *cmd, const char *string, int count) { TTFtextRow rows[2]; int nrows = 0, i; int oldAlign = state.align; int halign = state.align & (FONS_ALIGN_LEFT | FONS_ALIGN_CENTER | FONS_ALIGN_RIGHT); int valign = state.align & (FONS_ALIGN_TOP | FONS_ALIGN_MIDDLE | FONS_ALIGN_BOTTOM | FONS_ALIGN_BASELINE); float lineh; fonsPushState(ctx); fonsVertMetrics(ctx, nullptr, nullptr, &lineh); fonsSetAlign(ctx, FONS_ALIGN_LEFT | valign); float x = cmd->x; float y = cmd->y; lineh *= state.lineHeight; const char *end = TTF_CountChars(string, count); while ((nrows = TTF_BreakLines(string, end, cmd->w, rows, 2)) > 0) { for (i = 0; i < nrows; i++) { TTFtextRow* row = &rows[i]; if (halign & FONS_ALIGN_LEFT) fonsDrawText(ctx, x, y, row->start, row->end); else if (halign & FONS_ALIGN_CENTER) fonsDrawText(ctx, x + cmd->w * 0.5f - row->width*0.5f, y, row->start, row->end); else if (halign & FONS_ALIGN_RIGHT) fonsDrawText(ctx, x + cmd->w - row->width, y, row->start, row->end); y += lineh; } string = rows[nrows - 1].next; } fonsPopState(ctx); }
std::vector<FONSquad>& FontContext::rasterize(const std::string& _text, FontID _fontID, float _fontSize, float _sdf) { m_quadBuffer.clear(); fonsSetSize(m_fsContext, _fontSize); fonsSetFont(m_fsContext, _fontID); if (_sdf > 0){ fonsSetBlur(m_fsContext, _sdf); fonsSetBlurType(m_fsContext, FONS_EFFECT_DISTANCE_FIELD); } else { fonsSetBlurType(m_fsContext, FONS_EFFECT_NONE); } float advance = fonsDrawText(m_fsContext, 0, 0, _text.c_str(), _text.c_str() + _text.length(), 0); if (advance < 0) { m_quadBuffer.clear(); return m_quadBuffer; } return m_quadBuffer; }
/** * Render the font, called by Renderer.cpp */ void FontStashAdapter::render() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); glFrontFace( GL_CCW ); shaderLib->bind(); shaderLib->getShader()->setUniform("ortho", orthogonalProjection ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D , textureID ); shaderLib->getShader()->setUniform("font", 0 ); fonsClearState(context); for( auto text_info: texts ){ fonsSetFont ( context, text_info.fontID ); fonsSetSize ( context, text_info.fontSize ); fonsSetColor ( context, text_info.color ); fonsSetSpacing( context, text_info.spacing ); fonsSetBlur ( context, text_info.blur ); fonsDrawText ( context, text_info.x, text_info.y, text_info.text.c_str(), NULL ); } shaderLib->unbind(); }
float ofxFontStash2::draw(const string& text, const ofxFontStashStyle& style, float x, float y){ FONT_STASH_PRE_DRAW; ofPushMatrix(); ofScale(1/pixelDensity, 1/pixelDensity); applyStyle(style); float dx = fonsDrawText(fs, x*pixelDensity, y*pixelDensity, text.c_str(), NULL)/pixelDensity; ofPopMatrix(); FONT_STASH_POST_DRAW; return dx; }
bool CRenderEngine::DrawTextSt(const char* text, DuiRECT& pos,int style,int iFont,DWORD dwTextColor) { if (s_fs == NULL) { s_fs = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT); if (s_fs == NULL) { return false; } s_fontNormal = fonsAddFont(s_fs, "sans", "msyh.ttf"); if (s_fontNormal == FONS_INVALID) { return false; } } float line_height = 15.0f; //¸ù¾Ýstyle×óÓÒÖмä¶ÔÆë¼ÆËã float s_x = pos.left; float s_y = (pos.bottom - pos.top) / 2.f + pos.top; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); unsigned char a = (dwTextColor) >> 24; unsigned char r = (dwTextColor & 0xff0000) >> 16; unsigned char g = (dwTextColor & 0xff00) >> 8; unsigned char b = (dwTextColor & 0xff); unsigned int text_clr = glfonsRGBA(r,g,b,a); fonsClearState(s_fs); fonsSetSize(s_fs, line_height); fonsSetFont(s_fs, s_fontNormal); fonsSetColor(s_fs, text_clr); fonsDrawText(s_fs, s_x, s_y, text, NULL); return true; }
void GLHelper::drawText(const std::string& text, const Position& pos, const double layer, const double size, const RGBColor& col, const double angle, const int align, double width) { if (width <= 0) { width = size; } if (!initFont()) { return; }; glPushMatrix(); glAlphaFunc(GL_GREATER, 0.5); glEnable(GL_ALPHA_TEST); glTranslated(pos.x(), pos.y(), layer); glScaled(width / myFontSize, size / myFontSize, 1.); glRotated(-angle, 0, 0, 1); fonsSetAlign(myFont, align == 0 ? FONS_ALIGN_CENTER | FONS_ALIGN_MIDDLE : align); fonsSetColor(myFont, glfonsRGBA(col.red(), col.green(), col.blue(), col.alpha())); fonsDrawText(myFont, 0., 0., text.c_str(), nullptr); glPopMatrix(); }
int main() { int fontNormal = FONS_INVALID; int fontItalic = FONS_INVALID; int fontBold = FONS_INVALID; int fontJapanese = FONS_INVALID; GLFWwindow* window; const GLFWvidmode* mode; struct FONSparams params; struct FONScontext* fs = NULL; if (!glfwInit()) return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); memset(¶ms, 0, sizeof(params)); params.width = 512; params.height = 512; params.flags = FONS_ZERO_TOPLEFT; if (glstInit(¶ms) == 0) { printf("Could not create renderer.\n"); return -1; } fs = fonsCreate(¶ms); if (fs == NULL) { printf("Could not create stash.\n"); return -1; } fontNormal = fonsAddFont(fs, "../example/DroidSerif-Regular.ttf"); if (fontNormal == FONS_INVALID) { printf("Could not add font normal.\n"); return -1; } fontItalic = fonsAddFont(fs, "../example/DroidSerif-Italic.ttf"); if (fontItalic == FONS_INVALID) { printf("Could not add font italic.\n"); return -1; } fontBold = fonsAddFont(fs, "../example/DroidSerif-Bold.ttf"); if (fontBold == FONS_INVALID) { printf("Could not add font bold.\n"); return -1; } fontJapanese = fonsAddFont(fs, "../example/DroidSansJapanese.ttf"); if (fontJapanese == FONS_INVALID) { printf("Could not add font japanese.\n"); return -1; } while (!glfwWindowShouldClose(window)) { float sx, sy, dx, dy, lh = 0; int width, height; glfwGetFramebufferSize(window, &width, &height); // Update and render glViewport(0, 0, width, height); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,width,height,0,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glColor4ub(255,255,255,255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); unsigned int white = glstRGBA(255,255,255,255); unsigned int brown = glstRGBA(192,128,0,128); unsigned int blue = glstRGBA(0,192,255,255); sx = 100; sy = 100; dx = sx; dy = sy; dash(dx,dy); fonsSetSize(fs, 124.0f); fonsSetFont(fs, fontNormal); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh; dash(dx,dy); fonsSetSize(fs, 124.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"The quick ",&dx); fonsSetSize(fs, 48.0f); fonsSetFont(fs, fontItalic); fonsSetColor(fs, brown); fonsDrawText(fs, dx,dy,"brown ",&dx); fonsSetSize(fs, 24.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"fox ",&dx); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetFont(fs, fontItalic); fonsDrawText(fs, dx,dy,"jumps over ",&dx); fonsSetFont(fs, fontBold); fonsDrawText(fs, dx,dy,"the lazy ",&dx); fonsSetFont(fs, fontNormal); fonsDrawText(fs, dx,dy,"dog.",&dx); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetSize(fs, 12.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, blue); fonsDrawText(fs, dx,dy,"Now is the time for all good men to come to the aid of the party.",&dx); fonsVertMetrics(fs, NULL,NULL,&lh); dx = sx; dy += lh*1.2f*2; dash(dx,dy); fonsSetSize(fs, 18.0f); fonsSetFont(fs, fontItalic); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"Ég get etið gler án þess að meiða mig.",&dx); fonsVertMetrics(fs, NULL,NULL,&lh); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetFont(fs, fontJapanese); fonsDrawText(fs, dx,dy,"私はガラスを食べられます。それは私を傷つけません。asd",&dx); glEnable(GL_DEPTH_TEST); glfwSwapBuffers(window); glfwPollEvents(); } fonsDelete(fs); glfwTerminate(); return 0; }
void LikertHCI::initializeText(int threadId, FONScontext* fs, int fontNormal, int lineCount, float border, std::shared_ptr<GLSLProgram> shader, float textSize, const std::vector<std::string> &texts, std::string texKey, std::vector<std::vector<std::shared_ptr<Texture> > > &textures, std::vector<std::vector<glm::dvec2> > &sizes) { float sx, sy, lh = 0; unsigned int white = glfonsRGBA(255,255,255,255); unsigned int gray = glfonsRGBA(81, 76, 76, 255); fonsClearState(fs); fonsSetSize(fs, textSize); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsSetAlign(fs, FONS_ALIGN_CENTER | FONS_ALIGN_TOP); fonsVertMetrics(fs, NULL, NULL, &lh); for(int i=0; i < texts.size(); i++) { std::stringstream ss(texts[i]); std::string line; std::vector<std::string> lines; float maxWidth = 0; while(std::getline(ss, line, '\n')){ float width = fonsTextBounds(fs, line.c_str(), NULL, NULL); if (width > maxWidth) { maxWidth = width; } lines.push_back(line); } sx = maxWidth + (1.0f*border); sy = border; if (lineCount > lines.size()) { sy += lh * (lineCount - lines.size()) * 0.5; } float height = lh*lineCount+2.0*border; std::shared_ptr<Texture> depthTexture = Texture::createEmpty("depthTex", sx, height, 1, 1, false, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F); depthTexture->setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); depthTexture->setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); depthTexture->setTexParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); depthTexture->setTexParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture->getID(), 0); textures[threadId][i] = Texture::createEmpty("colorTex", sx, height, 1, 4, false, GL_TEXTURE_2D, GL_RGBA8); textures[threadId][i]->setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); textures[threadId][i]->setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); textures[threadId][i]->setTexParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); textures[threadId][i]->setTexParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); textures[threadId][i]->setTexParameterf(GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textures[threadId][i]->getID(), 0); GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: assert(false); break; case GL_FRAMEBUFFER_UNSUPPORTED: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: assert(false); break; default: break; } assert(status == GL_FRAMEBUFFER_COMPLETE); sizes[threadId].push_back(glm::dvec2(sx, height)); glViewport(0,0, sx, height); glClear(GL_COLOR_BUFFER_BIT); shader->setUniform("projection_mat", glm::ortho(0., (double)sx, (double)height, 0., -1., 1.)); shader->setUniform("view_mat", glm::dmat4(1.0)); shader->setUniform("model_mat", glm::dmat4(1.0)); shader->setUniform("has_lambertian_texture", false); glDisable(GL_DEPTH_TEST); // Draw the darker interior quad so we get a white border around the outside from the clear color float rim = border/4.0f; GLfloat vertices[] = {rim, height-rim, sx-rim, height-rim, rim, rim, sx-rim, rim}; GLfloat texCoords[] = { 0, 1, 1, 1, 1, 0, 0, 0 }; GLfloat colors[] = { 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0}; // create the vao GLuint vaoID = 0; glGenVertexArrays(1, &vaoID); glBindVertexArray(vaoID); GLuint quadVBO = 0; glGenBuffers(1, &quadVBO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices)+sizeof(texCoords)+sizeof(colors), 0, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // copy vertices starting from 0 offest glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(texCoords), texCoords); // copy texCoords after vertices glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices)+sizeof(texCoords), sizeof(colors), colors); // copy colours after normals // set up vertex attributes glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)sizeof(vertices)); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(vertices)+sizeof(texCoords))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); glDeleteBuffers(1, &quadVBO); glDeleteVertexArrays(1, &vaoID); shader->setUniform("has_lambertian_texture", true); glActiveTexture(GL_TEXTURE0); shader->setUniform("lambertian_texture", 0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for(int j=0; j < lines.size(); j++) { std::string text = boost::replace_all_copy(lines[j], "_", " "); fonsDrawText(fs, sx/2.0, sy, text.c_str(), NULL); sy += lh; } glDisable(GL_BLEND); textures[threadId][i]->generateMipMaps(); std::string textureKey = texKey + texts[i]; texMan->setTextureEntry(threadId, textureKey, textures[threadId][i]); depthTexture.reset(); } }
int main() { int fontNormal = FONS_INVALID; int fontItalic = FONS_INVALID; int fontBold = FONS_INVALID; int fontJapanese = FONS_INVALID; GLFWwindow* window; const GLFWvidmode* mode; if (!glfwInit()) return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwSetKeyCallback(window, key); glfwMakeContextCurrent(window); fs = glfonsCreate(256, 256, FONS_ZERO_TOPLEFT); if (fs == NULL) { printf("Could not create stash.\n"); return -1; } fonsSetErrorCallback(fs, stashError, fs); fontNormal = fonsAddFont(fs, "sans", "../example/DroidSerif-Regular.ttf"); if (fontNormal == FONS_INVALID) { printf("Could not add font normal.\n"); return -1; } fontItalic = fonsAddFont(fs, "sans-italic", "../example/DroidSerif-Italic.ttf"); if (fontItalic == FONS_INVALID) { printf("Could not add font italic.\n"); return -1; } fontBold = fonsAddFont(fs, "sans-bold", "../example/DroidSerif-Bold.ttf"); if (fontBold == FONS_INVALID) { printf("Could not add font bold.\n"); return -1; } fontJapanese = fonsAddFont(fs, "sans-jp", "../example/DroidSansJapanese.ttf"); if (fontJapanese == FONS_INVALID) { printf("Could not add font japanese.\n"); return -1; } while (!glfwWindowShouldClose(window)) { float sx, sy, dx, dy, lh = 0; int width, height; int atlasw, atlash; unsigned int white,black,brown,blue; char msg[64]; glfwGetFramebufferSize(window, &width, &height); // Update and render glViewport(0, 0, width, height); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,width,height,0,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glColor4ub(255,255,255,255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); white = glfonsRGBA(255,255,255,255); brown = glfonsRGBA(192,128,0,128); blue = glfonsRGBA(0,192,255,255); black = glfonsRGBA(0,0,0,255); sx = 50; sy = 50; dx = sx; dy = sy; dash(dx,dy); fonsClearState(fs); fonsSetSize(fs, size); fonsSetFont(fs, fontNormal); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh; dash(dx,dy); fonsSetSize(fs, size); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); dx = fonsDrawText(fs, dx,dy,"The quick ",NULL); fonsSetSize(fs, size/2); fonsSetFont(fs, fontItalic); fonsSetColor(fs, brown); dx = fonsDrawText(fs, dx,dy,"brown ",NULL); fonsSetSize(fs, size/3); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); dx = fonsDrawText(fs, dx,dy,"fox ",NULL); fonsSetSize(fs, 14); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, 20, height-20,"Press UP / DOWN keys to change font size and to trigger atlas full callback, R to reset atlas, E to expand atlas.",NULL); fonsGetAtlasSize(fs, &atlasw, &atlash); snprintf(msg, sizeof(msg), "Atlas: %d × %d", atlasw, atlash); fonsDrawText(fs, 20, height-50, msg, NULL); fonsDrawDebug(fs, width - atlasw - 20, 20.0); glEnable(GL_DEPTH_TEST); glfwSwapBuffers(window); glfwPollEvents(); } glfonsDelete(fs); glfwTerminate(); return 0; }
float ofxFontStash2::drawLines(const vector<StyledLine> &lines, float x, float y, bool debug){ // if possible get rid of this translate: #ifndef GL_VERSION_3 ofPushMatrix(); ofTranslate(x, y); #endif ofVec2f offset; #ifdef GL_VERSION_3 offset.x = x * pixelDensity; offset.y = y * pixelDensity; #endif // TS_START("count words"); // int nDrawnWords; // for(int i = 0; i < lines.size(); i++){ // for(int j = 0; j < lines[i].elements.size(); j++){ // nDrawnWords ++; // } // } // TS_STOP("count words"); //debug line heights! if(debug){ TS_START("draw line Heights"); ofSetColor(0,255,0,32); float yy = 0; for( const StyledLine &line : lines ){ ofDrawLine(offset.x + 0.5f, offset.y + yy + 0.5f, offset.x + line.lineW + 0.5f, offset.y + yy + 0.5f); yy += line.lineH; } TS_STOP("draw line Heights"); } ofxFontStashStyle drawStyle; drawStyle.fontSize = -1; float offY = 0.0f; // only track for return value TS_START("draw all lines"); FONT_STASH_PRE_DRAW; #ifndef GL_VERSION_3 if (pixelDensity != 1.0f){ //hmmmm ofScale(1.0f/pixelDensity, 1.0f/pixelDensity); } #endif for(int i = 0; i < lines.size(); i++){ y += lines[i].lineH; for(int j = 0; j < lines[i].elements.size(); j++){ if(lines[i].elements[j].content.type != SEPARATOR_INVISIBLE ){ //no need to draw the invisible chars const StyledLine &l = lines[i]; const LineElement &el = l.elements[j]; const string & texttt = el.content.styledText.text; if (el.content.styledText.style.valid && drawStyle != el.content.styledText.style ){ drawStyle = el.content.styledText.style; TS_START_ACC("applyStyle"); applyStyle(drawStyle); TS_STOP_ACC("applyStyle"); } //lines[i].elements[j].area.y += lines[i].lineH -lines[0].lineH; //TS_START_ACC("fonsDrawText"); fonsDrawText(fs, el.x * pixelDensity + offset.x, (el.baseLineY + l.lineH - lines[0].lineH) * pixelDensity + offset.y, texttt.c_str(), NULL); //TS_STOP_ACC("fonsDrawText"); //debug rects if(debug){ //TS_START_ACC("debug rects"); if(el.content.type == BLOCK_WORD) ofSetColor(70 * i, 255 - 70 * i, 0, 200); else ofSetColor(50 * i,255 - 50 * i, 0, 100); const ofRectangle &r = el.area; ofDrawRectangle(pixelDensity * r.x, pixelDensity * r.y, pixelDensity * r.width, pixelDensity * r.height); ofFill(); } } } } TS_STOP("draw all lines"); #ifndef GL_VERSION_3 ofPopMatrix(); #endif FONT_STASH_POST_DRAW; if(debug){ ofSetColor(255); } return offY; }