bool SizeParam::fromString(const std::string& str)
{
    if (str.length() < 2)
        return false;

    std::string temp;

    if (str[ 0 ] == 'p')
    {
        temp = str.substr(1, str.length() - 1);

        px(utility::parseInt(temp));
    }
    else if (str[ 0 ] == 'f')
    {
        if (str[ 1 ] == 'f')
            mFlMode = FM_FREE_SPACE;
        else if (str[ 1 ] == 'p')
            mFlMode = FM_PARENT;
        else
            MYGUI_EXCEPT("Second character of float mode in SizeParam is invalid!");

        temp = str.substr(2, str.length() - 2);

        mFl = utility::parseFloat(temp);
    }
    else MYGUI_EXCEPT("First character in SizeParam is invalid!");

    return true;
}
	void OverlappedLayer::destroyChildItemNode(ILayerNode* _item)
	{
		// если есть отец, то русть сам и удаляет
		ILayerNode* parent = _item->getParent();
		if (parent)
		{
			parent->destroyChildItemNode(_item);

			mOutOfDate = true;

			return;
		}

		// айтем рутовый, мы удаляем
		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
		{
			if ((*iter) == _item)
			{
				delete _item;
				mChildItems.erase(iter);

				mOutOfDate = true;

				return;
			}
		}

		MYGUI_EXCEPT("item node not found");
	}
	// поправить на виджет и проверять на рутовость
	void LayerManager::attachToLayerKeeper(const std::string& _name, WidgetPtr _item)
	{
		MYGUI_ASSERT(_item->isRootWidget(), "attached widget must be root");

		// сначала отсоединяем
		detachFromLayerKeeper(_item);

		// а теперь аттачим
		for (VectorLayerKeeper::iterator iter=mLayerKeepers.begin(); iter!=mLayerKeepers.end(); ++iter) {
			if (_name == (*iter)->getName()) {

				// запоминаем в рутовом виджете хранитель лееров
				_item->mLayerKeeper = (*iter);

				// достаем из хранителя леер для себя
				_item->mLayerItemKeeper = (*iter)->getItem();

				// подписываемся на пиккинг
				_item->mLayerItemKeeper->_addPeekItem(_item);

				// физически подсоединяем иерархию
				_item->_attachToLayerItemKeeper(_item->mLayerItemKeeper);

				return;
			}
		}
		MYGUI_EXCEPT("Layer '" << _name << "' is not found");
	}
Example #4
0
	// удяляет неудачника
	void Gui::_destroyChildWidget(Widget* _widget)
	{
		MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");

		VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
		if (iter != mWidgetChild.end())
		{
			// сохраняем указатель
			MyGUI::Widget* widget = *iter;

			// удаляем из списка
			*iter = mWidgetChild.back();
			mWidgetChild.pop_back();

			// отписываем от всех
			mWidgetManager->unlinkFromUnlinkers(_widget);

			// непосредственное удаление
			WidgetManager::getInstance()._deleteWidget(widget);
		}
		else
		{
			MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
		}
	}
	void OverlappedLayer::upChildItemNode(ILayerNode* _item)
	{
		// если есть отец, то пусть сам рулит
		ILayerNode* parent = _item->getParent();
		if (parent != nullptr)
		{
			parent->upChildItemNode(_item);

			mOutOfDate = true;

			return;
		}

		if ((2 > mChildItems.size()) || (mChildItems.back() == _item))
			return;

		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
		{
			if ((*iter) == _item)
			{
				mChildItems.erase(iter);
				mChildItems.push_back(_item);

				mOutOfDate = true;

				return;
			}
		}

		MYGUI_EXCEPT("item node not found");
	}
