示例#1
0
void Window::ShowDecorations()
{
    Hide();
    Rect clr = GetClientRect();
    SetWindowLong( _window_handle, GWL_STYLE, WS_TILEDWINDOW);
    Rect dr = GetWindowRect() - GetClientRect();
    Resize( clr.GetW() + dr.GetW(), clr.GetH() + dr.GetH() );
    Show();
}
示例#2
0
/**
 * Returns true if the given box is directly above the ground
 */
bool MovementMap::IsOnGround(const Rect box)
{
    // Checks the lower limit
    if (!IsZero(box.Center().GetX(), box.GetY()+box.GetH()+1)) return true;
    // Checks the lower-right limit
    if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()+1)) return true;
    // Checks the lower-left limit
    if (!IsZero(box.GetX(), box.GetY()+box.GetH()+1)) return true;
    return false;
}
    void WidgetTableWidget::RepaintImpl( const WidgetPainter &painter )
    {
        //HubWidget::Repaint(painter); -- nonsense

        Rect client_area = GetParent()->GetClientRect(this)-GetPosition();
        Rect influenced = GetCrossing( client_area );
        Pos p( influenced.GetX1(), influenced.GetY1() );

        for ( int j=0; j!=influenced.GetW(); ++j, ++p.x )
        {
            SettlerMap::Iterator iter;
            _settlers.Find( p, (SettlerMap::ConstIterator*)&iter);
            for ( int i=0; i!=influenced.GetH(); ++i, ++iter )
            {
                if (!iter) { break; }//< W/A GetCrossing() does not work corectly
                Widget &child = *iter->_settler;
                if ( child.IsVisible() )
                {
                    WidgetPainter child_painter( painter, child );
                    if ( child_painter.Intersect() ) 
                    {
                        child.Repaint(child_painter);
                        child_painter.RestoreClipper();
                    }
                }
            }
        }
    }
void TableListedItems::PaintClients( const WidgetPainter &painter )
{
    Pos p;
    Dim2i d( GetWidth(), 0);

    Rect client_area = GetParent()->GetClientRect(this)-GetPosition();
    Rect visibile = TableWidget::GetCrossing( client_area );
    
    p.y = RowRect( visibile.GetY1() ).GetY();
    for ( int i=visibile.GetY1(); i<visibile.GetY2(); ++i )
    {
        d.y = GetRowHeight(i);

        int last_col = GetNumColumns() -1;
        Rect fa = RowRect( i );

        if ( _skins.Select( GetState(i) ) )
        {
            _skins.SetSize( Dim2i(fa.GetW(),fa.GetH()) );
        }
        _skins.Paint( painter, fa.GetPos(), fa );

        p.y += d.y;
    }
}
示例#5
0
void MainState::Update() {
	// Moves the player in the specified direction
	if (m_PlayerDirState[kPlayerDirLeft]) {
		m_Player->TranslateBy(Vec2(-5.0, 0.0));
	}
	else if (m_PlayerDirState[kPlayerDirRight]) {
		m_Player->TranslateBy(Vec2(5.0, 0.0));
	}
	else if (m_PlayerDirState[kPlayerDirUp]) {
		m_Player->TranslateBy(Vec2(0.0, -5.0));
	}
	else if (m_PlayerDirState[kPlayerDirDown]) {
		m_Player->TranslateBy(Vec2(0.0, 5.0));
	}

	for (int i = 0; i < m_ProjectileArray.GetSize(); ++i) {
		Rect screenRect = m_EnginePtr->GetScene()->GetScreenRect();

		Projectile* projectile = m_ProjectileArray[i];

		Vec2 pos = projectile->GetWorldPosition();

		if (pos.GetX() < screenRect.GetX() ||
			pos.GetX() > (screenRect.GetX() + screenRect.GetW()) ||
			pos.GetY() < screenRect.GetY() ||
			pos.GetY() > (screenRect.GetY() + screenRect.GetH())) {

			LOG_PRINT("removed");
		}
	}
}
示例#6
0
/**
 * Corrects the box position relative to a given tileBox
 * and the previous position of the box.
 */
