int GraphicsElementManager::LoadTextureFont( const string& font_texture_filename,
											  int width, int height,
											  float bold, float italic, float shadow )
{
	LOG_PRINT( " - Loading a texture for font: " + font_texture_filename );

	TextureFont* pFont = new TextureFont();
	bool res = pFont->InitFont( font_texture_filename, (int)(width * m_fScale), (int)(height * m_fScale) );
	if( res )
	{
		// save the original size of the font
		// used when the scaling is requested
		m_vecOrigFontSize.push_back( Vector2( (float)width, (float)height ) );

//		pFont->SetBold( bold );
		pFont->SetItalic( italic );

		m_vecpFont.push_back( pFont );
		return (int)m_vecpFont.size() - 1;
	}
	else
	{
		LOG_PRINT_ERROR( " - Cannot load a texture for font: " + font_texture_filename );
		SafeDelete( pFont );
		return -1;
	}
}
예제 #2
0
void TextLayout::_RenderRaw(float maxWidth) const
{
	TextureFont *font = Gui::Screen::GetFont();
	float py = 0;
	init_clip_test();

	glPushMatrix();

	const float spaceWidth = font->GetGlyph(' ').advx;

	std::list<word_t>::const_iterator wpos = this->words.begin();
	// build lines of text
	while (wpos != this->words.end()) {
		float len = 0;
		int num = 0;

		std::list<word_t>::const_iterator i = wpos;
		len += (*i).advx;
		num++;
		bool overflow = false;
		bool explicit_newline = false;
		if ((*i).word != 0) {
			++i;
			for (; i != this->words.end(); ++i) {
				if ((*i).word == 0) {
					// newline
					explicit_newline = true;
					num++;
					break;
				}
				if (len + spaceWidth + (*i).advx > maxWidth) { overflow = true; break; }
				len += (*i).advx + spaceWidth;
				num++;
			}
		}

		float _spaceWidth;
		if ((m_justify) && (num>1) && overflow) {
			float spaceleft = maxWidth - len;
			_spaceWidth = spaceWidth + (spaceleft/float(num-1));
		} else {
			_spaceWidth = spaceWidth;
		}

		if (line_clip_test(py, py+font->GetHeight()*2.0)) {
			float px = 0;
			for (int j=0; j<num; j++) {
				if ((*wpos).word) font->RenderMarkup((*wpos).word, round(px), round(py));
				px += (*wpos).advx + _spaceWidth;
				wpos++;
			}
		} else {
			for (int j=0; j<num; j++) wpos++;
		}
		py += font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : LINE_SPACING);
	}
	glPopMatrix();
}
예제 #3
0
void TextLayout::_MeasureSizeRaw(const float layoutWidth, float outSize[2]) const
{
	TextureFont *font = Gui::Screen::GetFont();
	outSize[0] = 0;
	outSize[1] = 0;

	const float spaceWidth = font->GetGlyph(' ').advx;

	// build lines of text
	for (std::list<word_t>::const_iterator wpos = words.begin(); wpos != words.end(); ) {
		float len = 0;
		int num = 0;
		bool explicit_newline = false;

		std::list<word_t>::const_iterator i = wpos;
		len += (*i).advx;
		num++;
		bool overflow = false;
		if ((*i).word != 0) {
			++i;
			for (; i != words.end(); ++i) {
				if ((*i).word == 0) {
					// newline
					explicit_newline = true;
					num++;
					break;
				}
				if (len + spaceWidth + (*i).advx > layoutWidth) { overflow = true; break; }
				len += (*i).advx + spaceWidth;
				num++;
			}
		}

		float _spaceWidth;
		if ((m_justify) && (num>1) && overflow) {
			float spaceleft = layoutWidth - len;
			_spaceWidth = spaceWidth + (spaceleft/float(num-1));
		} else {
			_spaceWidth = spaceWidth;
		}

		float lineLen = 0;
		for (int j=0; j<num; j++) {
			word_t word = (*wpos);
			lineLen += word.advx;
			if (j < num-1) lineLen += _spaceWidth;
			wpos++;
		}
		if (lineLen > outSize[0]) outSize[0] = lineLen;
		outSize[1] += font->GetHeight() * (explicit_newline ? PARAGRAPH_SPACING : LINE_SPACING);
	}
	if (outSize[1]) outSize[1] += font->GetDescender();
}
예제 #4
0
/** Load a texture font from a chunk of data containing font data
  * in the TXF format used by GLUT.
  */
