ofRectangle ofxFTGLFont::getStringBoundingBox(wstring s, float x, float y){ if(loaded){ FTBBox bbox = font->BBox((wchar_t*)s.c_str(), -1, FTPoint(), trackingPoint); return ofRectangle(x, y-getAscender(), abs(bbox.Lower().Xf()-bbox.Upper().Xf()), abs(bbox.Upper().Yf()-bbox.Lower().Yf())); } return ofRectangle(); }
ofRectangle ofxFTGLESFont::getStringBoundingBox(wstring s, float x, float y){ if(loaded){ FTBBox bbox = font->BBox((wchar_t*)s.c_str()); return ofRectangle(x + bbox.Lower().Xf(), y + bbox.Lower().Yf(), bbox.Upper().Xf(), bbox.Upper().Yf()); } return ofRectangle(); }
void ftglGetGlyphBBox(FTGLglyph *g, float bounds[6]) { FTBBox ret = _ftglGetGlyphBBox(g); FTPoint lower = ret.Lower(), upper = ret.Upper(); bounds[0] = lower.Xf(); bounds[1] = lower.Yf(); bounds[2] = lower.Zf(); bounds[3] = upper.Xf(); bounds[4] = upper.Yf(); bounds[5] = upper.Zf(); }
void ftglGetFontBBox(FTGLfont *f, const char* s, int len, float c[6]) { FTBBox ret = _ftglGetFontBBox(f, s, len); FTPoint lower = ret.Lower(), upper = ret.Upper(); c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf(); c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf(); }
void Font::render(const vec3& pos, const std::string& text) const { if (simpleLayout_) { float delta = 0; std::string line; std::stringstream ss(text); std::getline(ss, line); FTPoint point(static_cast<double>(pos.x), static_cast<double>(pos.y), static_cast<double>(pos.z)); FTBBox box = font_->BBox(line.c_str(), -1, point); delta -= box.Upper().Yf() - box.Lower().Yf(); // height of first line Bounds bounds = getBounds(pos, text); float height = bounds.getURB().y - bounds.getLLF().y; switch(vAlign_) { case Font::Top: delta += height; break; case Font::Middle: delta += height * 0.5f; break; case Font::Bottom: break; } vec3 dpos = vec3(pos.x, pos.y + delta, pos.z); glPushMatrix(); glRasterPos3f(dpos.x, dpos.y, dpos.z); glTranslatef(dpos.x, dpos.y, dpos.z); simpleLayout_->Render(text.c_str(), -1, FTPoint(dpos.x, dpos.y, dpos.z)); glPopMatrix(); } }
void FTFont::BBox( const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox totalBBox; if((NULL != string) && ('\0' != *string)) { const wchar_t* c = string; float advance = 0; if(CheckGlyph( *c)) { totalBBox = glyphList->BBox( *c); advance = glyphList->Advance( *c, *(c + 1)); } while( *++c) { if(CheckGlyph( *c)) { FTBBox tempBBox = glyphList->BBox( *c); tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); totalBBox += tempBBox; advance += glyphList->Advance( *c, *(c + 1)); } } } llx = totalBBox.lowerX; lly = totalBBox.lowerY; llz = totalBBox.lowerZ; urx = totalBBox.upperX; ury = totalBBox.upperY; urz = totalBBox.upperZ; }
void ftgGetlLayoutBBox(FTGLlayout *l, const char * s, float c[6]) { FTBBox ret = _ftgGetlLayoutBBox(l, s); FTPoint lower = ret.Lower(), upper = ret.Upper(); c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf(); c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf(); }
void FTFont::BBox( const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox totalBBox; if((NULL != string) && ('\0' != *string)) { const unsigned char* c = (unsigned char*)string; CheckGlyph( *c); totalBBox = glyphList->BBox( *c); float advance = glyphList->Advance( *c, *(c + 1)); ++c; while( *c) { CheckGlyph( *c); FTBBox tempBBox = glyphList->BBox( *c); tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); totalBBox += tempBBox; advance += glyphList->Advance( *c, *(c + 1)); ++c; } } llx = totalBBox.lowerX; lly = totalBBox.lowerY; llz = totalBBox.lowerZ; urx = totalBBox.upperX; ury = totalBBox.upperY; urz = totalBBox.upperZ; }
ofRectangle ofxFTGLFont::getStringBoundingBox(const wstring& s, float x, float y){ if(loaded){ FTBBox bbox = font->BBox((wchar_t*)s.c_str(), -1, FTPoint(), trackingPoint); return ofRectangle(x + bbox.Lower().Xf(), y + bbox.Lower().Yf(), bbox.Upper().Xf(), bbox.Upper().Yf()); } return ofRectangle(); }
bool OglRenderer::getStringBBox(char *font, double size, char *string, rectObj *rect, double** advances) { FTFont* face = getFTFont(font, size); if (!face) { msSetError(MS_OGLERR, "Failed to load font (%s).", "OglRenderer::getStringBBox()", font); return false; } float llx =0.0f, lly=0.0f, llz=0.0f, urx=0.0f, ury=0.0f, urz=0.0f; glPushAttrib( GL_ALL_ATTRIB_BITS ); FTBBox boundingBox = face->BBox(string); glPopAttrib(); rect->minx = boundingBox.Lower().X(); rect->maxx = boundingBox.Upper().X(); rect->miny = -boundingBox.Upper().Y(); rect->maxy = -boundingBox.Lower().Y(); if (advances) { int length = strlen(string); *advances = new double[length]; for (int i = 0; i < length; ++i) { (*advances)[i] = face->Advance(&string[i], 1); } } return true; }
Vector2f Textprinter::getDimensions(const string& str) { const char *text = str.c_str(); FTBBox test = fonts[0]->BBox(text); Vector2f v(test.Upper().X(), test.Upper().Y()); return v; }
float FXFont::getWidth(const std::string & text) const{ FTBBox bb = ft->BBox(text.c_str()); float width = (bb.Upper().X() - bb.Lower().X()); return width; }
ofRectangle ofxFTGLSimpleLayout::getStringBoundingBox(string s, float x, float y) { if (loaded) { FTBBox bbox = layout->BBox(s.c_str()); return ofRectangle(x + bbox.Lower().Xf(), y + bbox.Lower().Yf(), bbox.Upper().Xf(), bbox.Upper().Yf()); } return ofRectangle(); }
Gwen::Point Chowdren::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString & text ) { FTSimpleLayout layout; layout.SetLineLength(10000); layout.SetFont(get_font(pFont->size)); FTBBox bbox = layout.BBox(text.c_str()); FTPoint size = bbox.Upper() - bbox.Lower(); return Gwen::Point((int)ceil(size.X()), (int)ceil(size.Y())); }
unsigned int Textprinter::getWidth(const char *fmt, ...) { va_list ap; /* our argument pointer */ char text[256]; va_start(ap, fmt); /* make ap point to first unnamed arg */ /* FIXME: we *should* do boundschecking or something to prevent buffer * overflows/segmentations faults */ vsprintf(text, fmt, ap); FTBBox test = fonts[0]->BBox(text); return test.Upper().X(); }
/* Drawing::textExtents * Returns the width and height of [text] when drawn with [font] *******************************************************************/ fpoint2_t Drawing::textExtents(string text, int font) { // Get desired font FTFont* ftgl_font = theFontManager->getFont(font); // If FTGL font is invalid, return empty if (!ftgl_font) return fpoint2_t(0,0); // Return width and height of text FTBBox bbox = ftgl_font->BBox(CHR(text), -1); return fpoint2_t(bbox.Upper().X() - bbox.Lower().X(), ftgl_font->LineHeight()); }
inline void FTSimpleLayoutImpl::OutputWrappedI(const T *buf, const int len, FTPoint position, int renderMode, const float remaining, FTBBox *bounds) { float distributeWidth = 0.0; // Align the text according as specified by Alignment switch (alignment) { case FTGL::ALIGN_LEFT: pen.X(0); break; case FTGL::ALIGN_CENTER: pen.X(remaining / 2); break; case FTGL::ALIGN_RIGHT: pen.X(remaining); break; case FTGL::ALIGN_JUSTIFY: pen.X(0); distributeWidth = remaining; break; } // If we have bounds expand them by the line's bounds, otherwise render // the line. if(bounds) { FTBBox temp = currentFont->BBox(buf, len); // Add the extra space to the upper x dimension temp = FTBBox(temp.Lower() + pen, temp.Upper() + pen + FTPoint(distributeWidth, 0)); // See if this is the first area to be added to the bounds if(bounds->IsValid()) { *bounds |= temp; } else { *bounds = temp; } } else { RenderSpace(buf, len, position, renderMode, distributeWidth); } }
float TextFTGL::LineHeight(const wchar_t* str, const int len) { static float result = -1000; if(result == -1000) { FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); result = box.Upper().Yf()- box.Lower().Yf(); if(result == 0) { result = ftFont->LineHeight(); } //printf("ftFont->BBox(''yW'')%f\n",result); } if(ftFont->Error()) { char szBuf[8096]=""; snprintf(szBuf,8096,"FTGL: error trying to get lineheight, #%d",ftFont->Error()); throw megaglest_runtime_error(szBuf); } return result; }
void FTTextGLObject::initContext(GLContextData& contextData) const { FTTextGLObjectDataItem* data = new FTTextGLObjectDataItem(); FTFontStyleNode* fs = text->fontStyle.getValue().getPointer(); contextData.addDataItem(this, data); FTBBox bbox = fs->ftfont->BBox(text->string.getValue(0).c_str()); text->boundingBox = Box(Point(bbox.Lower().X(), bbox.Lower().Y(), bbox.Lower().Z()), Point(bbox.Upper().X(), bbox.Upper().Y(), bbox.Upper().Z())); // Dodgy float width = (bbox.Upper().X() - bbox.Lower().X()); switch (fs->justify_major) { case FTFontStyle::FIRST: case FTFontStyle::BEGIN: data->offset = 0; break; case FTFontStyle::MIDDLE: data->offset = -width/2.0; break; case FTFontStyle::END: data->offset = -width; break; default: data->offset = 0; break; } }
void TextBBox(const double & i_dSize, const char * i_lpszString, PAIR<double> & o_cBot_Left, PAIR<double> & o_cTop_Right) { FTBBox cBBox; if (g_lpcCurrent_Face) { cBBox = g_lpcCurrent_Face->BBox(i_lpszString); o_cBot_Left.m_tX = cBBox.Lower().X(); o_cBot_Left.m_tY = cBBox.Lower().Y(); o_cTop_Right.m_tX = cBBox.Upper().X(); o_cTop_Right.m_tY = cBBox.Upper().Y(); if (o_cTop_Right.m_tX < o_cBot_Left.m_tX) { double dTemp = o_cBot_Left.m_tX; o_cBot_Left.m_tX = o_cTop_Right.m_tX; o_cTop_Right.m_tX = dTemp; } o_cBot_Left *= i_dSize * 0.0125; o_cTop_Right *= i_dSize * 0.0125; // scaling to size used in rendering } }
/* Drawing::drawText * Draws [text] at [x,y]. If [bounds] is not null, the bounding * coordinates of the rendered text string are written to it. *******************************************************************/ void Drawing::drawText(string text, int x, int y, rgba_t colour, int font, int alignment, frect_t* bounds) { // Get desired font FTFont* ftgl_font = theFontManager->getFont(font); // If FTGL font is invalid, do nothing if (!ftgl_font) return; // Setup alignment FTBBox bbox = ftgl_font->BBox(CHR(text), -1); int xpos = x; int ypos = y; float width = bbox.Upper().X() - bbox.Lower().X(); float height = ftgl_font->LineHeight(); if (alignment != ALIGN_LEFT) { if (alignment == ALIGN_CENTER) xpos -= MathStuff::round(width*0.5); else xpos -= width; } // Set bounds rect if (bounds) { bbox = ftgl_font->BBox(CHR(text), -1, FTPoint(xpos, ypos)); bounds->set(bbox.Lower().X(), bbox.Lower().Y(), bbox.Upper().X(), bbox.Lower().Y() + height); } // Draw the string glPushMatrix(); glTranslatef(xpos, ypos + ftgl_font->FaceSize(), 0.0f); glTranslatef(-0.375f, -0.375f, 0); glScalef(1.0f, -1.0f, 1.0f); if (text_outline_width > 0) { // Draw outline if set OpenGL::setColour(text_outline_colour); glTranslatef(-1.0f, -1.0f, 0.0f); ftgl_font->Render(CHR(text), -1); glTranslatef(0.0f, 2.0f, 0.0f); ftgl_font->Render(CHR(text), -1); glTranslatef(2.0f, 0.0f, 0.0f); ftgl_font->Render(CHR(text), -1); glTranslatef(0.0f, -2.0f, 0.0f); ftgl_font->Render(CHR(text), -1); glTranslatef(-1.0f, 1.0f, 0.0f); } OpenGL::setColour(colour); ftgl_font->Render(CHR(text), -1); glPopMatrix(); }
void testMoveBBox() { FTBBox boundingBox; FTPoint firstMove( 3.5f, 1.0f, -2.5f); FTPoint secondMove( -3.5f, -1.0f, 2.5f); boundingBox.Move( firstMove); CPPUNIT_ASSERT( boundingBox.lowerX == 3.5f); CPPUNIT_ASSERT( boundingBox.lowerY == 1.0f); CPPUNIT_ASSERT( boundingBox.lowerZ == -2.5f); CPPUNIT_ASSERT( boundingBox.upperX == 3.5f); CPPUNIT_ASSERT( boundingBox.upperY == 1.0f); CPPUNIT_ASSERT( boundingBox.upperZ == -2.5f); boundingBox.Move( secondMove); CPPUNIT_ASSERT( boundingBox.lowerX == 0.0f); CPPUNIT_ASSERT( boundingBox.lowerY == 0.0f); CPPUNIT_ASSERT( boundingBox.lowerZ == 0.0f); CPPUNIT_ASSERT( boundingBox.upperX == 0.0f); CPPUNIT_ASSERT( boundingBox.upperY == 0.0f); CPPUNIT_ASSERT( boundingBox.upperZ == 0.0f); }
Font::FONT_RECT Font::measureText(const wchar_t* wText) throw(invalid_argument, runtime_error) { ASSERT( (wText != 0), invalid_argument("wText") ); if(font_ == 0) { return Font::FONT_RECT(); } FTBBox bbox = font_->BBox(wText, -1); FTPoint low = bbox.Lower(); FTPoint hi = bbox.Upper(); Font::FONT_RECT rect; rect.width = hi.X() - low.X(); rect.height = hi.Y() - low.Y(); return rect; }
float Font::length(const String &txt) { if (txt.empty()) return 0.0f; if (' ' == txt.last()) return length(String(txt) << "_") - length("_"); MutexLocker locker(pMutex); if (!font) return 0.0f; #ifdef __FTGL__lower__ FTBBox box = font->BBox( txt.c_str() ); return fabsf((box.Upper().Xf() - box.Lower().Xf())); #else float x0, y0, z0, x1, y1, z1; # ifndef TA3D_PLATFORM_DARWIN WString wstr(txt); font->BBox(wstr.cw_str(), x0, y0, z0, x1, y1, z1); # else font->BBox(txt.c_str(), x0, y0, z0, x1, y1, z1); # endif return fabsf(x0 - x1); #endif }
Bounds Font::getBounds(const vec3& pos, const std::string& text) const { if (!font_) return Bounds(); FTPoint point(static_cast<double>(pos.x), static_cast<double>(pos.y), static_cast<double>(pos.z)); float delta = 0; std::string line; std::stringstream ss(text); std::getline(ss, line); FTBBox box_tmp = font_->BBox(line.c_str(), -1, point); delta -= box_tmp.Upper().Yf() - box_tmp.Lower().Yf(); // height of first line FTBBox box = simpleLayout_->BBox(text.c_str(), -1, point); FTPoint upper = box.Upper(); FTPoint lower = box.Lower(); float height = upper.Yf() - lower.Yf(); switch(vAlign_) { case Font::Top: delta += height; break; case Font::Middle: delta += height * 0.5f; break; case Font::Bottom: break; } vec3 upperTGT = vec3(upper.Xf(), upper.Yf() + delta, upper.Zf()); vec3 lowerTGT = vec3(lower.Xf(), lower.Yf() + delta, lower.Zf()); return Bounds(lowerTGT, upperTGT); }
inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, FTPoint position, int renderMode, FTBBox *bounds) { FTUnicodeStringItr<T> breakItr(buf); // points to the last break character FTUnicodeStringItr<T> lineStart(buf); // points to the line start float nextStart = 0.0; // total width of the current line float breakWidth = 0.0; // width of the line up to the last word break float currentWidth = 0.0; // width of all characters on the current line float prevWidth; // width of all characters but the current glyph float wordLength = 0.0; // length of the block since the last break char int charCount = 0; // number of characters so far on the line int breakCharCount = 0; // number of characters before the breakItr float glyphWidth, advance; FTBBox glyphBounds; // Reset the pen position pen.Y(0); // If we have bounds mark them invalid if(bounds) { bounds->Invalidate(); } // Scan the input for all characters that need output FTUnicodeStringItr<T> prevItr(buf); for (FTUnicodeStringItr<T> itr(buf); *itr; prevItr = itr++, charCount++) { // Find the width of the current glyph glyphBounds = currentFont->BBox(itr.getBufferFromHere(), 1); glyphWidth = glyphBounds.Upper().Xf() - glyphBounds.Lower().Xf(); advance = currentFont->Advance(itr.getBufferFromHere(), 1); prevWidth = currentWidth; // Compute the width of all glyphs up to the end of buf[i] currentWidth = nextStart + glyphWidth; // Compute the position of the next glyph nextStart += advance; // See if the current character is a space, a break or a regular character if((currentWidth > lineLength) || (*itr == '\n')) { // A non whitespace character has exceeded the line length. Or a // newline character has forced a line break. Output the last // line and start a new line after the break character. // If we have not yet found a break, break on the last character if(breakItr == lineStart || (*itr == '\n')) { // Break on the previous character breakItr = prevItr; breakCharCount = charCount - 1; breakWidth = prevWidth; // None of the previous words will be carried to the next line wordLength = 0; // If the current character is a newline discard its advance if(*itr == '\n') advance = 0; } float remainingWidth = lineLength - breakWidth; // Render the current substring FTUnicodeStringItr<T> breakChar = breakItr; // move past the break character and don't count it on the next line either ++breakChar; --charCount; // If the break character is a newline do not render it if(*breakChar == '\n') { ++breakChar; --charCount; } if(breakCharCount >= 0) { OutputWrapped(lineStart.getBufferFromHere(), breakCharCount, //breakItr.getBufferFromHere() - lineStart.getBufferFromHere(), position, renderMode, remainingWidth, bounds); } // Store the start of the next line lineStart = breakChar; // TODO: Is Height() the right value here? pen -= FTPoint(0, currentFont->LineHeight() * lineSpacing); // The current width is the width since the last break nextStart = wordLength + advance; wordLength += advance; currentWidth = wordLength + advance; // Reset the safe break for the next line breakItr = lineStart; charCount -= breakCharCount; } else if(iswspace(*itr)) { // This is the last word break position wordLength = 0; breakItr = itr; breakCharCount = charCount; // Check to see if this is the first whitespace character in a run if(buf == itr.getBufferFromHere() || !iswspace(*prevItr)) { // Record the width of the start of the block breakWidth = currentWidth; } } else { wordLength += advance; } } float remainingWidth = lineLength - currentWidth; // Render any remaining text on the last line // Disable justification for the last row if(alignment == FTGL::ALIGN_JUSTIFY) { alignment = FTGL::ALIGN_LEFT; OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode, remainingWidth, bounds); alignment = FTGL::ALIGN_JUSTIFY; } else { OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode, remainingWidth, bounds); } }
unsigned int Textprinter::getWidth(const string& str) { const char *text = str.c_str(); FTBBox test = fonts[0]->BBox(text); return test.Upper().X(); }
inline FTPoint FTBufferFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { const float padding = 3.0f; int width, height, texWidth, texHeight; int cacheIndex = -1; bool inCache = false; // Protect blending functions, GL_BLEND and GL_TEXTURE_2D glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); // Protect glPixelStorei() calls glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glEnable(GL_TEXTURE_2D); if ((renderMode & FTGL::RENDER_NOBLEND) == 0) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE } // Search whether the string is already in a texture we uploaded for(int n = 0; n < BUFFER_CACHE_SIZE; n++) { int i = (lastString + n + BUFFER_CACHE_SIZE) % BUFFER_CACHE_SIZE; if(stringCache[i] && !StringCompare(stringCache[i], string, len)) { cacheIndex = i; inCache = true; break; } } // If the string was not found, we need to put it in the cache and compute // its new bounding box. if(!inCache) { // FIXME: this cache is not very efficient. We should first expire // strings that are not used very often. cacheIndex = lastString; lastString = (lastString + 1) % BUFFER_CACHE_SIZE; if(stringCache[cacheIndex]) { free(stringCache[cacheIndex]); } // FIXME: only the first N bytes are copied; we want the first N chars. stringCache[cacheIndex] = StringCopy(string, len); bboxCache[cacheIndex] = BBox(string, len, FTPoint(), spacing); } FTBBox bbox = bboxCache[cacheIndex]; width = static_cast<int>(bbox.Upper().X() - bbox.Lower().X() + padding + padding + 0.5); height = static_cast<int>(bbox.Upper().Y() - bbox.Lower().Y() + padding + padding + 0.5); texWidth = NextPowerOf2(width); texHeight = NextPowerOf2(height); glBindTexture(GL_TEXTURE_2D, idCache[cacheIndex]); // If the string was not found, we need to render the text in a new // texture buffer, then upload it to the OpenGL layer. if(!inCache) { buffer->Size(texWidth, texHeight); buffer->Pos(FTPoint(padding, padding) - bbox.Lower()); advanceCache[cacheIndex] = FTFontImpl::Render(string, len, FTPoint(), spacing, renderMode); glBindTexture(GL_TEXTURE_2D, idCache[cacheIndex]); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* TODO: use glTexSubImage2D later? */ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texWidth, texHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, (GLvoid *)buffer->Pixels()); buffer->Size(0, 0); } FTPoint low = position + bbox.Lower(); FTPoint up = position + bbox.Upper(); glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(padding / texWidth, (texHeight - height + padding) / texHeight); glVertex2f(low.Xf(), up.Yf()); glTexCoord2f(padding / texWidth, (texHeight - padding) / texHeight); glVertex2f(low.Xf(), low.Yf()); glTexCoord2f((width - padding) / texWidth, (texHeight - padding) / texHeight); glVertex2f(up.Xf(), low.Yf()); glTexCoord2f((width - padding) / texWidth, (texHeight - height + padding) / texHeight); glVertex2f(up.Xf(), up.Yf()); glEnd(); glPopClientAttrib(); glPopAttrib(); return position + advanceCache[cacheIndex]; }
void renderFontmetrics() { FTBBox bbox; float x1, y1, z1, x2, y2, z2; // If there is a layout, use it to compute the bbox, otherwise query as // a string. if(layouts[currentLayout]) bbox = layouts[currentLayout]->BBox(myString); else bbox = fonts[current_font]->BBox(myString); x1 = bbox.Lower().Xf(); y1 = bbox.Lower().Yf(); z1 = bbox.Lower().Zf(); x2 = bbox.Upper().Xf(); y2 = bbox.Upper().Yf(); z2 = bbox.Upper().Zf(); // Draw the bounding box glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); // GL_ONE_MINUS_SRC_ALPHA glColor3f(0.0, 1.0, 0.0); // Draw the front face glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, z1); glVertex3f(x1, y2, z1); glVertex3f(x2, y2, z1); glVertex3f(x2, y1, z1); glEnd(); // Draw the back face if((GetStyle() == FTGL_EXTRUDE) && (z1 != z2)) { glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, z2); glVertex3f(x1, y2, z2); glVertex3f(x2, y2, z2); glVertex3f(x2, y1, z2); glEnd(); // Join the faces glBegin(GL_LINES); glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z2); glVertex3f(x1, y2, z1); glVertex3f(x1, y2, z2); glVertex3f(x2, y2, z1); glVertex3f(x2, y2, z2); glVertex3f(x2, y1, z1); glVertex3f(x2, y1, z2); glEnd(); } // Render layout-specific metrics if(!layouts[currentLayout]) { // There is no layout. Draw the baseline, Ascender and Descender glBegin(GL_LINES); glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(fonts[current_font]->Advance(myString), 0.0, 0.0); glVertex3f(0.0, fonts[current_font]->Ascender(), 0.0); glVertex3f(0.0, fonts[current_font]->Descender(), 0.0); glEnd(); } else if (layouts[currentLayout] && (dynamic_cast <FTSimpleLayout *>(layouts[currentLayout]))) { float lineWidth = ((FTSimpleLayout *)layouts[currentLayout])->GetLineLength(); // The layout is a SimpleLayout. Render guides that mark the edges // of the wrap region. glColor3f(0.5, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(0, 10000, 0); glVertex3f(0, -10000, 0); glVertex3f(lineWidth, 10000, 0); glVertex3f(lineWidth, -10000, 0); glEnd(); } // Draw the origin glColor3f(1.0, 0.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); glVertex3f(0.0, 0.0, 0.0); glEnd(); }
float TextFTGL::LineHeight(const char* str, const int len) { //FTBBox box = ftFont->BBox(str); //printf("String [%s] lineheight = %f upper_y = %f lower_y = %f\n",str,ftFont->LineHeight(),box.Upper().Y(),box.Lower().Y()); //printf("ftFont->Ascender():%f ftFont->Descender()*-1 = %f ftFont->LineHeight() = %f\n",ftFont->Ascender(),ftFont->Descender()*-1 , ftFont->LineHeight()); //return ftFont->Ascender() + ftFont->Descender()*-1 - ftFont->LineHeight(); //return ftFont->LineHeight(); //static float result = -1000; float result = -1000; if(result == -1000) { FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); GLenum error = glGetError(); if(error != GL_NO_ERROR) { printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); fflush(stdout); } result = box.Upper().Yf()- box.Lower().Yf(); if(result == 0) { result = ftFont->LineHeight(); GLenum error = glGetError(); if(error != GL_NO_ERROR) { printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); fflush(stdout); } } //printf("ftFont->BBox(''yW'')%f\n",result); } // else { // FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); // // GLenum error = glGetError(); // if(error != GL_NO_ERROR) { // printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); // fflush(stdout); // } // // int newresult = box.Upper().Y()- box.Lower().Y(); // if(newresult == 0) { // newresult = ftFont->LineHeight(); // // GLenum error = glGetError(); // if(error != GL_NO_ERROR) { // printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); // fflush(stdout); // } // } // // printf("Height for [%s] result [%d] [%d]\n",str,result,newresult); // } if(ftFont->Error()) { char szBuf[8096]=""; snprintf(szBuf,8096,"FTGL: error trying to get lineheight, #%d",ftFont->Error()); throw megaglest_runtime_error(szBuf); } return result; // printf("For str [%s] LineHeight = %f, result = %f\n",str, ftFont->LineHeight(),result); // return result; //float urx = box.Upper().X(); //float llx = box.Lower().X(); //float llx, lly, llz, urx, ury, urz; //ftFont->BBox(str, llx, lly, llz, urx, ury, urz); //return ury - lly; //Short_t halign = fTextAlign/10; //Short_t valign = fTextAlign - 10*halign; //Float_t dx = 0, dy = 0; // switch (halign) { // case 1 : dx = 0 ; break; // case 2 : dx = -urx/2; break; // case 3 : dx = -urx ; break; // } // switch (valign) { // case 1 : dy = 0 ; break; // case 2 : dy = -ury/2; break; // case 3 : dy = -ury ; break; // } //printf("For str [%s] advance = %f, urx = %f, llx = %f\n",str, ftFont->Advance(str, len),urx,llx); //return urx; }