Skip to content

Commit

Permalink
[#528] Redesign StringRenderer class and add unit tests for
Browse files Browse the repository at this point in the history
getHeight.
  • Loading branch information
jkcoding7 authored and prmr committed Mar 5, 2024
1 parent aeabbbe commit 0cb13a7
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 118 deletions.
119 changes: 1 addition & 118 deletions src/org/jetuml/rendering/StringRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,11 @@

import org.jetuml.annotations.Flyweight;
import org.jetuml.annotations.Immutable;
import org.jetuml.application.UserPreferences;
import org.jetuml.application.UserPreferences.IntegerPreference;
import org.jetuml.application.UserPreferences.IntegerPreferenceChangeHandler;
import org.jetuml.geom.Dimension;
import org.jetuml.geom.Rectangle;

import javafx.geometry.VPos;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.FontPosture;
import javafx.scene.text.TextAlignment;

/**
Expand All @@ -50,7 +44,7 @@
@Flyweight
public final class StringRenderer
{
private static final CanvasFont CANVAS_FONT = new CanvasFont();
private static final CanvasFont CANVAS_FONT = CanvasFont.instance();

private static final Dimension EMPTY = new Dimension(0, 0);
private static final int DEFAULT_HORIZONTAL_TEXT_PADDING = 7;
Expand Down Expand Up @@ -293,115 +287,4 @@ else if( aAlign.isVerticallyCentered() )
pGraphics.setTextBaseline(oldVPos);
pGraphics.setTextAlign(oldAlign);
}

/**
* Responsible for performing more rudimentary operations involving font,
* as well as being synchronized with the user's current font.
*/
private static final class CanvasFont implements IntegerPreferenceChangeHandler
{

private Font aFont;
private Font aFontBold;
private Font aFontItalics;
private Font aFontBoldItalics;
private FontMetrics aFontMetrics;
private FontMetrics aFontBoldMetrics;
private FontMetrics aFontItalicsMetrics;
private FontMetrics aFontBoldItalicsMetrics;

private CanvasFont()
{
refreshAttributes();
UserPreferences.instance().addIntegerPreferenceChangeHandler(this);
}

private Font getFont(boolean pBold, boolean pItalics)
{
if( pBold && pItalics )
{
return aFontBoldItalics;
}
else if( pBold )
{
return aFontBold;
}
else if( pItalics )
{
return aFontItalics;
}
return aFont;
}

private FontMetrics getFontMetrics(boolean pBold, boolean pItalics)
{
if( pBold && pItalics )
{
return aFontBoldItalicsMetrics;
}
else if( pBold )
{
return aFontBoldMetrics;
}
else if( pItalics )
{
return aFontItalicsMetrics;
}
return aFontMetrics;
}

/**
* Returns the dimension of a given string.
* @param pString The string to which the bounds pertain.
* @return The dimension of the string
*/
public Dimension getDimension(String pString, boolean pBold, boolean pItalics)
{
return getFontMetrics(pBold, pItalics).getDimension(pString);
}

/**
* Returns the height of a string including the leading space.
*
* @param pString The string.
* @param pBold Whether the text is in bold.
* @return The height of the string.
*/
public int getHeight(String pString, boolean pBold, boolean pItalics)
{
return getFontMetrics(pBold, pItalics).getHeight(pString);
}

/**
* Returns the font size the user currently specifies.
* @return The font size
*/
public int fontSize()
{
return (int) Math.round(aFont.getSize());
}

@Override
public void integerPreferenceChanged(IntegerPreference pPreference)
{
if ( pPreference == IntegerPreference.fontSize && aFont.getSize() != UserPreferences.instance().getInteger(pPreference) )
{
refreshAttributes();
}

}

private void refreshAttributes()
{
aFont = Font.font("System", UserPreferences.instance().getInteger(IntegerPreference.fontSize));
aFontBold = Font.font(aFont.getFamily(), FontWeight.BOLD, aFont.getSize());
aFontItalics = Font.font(aFont.getFamily(), FontPosture.ITALIC, aFont.getSize());
aFontBoldItalics = Font.font(aFont.getFamily(), FontWeight.BOLD, FontPosture.ITALIC, aFont.getSize());
aFontMetrics = new FontMetrics(aFont);
aFontBoldMetrics = new FontMetrics(aFontBold);
aFontItalicsMetrics = new FontMetrics(aFontItalics);
aFontBoldItalicsMetrics = new FontMetrics(aFontBoldItalics);
}

}
}
31 changes: 31 additions & 0 deletions test/org/jetuml/rendering/TestFontMetrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@
import org.junit.jupiter.params.provider.MethodSource;

import javafx.scene.text.Font;
import javafx.scene.text.Text;

