Recoloring shaded fonts

Archived from groups: rec.games.roguelike.development (More info?)

Does anyone know if there is an algorithm to recolor shaded font glyphs
(created by SDL_ttf/freetype2)?
At the moment my "print character" function renders the passed character
from scratch every time it's called. I would use a cache of pre-rendered
glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs in
every color used requires way too much memory.
The problem is that I use shaded glyphs (and will continue to do so) so I
can't just change the foreground color palette entry. The palette of the
glyphs is 8bit, containing multiple shades of the base color + black (I
guess / I render on black). Is there a fast way to "shift" the entire
palette to a different color?
I know this is not the best place to ask such questions but I don't usually
have to deal with GFX programming issues. What's a good place to ask such
questions?


copx
14 answers Last reply
More about recoloring shaded fonts
  1. Archived from groups: rec.games.roguelike.development (More info?)

    copx wrote:
    > Does anyone know if there is an algorithm to recolor shaded font glyphs
    > (created by SDL_ttf/freetype2)?
    > At the moment my "print character" function renders the passed character
    > from scratch every time it's called. I would use a cache of pre-rendered
    > glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs in
    > every color used requires way too much memory.
    > The problem is that I use shaded glyphs (and will continue to do so) so I
    > can't just change the foreground color palette entry. The palette of the
    > glyphs is 8bit, containing multiple shades of the base color + black (I
    > guess / I render on black). Is there a fast way to "shift" the entire
    > palette to a different color?
    > I know this is not the best place to ask such questions but I don't usually
    > have to deal with GFX programming issues. What's a good place to ask such
    > questions?

    I've never used shaded rendering with my fonts (I always stuck with
    either Solid (for speed), or Blended (for looks)), so I'm probably going
    to sound like an idiot here. If memory serves, shaded rendering blends
    the font color with the background, correct? Since you use black for
    the background, couldn't you just go ahead and manually shift all
    non-black pixels on the surface to the desired color? I'd imagine such
    an operation would be rather fast, even on an older machine.
  2. Archived from groups: rec.games.roguelike.development (More info?)

    Hello copx,

    I only cache any combination I actually use,
    which comes down to maybe a few hundred combinations.
    Then each new draw request checks the cache, and if the
    cache doesnt provide what I need, I add it to the cache.

    T.
  3. Archived from groups: rec.games.roguelike.development (More info?)

    copx a écrit :
    > Does anyone know if there is an algorithm to recolor shaded font glyphs
    > (created by SDL_ttf/freetype2)?
    > At the moment my "print character" function renders the passed character
    > from scratch every time it's called. I would use a cache of pre-rendered
    > glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs in
    > every color used requires way too much memory.
    > The problem is that I use shaded glyphs (and will continue to do so) so I
    > can't just change the foreground color palette entry. The palette of the
    > glyphs is 8bit, containing multiple shades of the base color + black (I
    > guess / I render on black). Is there a fast way to "shift" the entire
    > palette to a different color?
    > I know this is not the best place to ask such questions but I don't usually
    > have to deal with GFX programming issues. What's a good place to ask such
    > questions?

    My guess would be that if you render the glyph on a paletted surface,
    you can easily switch the palette as needed before you render.
  4. Archived from groups: rec.games.roguelike.development (More info?)

    "Christophe" <chris.cavalaria@free.fr> schrieb im Newsbeitrag
    news:43311498$0$7209$626a14ce@news.free.fr...
    > copx a écrit :
    >> Does anyone know if there is an algorithm to recolor shaded font glyphs
    >> (created by SDL_ttf/freetype2)?
    >> At the moment my "print character" function renders the passed character
    >> from scratch every time it's called. I would use a cache of pre-rendered
    >> glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs
    >> in every color used requires way too much memory.
    >> The problem is that I use shaded glyphs (and will continue to do so) so I
    >> can't just change the foreground color palette entry. The palette of the
    >> glyphs is 8bit, containing multiple shades of the base color + black (I
    >> guess / I render on black). Is there a fast way to "shift" the entire
    >> palette to a different color?
    >> I know this is not the best place to ask such questions but I don't
    >> usually have to deal with GFX programming issues. What's a good place to
    >> ask such questions?
    >
    > My guess would be that if you render the glyph on a paletted surface, you
    > can easily switch the palette as needed before you render.

    If I would do that I would need to cache the palettes which would still
    require > 10MB RAM.
    The palette is different for each glyph in each color!.
    That's (number of characters) * (number of colors) * (palette size) !

    copx
  5. Archived from groups: rec.games.roguelike.development (More info?)

    copx a écrit :
    > "Christophe" <chris.cavalaria@free.fr> schrieb im Newsbeitrag
    > news:43311498$0$7209$626a14ce@news.free.fr...
    >
    >>copx a écrit :
    >>
    >>>Does anyone know if there is an algorithm to recolor shaded font glyphs
    >>>(created by SDL_ttf/freetype2)?
    >>>At the moment my "print character" function renders the passed character
    >>>from scratch every time it's called. I would use a cache of pre-rendered
    >>>glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs
    >>>in every color used requires way too much memory.
    >>>The problem is that I use shaded glyphs (and will continue to do so) so I
    >>>can't just change the foreground color palette entry. The palette of the
    >>>glyphs is 8bit, containing multiple shades of the base color + black (I
    >>>guess / I render on black). Is there a fast way to "shift" the entire
    >>>palette to a different color?
    >>>I know this is not the best place to ask such questions but I don't
    >>>usually have to deal with GFX programming issues. What's a good place to
    >>>ask such questions?
    >>
    >>My guess would be that if you render the glyph on a paletted surface, you
    >>can easily switch the palette as needed before you render.
    >
    >
    > If I would do that I would need to cache the palettes which would still
    > require > 10MB RAM.
    > The palette is different for each glyph in each color!.
    > That's (number of characters) * (number of colors) * (palette size) !

    Not really. I'm sure the palette you get while rendering a shaded glyph
    doesn't change when you use the same foreground color. So you can just
    render the glyph once with say a black on white color and create a few
    palettes for the different colors you want.

    In fact, I could bet the palette you will get then is all the greys
    going from black at index 255 to white at index 0.
  6. Archived from groups: rec.games.roguelike.development (More info?)

    "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    news:8M9Ye.1092$845.301@fe03.lga...
    > copx wrote:
    >> Does anyone know if there is an algorithm to recolor shaded font glyphs
    >> (created by SDL_ttf/freetype2)?
    >> At the moment my "print character" function renders the passed character
    >> from scratch every time it's called. I would use a cache of pre-rendered
    >> glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs
    >> in every color used requires way too much memory.
    >> The problem is that I use shaded glyphs (and will continue to do so) so I
    >> can't just change the foreground color palette entry. The palette of the
    >> glyphs is 8bit, containing multiple shades of the base color + black (I
    >> guess / I render on black). Is there a fast way to "shift" the entire
    >> palette to a different color?
    >> I know this is not the best place to ask such questions but I don't
    >> usually have to deal with GFX programming issues. What's a good place to
    >> ask such questions?
    >
    > I've never used shaded rendering with my fonts (I always stuck with either
    > Solid (for speed), or Blended (for looks)), so I'm probably going to sound
    > like an idiot here. If memory serves, shaded rendering blends the font
    > color with the background, correct? Since you use black for the
    > background, couldn't you just go ahead and manually shift all non-black
    > pixels on the surface to the desired color? I'd imagine such an operation
    > would be rather fast, even on an older machine.

    "Desired color" is the problem. Shaded fonts are rendered in multiple shades
    so there are multiple colors.
    I don't know how "shifting" should work in this case. I suppose plain white
    (0xFFFFFF) would be a sensible base color for the catched glyphs. Now how do
    I shift all non-black pixels so that they are no longer shades of 0xFFFFFF
    but shades of 0x8D1C45 for example?!

    copx
  7. Archived from groups: rec.games.roguelike.development (More info?)

    copx wrote:
    > "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    > news:8M9Ye.1092$845.301@fe03.lga...
    >
    >>copx wrote:
    >>
    >>>Does anyone know if there is an algorithm to recolor shaded font glyphs
    >>>(created by SDL_ttf/freetype2)?
    >>>At the moment my "print character" function renders the passed character
    >>>from scratch every time it's called. I would use a cache of pre-rendered
    >>>glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs
    >>>in every color used requires way too much memory.
    >>>The problem is that I use shaded glyphs (and will continue to do so) so I
    >>>can't just change the foreground color palette entry. The palette of the
    >>>glyphs is 8bit, containing multiple shades of the base color + black (I
    >>>guess / I render on black). Is there a fast way to "shift" the entire
    >>>palette to a different color?
    >>>I know this is not the best place to ask such questions but I don't
    >>>usually have to deal with GFX programming issues. What's a good place to
    >>>ask such questions?
    >>
    >>I've never used shaded rendering with my fonts (I always stuck with either
    >>Solid (for speed), or Blended (for looks)), so I'm probably going to sound
    >>like an idiot here. If memory serves, shaded rendering blends the font
    >>color with the background, correct? Since you use black for the
    >>background, couldn't you just go ahead and manually shift all non-black
    >>pixels on the surface to the desired color? I'd imagine such an operation
    >>would be rather fast, even on an older machine.
    >
    >
    > "Desired color" is the problem. Shaded fonts are rendered in multiple shades
    > so there are multiple colors.
    > I don't know how "shifting" should work in this case. I suppose plain white
    > (0xFFFFFF) would be a sensible base color for the catched glyphs. Now how do
    > I shift all non-black pixels so that they are no longer shades of 0xFFFFFF
    > but shades of 0x8D1C45 for example?!

    Maybe something like this:

    (Pseudocode)

    function shift_font_color(int r, int g, int b)
    for x < (width of surface)
    for y < (height of surface)
    if surface.pixels(x, y) != 0
    surface.pixels(x, y).r += r
    surface.pixels(x, y).g += g
    surface.pixels(x, y).b += b
    end if
    end loop
    end loop
    end function

    Keep in mind, it's 5:30 in the morning, so I'm a bit tired, but I
    imagine that this would work.
  8. Archived from groups: rec.games.roguelike.development (More info?)

    "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    news:cHaYe.693$X6.250@fe05.lga...
    [snip]
    > Maybe something like this:
    >
    > (Pseudocode)
    >
    > function shift_font_color(int r, int g, int b)
    > for x < (width of surface)
    > for y < (height of surface)
    > if surface.pixels(x, y) != 0
    > surface.pixels(x, y).r += r
    > surface.pixels(x, y).g += g
    > surface.pixels(x, y).b += b
    > end if
    > end loop
    > end loop
    > end function
    >
    > Keep in mind, it's 5:30 in the morning, so I'm a bit tired, but I imagine
    > that this would work.

    Either you are really tired or I misunderstood something.
    To stick with my example what happens if you add 0x8D to 0xFF? I would say
    that's a nice overflow...
    Maybe you just wanted to show me how to do shifting in general than that's
    fine but that's not my problem.
    I need to figure out the values to shift by..

    copx
  9. Archived from groups: rec.games.roguelike.development (More info?)

    copx wrote:
    > "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    > news:cHaYe.693$X6.250@fe05.lga...
    > [snip]
    >
    >>Maybe something like this:
    >>
    >>(Pseudocode)
    >>
    >>function shift_font_color(int r, int g, int b)
    >> for x < (width of surface)
    >> for y < (height of surface)
    >> if surface.pixels(x, y) != 0
    >> surface.pixels(x, y).r += r
    >> surface.pixels(x, y).g += g
    >> surface.pixels(x, y).b += b
    >> end if
    >> end loop
    >> end loop
    >>end function
    >>
    >>Keep in mind, it's 5:30 in the morning, so I'm a bit tired, but I imagine
    >>that this would work.
    >
    >
    > Either you are really tired or I misunderstood something.

    Yeah, I'm *really* tired (it's been almost 48 hours since I've last slept).

    > To stick with my example what happens if you add 0x8D to 0xFF? I would say
    > that's a nice overflow...

    Oh, yeah, duh. Let me rephrase myself, here. Something along the lines
    of "surface.pixels(x, y).r -= (0xFF - red_value)" would make the
    appropriate shift, right? Then add in a check to make sure no values go
    below 0 (and if they do, set them to 0).

    To quickly test the above line, let's plug in a value:

    r -= (0xFF - 0x8D)
    r = 0xFF - (0xFF - 0x8D)
    r = 0xFF - 0x72
    r = 0x8D

    *Now* I think it should work. The revised bit should appropriately
    shift all of the values an appropriate amount, and preserve the shading.
    Or I could have no clue what the hell I'm babbling about. Pretty good
    chance of that, too.
  10. Archived from groups: rec.games.roguelike.development (More info?)

    "Christophe" <chris.cavalaria@free.fr> schrieb im Newsbeitrag
    news:4331287d$0$7217$626a14ce@news.free.fr...
    > copx a écrit :
    >> "Christophe" <chris.cavalaria@free.fr> schrieb im Newsbeitrag
    >> news:43311498$0$7209$626a14ce@news.free.fr...
    >>
    >>>copx a écrit :
    >>>
    >>>>Does anyone know if there is an algorithm to recolor shaded font glyphs
    >>>>(created by SDL_ttf/freetype2)?
    >>>>At the moment my "print character" function renders the passed character
    >>>>from scratch every time it's called. I would use a cache of pre-rendered
    >>>>glyphs if I knew how to recolor them 'cause storing pre-rendered glyphs
    >>>>in every color used requires way too much memory.
    >>>>The problem is that I use shaded glyphs (and will continue to do so) so
    >>>>I can't just change the foreground color palette entry. The palette of
    >>>>the glyphs is 8bit, containing multiple shades of the base color + black
    >>>>(I guess / I render on black). Is there a fast way to "shift" the entire
    >>>>palette to a different color?
    >>>>I know this is not the best place to ask such questions but I don't
    >>>>usually have to deal with GFX programming issues. What's a good place to
    >>>>ask such questions?
    >>>
    >>>My guess would be that if you render the glyph on a paletted surface, you
    >>>can easily switch the palette as needed before you render.
    >>
    >>
    >> If I would do that I would need to cache the palettes which would still
    >> require > 10MB RAM.
    >> The palette is different for each glyph in each color!.
    >> That's (number of characters) * (number of colors) * (palette size) !
    >
    > Not really. I'm sure the palette you get while rendering a shaded glyph
    > doesn't change when you use the same foreground color. So you can just
    > render the glyph once with say a black on white color and create a few
    > palettes for the different colors you want.
    >
    > In fact, I could bet the palette you will get then is all the greys going
    > from black at index 255 to white at index 0.

    You're right. My statement was based on the false assumption that the
    palette would only contain the colors which are actually used in the image.
    But it seems that SDL_tff uses a standard palette of shades which is not
    glyph-dependent. So I guess I could use the trick you suggested. Thanks!


    copx
  11. Archived from groups: rec.games.roguelike.development (More info?)

    At Wed, 21 Sep 2005 12:25:00 +0200,
    copx wrote:

    > "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    > news:8M9Ye.1092$845.301@fe03.lga...
    >> copx wrote:
    > "Desired color" is the problem. Shaded fonts are rendered in multiple shades
    > so there are multiple colors.
    > I don't know how "shifting" should work in this case. I suppose plain white
    > (0xFFFFFF) would be a sensible base color for the catched glyphs. Now how do
    > I shift all non-black pixels so that they are no longer shades of 0xFFFFFF
    > but shades of 0x8D1C45 for example?!

    Suppose you're starting with "all grays" palette as your base. So you've
    got 256 colors like:

    #FFFFFF R:100% G:100% B:100%
    #FEFEFE
    ....
    #808080 R:50% G:50% B:50%
    ....
    #010101
    #000000 R:0% G:0% B:0%

    Now, suppose you want to replace your white with your #8D1C45. You have
    to scale the rest of the colors proportionally:

    #8D1C45 R:55%*100% G:11%*100% B:27%*100%
    ....
    #460B23 R:55%*50% G:11%*50% B:27%*50%
    ....
    #000000 R:55%*0% G:11%*0% B:27%*0%

    Assuming linear scaling (you'll probably get better results with some
    non-linear functions).


    If you want it to be fast, you can do it without multiplications inside
    the loop (well, it's a little bit less accurate, but human eye won't
    see a difference).

    --
    Radomir `The Sheep' Dopieralski @**@_
    ($s) 3 Ching!
    . . . ..v.vVvVVvVvv.v.. .
  12. Archived from groups: rec.games.roguelike.development (More info?)

    At 21 Sep 2005 16:30:54 GMT,
    Radomir 'The Sheep' Dopieralski wrote:

    > At Wed, 21 Sep 2005 12:25:00 +0200,
    > copx wrote:
    >
    >> "Timothy Pruett" <drakalor.tourist@gmail.com> schrieb im Newsbeitrag
    >> news:8M9Ye.1092$845.301@fe03.lga...
    >>> copx wrote:
    >> "Desired color" is the problem. Shaded fonts are rendered in multiple shades
    >> so there are multiple colors.
    >> I don't know how "shifting" should work in this case. I suppose plain white
    >> (0xFFFFFF) would be a sensible base color for the catched glyphs. Now how do
    >> I shift all non-black pixels so that they are no longer shades of 0xFFFFFF
    >> but shades of 0x8D1C45 for example?!
    >
    > Suppose you're starting with "all grays" palette as your base. So you've
    > got 256 colors like:
    >
    > #FFFFFF R:100% G:100% B:100%
    > #FEFEFE
    > ...
    > #808080 R:50% G:50% B:50%
    > ...
    > #010101
    > #000000 R:0% G:0% B:0%
    >
    > Now, suppose you want to replace your white with your #8D1C45. You have
    > to scale the rest of the colors proportionally:
    >
    > #8D1C45 R:55%*100% G:11%*100% B:27%*100%
    > ...
    > #460B23 R:55%*50% G:11%*50% B:27%*50%
    > ...
    > #000000 R:55%*0% G:11%*0% B:27%*0%
    >
    > Assuming linear scaling (you'll probably get better results with some
    > non-linear functions).
    >
    >
    > If you want it to be fast, you can do it without multiplications inside
    > the loop (well, it's a little bit less accurate, but human eye won't
    > see a difference).

    Even starting with 0x8D1C45 and then substracting 0x010101 from each
    consecutive palette entry until you hit 0x000000 (and then filling
    the rest of the platette with zeroes) should give "good enough" result.
    Suse, some characters will be thinner than others, but since they will
    also be darker, I don't think it's easy to spot the difference.

    I wanted to make some sample images in GIMP, but it segfaults on me when
    I try to create a '@' pattern :/. Very annoying.

    --
    Radomir `The Sheep' Dopieralski @**@_
    (--) 3 ..zzZZ
    . . . ..v.vVvVVvVvv.v.. .
  13. Archived from groups: rec.games.roguelike.development (More info?)

    "Radomir 'The Sheep' Dopieralski" <thesheep@ sheep.prv.pl> schrieb im
    Newsbeitrag news:slrndj32lu.bgt.thesheep@atos.wmid.amu.edu.pl...
    [snip]
    > Now, suppose you want to replace your white with your #8D1C45. You have
    > to scale the rest of the colors proportionally:
    >
    > #8D1C45 R:55%*100% G:11%*100% B:27%*100%
    > ...
    > #460B23 R:55%*50% G:11%*50% B:27%*50%
    > ...
    > #000000 R:55%*0% G:11%*0% B:27%*0%
    >
    > Assuming linear scaling (you'll probably get better results with some
    > non-linear functions).
    >
    >
    > If you want it to be fast, you can do it without multiplications inside
    > the loop (well, it's a little bit less accurate, but human eye won't
    > see a difference).

    Thanks but I'll use the palette switching trick. It's dead simple and faster
    than anything else (just one table lookup + one pointer assignment).


    copx
  14. Archived from groups: rec.games.roguelike.development (More info?)

    At Wed, 21 Sep 2005 18:43:14 +0200,
    copx wrote:

    >
    > "Radomir 'The Sheep' Dopieralski" <thesheep@ sheep.prv.pl> schrieb im
    > Newsbeitrag news:slrndj32lu.bgt.thesheep@atos.wmid.amu.edu.pl...
    > [snip]
    >> Now, suppose you want to replace your white with your #8D1C45. You have
    >> to scale the rest of the colors proportionally:
    >>
    >> #8D1C45 R:55%*100% G:11%*100% B:27%*100%
    >> ...
    >> #460B23 R:55%*50% G:11%*50% B:27%*50%
    >> ...
    >> #000000 R:55%*0% G:11%*0% B:27%*0%
    >>
    >> Assuming linear scaling (you'll probably get better results with some
    >> non-linear functions).
    >>
    >>
    >> If you want it to be fast, you can do it without multiplications inside
    >> the loop (well, it's a little bit less accurate, but human eye won't
    >> see a difference).
    >
    > Thanks but I'll use the palette switching trick. It's dead simple and faster
    > than anything else (just one table lookup + one pointer assignment).

    Of course, but you still need the paltette to switch to, don't you? ;)

    --
    Radomir `The Sheep' Dopieralski @**@_
    (><) 3 Ouch!
    . . . ..v.vVvVVvVvv.v.. .
Ask a new question

Read More

Development Video Games