Java2D drawing colored bitmap fonts

Would it be stupid to keep switching the composite mode for each character being drawn, so the color rect that goes over it EXACTLY fits each letter drawn?

How would it be any different from drawing 1 rect? Yes, it would be :slight_smile:

There’s no way to get a single rect to fit the shape of the text exactly if there’s a line wrap.

Then stretch the rect to the entire BufferedImage, or calculate the wrap.

the stretch method won’t allow multiple colors?

Draw the letters, set the Composite, set the Color, fill the entire image, draw the image to the screen, clear the image. Repeat :slight_smile:

oh are you saying to do all of that within one frame, per text && text_color?

so if i wanna draw something in red, then something in orange, i’m “drawing the letters, setting the composite, setting the color, filling the image, drawing the image, clearing the image” once for red, and once again for orange (all in the same rendering frame)

Well if you want to draw multiple colors at time, you will have to know the X, Y, width and height of each letter draw, which you already should know. So you can do it all at one time.


public void drawString(....) {
   for(each letter) {
       //figure out X, Y, width and height of letter
       //draw the letter
       
       //set composite, draw colored rect (X,Y,width,height) , reset composite
   }
}

er…

Perhaps I did not explain my example very well…

Let’s say I want to draw a string of information in red, and then later (somewhere else, in some other class or on some other GUI window) in a completely separate function call, I want to draw a string of information in orange.

Hrmm… so you’re looking for Win32 PatBlt functionality? That is where you take a grey-scale bitmapped glyph and you want to stamp it on the canvas in any color you want?

From some serious searching and forums asking I doubt that it’s possible to do this in an efficient manner in Java2D. The problem being that Java2D has to be cross-platform and not all platforms will have a nice native call that does this.

However, it’s really easy to do this in OpenGL using textures and alpha channels.

Supporting ogl is over kill for this project

perhaps i’ll do what minicraft did by just modifying the array’s my self

Here is a little image tint class based on Romain Guy’s ColorTintFilter:
http://pastebin.java-gaming.org/54a6b5d74

Hopefully there’s a Java2D guru out there who knows of a better solution, but this seems to work OK on my end. Of course, the font image needs to be white (or close to white) to work.

Optimizations:

  • Minimize re-tinting by “batching” your colours. Draw all red text first, then all green text, etc.
  • Use resetTint instead of tinting to white.
  • You might still want to think about rendering the text variations to a transparent buffered image to “cache” it, instead of re-tinting many times per frame.

What’s the easiest and best solution? Use LWJGL (or a derivative) to create sprite-based games in Java… ::slight_smile: It’s harder to muck around with hacks like these in Java2D. And since you’ll probably end up enabling OpenGL/D3D acceleration anyways (the JVM flag), you may as well just use OpenGL directly instead of limiting yourself to Java2D’s API.

Thanks so much for this. The reason I am really forcing the J2D is because I don’t want to go down that spiral of signed jar’s for browser applets etc. etc.
If there’s a really easy way to get OGL in a Java applet without asking the user anything… and I can use a pixel-level screen format (1 + 1 = 2 pixels) I’M IN!!

The original font image is never modified, so you can simply redraw the white letters with a different color rect later :stuck_out_tongue:

I was never under the impression or assumption that the original font image is modified.

I am asking if I can do this (and if it is fast, and if its the right way to go about it):


...//font class
public void drawString(String s, Color r) {
    blah blah blah
    draw bitmap images / letters to font buffer image
    change composite
    set color, draw color rect
    reset composite back
}
...//gui code
Font.drawString("hello", red); //composite is changed, color is drawn
//later in code
Font.drawString("cool", orange); //composite is changed again, another color is drawn
...
//game loop
Font.clear();
GuiCode();
Font.render(g);//draws the font buffer image to the screen image
...

If the above is slow or not the proper way to do it, then the only other way to do it with one composite change and multiple colors would be some sort of batch buffer.

Of course, that’s fine. Why would you think it wouldn’t work? The only “slow” part is actually drawing the bitmap images and the color, but that should be much faster than copying each pixel one by one, unmanaging the image in the process.

Ok, cool. I think I will experiment a lot with this. This could perhaps lead to dynamic lighting of some sort as well by maybe rendering a light map image to composite over the scene.

Just to make sure - I assume you’re rendering text in lots (hundreds maybe?) of different colors, maybe cycling through them for effect? Because if you’re only writing text in a few different colors, why not simply create a Map<Color, Font>, where each value is created as a copy of the original font image with the original color (e.g. white or black) changed to the new one, and lazily create entries per color?

Just wanted a system that was “smart enough” to do any color without having a version of it in memory. Considering we’re just putting pixels on the screen, it should be doable via mathematical equation.