Font that shows up well on any background

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
Post Reply
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Font that shows up well on any background

Post by Jive Dadson »

I need a font that shows up well on any background. Otherwise it should be nondescript. The usual trick is to have a light color with a dark outline on each letter. Some transparency might be nice. The font must render in neutral grays, no chroma. Currently I am using SWISS and changing the value of the letters' color based on the value of the background. The solution is not ideal. If wxWidgets comes with such a font in the box, I have not found it. Any ideas?

P.s. I only need the letters R,Y,G,B,P, and N, r, g, and b, numerals, period, and virgule. And space.

Image
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: Font that shows up well on any background

Post by Auria »

I don't have a magic solution. but if performance is not too critical, one not-too-clean but working hack you could do it render the text in white 4 times, at (x - 2, y - 2), (x - 2, y + 2), (x + 2, y - 2), (x + 2, y + 2). And then once render in black at (x, y). I do that in one project and it's quite effective ;)
"Keyboard not detected. Press F1 to continue"
-- Windows
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Re: Font that shows up well on any background

Post by Jive Dadson »

Auria wrote:I don't have a magic solution. but if performance is not too critical, one not-too-clean but working hack you could do it render the text in white 4 times, at (x - 2, y - 2), (x - 2, y + 2), (x + 2, y - 2), (x + 2, y + 2). And then once render in black at (x, y). I do that in one project and it's quite effective ;)
If nothing else avails itself, I will give that a go. Problem is, the thing is a static text box now, so I would have to change that to some kind of panel I can draw on, rather than just telling it to "text me."
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Re: Font that shows up well on any background

Post by Jive Dadson »

Okay, I gave it a go.

Code: Select all

void djStaticText::render(wxDC& dc)
{
    wxString label = GetLabel();
    dc.Clear();
    SetForegroundColour(wxColor("BLACK"));
    dc.DrawText(label, wxPoint(0,0));
    dc.DrawText(label, wxPoint(0,2));
    dc.DrawText(label, wxPoint(2,0));
    dc.DrawText(label, wxPoint(2,2));
    SetForegroundColour(wxColor("WHITE"));
    dc.DrawText(label, wxPoint(1,1));
}
The result is not as planned. All the text turns WHITE. The foreground color is white when the render routine gets called. Apparently the call to SetForegroundColour is
not taking effect right away. It is using the old foreground color. What to do?

EDIT: I found a way to make it work. I searched through all the methods of class wxDC and found, voila!, SetTextForeground. That did the trick.

Code: Select all

void BasicDrawPane::render(wxDC& dc)
{
	wxString label = GetLabel();
	dc.Clear();

	dc.SetTextForeground(wxColour("BLACK"));
    dc.DrawText(label, wxPoint(0,0));
	dc.DrawText(label, wxPoint(0,2));
	dc.DrawText(label, wxPoint(2,0));
	dc.DrawText(label, wxPoint(2,2));
	dc.SetTextForeground(wxColour("WHITE"));
	dc.DrawText(label, wxPoint(1,1));
}
It is a puzlement to me why a call to the wxPanel::SetForegroundColour took effect when made right before the call to render(), but calling it in render() itself had no effect. There seems to be a race condition. I cannot come up with any other hypothesis. I noticed that sometimes it did work when I was stopping on breakpoints in the debugger. I also notice that threads are continually starting and finishing. Nothing is ever easy.

Image
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: Font that shows up well on any background

Post by catalin »

Jive Dadson wrote:It is a puzlement to me why a call to the wxPanel::SetForegroundColour took effect when made right before the call to render(), but calling it in render() itself had no effect.
AFAIK that call is supposed to be effective for the next wxDC that is created after it. IOW it didn't work for you because the wxDC had already been created when you called it.
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Re: Font that shows up well on any background

Post by Jive Dadson »

No doubt that is correct. My culpa. I do not know what IOW stands for. I googled it (duckduckgo'ed it, actually), and came up with "Inert Ordinance Wearhouse," and "Infected Open Wound."
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Re: Font that shows up well on any background

Post by Jive Dadson »

Release candidate. CamelBackNames to match wxWidgets. Not my first choice by any means.

Code: Select all

// Not to be called directly. Use "paintNow" instead.
void djStaticText::OnPaintEvent(wxPaintEvent &)
{
    wxPaintDC dc(this);
    Render(dc);
}

void djStaticText::PaintNow()
{
    wxClientDC dc(this);
    Render(dc);
}
 

void djStaticText::Render(wxDC& dc)
{
	wxString label = GetLabel();
	wxColor bg = GetBackgroundColour();
	dc.Clear();
	dc.SetBackground(wxBrush(bg));
	const int dark = 30;
	dc.SetTextForeground(wxColour(dark,dark,dark));
    dc.DrawText(label, wxPoint(0,0));
	dc.DrawText(label, wxPoint(0,2));
	dc.DrawText(label, wxPoint(2,0));
	dc.DrawText(label, wxPoint(2,2));
	const int light = 220;
	dc.SetTextForeground(wxColor(light,light,light));
	dc.DrawText(label, wxPoint(1,1));
}
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: Font that shows up well on any background

Post by catalin »

"IOW" should be read "in other words". It took me a while to get such acronyms but after reading them a lot they kind of stuck there in my head; probably just more proof of being lazy, as if it was still needed... :roll:

The code looks good at first glance, but in case you didn't try it already: you might not even need PaintNow(). When you need to "paint now" try to do call myTextCtrl->Refresh() (possibly followed by myTextCtrl->Update()) and that should trigger the OnPaint() handler.
Jive Dadson
Experienced Solver
Experienced Solver
Posts: 60
Joined: Thu Sep 06, 2012 8:00 pm

Re: Font that shows up well on any background

Post by Jive Dadson »

I added painting the background because before I did, whenever I made the panel larger with my mouse, the part that got uncovered was not painted. It does not appear to be necessary when I do the Refresh() thing rather than the PaintNow() thing. Well, whatever. It is working now. IOW, IIAGMTM - SV, AFAICPK.

Image
Post Reply