Page 1 of 1

Font that shows up well on any background

Posted: Tue Sep 18, 2012 7:41 pm
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

Re: Font that shows up well on any background

Posted: Tue Sep 18, 2012 10:33 pm
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 ;)

Re: Font that shows up well on any background

Posted: Wed Sep 19, 2012 10:55 pm
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."

Re: Font that shows up well on any background

Posted: Wed Sep 26, 2012 4:05 am
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

Re: Font that shows up well on any background

Posted: Wed Sep 26, 2012 8:05 am
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.

Re: Font that shows up well on any background

Posted: Wed Sep 26, 2012 10:12 pm
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."

Re: Font that shows up well on any background

Posted: Wed Sep 26, 2012 10:17 pm
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));
}

Re: Font that shows up well on any background

Posted: Wed Sep 26, 2012 10:28 pm
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.

Re: Font that shows up well on any background

Posted: Thu Sep 27, 2012 5:59 am
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