Example #6
0
void RenderItem::renderToTarget(IRenderTarget* _target, bool _update)
{
    if (mTexture == nullptr)
        return;

    mRenderTarget = _target;

    mCurrentUpdate = _update;

    if (mOutOfDate || _update)
    {
        mCountVertex = 0;
        Vertex* buffer = mVertexBuffer->lock();

        mOutOfDate = false;

        if (buffer != nullptr)
        {
            for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
            {
                // перед вызовом запоминаем позицию в буфере
                mCurrentVertex = buffer;
                mLastVertexCount = 0;

                (*iter).first->doRender();

                // колличество отрисованных вершин
                MYGUI_DEBUG_ASSERT(mLastVertexCount <= (*iter).second, "It is too much vertexes");
                buffer += mLastVertexCount;
                mCountVertex += mLastVertexCount;
            }

            mVertexBuffer->unlock();
        }
    }

    // хоть с 0 не выводиться батч, но все равно не будем дергать стейт и операцию
    if (0 != mCountVertex)
    {
#if MYGUI_DEBUG_MODE == 1
        if (!RenderManager::getInstance().checkTexture(mTexture))
        {
            mTexture = nullptr;
            MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'");
            return;
        }
#endif
        // непосредственный рендринг
        if (mManualRender)
        {
            for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
                (*iter).first->doManualRender(mVertexBuffer, mTexture, mCountVertex);
        }
        else
        {
            _target->doRender(mVertexBuffer, mTexture, mCountVertex);
        }
    }
}
	size_t MultiList::convertFromSort(size_t _index)
	{
		for (size_t pos=0; pos<mToSortIndex.size(); ++pos) {
			if (mToSortIndex[pos] == _index) return pos;
		}
		MYGUI_EXCEPT("index not found");
		return ITEM_NONE;
	}
	size_t MenuControl::getItemIndexById(const std::string& _id)
	{
		for (size_t index = 0; index < mItemsInfo.size(); index++)
		{
			if (mItemsInfo[index].id == _id)
				return index;
		}
		MYGUI_EXCEPT("item id (" << _id << ") not found, source 'MenuControl::getItemById'");
	}
	size_t MenuControl::getItemIndex(MenuItem* _item)
	{
		for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
		{
			if (mItemsInfo[pos].item == _item)
				return pos;
		}
		MYGUI_EXCEPT("item (" << _item << ") not found, source 'MenuControl::getItemIndex'");
	}
	bool SizeDescription::checkBehaviour( uint8 _beh ) const
	{
		if( ( _beh & SB_MIN ) && ( _beh & SB_MAX ) )
		{
			MYGUI_EXCEPT( "Can't be min and max!" ); 
			return false;
		}

		return true;
	}
Example #11
0
	IResourcePtr ResourceManager::getByID(const Guid& _id, bool _throw)
	{
		MapResourceID::iterator iter = mResourcesID.find(_id);
		if (iter == mResourcesID.end())
		{
			if (_throw) MYGUI_EXCEPT("resource '" << _id.print() << "' not found");
			MYGUI_LOG(Warning, "resource '" << _id.print() << "' not found");
			return nullptr;
		}
		return iter->second;
	}
Example #12
0
void DynLib::unload()
{
    // Log library unload
    MYGUI_LOG(Info, "Unloading library " << mName);
#if MYGUI_PLATFORM == MYGUI_PLATFORM_APPLE
    //APPLE SPECIFIC CODE HERE
#else
    if (MYGUI_DYNLIB_UNLOAD(mInstance))
    {
        MYGUI_EXCEPT("Could not unload dynamic library '" << mName << "'. System Error: " << dynlibError());
    }
#endif
}
Example #13
0
	void LayerNode::destroyChildItemNode(ILayerNode* _node)
	{
		for (VectorILayerNode::iterator iter=mChildItems.begin(); iter!=mChildItems.end(); ++iter)
		{
			if ((*iter) == _node)
			{
				delete _node;
				mChildItems.erase(iter);
				return;
			}
		}
		MYGUI_EXCEPT("item node not found");
	}
	Widget* WidgetManager::createWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Widget* _parent, ICroppedRectangle* _cropeedParent, const std::string& _name)
	{
		IObject* object = FactoryManager::getInstance().createObject("Widget", _type);
		if (object != nullptr)
		{
			Widget* widget = object->castType<Widget>();
			widget->_initialise(_style, _coord, _skin, _parent, _cropeedParent, _name);

			return widget;
		}

		MYGUI_EXCEPT("factory '" << _type << "' not found");
	}
