Esempio n. 1
0
void Text::updateMetrics(FontResource &fontResource) {
	_width = 0;
	_height = 0;

	for (uint i = 0; i < _text.size(); ++i) {
		const Common::Rect &curRect = fontResource.getCharacterRect((byte)_text[i]);
		_width += curRect.width();
		if (i != _text.size() - 1)
			_width += fontResource.getGapWidth();
		if (_height < curRect.height())
			_height = curRect.height();
	}
}
Esempio n. 2
0
void FontLoader::loadPendingFonts()
{
    ASSERT(m_resourceFetcher);

    FontsToLoadVector fontsToBeginLoading;
    fontsToBeginLoading.swap(m_fontsToBeginLoading);
    for (FontsToLoadVector::iterator it = fontsToBeginLoading.begin(); it != fontsToBeginLoading.end(); ++it) {
        FontResource* fontResource = it->first.get();
        fontResource->beginLoadIfNeeded(m_resourceFetcher);
    }

    // When the local fontsToBeginLoading vector goes out of scope it will
    // decrement the request counts on the ResourceFetcher for all the fonts
    // that were just loaded.
}
Esempio n. 3
0
bool Text::doRender() {
	// Font-Resource locken.
	FontResource *fontPtr = lockFontResource();
	if (!fontPtr)
		return false;

	// Charactermap-Resource locken.
	ResourceManager *rmPtr = getResourceManager();
	BitmapResource *charMapPtr;
	{
		Resource *pResource = rmPtr->requestResource(fontPtr->getCharactermapFileName());
		if (!pResource) {
			BS_LOG_ERRORLN("Could not request resource \"%s\".", fontPtr->getCharactermapFileName().c_str());
			return false;
		}
		if (pResource->getType() != Resource::TYPE_BITMAP) {
			BS_LOG_ERRORLN("Requested resource \"%s\" is not a bitmap.", fontPtr->getCharactermapFileName().c_str());
			return false;
		}

		charMapPtr = static_cast<BitmapResource *>(pResource);
	}

	// Framebufferobjekt holen.
	GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx();
	BS_ASSERT(gfxPtr);

	bool result = true;
	Common::Array<Line>::iterator iter = _lines.begin();
	for (; iter != _lines.end(); ++iter) {
		// Feststellen, ob überhaupt Buchstaben der aktuellen Zeile vom Update betroffen sind.
		Common::Rect checkRect = (*iter).bbox;
		checkRect.translate(_absoluteX, _absoluteY);

		// Jeden Buchstaben einzeln Rendern.
		int curX = _absoluteX + (*iter).bbox.left;
		int curY = _absoluteY + (*iter).bbox.top;
		for (uint i = 0; i < (*iter).text.size(); ++i) {
			Common::Rect curRect = fontPtr->getCharacterRect((byte)(*iter).text[i]);

			Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height());
			int renderX = curX + (renderRect.left - renderRect.left);
			int renderY = curY + (renderRect.top - renderRect.top);
			renderRect.translate(curRect.left - curX, curRect.top - curY);
			result = charMapPtr->blit(renderX, renderY, Image::FLIP_NONE, &renderRect, _modulationColor);
			if (!result)
				break;

			curX += curRect.width() + fontPtr->getGapWidth();
		}
	}

	// Charactermap-Resource freigeben.
	charMapPtr->release();

	// Font-Resource freigeben.
	fontPtr->release();

	return result;
}
Esempio n. 4
0
bool Text::doRender(RectangleList *updateRects) {
	// lock Font Resource
	FontResource *fontPtr = lockFontResource();
	if (!fontPtr)
		return false;

	// lock Character map resource
	ResourceManager *rmPtr = getResourceManager();
	BitmapResource *charMapPtr;
	{
		Resource *pResource = rmPtr->requestResource(fontPtr->getCharactermapFileName());
		if (!pResource) {
			warning("Could not request resource \"%s\".", fontPtr->getCharactermapFileName().c_str());
			return false;
		}
		if (pResource->getType() != Resource::TYPE_BITMAP) {
			error("Requested resource \"%s\" is not a bitmap.", fontPtr->getCharactermapFileName().c_str());
			return false;
		}

		charMapPtr = static_cast<BitmapResource *>(pResource);
	}

	// Getting frame buffer object
	GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx();
	assert(gfxPtr);

	bool result = true;
	Common::Array<Line>::iterator iter = _lines.begin();
	for (; iter != _lines.end(); ++iter) {
		// Determine whether any letters of the current line are affected by the update.
		Common::Rect checkRect = (*iter).bbox;
		checkRect.translate(_absoluteX, _absoluteY);

		// Render each letter individually.
		int curX = _absoluteX + (*iter).bbox.left;
		int curY = _absoluteY + (*iter).bbox.top;
		for (uint i = 0; i < (*iter).text.size(); ++i) {
			Common::Rect curRect = fontPtr->getCharacterRect((byte)(*iter).text[i]);

			Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height());
			renderRect.translate(curRect.left - curX, curRect.top - curY);
			result = charMapPtr->blit(curX, curY, Graphics::FLIP_NONE, &renderRect, _modulationColor, -1, -1, updateRects);
			if (!result)
				break;

			curX += curRect.width() + fontPtr->getGapWidth();
		}
	}

	// Free Character map resource
	charMapPtr->release();

	// Free Font resource
	fontPtr->release();

	return result;
}
void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip)
{
	xml_node<>* child;

	if (!resList)
		return;

	child = resList->first_node("resource");
	while (child != NULL)
	{
		xml_attribute<>* attr = child->first_attribute("type");
		if (!attr)
			break;

		std::string type = attr->value();

		if (type == "font")
		{
			FontResource* res = new FontResource(child, pZip);
			if (res == NULL || res->GetResource() == NULL)
			{
				xml_attribute<>* attr_name = child->first_attribute("name");

				if (!attr_name) {
					std::string res_name = attr_name->value();
					LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
				} else
					LOGERR("Resource type (%s) failed to load\n", type.c_str());

				delete res;
			}
			else
			{
				mResources.push_back((Resource*) res);
			}
		}
		else if (type == "image")
		{
			ImageResource* res = new ImageResource(child, pZip);
			if (res == NULL || res->GetResource() == NULL)
			{
				xml_attribute<>* attr_name = child->first_attribute("name");

				if (!attr_name) {
					std::string res_name = attr_name->value();
					LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
				} else
					LOGERR("Resource type (%s) failed to load\n", type.c_str());

				delete res;
			}
			else
			{
				mResources.push_back((Resource*) res);
			}
		}
		else if (type == "animation")
		{
			AnimationResource* res = new AnimationResource(child, pZip);
			if (res == NULL || res->GetResource() == NULL)
			{
				xml_attribute<>* attr_name = child->first_attribute("name");

				if (!attr_name) {
					std::string res_name = attr_name->value();
					LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
				} else
					LOGERR("Resource type (%s) failed to load\n", type.c_str());

				delete res;
			}
			else
			{
				mResources.push_back((Resource*) res);
			}
		}
		else
		{
			LOGERR("Resource type (%s) not supported.\n", type.c_str());
		}

		child = child->next_sibling("resource");
	}
}
Esempio n. 6
0
void C_Renderer::CalculateRect(IResource* font, RectangleI* pt, const wchar_t* str, unsigned int start, unsigned int end, unsigned int style, float scale)
{
	if(font==0) return;
#ifdef USE_BITMAPFONT
	Sprite* Font = CAST_RES(Sprite*, font);
	FontResource* rc = (FontResource*)font;
#else
	LPD3DXFONT Font = CAST_RES(LPD3DXFONT, font);
#endif
	if(Font==0) return;

#ifdef USE_BITMAPFONT
#else
	D3DXMatrixScaling(&mat, scale, scale, 1.0f);
	m_sprite->GetTransform(&m2);
	m_sprite->SetTransform(&(mat * m2));
	pt->left = (LONG)(pt->left/scale);
	pt->top = (LONG)(pt->top/scale);
	pt->right = (LONG)(pt->right/scale);
	pt->bottom = (LONG)(pt->bottom/scale);
#endif	

#ifdef USE_BITMAPFONT
	float sw = 0.0f;
	RectangleI* rct = 0;
	RectangleF rect;
	rect.left = (float)pt->left;
	rect.top = (float)pt->top;
	rect.right = (float)pt->right;
	rect.bottom = (float)pt->bottom;

	unsigned int txtsize = wcslen(str);

	float fsize = (float)rc->GetSize();

	if(start>=txtsize || end>txtsize) return;

	float fwidth = 0.0f;
	float fheight = 0.0f;
	for(unsigned int i=start; i< start + end; i++)
	{
		rct = Font->GetSpriteRect((unsigned int)str[i]);

		if(rct!=0)
		{
			float scale2 = fsize / (rct->bottom - rct->top);
			fwidth += ((rct->right - rct->left - BFONTSPACEW) * scale2) * scale;
			fheight = ((rct->bottom - rct->top) * scale2) * scale;
		}
	}

	if(style&FONT_STYLE_MULTILINE)
	{
		rect.left -= BFONTSPACE;
		rect.right -= BFONTSPACE;
	}
	else
	{
		rect.left -= BFONTSPACE;
		rect.right = rect.left + fwidth - BFONTSPACE;
		rect.bottom = rect.top + fheight;

		pt->left = (int)(rect.left/scale);
		pt->top = (int)(rect.top/scale);
		pt->right = (int)(rect.right/scale);
		pt->bottom = (int)(rect.bottom/scale);
	}

#else
	Font->DrawTextW(m_sprite, str + start, end, (LPRECT)pt, style | DT_CALCRECT, D3DXCOLOR(0,0,0,1));
	m_sprite->SetTransform(&m2);
#endif
}
Esempio n. 7
0
void C_Renderer::DrawText(IResource* font, const wchar_t* text, int dx, int dy, int dr, int db, unsigned int color, unsigned int style, float scale, int Drawonly)
{
	if(font==0) return;
#ifdef USE_BITMAPFONT
	Sprite* Font = CAST_RES(Sprite*, font);
	FontResource* rc = (FontResource*)font;
#else
	LPD3DXFONT Font = CAST_RES(LPD3DXFONT, font);
#endif

	if(Font==0) return;

#ifdef USE_BITMAPFONT
#else
	D3DXMatrixScaling(&mat, scale, scale, 1.0f);
	m_sprite->GetTransform(&m2);
	m_sprite->SetTransform(&(mat * m2));

	rect.left = (LONG)(dx/scale);
	rect.top = (LONG)(dy/scale);
	rect.right = (LONG)(dr/scale);
	rect.bottom = (LONG)(db/scale);
#endif


#ifdef USE_BITMAPFONT
	float sw = 0.0f;
	RectangleI* rct = 0;
	RectangleF rect;
	rect.left = (float)dx;
	rect.top = (float)dy;
	rect.right = (float)dr;
	rect.bottom = (float)db;

	unsigned int txtsize = wcslen(text);

	float fsize = (float)rc->GetSize();

	float fwidth = 0.0f;
	float fheight = 0.0f;
	for(unsigned int i=0; i<txtsize; i++)
	{
		rct = Font->GetSpriteRect((unsigned int)text[i]);

		if(rct!=0)
		{
			float scale2 = fsize / (rct->bottom - rct->top);
			fwidth += ((rct->right - rct->left - BFONTSPACEW) * scale2) * scale;
			fheight = ((rct->bottom - rct->top) * scale2) * scale;
		}
	}

	if(style&FONT_STYLE_MULTILINE)
	{
		rect.left -= BFONTSPACE;
		rect.right -= BFONTSPACE;
	}
	else
	{
		if(style&FONT_STYLE_CENTERALIGN)
		{
			float hfwidth = fwidth / 2.0f;
			float hwidth = (rect.right - rect.left) / 2.0f;
			rect.left = (rect.left + hwidth) - hfwidth - BFONTSPACEW;
			rect.right = rect.left + fwidth - BFONTSPACEW;
		}
		else if(style&FONT_STYLE_RIGHTALIGN)
		{
			rect.left = rect.right - fwidth - BFONTSPACE;
			rect.right = rect.left + fwidth - BFONTSPACE;
		}
		else
		{
			rect.left -= BFONTSPACE;
			rect.right = rect.left + fwidth - BFONTSPACE;
		}

	
		if(style&FONT_STYLE_VCENTERALIGN)
		{
			float hfheight = fheight / 2.0f;
			float hheight = (rect.bottom - rect.top) / 2.0f;
			rect.top = (rect.top + hheight) - hfheight;
			rect.bottom = rect.top + fheight;
		}
		else if(style&FONT_STYLE_BOTTOMALIGN)
		{
			rect.top = rect.bottom - fheight;
			rect.right = rect.top + fheight;
		}
		else
		{
			rect.bottom = rect.top + fheight;
		}
	}


	float ty = 0.0f;
	float tx = 0;

	for(unsigned int i=0; i<txtsize; i++)
	{
		rct = Font->GetSpriteRect((unsigned int)text[i]);

		if(rct!=0)
		{
			float scale2 = fsize / (rct->bottom - rct->top);
			if(style&FONT_STYLE_MULTILINE)
			{
				RectangleF rect2 = rect;
				rect2.left = rect.left + tx;
				rect2.right = (rect2.left + (rct->right - rct->left) * scale2  * scale);
				if(rect2.right>rect.right || text[i] == L'\n' || text[i] == L'\r')
				{
					ty += fsize * scale + BFONTVSPACE;
					tx = 0;

					rect2.left = rect.left + tx;
					rect2.right = (rect2.left + (rct->right - rct->left) * scale2  * scale);
				}

				rect2.top = rect.top + ty;
				rect2.bottom = (rect2.top + fsize * scale);

				if(!(text[i] == L'\n' || text[i] == L'\r'))
				{
					Font->SetIndex((unsigned int)text[i]);
					if(Drawonly==-1 || Drawonly==i) Font->Draw(this, rect2, color, 0.0f, 0.0f);
					tx += ((rct->right - rct->left - BFONTSPACEW) * scale2) * scale;
				}
			}
			else
			{
				rect.right = (rect.left + (rct->right - rct->left) * scale2  * scale);
				rect.bottom = (rect.top + fsize  * scale);
				Font->SetIndex((unsigned int)text[i]);
				if(Drawonly==-1 || Drawonly==i) Font->Draw(this, rect, color, 0.0f, 0.0f);
				rect.left += ((rct->right - rct->left - BFONTSPACEW) * scale2) * scale;
			}
		}
	}	
#else
	Font->DrawTextW(m_sprite, text, -1, (LPRECT)&rect, style, color);
	m_sprite->SetTransform(&m2);
#endif
}
Esempio n. 8
0
void Text::updateFormat() {
	FontResource *fontPtr = lockFontResource();
	assert(fontPtr);

	updateMetrics(*fontPtr);

	_lines.resize(1);
	if (_autoWrap && (uint) _width >= _autoWrapThreshold && _text.size() >= 2) {
		_width = 0;
		uint curLineWidth = 0;
		uint curLineHeight = 0;
		uint curLine = 0;
		uint tempLineWidth = 0;
		uint lastSpace = 0; // we need at least 1 space character to start a new line...
		_lines[0].text = "";
		for (uint i = 0; i < _text.size(); ++i) {
			uint j;
			tempLineWidth = 0;
			lastSpace = 0;
			for (j = i; j < _text.size(); ++j) {
				if ((byte)_text[j] == ' ')
					lastSpace = j;

				const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]);
				tempLineWidth += curCharRect.width();
				tempLineWidth += fontPtr->getGapWidth();

				if ((tempLineWidth >= _autoWrapThreshold) && (lastSpace > 0))
					break;
			}

			if (j == _text.size()) // everything in 1 line.
				lastSpace = _text.size();

			curLineWidth = 0;
			curLineHeight = 0;
			for (j = i; j < lastSpace; ++j) {
				_lines[curLine].text += _text[j];

				const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]);
				curLineWidth += curCharRect.width();
				curLineWidth += fontPtr->getGapWidth();
				if ((uint)curCharRect.height() > curLineHeight)
					curLineHeight = curCharRect.height();
			}

			_lines[curLine].bbox.right = curLineWidth;
			_lines[curLine].bbox.bottom = curLineHeight;
			if ((uint)_width < curLineWidth)
				_width = curLineWidth;

			if (lastSpace < _text.size()) {
				++curLine;
				assert(curLine == _lines.size());
				_lines.resize(curLine + 1);
				_lines[curLine].text = "";
			}

			i = lastSpace;
		}

		// Bounding box of each line relative to the first set (center aligned).
		_height = 0;
		Common::Array<Line>::iterator iter = _lines.begin();
		for (; iter != _lines.end(); ++iter) {
			Common::Rect &bbox = (*iter).bbox;
			bbox.left = (_width - bbox.right) / 2;
			bbox.right = bbox.left + bbox.right;
			bbox.top = (iter - _lines.begin()) * fontPtr->getLineHeight();
			bbox.bottom = bbox.top + bbox.bottom;
			_height += bbox.height();
		}
	} else {
		// No auto format, so all the text is copied to a single line.
		_lines[0].text = _text;
		_lines[0].bbox = Common::Rect(0, 0, _width, _height);
	}

	fontPtr->release();
}
Esempio n. 9
0
void Environment::renderScreen()
{
  SDL_Rect q,r;
  Element *t;
  char buf[255];
  char *bufp;

  // if we're in a fadeout, use a faded mBuffer and just blit it to
  // the screen
  if (mMenuState == State_ChangeMenu && mMenuStatePosition == 1) {
    SDL_BlitSurface(mScreen, 0x00, mBuffer, 0x00);

    /*SDL_SetAlpha(mBuffer, SDL_SRCALPHA, 255-(mMenuStatePosition*10));
      SDL_FillRect(mScreen, 0, 0);
      SDL_BlitSurface(mBuffer, 0x00, mScreen, 0x00);
      SDL_Flip(mScreen);
      return; */
  }

  // draw background
  t = mElements->getElementByContent(CONTENT_BACKGROUND_IMAGE, mMenu->getSkinID());   
  if (t) {
    t->drawImage(mScreen);
  }


  //if (t && t->getResource() /*&& typeid(*t->getResource()) == typeid(ImageResource) */) {
  //   ImageResource *tmp = (ImageResource *) t->getResource();
  //   SDL_BlitSurface(tmp->getImage(), 0x00, mScreen, 0);
  //}


  // draw menu in proper dimensions
  t = mElements->getElementByContent(CONTENT_MENU, mMenu->getSkinID());
  if (mMenuSurface && t) {
    r = t->getDimensions();
    q.w = r.w;
    q.h = r.h;
    q.x = 0;
    q.y = (mMenuOffset-50-mMenuRenderOffset);
    if (q.y < 0) {
      q.y = 0;
    }
    SDL_BlitSurface(mMenuSurface, &q, mScreen, &r);
  }

  // draw the remaining Elements.
  List<Element> *e = mElements->getElements();
  while (e) {
    if (e->getData() && (!e->getData()->getSkinID() || !e->getData()->getSkinID() || !strcmp(e->getData()->getSkinID(), mMenu->getSkinID()))) {
      if (e->getData()->getContent() == CONTENT_STATUS) {
        if (mSelectedNode && mSelectedNode->getStatusText()) {
          e->getData()->drawText(mSelectedNode->getStatusText(), mScreen);
        }
      } else if (e->getData()->getContent() == CONTENT_BOARDTEMP) {

        sprintf(buf, "%d C", mXboxInfo->getBoardTemp());
        e->getData()->drawText(buf, mScreen);
      } else if (e->getData()->getContent() == CONTENT_CPUTEMP) {

        sprintf(buf, "%d C", mXboxInfo->getCPUTemp());
        e->getData()->drawText(buf, mScreen);

      } else if (e->getData()->getContent() == CONTENT_TRAYSTATE) {
        FontResource *fRes = (FontResource *) e->getData()->getResource();
        int i = mXboxInfo->getTrayState();
        if (i == Tray_Open) {
          if (mDialog && (bufp = mDialog->getValue("TrayOpen"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "Open");
          }
        } else if (i == Tray_NoDisk) {
          if (mDialog && (bufp = mDialog->getValue("TrayNoDisk"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "No Disk");
          }
        } else if (i == Tray_Disk) {
          if (mDialog && (bufp == mDialog->getValue("TrayDisk"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "Disk");
          }
        } else if (i == Tray_Opening) {
          if (mDialog && (bufp == mDialog->getValue("TrayOpening"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "Opening");
          }
        } else if (i == Tray_Closing) {
          if (mDialog && (bufp == mDialog->getValue("TrayClosing"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "Closing");
          }
        } else if (i == Tray_Reading) {
          if (mDialog && (bufp == mDialog->getValue("TrayBusy"))) {
            strcpy(buf, bufp);
          } else {
            sprintf(buf, "Busy");
          }
        }
        if (fRes && fRes->getFont()) {
          e->getData()->drawText(buf, mScreen);
        }
      }
    }
    e = e->getLink();
  }
}
Esempio n. 10
0
void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH)
{
	unsigned char keychar = key.key;
	if (!keychar)
		return;

	// key background
	COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther;
	gr_color(c.red, c.green, c.blue, c.alpha);
	keyX += mKeyMarginX;
	keyY += mKeyMarginY;
	keyW -= mKeyMarginX * 2;
	keyH -= mKeyMarginY * 2;
	gr_fill(keyX, keyY, keyW, keyH);

	// key label
	FontResource* labelFont = mFont;
	string labelText;
	ImageResource* labelImage = NULL;
	if (keychar > 32 && keychar < 127) {
		labelText = (char) keychar;
		gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
	}
	else {
		// search for a special key label
		for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) {
			if (it->layout_from > 0 && it->layout_from != currentLayout)
				continue; // this label is for another layout
			if (it->key == key.key && it->layout_to == key.layout)
			{
				// found a label
				labelText = it->text;
				labelImage = it->image;
				break;
			}
		}
		labelFont = mSmallFont;
		gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha);
	}

	if (labelImage)
	{
		int w = labelImage->GetWidth();
		int h = labelImage->GetHeight();
		int x = keyX + (keyW - w) / 2;
		int y = keyY + (keyH - h) / 2;
		gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y);
	}
	else if (!labelText.empty())
	{
		void* fontResource = labelFont->GetResource();
		int textW = gr_measureEx(labelText.c_str(), fontResource);
		int textH = labelFont->GetHeight();
		int textX = keyX + (keyW - textW) / 2;
		int textY = keyY + (keyH - textH) / 2;
		gr_textEx(textX, textY, labelText.c_str(), fontResource);
	}

	// longpress key label (only if font is defined)
	keychar = key.longpresskey;
	if (keychar > 32 && keychar < 127 && mLongpressFont->GetResource()) {
		void* fontResource = mLongpressFont->GetResource();
		gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha);
		string text(1, keychar);
		int textH = mLongpressFont->GetHeight();
		int textW = gr_measureEx(text.c_str(), fontResource);
		int textX = keyX + keyW - longpressOffsetX - textW;
		int textY = keyY + longpressOffsetY;
		gr_textEx(textX, textY, text.c_str(), fontResource);
	}
}
Esempio n. 11
0
void Text::updateFormat() {
	FontResource *fontPtr = lockFontResource();
	BS_ASSERT(fontPtr);

	updateMetrics(*fontPtr);

	_lines.resize(1);
	if (_autoWrap && (uint) _width >= _autoWrapThreshold && _text.size() >= 2) {
		_width = 0;
		uint curLineWidth = 0;
		uint curLineHeight = 0;
		uint curLine = 0;
		uint tempLineWidth = 0;
		uint lastSpace = 0; // we need at least 1 space character to start a new line...
		_lines[0].text = "";
		for (uint i = 0; i < _text.size(); ++i) {
			uint j;
			tempLineWidth = 0;
			lastSpace = 0;
			for (j = i; j < _text.size(); ++j) {
				if ((byte)_text[j] == ' ')
					lastSpace = j;

				const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]);
				tempLineWidth += curCharRect.width();
				tempLineWidth += fontPtr->getGapWidth();

				if ((tempLineWidth >= _autoWrapThreshold) && (lastSpace > 0))
					break;
			}

			if (j == _text.size()) // everything in 1 line.
				lastSpace = _text.size();

			curLineWidth = 0;
			curLineHeight = 0;
			for (j = i; j < lastSpace; ++j) {
				_lines[curLine].text += _text[j];

				const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]);
				curLineWidth += curCharRect.width();
				curLineWidth += fontPtr->getGapWidth();
				if ((uint)curCharRect.height() > curLineHeight)
					curLineHeight = curCharRect.height();
			}

			_lines[curLine].bbox.right = curLineWidth;
			_lines[curLine].bbox.bottom = curLineHeight;
			if ((uint)_width < curLineWidth)
				_width = curLineWidth;

			if (lastSpace < _text.size()) {
				++curLine;
				BS_ASSERT(curLine == _lines.size());
				_lines.resize(curLine + 1);
				_lines[curLine].text = "";
			}

			i = lastSpace;
		}

		// Bounding-Box der einzelnen Zeilen relativ zur ersten festlegen (vor allem zentrieren).
		_height = 0;
		Common::Array<Line>::iterator iter = _lines.begin();
		for (; iter != _lines.end(); ++iter) {
			Common::Rect &bbox = (*iter).bbox;
			bbox.left = (_width - bbox.right) / 2;
			bbox.right = bbox.left + bbox.right;
			bbox.top = (iter - _lines.begin()) * fontPtr->getLineHeight();
			bbox.bottom = bbox.top + bbox.bottom;
			_height += bbox.height();
		}
	} else {
		// Keine automatische Formatierung, also wird der gesamte Text in nur eine Zeile kopiert.
		_lines[0].text = _text;
		_lines[0].bbox = Common::Rect(0, 0, _width, _height);
	}

	fontPtr->release();
}
Esempio n. 12
0
File: ui.cpp Progetto: fulhax/tesla
void Ui::print(const std::string &fontfile, int x, int y,
               const std::string &in)
{
    static uint32_t vertex_buffer = 0;
    static uint32_t uv_buffer = 0;

    static Shader shader;
    static bool first = true;

    if (first) {
        shader.attach("shaders/font.frag");
        shader.attach("shaders/font.vert");
        first = false;
    }

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    if (shader.use()) {
        FontResource *font = engine.resources.getFont(fontfile.c_str());

        if (font) {
            if (!vertex_buffer) {
                glGenBuffers(1, &vertex_buffer);
            }

            if (!uv_buffer) {
                glGenBuffers(1, &uv_buffer);
            }

            TextData *text = font->print(in);

            shader.setUniform("in_UiPos", glm::vec2(x, y));
            shader.setUniform("in_Color", glm::vec4(1, 1, 1, 1));
            shader.setUniform("in_OrthoMatrix", engine.video.OrthoMat);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, font->id);
            shader.setUniform("FontTexture", 0);

            glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
            glBufferData(
                GL_ARRAY_BUFFER,
                sizeof(glm::vec2) * text->verts.size(),
                &text->verts[0],
                GL_STATIC_DRAW);

            glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
            glBufferData(
                GL_ARRAY_BUFFER,
                sizeof(glm::vec2) * text->uvs.size(),
                &text->uvs[0],
                GL_STATIC_DRAW);

            shader.bindAttribLocation(0, "in_Position");
            shader.bindAttribLocation(1, "in_TexCoord");

            glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
            glVertexAttribPointer(
                0,
                2,
                GL_FLOAT,
                GL_FALSE,
                sizeof(glm::vec2),
                nullptr);

            glEnableVertexAttribArray(0);

            glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
            glVertexAttribPointer(
                1,
                2,
                GL_FLOAT,
                GL_FALSE,
                sizeof(glm::vec2),
                nullptr);

            glEnableVertexAttribArray(1);

            glDrawArrays(GL_QUADS, 0, text->verts.size());

            glBindBuffer(GL_ARRAY_BUFFER, 0);

            glDisableVertexAttribArray(0);
            glDisableVertexAttribArray(1);

            glUseProgram(0);

            delete text;
        }
    }

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glDisable(GL_BLEND);
}