void MovementMap::CorrectCollision(Rect& box, Rect tileBox)
{
    if (!Collision::IsColliding(box, tileBox, 0, 0)) return;
    // If the previous position was to the left of the tile
    if (previousPos.GetX()+previousPos.GetW() <= tileBox.GetX())
        box.MoveRect(tileBox.GetX() - (box.GetX()+box.GetW()), 0);
    // If the previous position was to the right of the tile
    else if (previousPos.GetX() >= tileBox.GetX()+tileBox.GetW())
        box.MoveRect((tileBox.GetX()+tileBox.GetW()) - box.GetX(), 0);
    // If the previous position was below the tile
    else if (previousPos.GetY() > tileBox.GetY())
        box.MoveRect(0, tileBox.GetY()+tileBox.GetH() - box.GetY());
    // If the previous position was above the tile
    else
        box.MoveRect(0, tileBox.GetY()-(box.GetY()+box.GetH()));
}
示例#7
0
void Window::HideDecorations()
{
    Hide();
    Rect clr = GetClientRect();
    SetWindowLong( _window_handle, GWL_STYLE, WS_POPUP);
    Resize( clr.GetW(), clr.GetH());
    Show();
}
示例#8
0
Rect TableWidget::RowRect( int row ) const
{
    int last_col = GetNumColumns() -1;
    
    Rect R = CellRect( 0, row) | CellRect( last_col, row);
    Rect r = ClientRect( 0, row) | ClientRect( last_col, row);

    return Rect( R.GetX1(), r.GetY1(), R.GetW(), r.GetH() );
}
示例#9
0
Rect TableWidget::ColumnRect( int column ) const
{
    int last_row = GetNumRows() -1;
    
    Rect R = CellRect( column, 0) | CellRect( column, last_row);
    Rect r = ClientRect( column, 0) | ClientRect( column, last_row);

    return Rect( r.GetX1(), R.GetY1(), r.GetW(), R.GetH() );
}
示例#10
0
Point<double> DDScreen::GetZoomFactors() const
{
    DDSurface *p_back = DDrawWindow::GetDisplay().GetBackBuffer();
    Rect client = Window::GetClientRect();
    assert( p_back );
    double factor_x = client.GetW()/ (double)p_back->GetWidth();
    double factor_y = client.GetH()/ (double)p_back->GetHeight();

    return Point<double>( factor_x, factor_y );
}
示例#11
0
Vec2 CollisionDetector::AABBToAABB(const Rect& rect1, const Rect& rect2) {
	// Prevents false collision if either rects has no width and height
	if ((rect1.GetW() == 0 && rect1.GetH() == 0) ||
		(rect2.GetW() == 0 && rect2.GetH() == 0)) {
		return Vec2(0.0, 0.0); 
	}

	Vec2 min1(rect1.GetX(), rect1.GetY());
	Vec2 max1(rect1.GetX() + rect1.GetW(), rect1.GetY() + rect1.GetH());
	Vec2 min2(rect2.GetX(), rect2.GetY());
	Vec2 max2(rect2.GetX() + rect2.GetW(), rect2.GetY() + rect2.GetH());

	if ((max1.GetX() < min2.GetX()) || (max1.GetY() < min2.GetY())) {
		return Vec2(0.0, 0.0);
	}

	if ((max2.GetX() < min1.GetX()) || (max2.GetY() < min1.GetY())) {
		return Vec2(0.0, 0.0);
	}

	// Potential resolution offsets
	double negX = max1.GetX() - min2.GetX();
	double posX = max2.GetX() - min1.GetX();
	double negY = max1.GetY() - min2.GetY();
	double posY = max2.GetY() - min1.GetY();

	// Returns the component vector that needs the least offset to resolve the collision
	if (negX <= posX && negX <= negY && negX <= posY) {
		return Vec2(-negX, 0.0);
	}
	else if (posX <= negY && posX <= posY) {
		return Vec2(posX, 0.0);
	}
	else if (negY <= posY) {
		return Vec2(0.0, -negY);
	}
	else {
		return Vec2(0.0, posY);
	}

	return Vec2(0.0, 0.0);
}
void ListedTextItems::PaintArea( const Painter &painter, const Rect &area, int stateID)
{
    if ( _skins.Select(stateID) )
    {
        int cur_w = _skins.GetWidth();
        int cur_h = _skins.GetHeight();
        _skins.SetSize( Dim2i( area.GetW(), area.GetH()));
        _skins.Paint( painter, area.GetPos());
        _skins.SetSize( Dim2i( cur_w, cur_h));
    }
}
示例#13
0
/**
 * Returns a vector of Rects corresponding to the tiles
 * that are colliding with the given box
 */