public class TestFontMetrics {

private static final FontMetrics aMetrics = new FontMetrics(Font.font("System", DEFAULT_FONT_SIZE));
private static final Font DEFAULT_FONT = Font.font("System", DEFAULT_FONT_SIZE);
// Ensures there is no caching of sorts when reusing the same Text object
@ParameterizedTest
@MethodSource("stringPairParameters")
Expand All @@ -64,4 +66,33 @@ public void testGetDimensions()
assertEquals(new Dimension(osDependent(95, 92, 92), osDependent(13, 12, 12)), aMetrics.getDimension("Single-Line-String"));
assertEquals(new Dimension(osDependent(31, 30, 30), osDependent(45, 40, 45)), aMetrics.getDimension("Multi\nLine\nString"));
}

private static int textBoxHeight(Text pText)
{
return (int) Math.round(pText.getLayoutBounds().getHeight());
}

@Test
public void testGetHeight_EmptyText()
{
Text emptyText = new Text("");
emptyText.setFont(DEFAULT_FONT);
assertEquals(textBoxHeight(emptyText), aMetrics.getHeight(""));
}

@Test
public void testGetHeight_SingleLineText()
{
Text singleLineText = new Text("Single-Line-String");
singleLineText.setFont(DEFAULT_FONT);
assertEquals(textBoxHeight(singleLineText), aMetrics.getHeight("Single-Line-String"));
}

@Test
public void testGetHeight_MultiLineText()
{
Text multiLineText = new Text("Multi\nLine\nString");
multiLineText.setFont(DEFAULT_FONT);
assertEquals(textBoxHeight(multiLineText), aMetrics.getHeight("Multi\nLine\nString"));
}
}
52 changes: 52 additions & 0 deletions test/org/jetuml/rendering/TestStringViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,20 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;

public class TestStringViewer
{
private static int userDefinedFontSize;
private StringRenderer topCenter;
private StringRenderer topCenterPadded;
private StringRenderer topCenterBold;
private StringRenderer bottomCenterPadded;
private StringRenderer topCenterItalics;
private StringRenderer topCenterBoldItalics;

@BeforeAll
public static void setupClass()
Expand All @@ -58,6 +65,8 @@ public void setup()
topCenterPadded = StringRenderer.get(Alignment.TOP_CENTER, TextDecoration.PADDED);
topCenterBold = StringRenderer.get(Alignment.TOP_CENTER, TextDecoration.BOLD);
bottomCenterPadded = StringRenderer.get(Alignment.BOTTOM_CENTER, TextDecoration.PADDED);
topCenterItalics = StringRenderer.get(Alignment.TOP_LEFT, TextDecoration.ITALICS);
topCenterBoldItalics = StringRenderer.get(Alignment.TOP_LEFT, TextDecoration.BOLD, TextDecoration.ITALICS);
}

@AfterAll
Expand Down Expand Up @@ -120,4 +129,47 @@ public void testWrapString()
assertEquals("A\nreally\nlong\nstring\nthat\nshould\nprobably\nbe\nwrapped",
StringRenderer.wrapString("A really long string that should probably be wrapped", 1));
}

@Test
public void testGetHeight_12ptFont()
{
Font defaultFont = Font.font("System", 12);
Font boldFont = Font.font("System", FontWeight.BOLD, 12);
Font italicFont = Font.font("System", FontPosture.ITALIC, 12);
Font boldItalicFont = Font.font("System", FontWeight.BOLD, FontPosture.ITALIC, 12);
Text text = new Text("Display String");
text.setFont(defaultFont);
assertEquals(textBoxHeight(text), topCenter.getHeight("Display String"));
text.setFont(boldFont);
assertEquals(textBoxHeight(text), topCenterBold.getHeight("Display String"));
text.setFont(italicFont);
assertEquals(textBoxHeight(text), topCenterItalics.getHeight("Display String"));
text.setFont(boldItalicFont);
assertEquals(textBoxHeight(text), topCenterBoldItalics.getHeight("Display String"));
}

@Test
public void testGetHeight_24ptFont()
{
UserPreferences.instance().setInteger(IntegerPreference.fontSize, 24);
Font defaultFont = Font.font("System", 24);
Font boldFont = Font.font("System", FontWeight.BOLD, 24);
Font italicFont = Font.font("System", FontPosture.ITALIC, 24);
Font boldItalicFont = Font.font("System", FontWeight.BOLD, FontPosture.ITALIC, 24);
Text text = new Text("Display String");
text.setFont(defaultFont);
assertEquals(textBoxHeight(text), topCenter.getHeight("Display String"));
text.setFont(boldFont);
assertEquals(textBoxHeight(text), topCenterBold.getHeight("Display String"));
text.setFont(italicFont);
assertEquals(textBoxHeight(text), topCenterItalics.getHeight("Display String"));
text.setFont(boldItalicFont);
assertEquals(textBoxHeight(text), topCenterBoldItalics.getHeight("Display String"));
UserPreferences.instance().setInteger(IntegerPreference.fontSize, DEFAULT_FONT_SIZE);
}

private static int textBoxHeight(Text pText)
{
return (int) Math.round(pText.getLayoutBounds().getHeight());
}
}

0 comments on commit 0cb13a7

Please sign in to comment.