How to compare OpenType fonts with different weight to see if they are the same?

805 views Asked by At

I have a bunch of OpenType font files with different weights and style (For example, ComicSans100.otf, ComicSans200.otf, ComicSans300.otf and TimeNewRoman.otf and TimesNewRomanItalic.otf). The person who provided me these files wasn't sure if the weight and style of the different fonts were modified. For example, characters in ComicSans400.otf are from ComicSans100.otf with a weight of 400, but tweaked to look better.

I want to know if there is a way to be sure that if I take ComicSans100.otf and apply it a weight of 400, all the characters will look the same as the characters from ComicSans400.otf.

The reason I'm asking this is that I want to use these fonts in an Android app. And every font increases the size of the app.

2

There are 2 answers

3
Cheticamp On BEST ANSWER

Here is a simple and visual way to validate that two of your fonts produce the same characters.

  1. Define a ConstraintLayout with four TextViews: tv1, tv2, tv3 and tv4. Define the text colors and fonts as follows. You are checking font1 and font2 against each other. (Make sure that the background of the TextViews is transparent.

    • tv1: red, font1
    • tv2: blue, font2
    • tv3: blue, font2
    • tv4: red, font1
  2. Place tv1 on top of tv2 and tv3 on tv4.

  3. Place all the characters you want to check into each of the TextViews. Look for any color that doesn't match the color of the top TextView. For tv1 on top of tv2 your should see all red and no blue. For tv3 on top of tv4 your should see all blue and no red.

This could be automated but may not be worth the effort if a simple setup and visual inspection will suffice. One worthwhile automation may be to look for pixels of an offending color.

Here is what the layout could be. This trivial case just looks at the default font as bold and not bold.

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:text="ABCEFGHIJKLMNOPQRSTUVWXYZ"
        android:textColor="@android:color/holo_blue_light"
        android:textSize="20sp"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:text="ABCEFGHIJKLMNOPQRSTUVWXYZ"
        android:textColor="@android:color/holo_red_light"
        android:textSize="20sp"
        android:textStyle="bold"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:text="ABCEFGHIJKLMNOPQRSTUVWXYZ"
        android:textColor="@android:color/holo_red_light"
        android:textSize="20sp"
        android:textStyle="bold"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/guideline" />

    <TextView
        android:id="@+id/tv4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:text="ABCEFGHIJKLMNOPQRSTUVWXYZ"
        android:textColor="@android:color/holo_blue_light"
        android:textSize="20sp"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/guideline" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>

Here is the output to see the differences. This snapshot is from the Android Studio designer.

enter image description here


If there are potentially a lot of characters to check, the above method will be difficult and prone to error. A more automated way is to define two text views like above, load them with identical text but use two fonts that will be tested against each other.

MainActivity.java
Here is a short bit of code that takes two TextViews and compares them pixel-by-pixel and logs if they are different or the same.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tv1, tv2;
        tv1 = findViewById(R.id.tv1);
        tv2 = findViewById(R.id.tv2);
        // Get all characters to check into a string.
        String s = getTextToCheck();
        tv1.setText(s);
        tv2.setText(s);
        final ConstraintLayout mLayout = findViewById(R.id.layout);
        mLayout.post(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = Bitmap.createBitmap(mLayout.getWidth(), mLayout.getHeight(),
                                                    Bitmap.Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);
                mLayout.draw(canvas);
                compareRects(bitmap, getViewRect(tv1), getViewRect(tv2));
            }
        });
    }

    private void compareRects(Bitmap bitmap, Rect rect1, Rect rect2) {
        int x1 = rect1.left;
        int x2 = rect2.left;
        if (rect1.width() != rect2.width()) {
            Log.i("CompareFonts", "<<<< TextView widths do not match");
        }
        if (rect1.height() != rect2.height()) {
            Log.i("CompareFonts", "<<<< TextView heights do not match");
        }

        int totalPixels = 0;
        int diffCount = 0;

        while (x1 < rect1.right && x2 < rect2.right) {
            int y1 = rect1.top;
            int y2 = rect2.top;
            while (y1 < rect1.bottom && y2 < rect2.bottom) {
                int pixel1 = bitmap.getPixel(x1, y1);
                int pixel2 = bitmap.getPixel(x2, y2);
                if (pixel1 != pixel2) {
                    diffCount++;
                    totalPixels++;
                } else if (pixel1 != 0) {
                    totalPixels++;
                }
                y1++;
                y2++;
            }
            x1++;
            x2++;
        }
        Log.i("CompareFonts", String.format(Locale.US, "<<<< Total pixels compared = %,d", totalPixels));
        Log.i("CompareFonts", String.format(Locale.US, "<<<< Different pixel count = %,d (%%%.2f) ",
                                            diffCount, (float) diffCount * 100 / totalPixels));

    }

    private Rect getViewRect(View view) {
        Rect rect = new Rect();
        rect.left = view.getLeft() + view.getPaddingLeft();
        rect.right = view.getRight() - view.getPaddingRight();
        rect.top = view.getTop() + view.getPaddingTop();
        rect.bottom = view.getBottom() - view.getPaddingBottom();
        return rect;
    }

    private String getTextToCheck() {
        // Define any text to check. This is just the printable ASCII character set.
        StringBuilder sb = new StringBuilder();

        for (int i = 32; i <= 126; i++) {
            sb.append((char) i);
        }
        return sb.toString();
    }
}
3
MrMartin On

The tool of choice for manually analysing fonts is FontForge.

To perform your comparison, first open your similar fonts side-by-side: enter image description here

You can see my two fonts are A750Sant-Regular (left), and A750Sans-Bold (right).

Next, to compare the Bold with the Regular with increased weight, click "Edit -> Select All", and then "Element -> Style -> Change Weight", and you can visually compare the results.

enter image description here

For my example fonts, there's a huge difference, so I'd keep both.

There is also an automatic function to compare two fonts, under "Element -> Compare Fonts", but I think that's not what you're looking for.