std::vector<Rect> MovementMap::GetCollidingTiles(const Rect& box)
{
    std::vector<Rect> collidingTiles;
    // Check the upper point
    if (!IsZero(box.GetX()+box.GetW()/2, box.GetY()))
        collidingTiles.push_back(TileToRect(box.GetX(), box.GetY()));
    // Check the right point
    if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()/2))
        collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY()));
    // Check the left point
    if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2))
        collidingTiles.push_back(TileToRect(box.GetX(), box.GetY()+box.GetH()));
    // Check the lower point
    if (!IsZero(box.GetX()+box.GetW()/2, box.GetY()+box.GetH()))
        collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY()+box.GetH()));
//    for (int i = 0; i < collidingTiles.size(); i++)
//    {
//        std::cout << std::endl;
//        std::cout << "(" << collidingTiles[i].GetX() << "," << collidingTiles[i].GetY() << ")" << std::endl;
//        std::cout << "Width: " << collidingTiles[i].GetW() << " Height: " << collidingTiles[i].GetH() << std::endl;
//    }
    return collidingTiles;
}
示例#14
0
/**
 * This method uses the new position of the given object,
 * its previous position and the map to determine whether
 * the object is colliding with the walls
 */
bool MovementMap::IsColliding(const Rect box)
{
//    // Checks the center
//    if (!IsZero(box.Center().GetX(), box.Center().GetY())) return true;
    // Checks the above limit
    if (!IsZero(box.GetX()+box.GetW()/2, box.GetY())) return true;
    // Checks the right limit
    if (!IsZero(box.GetX() + box.GetW(), box.GetY() + box.GetH()/2)) return true;
    // Checks the left limit
    if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2)) return true;
    // Checks the upper-right limit
    if (!IsZero(box.GetX()+box.GetW(), box.GetY())) return true;
    // Checks the upper-left limit
    if (!IsZero(box.GetX(), box.GetY())) return true;
    // Checks the lower limit
    if (!IsZero(box.Center().GetX(), box.Center().GetY() + box.GetH()/2)) return true;
    // Checks the lower-right limit
    if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH())) return true;
    // Checks the lower-left limit
    if (!IsZero(box.GetX(), box.GetY()+box.GetH())) return true;
    return false;