Example #15
0
	void LayerNode::upChildItemNode(ILayerNode* _item)
	{
		for (VectorILayerNode::iterator iter=mChildItems.begin(); iter!=mChildItems.end(); ++iter)
		{
			if ((*iter) == _item)
			{
				mChildItems.erase(iter);
				mChildItems.push_back(_item);
				return;
			}
		}
		MYGUI_EXCEPT("item node not found");
	}
Example #16
0
	// удяляет только негодных батюшке государю
	void Widget::_destroyChildWidget(WidgetPtr _widget)
	{
		VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
		if(iter != mWidgetChild.end())
		{
			delete *iter;
			// удаляем из списка
			*iter = mWidgetChild.back();
			mWidgetChild.pop_back();
			return;
		}
		MYGUI_EXCEPT("Widget not found");
	}
Example #17
0
 MyGUI::Widget* Layout::getWidget(const std::string &_name)
 {
     for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin();
     iter!=mListWindowRoot.end(); ++iter)
     {
         MyGUI::Widget* find = (*iter)->findWidget(mPrefix + _name);
         if (nullptr != find)
         {
             return find;
         }
     }
     MYGUI_EXCEPT("widget name '" << _name << "' in layout '" << mLayoutName << "' not found.");
 }
Example #18
0
	void LayerNode::detachLayerItem(ILayerItem* _item)
	{
		for (VectorLayerItem::iterator iter=mLayerItems.begin(); iter!=mLayerItems.end(); ++iter)
		{
			if ((*iter) == _item)
			{
				(*iter) = mLayerItems.back();
				mLayerItems.pop_back();
				return;
			}
		}
		MYGUI_EXCEPT("layer item not found");
	}
Example #19
0
	void LayerNode::detachLayerItem(ILayerItem* _item)
	{
		for (VectorLayerItem::iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
		{
			if ((*iter) == _item)
			{
				mLayerItems.erase(iter);

				mOutOfDate = true;

				return;
			}
		}
		MYGUI_EXCEPT("layer item not found");
	}
Example #20
0
void BaseLayout::loadLayout(MyGUI::WidgetPtr _parent)
{
	mParentWidget = _parent;
	mListWindowRoot = MyGUI::LayoutManager::getInstance().loadLayout(mLayoutName, mPrefix, _parent, GUI_RESOURCE_GROUP);

	//if (mParentWidget == null) {
		const std::string main_name = mPrefix + MAIN_WINDOW;
		for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); iter!=mListWindowRoot.end(); ++iter) {
			if ((*iter)->getName() == main_name) {
				mMainWidget = (*iter);
				return;
			}
		}
		MYGUI_EXCEPT("root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found.");
	//}
}
Example #21
0
	void RenderItem::reallockDrawItem(ISubWidget* _item, size_t _count)
	{
		for (VectorDrawItem::iterator iter=mDrawItems.begin(); iter!=mDrawItems.end(); ++iter)
		{
			if ((*iter).first == _item)
			{
				// если нужно меньше, то ниче не делаем
				if ((*iter).second < _count)
				{
					mNeedVertexCount -= (*iter).second;
					mNeedVertexCount += _count;
					(*iter).second = _count;
					mOutDate = true;

					mVertexBuffer->setVertextCount(mNeedVertexCount);
				}
				return;
			}
		}
		MYGUI_EXCEPT("DrawItem not found");
	}
	WidgetPtr WidgetManager::createWidget(const Ogre::String & _type, const Ogre::String & _skin, const IntCoord& _coord, Align _align, CroppedRectanglePtr _parent, const Ogre::String & _name)
	{
		Ogre::String name;
		if (false == _name.empty()) {
			MapWidgetPtr::iterator iter = mWidgets.find(_name);
			MYGUI_ASSERT(iter == mWidgets.end(), "widget with name '" << _name << "' already exist");
			name = _name;
		} else {
			static long num=0;
			name = utility::toString(num++, "_", _type);
		}

		for (SetWidgetFactory::iterator factory = mFactoryList.begin(); factory != mFactoryList.end(); factory++) {
			if ( (*factory)->getType() == _type) {
				WidgetPtr widget = (*factory)->createWidget(_skin, _coord, _align, _parent, name);
				mWidgets[name] = widget;
				return widget;
			}
		}
		MYGUI_EXCEPT("factory '" << _type << "' not found");
		return null;
	}