TextureFont*
TextureFont::LoadTxf(const DataChunk* data)
{
    TextureFont* font = new TextureFont();
    if (font->loadTxf(data))
    {
        // TODO: Should skip the addRef
        font->addRef();
    }
    else
    {
        delete font;
        font = NULL;
    }

    return font;
}
예제 #5
0
float FontManager::getStrLength(int faceID, float size, std::string text)
{
  if (text.size() == 0)
    return 0;

  if ((faceID < 0) || (faceID > getNumFaces())) {
    DEBUG2("Trying to find length of string for invalid Font Face ID %d\n", faceID);
    return 0;
  }

  TextureFont* pFont = getClosestSize(faceID, size);

  if (!pFont)
    return 0;

  float scale = size / (float)pFont->getSize();

  return pFont->getStrLength(scale, stripAnsiCodes(text).c_str());
}
예제 #6
0
void FontManager::loadAll(std::string directory)
{
  if (directory.size() == 0)
    return;

  OSFile file;

  OSDir dir(directory.c_str());

  while (dir.getNextFile(file, true)) {
    const char *ext = file.getExtension();

    if (ext) {
      if (strcasecmp(ext, "fmt") == 0) {
	TextureFont *pFont = new TextureFont;
	if (pFont) {
	  if (pFont->load(file)) {
	    std::string	str = pFont->getFaceName();
	    GetTypeFaceName((char*)str.c_str());

	    FontFaceMap::iterator faceItr = faceNames.find(str);
	    
	    int faceID = 0;
	    if (faceItr == faceNames.end()) {
	      // its new
	      FontSizeMap faceList;
	      fontFaces.push_back(faceList);
	      faceID = (int)fontFaces.size() - 1;
	      faceNames[str] = faceID;
	    } else {
	      faceID = faceItr->second;
	    }

	    fontFaces[faceID][pFont->getSize()] = pFont;
	  } else {
	    DEBUG4("Font Texture load failed: %s\n", file.getOSName());
	    delete(pFont);
	  }
	}
      }
    }
  }
}
예제 #7
0
void FontManager::drawString(float x, float y, float z, int faceID, float size, std::string text)
{
  if (text.size() == 0)
    return;

  if ((faceID < 0) || (faceID > getNumFaces())) {
    DEBUG2("Trying to draw with invalid Font Face ID %d\n", faceID);
    return;
  }

  TextureFont* pFont = getClosestSize(faceID, size);

  if (!pFont)
    return;

  float scale = size / (float)pFont->getSize();

  /* 
   * Colorize text based on ANSI codes embedded in it
   * Break the text every time an ANSI code
   * is encountered and do a separate pFont->drawString code for
   * each segment, with the appropriate color parameter
   */

  // sane defaults
  bool bright = true;
  bool blink = false;	  //FIXME: blinking
  bool underline = false; //FIXME: underline
  // negatives are invalid, we use them to signal "no change"
  GLfloat color[3] = {-1.0f, -1.0f, -1.0f}; 

  // set underline color
  const char* uColor = BZDB.get("underlineColor").c_str();
  GLfloat underlineColor[3] = {-1.0f, -1.0f, -1.0f};
  if (strcasecmp(uColor, "text") == 0) {
    // use the initialized color, no change
  } else if (strcasecmp(uColor, "cyan") == 0) {
    underlineColor[0] = BrightColors[CyanColor][0];
    underlineColor[1] = BrightColors[CyanColor][1];
    underlineColor[2] = BrightColors[CyanColor][2];
  } else if (strcasecmp(uColor, "grey") == 0) {
    underlineColor[0] = BrightColors[GreyColor][0];
    underlineColor[1] = BrightColors[GreyColor][1];
    underlineColor[2] = BrightColors[GreyColor][2];
  }

  /*
   * ANSI code interpretation is somewhat limited, we only accept values
   * which have been defined in AnsiCodes.h
   */

  bool doneLastSection = false;
  int startSend = 0;
  int endSend = (int)text.find("\033[", startSend);
  std::string tmpText;
  bool tookCareOfANSICode = false;
  float width = 0;
  // run at least once
  if (endSend == -1) {
    endSend = (int)text.size();
    doneLastSection = true;
  }
  // split string into parts based on the embedded ANSI codes, render each separately
  // there has got to be a faster way to do this
  while (endSend >= 0) {
    // blink the text, if desired
    if (blink)
      getBlinkColor(color, color);
    // render text
    if (endSend - startSend > 0) {
      tmpText = text.substr(startSend, (endSend - startSend));
      // get substr width, we may need it a couple times
      width = getStrLength(faceID, size, tmpText);
      glPushMatrix();
      glTranslatef(x, y, z);
      GLboolean depthMask;
      glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
      glDepthMask(0);
      pFont->drawString(scale, color, tmpText.c_str());
      if (underline) {
	OpenGLGState::resetState();  // FIXME - full reset required?
	if (underlineColor[0] >= 0)
	  glColor3fv(underlineColor);
	// still have a translated matrix, these coordinates are
	// with respect to the string just drawn
	glBegin(GL_LINES);
	glVertex2f(0, -1.0f);
	glVertex2f(width, -1.0f);
	glEnd();
      }
      glDepthMask(depthMask);
      glPopMatrix();
      // x transform for next substr
      x += width;
    }
    if (!doneLastSection) {
      startSend = (int)text.find("m", endSend) + 1;
    }
    // we stopped sending text at an ANSI code, find out what it is and do something about it
    if (endSend != (int)text.size()) {
      tookCareOfANSICode = false;
      tmpText = text.substr(endSend, (text.find("m", endSend) - endSend) + 1);
      // colors
      for (int i = 0; i < 8; i++) {
	if (tmpText == ColorStrings[i]) {
	  if (bright) {
	    color[0] = BrightColors[i][0];
	    color[1] = BrightColors[i][1];
	    color[2] = BrightColors[i][2];
	  } else {
	    color[0] = DimColors[i][0];
	    color[1] = DimColors[i][1];
	    color[2] = DimColors[i][2];
	  }
	  tookCareOfANSICode = true;
	  break;
	}
      }
      // didn't find a matching color
      if (!tookCareOfANSICode) {
	// settings other than color
	if (tmpText == ANSI_STR_RESET) {
	  bright = true;
	  blink = false;
	  underline = false;
	  color[0] = BrightColors[WhiteColor][0];
	  color[1] = BrightColors[WhiteColor][1];
	  color[2] = BrightColors[WhiteColor][2];
	} else if (tmpText == ANSI_STR_RESET_FINAL) {
	  bright = false;
	  blink = false;
	  underline = false;
	  color[0] = DimColors[WhiteColor][0];
	  color[1] = DimColors[WhiteColor][1];
	  color[2] = DimColors[WhiteColor][2];
	} else if (tmpText == ANSI_STR_BRIGHT) {
	  bright = true;
	} else if (tmpText == ANSI_STR_DIM) {
	  bright = false;
	} else if (tmpText == ANSI_STR_UNDERLINE) {
	  underline = !underline;
	} else if (tmpText == ANSI_STR_BLINK) {
	  blink = !blink;
	} else {
	  DEBUG2("ANSI Code %s not supported\n", tmpText.c_str());
	}
      }
    }
    endSend = (int)text.find("\033[", startSend);
    if ((endSend == -1) && !doneLastSection) {
      endSend = (int)text.size();
      doneLastSection = true;
    }
  }
}
예제 #8
0
파일: texturefont.cpp 프로젝트: jpcoles/ZM
TextureFont* TextureFont::load(istream& in)
{
    char header[4];

    in.read(header, sizeof header);
    if (!in.good() || strncmp(header, "\377txf", 4) != 0)
    {
        DPRINTF(0, "Stream is not a texture font!.\n");
        return NULL;
    }

    uint32 endiannessTest = 0;
    in.read(reinterpret_cast<char*>(&endiannessTest), sizeof endiannessTest);
    if (!in.good())
    {
        DPRINTF(0, "Error reading endianness bytes in txf header.\n");
        return NULL;
    }

    bool byteSwap;
    if (endiannessTest == 0x78563412)
        byteSwap = true;
    else if (endiannessTest == 0x12345678)
        byteSwap = false;
    else
    {
        DPRINTF(0, "Stream is not a texture font!.\n");
        return NULL;
    }

    int format = readUint32(in, byteSwap);
    unsigned int texWidth = readUint32(in, byteSwap);
    unsigned int texHeight = readUint32(in, byteSwap);
    unsigned int maxAscent = readUint32(in, byteSwap);
    unsigned int maxDescent = readUint32(in, byteSwap);
    unsigned int nGlyphs = readUint32(in, byteSwap);

    if (!in)
    {
        DPRINTF(0, "Texture font stream is incomplete");
        return NULL;
    }

    DPRINTF(1, "Font contains %d glyphs.\n", nGlyphs);

    TextureFont* font = new TextureFont();
    assert(font != NULL);

    font->setMaxAscent(maxAscent);
    font->setMaxDescent(maxDescent);

    float dx = 0.5f / texWidth;
    float dy = 0.5f / texHeight;

    for (unsigned int i = 0; i < nGlyphs; i++)
    {
        uint16 __id = readUint16(in, byteSwap);
        TextureFont::Glyph glyph(__id);

        glyph.width = readUint8(in);
        glyph.height = readUint8(in);
        glyph.xoff = readInt8(in);
        glyph.yoff = readInt8(in);
        glyph.advance = readInt8(in);
        readInt8(in);
        glyph.x = readInt16(in, byteSwap);
        glyph.y = readInt16(in, byteSwap);
        
        if (!in)
        {
            DPRINTF(0, "Error reading glyph %ud from texture font stream.\n", i);
            delete font;
            return NULL;
        }

        float fWidth = texWidth;
        float fHeight = texHeight;
        glyph.texCoords[0].u = glyph.x / fWidth + dx;
        glyph.texCoords[0].v = glyph.y / fHeight + dy;
        glyph.texCoords[1].u = (glyph.x + glyph.width) / fWidth + dx;
        glyph.texCoords[1].v = glyph.y / fHeight + dy;
        glyph.texCoords[2].u = (glyph.x + glyph.width) / fWidth + dx;
        glyph.texCoords[2].v = (glyph.y + glyph.height) / fHeight + dy;
        glyph.texCoords[3].u = glyph.x / fWidth + dx;
        glyph.texCoords[3].v = (glyph.y + glyph.height) / fHeight + dy;

        font->addGlyph(glyph);
    }

    font->texWidth = texWidth;
    font->texHeight = texHeight;
    if (format == TxfByte)
    {
        unsigned char* fontImage = new unsigned char[texWidth * texHeight];
        if (fontImage == NULL)
        {
            DPRINTF(0, "Not enough memory for font bitmap.\n");
            delete font;
            return NULL;
        }

        DPRINTF(1, "Reading %d x %d 8-bit font image.\n", texWidth, texHeight);

        in.read(reinterpret_cast<char*>(fontImage), texWidth * texHeight);
        if (in.gcount() != (signed)(texWidth * texHeight))
        {
            DPRINTF(0, "Missing bitmap data in font stream.\n");
            delete font;
            delete[] fontImage;
            return NULL;
        }

        font->fontImage = fontImage;
    }
    else
    {
        int rowBytes = (texWidth + 7) >> 3;
        unsigned char* fontBits = new unsigned char[rowBytes * texHeight];
        unsigned char* fontImage = new unsigned char[texWidth * texHeight];
        if (fontImage == NULL || fontBits == NULL)
        {
            DPRINTF(0, "Not enough memory for font bitmap.\n");
            delete font;
            if (fontBits != NULL)
                delete[] fontBits;
            if (fontImage != NULL)
                delete[] fontImage;
            return NULL;
        }

        DPRINTF(1, "Reading %d x %d 1-bit font image.\n", texWidth, texHeight);

        in.read(reinterpret_cast<char*>(fontBits), rowBytes * texHeight);
        if (in.gcount() != (signed)(rowBytes * texHeight))
        {
            DPRINTF(0, "Missing bitmap data in font stream.\n");
            delete font;
            return NULL;
        }

        for (unsigned int y = 0; y < texHeight; y++)
        {
            for (unsigned int x = 0; x < texWidth; x++)
            {
                if ((fontBits[y * rowBytes + (x >> 3)] & (1 << (x & 0x7))) != 0)
                    fontImage[y * texWidth + x] = 0xff;
                else
                    fontImage[y * texWidth + x] = 0x0;
            }
        }

        font->fontImage = fontImage;
        delete[] fontBits;
    }
예제 #9
0
파일: main.cpp 프로젝트: KAlO2/Pea
int main()
{
    auto error_callback = [](int error, const char* description)
    {
        slog.e(TAG, "Error (%d): %s\n", error, description);
    };
    glfwSetErrorCallback(error_callback);

    if(glfwInit() != GLFW_TRUE)
    {
        slog.e(TAG, "Failed to initialize GLFW library" );
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Open a window and create its OpenGL context
    GLFWwindow* window = glfwCreateWindow(window_size.width, window_size.height, TAG, NULL, NULL);
    if(!window)
    {
        slog.e(TAG, "Failed to open GLFW window. Not OpenGL 3.3 compatible");
        glfwTerminate();
        return -2;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLEW
    glewExperimental = true; // Needed for core profile
    if(glewInit() != GLEW_OK)
    {
        slog.e(TAG, "Failed to initialize GLEW library");
        glfwTerminate();
        return -3;
    }

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // Hide the mouse and enable unlimited mouvement
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

    glfwPollEvents();

    // Set the mouse at the center of the screen
    glfwSetCursorPos(window, window_size.width/2, window_size.height/2);

    // Enable depth test
    glEnable(GL_DEPTH_TEST);

    // Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);

    // Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE);

//	double lastTime = glfwGetTime();

    std::string dir = File::dirname(__FILE__);
    bool flag = Program::loadFromFile(program, dir + "/font.vert", dir + "/font.frag");
    assert(flag);
    program.use();

    font.load(File::getResourcePath() + "/font/FreeSans.ttf", 48);
    while(true)
    {
        // Dark blue background
        glClearColor(0.0f, 0.0f, 0.24f, 0.0f);

        glClear(GL_COLOR_BUFFER_BIT);


        // Check if the ESC key was pressed or the window was closed
        if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS
                || glfwWindowShouldClose(window) != 0)
            break;
    }

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}