The short answer is, you can't using the DrawThemeTextEx API: it only allows you to change the text color, not the background glow colour.
The long answer is that you can achieve the same effect by:
- Drawing text with a glow;
- Tinting the resulting image using the alpha as a colour intensity, to get a single-colour image of the text plus the glow;
- Drawing the text over the top with no glow effect.
Example image showing the result of the technique
The second step, tinting the image, is the main one that requires explanation.
Draw black text with a glow to a temporary bitmap. You will then have an area with white and black colours (white is the only glow colour Windows renders), varying alpha, and in between black and white on the edge of the text antialiased pixels which may (due to the algorithm being used) be coloured slightly, ie not be a pure shade of grey.
Glowing text drawn over a coloured background, so you can see the white glow and the text antialiasing
There are two options. The first is to use the colour ("whiteness" vs "blackness") and tint to change the white area to the background colour and the black area to the text colour. This will work, but may give antialiasing errors, especially with coloured text, compared to how that text would have been rendered and antialiased by Windows. A better approach is to realise that the text will be overlaid, and antialiased to, the background glow anyway: tint everything (glow and text) to the one colour - whatever is 100% alpha text can be treated as 100% white glow underneath the text - then simply draw the text over again antialiasing to the background.
To tint is then quite simple. Pixels will have an alpha value and premultiplied alpha colour values - for example, ABGR of (2, 2, 2, 2) is an alpha of 2, and BGR of white, premultiplied by the alpha. Ignore the existing colour and set any non-zero alpha pixels to a premultiplied alpha value of the background colour, based on the existing alpha of the pixel.
Using a TQuadColor struct to represent four bytes of an alpha-aware 32-bit pixel, loop through your temporary bitmap and set the colour using the existing alpha as an intensity:
// PQuad is a pointer to the first pixel, a TQuadColor (see link, basically a packed struct of ABGR bytes)
for Loop := 0 to FWidth * FHeight - 1 do begin
if PQuad.Alpha <> 0 then begin
PQuad.SetFromColorMultAlpha(Color); // Sets the colour, and multiplies the alphas together
end;
Inc(PQuad);
end;
The key is PQuad.SetFromColorMultAlpha
:
procedure TQuadColor.SetFromColorMultAlpha(const Color: TQuadColor);
var
MultAlpha : Byte;
begin
Red := Color.Red;
Green := Color.Green;
Blue := Color.Blue;
MultAlpha := Round(Integer(Alpha) * Integer(Color.Alpha) / 255.0);
SetAlpha(MultAlpha, MultAlpha / 255.0);
end;
This takes a quad colour (that is, alpha with RGB) and multiplies the two alphas together to get a resulting alpha. This lets you tint by a transparent colour. SetAlpha
then converts to premultiplied alpha:
procedure TQuadColor.SetAlpha(const Transparency: Byte; const PreMult: Single);
begin
Alpha := Transparency;
Blue := Trunc(Blue * PreMult);
Green := Trunc(Green * PreMult);
Red := Trunc(Red * PreMult);
end;
The result is a tinted glow:
Draw the text over the top (using the same API to keep the same text rendering) with no glow:
And you have glowing text with a coloured, non-white glow colour.
You can find full source code at my MPL-licensed TTransparentCanvas
project on Google Code.