Example #23
0
	void RenderItem::removeDrawItem(ISubWidget* _item)
	{
		for (VectorDrawItem::iterator iter=mDrawItems.begin(); iter!=mDrawItems.end(); ++iter)
		{
			if ((*iter).first == _item)
			{
				mNeedVertexCount -= (*iter).second;
				mDrawItems.erase(iter);
				mOutDate = true;

				mVertexBuffer->setVertextCount(mNeedVertexCount);

				// если все отдетачились, расскажем отцу
				if (mDrawItems.empty())
				{
					mTexture = nullptr;
					mCompression = true;
				}

				return;
			}
		}
		MYGUI_EXCEPT("DrawItem not found");
	}
	void ResourceTrueTypeFont::initialiseFreeType()
	{
		//-------------------------------------------------------------------//
		// Initialise FreeType and load the font.
		//-------------------------------------------------------------------//

		FT_Library ftLibrary;

		if (FT_Init_FreeType(&ftLibrary) != 0)
			MYGUI_EXCEPT("ResourceTrueTypeFont: Could not init the FreeType library!");

		uint8* fontBuffer = nullptr;

		FT_Face ftFace = loadFace(ftLibrary, fontBuffer);

		if (ftFace == nullptr)
		{
			MYGUI_LOG(Error, "ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
			return;
		}

		//-------------------------------------------------------------------//
		// Calculate the font metrics.
		//-------------------------------------------------------------------//

		// The font's overall ascent and descent are defined in three different places in a TrueType font, and with different
		// values in each place. The most reliable source for these metrics is usually the "usWinAscent" and "usWinDescent" pair of
		// values in the OS/2 header; however, some fonts contain inaccurate data there. To be safe, we use the highest of the set
		// of values contained in the face metrics and the two sets of values contained in the OS/2 header.
		int fontAscent = ftFace->size->metrics.ascender >> 6;
		int fontDescent = -ftFace->size->metrics.descender >> 6;

		TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(ftFace, ft_sfnt_os2);

		if (os2 != nullptr)
		{
			setMax(fontAscent, os2->usWinAscent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
			setMax(fontDescent, os2->usWinDescent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);

			setMax(fontAscent, os2->sTypoAscender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
			setMax(fontDescent, -os2->sTypoDescender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
		}

		// The nominal font height is calculated as the sum of its ascent and descent as specified by the font designer. Previously
		// it was defined by MyGUI in terms of the maximum ascent and descent of the glyphs currently in use, but this caused the
		// font's line spacing to change whenever glyphs were added to or removed from the font definition. Doing it this way
		// instead prevents a lot of layout problems, and it is also more typographically correct and more aesthetically pleasing.
		mDefaultHeight = fontAscent + fontDescent;

		// Set the load flags based on the specified type of hinting.
		FT_Int32 ftLoadFlags;

		switch (mHinting)
		{
		case HintingForceAuto:
			ftLoadFlags = FT_LOAD_FORCE_AUTOHINT;
			break;
		case HintingDisableAuto:
			ftLoadFlags = FT_LOAD_NO_AUTOHINT;
			break;
		case HintingDisableAll:
			// When hinting is completely disabled, glyphs must always be rendered -- even during layout calculations -- due to
			// discrepancies between the glyph metrics and the actual rendered bitmap metrics.
			ftLoadFlags = FT_LOAD_NO_HINTING | FT_LOAD_RENDER;
			break;
		case HintingUseNative:
			ftLoadFlags = FT_LOAD_DEFAULT;
			break;
		}

		//-------------------------------------------------------------------//
		// Create the glyphs and calculate their metrics.
		//-------------------------------------------------------------------//

		GlyphHeightMap glyphHeightMap;
		int texWidth = 0;

		// Before creating the glyphs, add the "Space" code point to force that glyph to be created. For historical reasons, MyGUI
		// users are accustomed to omitting this code point in their font definitions.
		addCodePoint(FontCodeType::Space);

		// Create the standard glyphs.
		for (CharMap::iterator iter = mCharMap.begin(); iter != mCharMap.end(); )
		{
			const Char& codePoint = iter->first;
			FT_UInt glyphIndex = FT_Get_Char_Index(ftFace, codePoint);

			texWidth += createFaceGlyph(glyphIndex, codePoint, fontAscent, ftFace, ftLoadFlags, glyphHeightMap);

			// If the newly created glyph is the "Not Defined" glyph, it means that the code point is not supported by the font.
			// Remove it from the character map so that we can provide our own substitute instead of letting FreeType do it.
			if (iter->second != 0)
				++iter;
			else
				mCharMap.erase(iter++);
		}

		// Do some special handling for the "Space" and "Tab" glyphs.
		GlyphInfo* spaceGlyphInfo = getGlyphInfo(FontCodeType::Space);

		if (spaceGlyphInfo != nullptr && spaceGlyphInfo->codePoint == FontCodeType::Space)
		{
			// Adjust the width of the "Space" glyph if it has been customized.
			if (mSpaceWidth != 0.0f)
			{
				texWidth += (int)std::ceil(mSpaceWidth) - (int)std::ceil(spaceGlyphInfo->width);
				spaceGlyphInfo->width = mSpaceWidth;
				spaceGlyphInfo->advance = mSpaceWidth;
			}

			// If the width of the "Tab" glyph hasn't been customized, make it eight spaces wide.
			if (mTabWidth == 0.0f)
				mTabWidth = mDefaultTabWidth * spaceGlyphInfo->advance;
		}

		// Create the special glyphs. They must be created after the standard glyphs so that they take precedence in case of a
		// collision. To make sure that the indices of the special glyphs don't collide with any glyph indices in the font, we must
		// use glyph indices higher than the highest glyph index in the font.
		FT_UInt nextGlyphIndex = (FT_UInt)ftFace->num_glyphs;

		float height = (float)mDefaultHeight;

		texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Tab), 0.0f, 0.0f, mTabWidth, 0.0f, 0.0f), glyphHeightMap);
		texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Selected), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);
		texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::SelectedBack), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);
		texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Cursor), mCursorWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);

		// If a substitute code point has been specified, check to make sure that it exists in the character map. If it doesn't,
		// revert to the default "Not Defined" code point. This is not a real code point but rather an invalid Unicode value that
		// is guaranteed to cause the "Not Defined" special glyph to be created.
		if (mSubstituteCodePoint != FontCodeType::NotDefined && mCharMap.find(mSubstituteCodePoint) == mCharMap.end())
			mSubstituteCodePoint = static_cast<Char>(FontCodeType::NotDefined);

		// Create the "Not Defined" code point (and its corresponding glyph) if it's in use as the substitute code point.
		if (mSubstituteCodePoint == FontCodeType::NotDefined)
			texWidth += createFaceGlyph(0, static_cast<Char>(FontCodeType::NotDefined), fontAscent, ftFace, ftLoadFlags, glyphHeightMap);

		// Cache a pointer to the substitute glyph info for fast lookup.
		mSubstituteGlyphInfo = &mGlyphMap.find(mSubstituteCodePoint)->second;

		// Calculate the average height of all of the glyphs that are in use. This value will be used for estimating how large the
		// texture needs to be.
		double averageGlyphHeight = 0.0;

		for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j)
			averageGlyphHeight += j->first * j->second.size();

		averageGlyphHeight /= mGlyphMap.size();

		//-------------------------------------------------------------------//
		// Calculate the final texture size.
		//-------------------------------------------------------------------//

		// Round the current texture width and height up to the nearest powers of two.
		texWidth = Bitwise::firstPO2From(texWidth);
		int texHeight = Bitwise::firstPO2From((int)ceil(averageGlyphHeight) + mGlyphSpacing);

		// At this point, the texture is only one glyph high and is probably very wide. For efficiency reasons, we need to make the
		// texture as square as possible. If the texture cannot be made perfectly square, make it taller than it is wide, because
		// the height may decrease in the final layout due to height packing.
		while (texWidth > texHeight)
		{
			texWidth /= 2;
			texHeight *= 2;
		}

		// Calculate the final layout of all of the glyphs in the texture, packing them tightly by first arranging them by height.
		// We assume that the texture width is fixed but that the texture height can be adjusted up or down depending on how much
		// space is actually needed.
		// In most cases, the final texture will end up square or almost square. In some rare cases, however, we can end up with a
		// texture that's more than twice as high as it is wide; when this happens, we double the width and try again.
		do
		{
			if (texHeight > texWidth * 2)
				texWidth *= 2;

			int texX = mGlyphSpacing;
			int texY = mGlyphSpacing;

			for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j)
			{
				for (GlyphHeightMap::mapped_type::const_iterator i = j->second.begin(); i != j->second.end(); ++i)
				{
					GlyphInfo& info = *i->second;

					int glyphWidth = (int)std::ceil(info.width);
					int glyphHeight = (int)std::ceil(info.height);

					autoWrapGlyphPos(glyphWidth, texWidth, glyphHeight, texX, texY);

					if (glyphWidth > 0)
						texX += mGlyphSpacing + glyphWidth;
				}
			}

			texHeight = Bitwise::firstPO2From(texY + glyphHeightMap.rbegin()->first);
		}
		while (texHeight > texWidth * 2);

		//-------------------------------------------------------------------//
		// Create the texture and render the glyphs onto it.
		//-------------------------------------------------------------------//

		if (mTexture)
		{
			RenderManager::getInstance().destroyTexture( mTexture );
			mTexture = nullptr;
		}

		mTexture = RenderManager::getInstance().createTexture(MyGUI::utility::toString((size_t)this, "_TrueTypeFont"));

		mTexture->createManual(texWidth, texHeight, TextureUsage::Static | TextureUsage::Write, Pixel<LAMode>::getFormat());
		mTexture->setInvalidateListener(this);

		uint8* texBuffer = static_cast<uint8*>(mTexture->lock(TextureUsage::Write));

		if (texBuffer != nullptr)
		{
			// Make the texture background transparent white.
			for (uint8* dest = texBuffer, * endDest = dest + texWidth * texHeight * Pixel<LAMode>::getNumBytes(); dest != endDest; )
				Pixel<LAMode, false, false>::set(dest, charMaskWhite, charMaskBlack);

			renderGlyphs<LAMode, Antialias>(glyphHeightMap, ftLibrary, ftFace, ftLoadFlags, texBuffer, texWidth, texHeight);

			mTexture->unlock();

			MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using texture size " << texWidth << " x " << texHeight << ".");
			MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using real height " << mDefaultHeight << " pixels.");
		}
		else
		{
			MYGUI_LOG(Error, "ResourceTrueTypeFont: Error locking texture; pointer is nullptr.");
		}

		FT_Done_Face(ftFace);
		FT_Done_FreeType(ftLibrary);

		delete [] fontBuffer;
	}
