M
Mario
Gast
Hallo, ich bin gerade dabei eine Klasse zu schreiben, die die Schriftgröße eines übergebenen Font-Objects soweit vergrößert/verkleinert, dass ein bestimmter String möglichst genau bestimmte Ausmaße (Dimension) annimmt.
Ist der String z.B. kleiner als die angegebene Dimension, soll er soweit vergrößert werden, bis er entweder zu hoch oder zu breit ist.
(Und dann die Schriftgröße natürlich wieder um eins verkleinern.) Aber da ist schon mein erstes, kleineres, Problem.
deriveFont akzeptiert int und float Werte. Welche Genauigkeit ist bei float sinnvoll? Sieht ein Text der Schriftgröße 10.1f anders aus als der Größe 10, oder wird z.B. der float-Wert auf einen int-Wert gerundet..?
Mein eigentliches Problem ist jedoch ein anderes. Die Breite des Strings herauszufinden scheint ganz gut zu klappen mit <FontMetrics>.stringWidth(<String>), die Höhe macht mir da sehr viel mehr Schwierigkeiten:
Mit
sowie
und allem was ich noch probiert habe (z.B. mit ascent und descent) bekomm ich für den String "E" das selbe Ergebnis wie für "e" oder ".".
Die Folge ist, viele Strings werden als zu hoch bewertet und die Schriftgröße verkleinert, obwohl über einem String wie "..." noch sehr viel Platz ist. Sogar bei Großbuchstaben ist oben noch Platz. (Den Fehler, dass die Schriftgröße nur aufgrund der Breite und nicht der Höhe verkleinert wurde hab ich nicht gemacht.)
(Bei einer Funktion, die die richtige Höhe liefert, muss ich dann auch noch wissen, wie weit unter dem obersten Pixel die baseline liegt.)
Gibt es eine Möglichkeit die Höhe von Chars bzw. eines Strings in Pixeln (im Gegensatz zu der Höhe einer Zeile) zu ermitteln?
Ich hoffe ich habmein Problem verständlich dargelegt, für alle Fälle hier nochmal der Code:
Ist der String z.B. kleiner als die angegebene Dimension, soll er soweit vergrößert werden, bis er entweder zu hoch oder zu breit ist.
(Und dann die Schriftgröße natürlich wieder um eins verkleinern.) Aber da ist schon mein erstes, kleineres, Problem.
deriveFont akzeptiert int und float Werte. Welche Genauigkeit ist bei float sinnvoll? Sieht ein Text der Schriftgröße 10.1f anders aus als der Größe 10, oder wird z.B. der float-Wert auf einen int-Wert gerundet..?
Mein eigentliches Problem ist jedoch ein anderes. Die Breite des Strings herauszufinden scheint ganz gut zu klappen mit <FontMetrics>.stringWidth(<String>), die Höhe macht mir da sehr viel mehr Schwierigkeiten:
Mit
Code:
fm.getStringBounds(String, context).getHeight();
Code:
fm.stringHeight(String)
Die Folge ist, viele Strings werden als zu hoch bewertet und die Schriftgröße verkleinert, obwohl über einem String wie "..." noch sehr viel Platz ist. Sogar bei Großbuchstaben ist oben noch Platz. (Den Fehler, dass die Schriftgröße nur aufgrund der Breite und nicht der Höhe verkleinert wurde hab ich nicht gemacht.)
(Bei einer Funktion, die die richtige Höhe liefert, muss ich dann auch noch wissen, wie weit unter dem obersten Pixel die baseline liegt.)
Gibt es eine Möglichkeit die Höhe von Chars bzw. eines Strings in Pixeln (im Gegensatz zu der Höhe einer Zeile) zu ermitteln?
Ich hoffe ich habmein Problem verständlich dargelegt, für alle Fälle hier nochmal der Code:
Code:
private Component paintOn;
private String Text;
private Dimension Size;
private Point Corner;
private int xPadding;
private int yPadding;
private Dimension TextSize;
private int X;
private int Y;
private Font useFont;
private float accuracy;
private void Berechnen()
{
FontMetrics fm;
Rectangle2D StringBounds;
Graphics context = paintOn.getGraphics();
//FontMetrics-Objekt der aktuellen Schrift(größe)
fm = paintOn.getFontMetrics(useFont);
StringBounds = fm.getStringBounds(Text, context);
//Schriftgröße schätzen, je nachdem Höhe oder Breite
useFont = useFont.deriveFont(useFont.getSize2D() * (float) Math.min(TextSize.width / StringBounds.getWidth(), TextSize.height / StringBounds.getHeight()));
//FontMetrics-Objekt aktualisieren
fm = paintOn.getFontMetrics(useFont);
StringBounds = fm.getStringBounds(Text, context);
//vergrößern wenn zu klein, (Ergebnis größer/gleich)
while (StringBounds.getWidth() < TextSize.width && StringBounds.getHeight() < TextSize.height)
{
//vergrößern
useFont = useFont.deriveFont(useFont.getSize2D() + accuracy);
//FontMetrics-Objekt aktualisieren
fm = paintOn.getFontMetrics(useFont);
StringBounds = fm.getStringBounds(Text, context);
}
//verkleinern wenn zu groß, (Ergebnis kleiner/gleich)
while (StringBounds.getWidth() > TextSize.width || StringBounds.getHeight() > TextSize.height)
{
//verkleinern
useFont = useFont.deriveFont(useFont.getSize2D() - accuracy);
//FontMetrics-Objekt aktualisieren
fm = paintOn.getFontMetrics(useFont);
StringBounds = fm.getStringBounds(Text, context);
}
//zentrieren, Übergabepunkt für DrawString bestimmen
X = Corner.x + (int) Math.floor((Size.width - StringBounds.getWidth()) / 2);
//Y = Corner.y + (int) StringBounds.getHeight() + (int) Math.floor((Size.height - StringBounds.getHeight()) / 2);
}