//    return IsCollidingWithGround(box);
}
示例#15
0
void TableSkin::TableDice( const Rect &bound, int x1, int x2, int x3, int y1, int y2, int y3, bool no_interrior)
{
    AssocVector<int ,Rect> assoc_rects;

    Pos p0;// = bound.GetPos();

    int x[5] = { 0, x1, x2, x3, bound.GetW() };
    int y[5] = { 0, y1, y2, y3, bound.GetH() };

    assoc_rects.Insert( TOP+HEAD, CheckedRect( x[0], y[0], x[1]-x[0], y[1]-y[0]) +p0);
    assoc_rects.Insert( TOP+BODY, CheckedRect( x[1], y[0], x[2]-x[1], y[1]-y[0]) +p0);
    assoc_rects.Insert( TOP+TAIL, CheckedRect( x[3], y[0], x[4]-x[3], y[1]-y[0]) +p0);

    assoc_rects.Insert( MIDDLE+HEAD, CheckedRect( x[0], y[1], x[1]-x[0], y[2]-y[1]) +p0);

    if ( !no_interrior )
    assoc_rects.Insert( MIDDLE+BODY, CheckedRect( x[1], y[1], x[2]-x[1], y[2]-y[1]) +p0);

    assoc_rects.Insert( MIDDLE+TAIL, CheckedRect( x[3], y[1], x[4]-x[3], y[2]-y[1]) +p0);

    assoc_rects.Insert( BOTTOM+HEAD, CheckedRect(x[0], y[3], x[1]-x[0], y[4]-y[3]) +p0);
    assoc_rects.Insert( BOTTOM+BODY, CheckedRect(x[1], y[3], x[2]-x[1], y[4]-y[3]) +p0);
    assoc_rects.Insert( BOTTOM+TAIL, CheckedRect(x[3], y[3], x[4]-x[3], y[4]-y[3]) +p0);

    assoc_rects.Insert( HEAD+HDIV , CheckedRect( x[0], y[2], x[1]-x[0], y[3]-y[2]) +p0);
    assoc_rects.Insert( BODY+HDIV , CheckedRect( x[1], y[2], x[2]-x[1], y[3]-y[2]) +p0);
    assoc_rects.Insert( TAIL+HDIV , CheckedRect( x[3], y[2], x[4]-x[3], y[3]-y[2]) +p0);

    assoc_rects.Insert( HEAD+VDIV , CheckedRect( x[2], y[0], x[3]-x[2], y[1]-y[0]) +p0);
    assoc_rects.Insert( BODY+VDIV , CheckedRect( x[2], y[1], x[3]-x[2], y[2]-y[1]) +p0);
    assoc_rects.Insert( TAIL+VDIV , CheckedRect( x[2], y[3], x[3]-x[2], y[4]-y[3]) +p0);

    assoc_rects.Insert( CROSSING  , CheckedRect( x[2], y[2], x[3]-x[2], y[3]-y[2]) +p0);

    ImageDicer::Dice(assoc_rects);
    SetSize( Dim2i(bound.GetW(), bound.GetH()) );
}
示例#16
0
/*! Place self inside parents-client area.
 *  Proportions are rect.{x|y|w|h} / base.{x|y|x|y}.
 *  If base.{x|y}==0 then position and size in {X|Y} direction will be preserved.
 */