Example #25
0
	Widget* Spacer::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
	{
		MYGUI_EXCEPT("Have you ever seen that nothing has anything? I'm not sure that it's wright, so I put there exception that notify you (and me :) ) not to put anything here. Yes, don't put anything to Spacer!" );
	}
	FT_Face ResourceTrueTypeFont::loadFace(const FT_Library& _ftLibrary, uint8*& _fontBuffer)
	{
		FT_Face result = nullptr;

		// Load the font file.
		IDataStream* datastream = DataManager::getInstance().getData(mSource);

		if (datastream == nullptr)
			return result;

		size_t fontBufferSize = datastream->size();
		_fontBuffer = new uint8[fontBufferSize];
		datastream->read(_fontBuffer, fontBufferSize);

		DataManager::getInstance().freeData(datastream);
		datastream = nullptr;

		// Determine how many faces the font contains.
		if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, -1, &result) != 0)
			MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

		FT_Long numFaces = result->num_faces;
		FT_Long faceIndex = 0;

		// Load the first face.
		if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
			MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

		if (result->face_flags & FT_FACE_FLAG_SCALABLE)
		{
			// The font is scalable, so set the font size by first converting the requested size to FreeType's 26.6 fixed-point
			// format.
			FT_F26Dot6 ftSize = (FT_F26Dot6)(mSize * (1 << 6));

			if (FT_Set_Char_Size(result, ftSize, 0, mResolution, mResolution) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");

			// If no code points have been specified, use the Unicode Basic Multilingual Plane by default.
			if (mCharMap.empty())
				addCodePointRange(0, 0xFFFF);
		}
		else
		{
			// The font isn't scalable, so try to load it as a Windows FNT/FON file.
			FT_WinFNT_HeaderRec fnt;

			// Enumerate all of the faces in the font and select the smallest one that's at least as large as the requested size
			// (after adjusting for resolution). If none of the faces are large enough, use the largest one.
			std::map<float, FT_Long> faceSizes;

			do
			{
				if (FT_Get_WinFNT_Header(result, &fnt) != 0)
					MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

				faceSizes.insert(std::make_pair((float)fnt.nominal_point_size * fnt.vertical_resolution / mResolution, faceIndex));

				FT_Done_Face(result);

				if (++faceIndex < numFaces)
					if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
						MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
			}
			while (faceIndex < numFaces);

			std::map<float, FT_Long>::const_iterator iter = faceSizes.lower_bound(mSize);

			faceIndex = (iter != faceSizes.end()) ? iter->second : faceSizes.rbegin()->second;

			if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

			// Select the first bitmap strike available in the selected face. This needs to be done explicitly even though Windows
			// FNT/FON files contain only one bitmap strike per face.
			if (FT_Select_Size(result, 0) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");

			// Windows FNT/FON files do not support Unicode, so restrict the code-point range to either ISO-8859-1 or ASCII,
			// depending on the font's encoding.
			if (mCharMap.empty())
			{
				// No code points have been specified, so add the printable ASCII range by default.
				addCodePointRange(0x20, 0x7E);

				// Additionally, if the font's character set is CP-1252, add the range of non-ASCII 8-bit code points that are
				// common between CP-1252 and ISO-8859-1; i.e., everything but 0x80 through 0x9F.
				if (fnt.charset == FT_WinFNT_ID_CP1252)
					addCodePointRange(0xA0, 0xFF);
			}
			else
			{
				// Some code points have been specified, so remove anything in the non-printable ASCII range as well as anything
				// over 8 bits.
				removeCodePointRange(0, 0x1F);
				removeCodePointRange(0x100, std::numeric_limits<Char>::max());

				// Additionally, remove non-ASCII 8-bit code points (plus ASCII DEL, 0x7F). If the font's character set is CP-1252,
				// remove only the code points that differ between CP-1252 and ISO-8859-1; otherwise, remove all of them.
				if (fnt.charset == FT_WinFNT_ID_CP1252)
					removeCodePointRange(0x7F, 0x9F);
				else
					removeCodePointRange(0x7F, 0xFF);
			}
		}

		return result;
	}