07-28-2008 08:06 PM
My application requires a fixed width font. This is so that numbers when arranged in columns look uniform (and decimal points align).
The font "BBSerifFixed" isn't really non-proportional, despite the name.
However, by deriving a font and using the effect Font.MONO_WIDTH_EFFECT, one gets something a little bit better. However one then has to specify the largely undocumented anti-aliasing effects in the derive() invocation.
It would be nice if it was possibly to apply an effect to a font without all the other parameters.
But the worst things is that the MONO_WIDTH_EFFECT produces the most horrible font spacing one could imagine. The characters are more-or-less double-spaced. Presumably this is because of internal miscalculations or the existence of a single well-over-normal-width character.
I also note the the '.' character is always aligned to the left when it should be centered within its space when MONO_WIDTH_EFFECT is in effect.
When will BlackBerry be able to support user installed fonts? The current fonts cripple an applications appearance significantly.
07-28-2008 08:58 PM
I ran into a similar problem...I needed a series of numeric edit fields that would display fixed width fonts, and no combination of built in fonts gave me what I wanted. There are some posts in the old forums that led me to this solution, but its basically to roll a custom field class. In my case, the edit fields contain a fixed number of digits, so it makes the math a little easier. This class also doesn't support decimals, but it shouldn't be too hard too adapt.
class FixedWidthNumericEditField extends BasicEditField { private static final long STYLE = DrawStyle.VCENTER | DrawStyle.HCENTER | Field.FIELD_VCENTER | Field.FIELD_HCENTER | BasicEditField.FILTER_NUMERIC; private final int digitWidth; private final int fieldWidth; public FixedWidthNumericEditField(final int length, final int fieldWidth, final Font font, final FieldChangeListener fieldChangeListener) { super("", "", length, STYLE); digitWidth = fieldWidth / length; this.fieldWidth = fieldWidth; setChangeListener(fieldChangeListener); setFont(font); // This is needed because of our custom drawFocus logic. Without invalidating the control, // there are areas of the screen that do not get redrawn as you move the cursor around setFocusListener(new FocusChangeListener() { public void focusChanged(Field field, int eventType) { invalidate(); } }); } public int getPreferredWidth() { return fieldWidth; } public int getPreferredHeight() { return super.getPreferredHeight(); } protected void layout(int width, int height) { width = getPreferredWidth(); height = getPreferredHeight(); super.layout(width, height); super.setExtent(width, height); } protected void drawFocus(Graphics graphics, boolean on) { int pos = getCursorPosition(); int x = (pos * digitWidth) + (getFont().getAdvance(getLabel())); int y = 1; drawHighlightRegion(graphics, Field.HIGHLIGHT_FOCUS, on, x, y, digitWidth, getHeight()); } protected void paint(Graphics graphics) { int x = 0; int y = 0; int digitCount = getTextLength(); Font f = getFont(); char c; int charWidth; int digitCenter; int left; for (int i = 0; i < digitCount; i++) { c = charAt(i); charWidth = f.getAdvance(c); digitCenter = x + (digitWidth / 2); left = digitCenter - (charWidth / 2); graphics.drawText(c, left, y, 0, digitWidth); x += digitWidth; } int w = getWidth(); int h = getHeight(); graphics.setColor(0x00000000); graphics.drawRect(0, 0, w, h); } }
07-28-2008 09:11 PM
Thanks for the hint. Yes, I am already doing that. For vertical text rotated 90 degrees I have to position each individual character. And I have to use the metrics from the original unrotated font. And I have to iterate over just the characters I intend using to find the true maximum width. But it still looks terrible. And it impacts badly on performance. So I haven't resorted to that technique for the normal horizontal font yet.
But one shouldn't have to stoop so low. Fonts should be installable. And their metrics should be accurate.