void Widget::Place ( const Rect &rect, const Pos &base)
{
    Rect client_area = GetParent()->GetClientRect( this);
    Rect my_rect = GetBoundingRect() + GetPosition();
    double x = my_rect.GetX();
    double y = my_rect.GetY();
    double w = my_rect.GetW();
    double h = my_rect.GetH();
    if ( base.x > 0) { x = as_double( client_area.GetW() * rect.GetX() ) / as_double( base.x ); }
    if ( base.y > 0) { y = as_double( client_area.GetH() * rect.GetY() ) / as_double( base.y ); }
    if ( base.x > 0) { w = as_double( client_area.GetW() * rect.GetW() ) / as_double( base.x ); }
    if ( base.y > 0) { h = as_double( client_area.GetH() * rect.GetH() ) / as_double( base.y ); }
    SetPosition( client_area.GetPos() + Pos( std::floor(x), std::floor(y) ));
    Resize( std::ceil(w), std::ceil(h) );
}
示例#17
0
// Fills parent client-area with self
void Widget::Fill( const Rect& area, const Rect &padding )
{   
    Rect cr = area;
    if (!cr)
    {
        assert( _parent && "Widget::Fill(): Impossibile due no parent");
        cr = _parent->GetClientRect(this);
    }
    cr.x += padding.x;
    cr.y += padding.y;
    cr.w -= padding.w + padding.x;
    cr.h -= padding.h + padding.y;
    SetPosition( cr.GetPos() );
    Resize( cr.GetW(), cr.GetH() );
}
示例#18
0
// Methos allocates space for widget
void Widget::SetBoundingRect( const Rect &r )
{
    Rect previous = _bound;
    _bound = r;
    bool anything_changed=false;

    if ( GetEnvironment() )
    {
        _parent->SetDirty( previous | _bound );
    }
    if ( _bound.GetX() != previous.GetX() || _bound.GetY() != previous.GetY() )
    {
        OnReposition.Send_1( Pos( _bound.GetX(), _bound.GetY() ));
        anything_changed=true;
    }
    if ( _bound.GetW() != previous.GetW() || _bound.GetH() != previous.GetH() )
    {
        OnResize.Send_2( _bound.GetW(), _bound.GetH() );
        anything_changed=true;
    }
    if ( anything_changed )
        NotifyAncestors(true);
}
void TableSystemWidget::Fit()
{
    int w = GetWidth(), h=GetHeight();
    int sb_width = _sb_width;
    int sb_height = _sb_height;

    if (_p_verti_scrollbar && _p_verti_scrollbar->Atom().IsVisible() )
    {
        _ResizePositive( _p_verti_scrollbar->AtomPtr(), sb_width, h-(_cs_height+sb_height) );
        _p_verti_scrollbar->Atom().SetPosition ( Pos( w-sb_width, _cs_height) );
    }
    if (_p_horiz_scrollbar && _p_horiz_scrollbar->Atom().IsVisible() )
    {
        _ResizePositive( _p_horiz_scrollbar->AtomPtr(), w-sb_width, sb_height );
        _p_horiz_scrollbar->Atom().SetPosition ( Pos( 0, h-sb_height ) );
    }

    if (_p_table_frame)
    {
        int frame_w = w-sb_width;
        int frame_h = h-sb_height;

        _p_table_frame->Fill( Rect( 0, 0, frame_w, frame_h ));
        Rect c = _p_table_frame->GetClientRect( _p_caption_scroller );
        _p_caption_scroller->Resize( c.GetW(), _cs_height );
        _p_caption_scroller->SetPosition( c.GetPos() );
        _ResizePositive( _p_table_scroller, c.GetW(), c.GetH()-_cs_height );
        _p_table_scroller->SetPosition( c.GetPos() + Pos( 0, _cs_height) );
    }
    else
    {
        if (_p_caption_scroller)
        {
            _p_caption_scroller->Resize( w-sb_width, _cs_height );
            _p_caption_scroller->SetPosition( Pos(0,0) );
        }
        if (_p_table_scroller)
        {
            _ResizePositive( _p_table_scroller, w-sb_width, h-(_cs_height+sb_height) );
            _p_table_scroller->SetPosition  ( Pos(0,_cs_height) );
        }
    }

    if ( _p_top_gadget )
    {
        _p_top_gadget->SetPosition( Pos( w-_p_top_gadget->GetWidth(), 0) );
        HubWidget::BringOnTop( _p_top_gadget );
    }
    if ( _p_bottom_gadget )
    {
        if ( sb_width && sb_height )
        { 
            _p_bottom_gadget->SetPosition( Pos( w-sb_width, h-sb_height) );

            if ( !_p_bottom_gadget->Atom().IsVisible() ) { _p_bottom_gadget->Atom().Show(); }
        }
        else if ( _p_bottom_gadget->Atom().IsVisible() ) { _p_bottom_gadget->Atom().Hide(); }
    }

    if ( _auto_cover )
    {
        int pri_tbl_width = _pri_tbl_width;
        int pri_tbl_height= _pri_tbl_height;
        int table_w = pri_tbl_width;
        int table_h = pri_tbl_height;
        int client_w = _p_table_scroller->GetWidth();
        int client_h = _p_table_scroller->GetHeight();

        // try to cover all client area by table (if table is smaller than area)
        if ( client_w > table_w )
        {
            _p_main_table->Atom().Resize( client_w, table_h );
        }
        else if ( client_w < pri_tbl_width )
        {
            _p_main_table->Atom().Resize( pri_tbl_width, table_h );
        }
    
        table_w = _p_main_table->Atom().GetWidth();

        if ( client_h > table_h )
        {
            _p_main_table->Atom().Resize( table_w, client_h );
        }
        else if ( client_h < pri_tbl_height )
        {
            _p_main_table->Atom().Resize( table_w, pri_tbl_height );
        }

        table_h = _p_main_table->Atom().GetHeight();

        // right scrollbar dissappears only if top-gadget does not exist
        if ( !_p_top_gadget )
        {
            // Check if full table would be visible if we hide both scrollbars
            bool would_fit_width = client_w + sb_width >= table_w;
            bool would_fit_height= client_h + sb_height >= table_h;
    
            if ( would_fit_width && would_fit_height )
            {
                _p_main_table->Atom().Resize( client_w + sb_width, client_h + sb_height);
                _sb_width = _sb_height = 0;
            }
        }
        _pri_tbl_width = pri_tbl_width;
        _pri_tbl_height= pri_tbl_height;
    }

    // Make sure that scrollbar sizes have not been changed, and if so try again
    if ( _sb_width!=sb_width || _sb_height!=sb_height ) { Fit(); }
}
示例#20
0
Vec2 CollisionDetector::LineToAABB(const Vec2& linePt, const Vec2& lineDir, const Rect& rect) {
	// Prevents false collision if either rects has no width and height
	if (rect.GetW() == 0 && rect.GetH() == 0) {
		return Vec2(0.0, 0.0); 
	}

	Vec2 linePt1 = linePt;
	Vec2 linePt2 = linePt + lineDir;

	Vec2 rectPtArray[] = { 	Vec2(rect.GetX(), rect.GetY()),
							Vec2(rect.GetX() + rect.GetW(), rect.GetY()),
							Vec2(rect.GetX() + rect.GetW(), rect.GetY() + rect.GetH()),
							Vec2(rect.GetX(), rect.GetY() + rect.GetH()) };

	double currentDirMag = 1.0f; // Current direction vector magnitude

	// Test intersection for all four line segments of the rectangle
	for (int i = 0; i < 4; ++i) {
		// i is the index of the first point, j the second
		// set j to 0 if i equals 3
		int j = (i < 3) ? (i + 1) : 0;

		Vec2 rectPt1 = rectPtArray[i];
		Vec2 rectPt2 = rectPtArray[j];

		double sNumer = (	(linePt1.GetY() - rectPt1.GetY()) *
							(rectPt2.GetX() - rectPt1.GetX())	) - 
						(	(linePt1.GetX() - rectPt1.GetX()) *
							(rectPt2.GetY() - rectPt1.GetY())	);

		double sDenom =	(	(linePt2.GetX() - linePt1.GetX()) *
							(rectPt2.GetY() - rectPt1.GetY())	) -
						(	(linePt2.GetY() - linePt1.GetY()) *
							(rectPt2.GetX() - rectPt1.GetX())	);

		double tNumer =	(	(linePt1.GetY() - rectPt1.GetY()) *
							(linePt2.GetX() - linePt1.GetX())	) -
						(	(linePt1.GetX() - rectPt1.GetX()) *
							(linePt2.GetY() - linePt1.GetY())	);

		double tDenom = 	(	(linePt2.GetX() - linePt1.GetX()) *
							(rectPt2.GetY() - rectPt1.GetY())	) -
						(	(linePt2.GetY() - linePt1.GetY()) *
							(rectPt2.GetX() - rectPt1.GetX())	);

		double s = sNumer / sDenom;
		double t = tNumer / tDenom;
		
		// Lines intersect if s and t are in range [0,1]
		if ((s >= 0.0 && s <= 1.0) && (t >= 0.0 && t <= 1.0)) {
			currentDirMag = t < currentDirMag ? s : currentDirMag;
		}
	}

	if (currentDirMag == 1.0) {
		return Vec2(0.0, 0.0);
	}
	else {
		return Vec2(linePt + (lineDir * currentDirMag));
	}
}
示例#21
0
void Font::ConvertToBitmapFont(Display* display, int numchar)
{
	int textureW = size * sqrt(numchar);
	int textureH = size * sqrt(numchar);

	bitmapFont = SDL_CreateTexture(display->GetRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, textureW, textureH);

	if (bitmapFont == nullptr)
	{
		LOG_ERROR("Couldn't create texture for bitmap font creating! Error: " << SDL_GetError());
	}

	if(SDL_SetTextureBlendMode(bitmapFont, SDL_BLENDMODE_BLEND) == -1)
		LOG_ERROR("Couldn't set blendmode for texture when creating bitmap font!");


	if(SDL_SetRenderTarget(display->GetRenderer(), bitmapFont) == -1)
		LOG_ERROR("Couldn't set render target to texture when creating bitmap font!");

	display->PushRenderColor();
	display->SetRenderColor(255, 255, 255, 0);

	if(SDL_RenderClear(display->GetRenderer()) == -1)
		LOG_ERROR("Couldn't clear texture when creating bitmap font!");

	display->PopRenderColor();

	int x = 0;
	int y = 0;	

	for (int i = 0; i < numchar; i++)
	{	
		
		//If break line charater skip
		if (i == 10)
		{ 
			glyphPositions.push_back(Rect(0, 0, 0, 0));
			continue;
		}

		SDL_Surface* surface = nullptr;
		surface = TTF_RenderGlyph_Blended(font, i, COLOR_WHITE.ToSDLColor());

		if (surface == nullptr)
		{
			//Don't show error on the NULL character
			if (i != 0)
			{
				LOG_ERROR("Couldn't create glyph surface! Using letter " << (char)i);
			}
			glyphPositions.push_back(Rect(0, 0, 0, 0));
			continue;
		}

		SDL_Texture* texture = nullptr;
		texture = SDL_CreateTextureFromSurface(display->GetRenderer(), surface);

		SDL_FreeSurface(surface);

		if (texture == nullptr)
		{
			LOG_ERROR("Couldn't create glyph texture! Using letter " << (char)i);
			glyphPositions.push_back(Rect(0, 0, 0, 0));
			continue;
		}

		Rect pos;
		if (SDL_QueryTexture(texture, NULL, NULL, &pos.w, &pos.h) == -1)
		{
			LOG_ERROR("Couldn't query texture when creating bitmap font!");
			break;
		}

		if (x + pos.GetW() > textureW)
		{
			x = 0;
			y++;
		}
		if (y * pos.h > textureH)
		{
			LOG_ERROR("Can't render anymore letters to the texture it's full! Font size: " << size);
			SDL_DestroyTexture(texture);
			break;
		}

		pos.x = x;
		pos.y = y * pos.h;

		height = pos.GetH();

		glyphPositions.push_back(pos);

		x += pos.GetW();

		//Don't render tab character
		if (i != 9)
		{
			if (SDL_RenderCopy(display->GetRenderer(), texture, NULL, pos.ToSDLRect()) == -1)
				LOG_ERROR("Couldn't draw on texture when creating bitmap font!");
		}

		SDL_DestroyTexture(texture);
	}

	if(SDL_SetRenderTarget(display->GetRenderer(), NULL) == -1)
		LOG_ERROR("Couldn't set render target back to renderer when creating bitmap font!");
	
	return;
}