Example #1
0
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();
}
Example #2
0
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();
}
Example #3
0
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();
}
Example #5
0
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();
    }
}
Example #6
0
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;
}
Example #7
0
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();
}
Example #8
0
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;
}
Example #9
0
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();
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
0
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()));
 }
Example #15
0
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();
}
Example #16
0
/* 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());
}
Example #17
0
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;
}
Example #19
0
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;
  }
}
Example #20
0
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
	}
}
Example #21
0
/* 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();
}
Example #22
0
    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);
    }
Example #23
0
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;

}
Example #24
0
	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
	}
Example #25
0
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);
}
Example #26
0
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);
    }
}
Example #27
0
unsigned int Textprinter::getWidth(const string& str) {
    const char *text = str.c_str();

    FTBBox test = fonts[0]->BBox(text);
    return test.Upper().X();
}
Example #28
0
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];
}
Example #29
0
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;

}