Thread: Fonts and SDL help

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    89

    Fonts and SDL help

    I decided to make my own fonts with SDL and am almost finished. Unfortunately I have a small problem and dont really know how to describe it.

    This is supposed to be a two but for some reason is messing up. Screenshot at bottom of post. Any help is appreciated.

    Here is some of my font array
    Code:
    // myfonts.h
    
    const int CHAR_WIDTH = 8;
    const int CHAR_HEIGHT = 12;
    
    const unsigned char font1[][96] =
    {
        // Character /* / */ == 47
        {
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,1,
            0,0,0,0,0,0,1,1,
            0,0,0,0,0,1,1,0,
            0,0,0,0,1,1,0,0,
            0,0,0,1,1,0,0,0,
            0,0,1,1,0,0,0,0,
            0,1,1,0,0,0,0,0,
            1,1,0,0,0,0,0,0,
            1,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        },
    
        // Number 0
        {
            0,1,1,1,1,1,0,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            0,1,1,1,1,1,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
        },
    
        // Number 1
        {
            0,0,0,1,0,0,0,0,
            0,0,1,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,1,1,1,1,1,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        },
    
        // Number 2
        {
            0,1,1,1,1,1,0,0,
            1,0,0,0,0,0,1,0,
            1,0,0,0,0,0,1,0,
            0,0,0,0,0,1,0,0,
            0,0,0,0,1,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,1,0,0,0,0,0,
            0,1,0,0,0,0,0,0,
            1,0,0,0,0,0,0,0,
            1,1,1,1,1,1,1,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        },  etc...
    Code:
    // CFont.cpp
    #include "CFont.h"
    #include "myfonts.h"
    
    CFont::CFont(SDL_Surface* nScreen)
    {
        //ctor
        m_Screen = nScreen;
    
        m_RealWidth = m_Screen->pitch / 4;
    }
    
    CFont::~CFont()
    {
        //dtor
        m_Screen = NULL;
    }
    
    void CFont::PrintString(int nX, int nY, std::string nString)
    {
        if(!m_Screen)
            return;
    
        m_X = nX;
        m_Y = nY;
    
        int length = nString.size();
    
        // Calculate Screen position
        m_Position = m_Y * m_RealWidth + m_X;
    
        for(int index = 0; index < length; index++)
        {
            PrintASCIIChar(nString[index]);
    
            // Move screen position along x axis to print next char
            m_Position += 8;
        }
    
    }
    
    void CFont::PrintASCIIChar(char ch)
    {
        if(!m_Screen)
            return;
    
        // This is to keep within range of our font values
        if(ch < 47 || ch > 122)
            return;
    
        // Offset into the font array so that we draw the correct character
        int i = ch - 47;
    
        int factor = 0;
    
        // Making variables local
        int position = m_Position; /*Screen Position*/
        int realWidth = m_RealWidth;
        int width = CHAR_WIDTH;
        int x = m_X;
        int y = m_Y;
    
        // each character is  8 * 12 = 96
        // character width is 8 so factor is used to track so I know when I hit the character width
        for(int alpha = 0; alpha < 96; alpha++, factor++)
        {
            if(font1[i][alpha])
            {
                // Set pixel to white at current screen postion adding in the factor to move along the x axis
                ((unsigned int*)m_Screen->pixels)[position + factor] = 0xffffff;
            }
    
            if(factor == width)
            {
                factor = 0;
    
                // Move screen postion along y axis to print the next line in the array
                y++;
            }
    
            // Recalculate screen position
            position = y * realWidth + x;
        }
    }
    Last edited by eaane74; 09-08-2008 at 11:04 AM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Should you not check that factor==width (and reset as appropriate) before printing the dot, rather than after?

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    So instead i should

    Code:
    if(factor == width)
    {
          factor = 0;
    
          // Move screen postion along y axis to print the next line in the array
          y++;
    }
    
    if(font1[i][alpha])
    {
       // Set pixel to white at current screen postion adding in the factor to move along the x axis
     ((unsigned int*)m_Screen->pixels)[position + factor] = 0xffffff;
    }
    // Recalculate screen position
            position = y * realWidth + x;

  4. #4
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    thanks that fixed it though I am not sure why.
    the y variable was a little off after that fix...but I fixed that my doing my screen calculation inside the if statement. Something I probably should have done to begin with.

    Code:
    // each character is  8 * 12 = 96
        // character width is 8 so factor is used to track so I when I hit the character width
        for(int alpha = 0; alpha < 96; alpha++, factor++)
        {
            if(factor == width)
            {
                factor = 0;
                y++;
                position = y * realWidth + x;
            }
    
            if(font1[i][alpha])
            {
                // Set pixel to white at current screen postion adding in the factor to move along the x axis
                ((unsigned int*)m_Screen->pixels)[position + factor] = 0xffffff;
            }
    Last edited by eaane74; 09-08-2008 at 11:44 AM.

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Here's what it looks like. My next step is to anti alias them

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by eaane74 View Post
    thanks that fixed it though I am not sure why.
    Because you were printing pixel (5,0) at location (4,8), since you didn't move back left and/or down until after the pixel was printed out.

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    ok I have started my anti aliasing font project and have already run into a slight problem.
    In the screen shot I am printing out a bunch of exclamation points, unfortunately they are
    printed out on two lines when they need to be on one.

    Here's the code:

    myfont.h
    Code:
    // ASCII range
    const int CHAR__MIN = 33;
    const int CHAR__MAX = 122;
    
    // Character attributes
    const int CHAR_WIDTH = 8;
    const int CHAR_HEIGHT = 12;
    
    const int fontColor[3] =
    {
        0xffffff, 0xbbbbbb, 0x555555
    };
    
    const char font1[3][96] =
    {
        // ! == 0
        {
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,1,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        },
    
        // ! == 0
        {
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,1,0,1,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        },
    
        // ! == 0
        {
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0
        }
    
    };
    CFont.cpp
    Code:
    #include "CFont.h"
    #include "myfont.h"
    
    CFont::CFont(SDL_Surface* nScreen)
    {
        //ctor
        m_Screen = nScreen;
    
        m_RealWidth = m_Screen->pitch / 4;
    }
    
    CFont::~CFont()
    {
        //dtor
        m_Screen = NULL;
    }
    
    void CFont::PrintString(int nX, int nY, std::string nString)
    {
        if(!m_Screen)
            return;
    
        m_X = nX;
        m_Y = nY;
    
        int length = nString.size();
    
        // Calculate Screen position
        m_Position = m_Y * m_RealWidth + m_X;
    
        for(int index = 0; index < length; index++, m_X += CHAR_WIDTH)
        {
            PrintASCIIChar(nString[index]);
    
            // Move screen position along x axis to print next char
            m_Position += CHAR_WIDTH;
        }
    
    }
    
    void CFont::PrintASCIIChar(const char ch)
    {
        if(!m_Screen)
            return;
    
        int min = CHAR__MIN;
        int max = CHAR__MAX;
    
        // This is to keep within range of our font values
        if(ch < min || ch > max)
            return;
    
        // Making variables local
        int position; /*Screen Position*/
        int realWidth = m_RealWidth;
        int x = m_X;
        int y = m_Y;
        int width = CHAR_WIDTH;
        int height = CHAR_HEIGHT;
    
        // Offset into the font array so that we draw the correct character
        int i = (width * height) * (ch - min);
    
        int factor = 0;
    
        for(int index = 0; index < 3; index++)
        {
            // Should reset screen position back to original screen position???
            position = m_Y * realWidth + m_X;
    
            for(int alpha = 0; alpha < (width * height); alpha++, factor++)
            {
                if(factor == width)
                {
                    factor = 0;
                    y++;
                    position = y * realWidth + x;
                }
    
                if(font1[index][i + alpha])
                {
                    // Set pixel to white at current screen postion adding in the factor to move along the x axis
                    ((unsigned int*)m_Screen->pixels)[position + factor] = fontColor[index];
                }
            }
        }
    }
    Last edited by eaane74; 09-09-2008 at 06:26 PM.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    And how are these functions called? In other words, why do you expect to see one line of text?

  9. #9
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    like this:

    font.PrintString(0, 0, "!!!!!!!!!");

    the second line is printed at 2/3 white and is supposed to be superimposed over the first line, which is printed at full white.
    I want to be able to anti aliasfonts with just one function call.

    I think my problem is that the screen position is not getting reset after the first interation thru the first for loop.
    Last edited by eaane74; 09-09-2008 at 07:44 PM.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You are continually doing y++; but when you switch from index = 0 to index = 1 (your ! to your !!) y does not magically reset to 0.

  11. #11
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Can I use the original x and y values that were passed in to the PrintString function?
    by that I mean is to use those values to recalculate the screen position in the first for loop.

    PrintASCIIChar function is suppose to print one character 3 times in the same place.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    void CFont::PrintASCIIChar(const char ch)
    {
        if(!m_Screen)
            return;
    
        int min = CHAR__MIN;
        int max = CHAR__MAX;
    
        // This is to keep within range of our font values
        if(ch < min || ch > max)
            return;
    
        // Making variables local
        int position; /*Screen Position*/
        int realWidth = m_RealWidth;
        int x = m_X;  
        int y = m_Y;  /* here is bad */
        int width = CHAR_WIDTH;
        int height = CHAR_HEIGHT;
    
        // Offset into the font array so that we draw the correct character
        int i = (width * height) * (ch - min);
    
        int factor = 0;
    
        for(int index = 0; index < 3; index++)
        {
            // Should reset screen position back to original screen position???
            int y = m_Y; //here is good, since you want to reset screen position back to original screen position
            position = m_Y * realWidth + m_X;
    
            for(int alpha = 0; alpha < (width * height); alpha++, factor++)
            {
                if(factor == width)
                {
                    factor = 0;
                    y++;
                    position = y * realWidth + x;
                }
    
                if(font1[index][i + alpha])
                {
                    // Set pixel to white at current screen postion adding in the factor to move along the x axis
                    ((unsigned int*)m_Screen->pixels)[position + factor] = fontColor[index];
                }
            }
        }
    }

  13. #13
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    thanks...that worked

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. lots of freeware
    By major_small in forum General Discussions
    Replies: 60
    Last Post: 02-14-2017, 03:00 AM
  2. Fonts
    By AceBlkwell in forum Game Programming
    Replies: 6
    Last Post: 12-02-2007, 11:30 AM
  3. sin and cos ?
    By MathFan in forum Game Programming
    Replies: 2
    Last Post: 12-27-2003, 10:21 AM