Loading graphics/java/android/graphics/fonts/Font.java +10 −7 Original line number Diff line number Diff line Loading @@ -801,6 +801,15 @@ public final class Font { return myBuffer.equals(otherBuffer); } /** @hide */ public boolean paramEquals(@NonNull Font f) { return f.getStyle().equals(getStyle()) && f.getTtcIndex() == getTtcIndex() && Arrays.equals(f.getAxes(), getAxes()) && Objects.equals(f.getLocaleList(), getLocaleList()) && Objects.equals(getFile(), f.getFile()); } @Override public boolean equals(@Nullable Object o) { if (o == this) { Loading @@ -818,13 +827,7 @@ public final class Font { return true; } boolean paramEqual = f.getStyle().equals(getStyle()) && f.getTtcIndex() == getTtcIndex() && Arrays.equals(f.getAxes(), getAxes()) && Objects.equals(f.getLocaleList(), getLocaleList()) && Objects.equals(getFile(), f.getFile()); if (!paramEqual) { if (!paramEquals(f)) { return false; } Loading graphics/java/android/graphics/fonts/SystemFonts.java +42 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** Loading @@ -46,7 +47,6 @@ import java.util.Set; */ public final class SystemFonts { private static final String TAG = "SystemFonts"; private static final String DEFAULT_FAMILY = "sans-serif"; private static final String FONTS_XML = "/system/etc/fonts.xml"; /** @hide */ Loading @@ -59,7 +59,36 @@ public final class SystemFonts { private static final Object LOCK = new Object(); private static @GuardedBy("sLock") Set<Font> sAvailableFonts; private static @GuardedBy("sLock") Map<String, FontFamily[]> sFamilyMap; /** * Helper wrapper class for skipping buffer equality check of Font#equals. * * Due to historical reasons, the Font#equals checks the byte-by-byte buffer equality which * requires heavy IO work in getAvailableFonts. Since the fonts came from system are all regular * file backed font instance and stored in the unique place, just comparing file path should be * good enough for this case. */ private static final class SystemFontHashWrapper { private final Font mFont; SystemFontHashWrapper(Font font) { mFont = font; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; // All system fonts are regular-file backed font instance, so no need to // compare buffers. return mFont.paramEquals(((SystemFontHashWrapper) o).mFont); } @Override public int hashCode() { return Objects.hash(mFont); } } /** * Returns all available font files in the system. Loading @@ -69,17 +98,25 @@ public final class SystemFonts { public static @NonNull Set<Font> getAvailableFonts() { synchronized (LOCK) { if (sAvailableFonts == null) { Set<Font> set = new ArraySet<>(); Set<SystemFontHashWrapper> set = new ArraySet<>(); for (Typeface tf : Typeface.getSystemFontMap().values()) { List<FontFamily> families = tf.getFallback(); for (int i = 0; i < families.size(); ++i) { FontFamily family = families.get(i); for (int j = 0; j < family.getSize(); ++j) { set.add(family.getFont(j)); set.add(new SystemFontHashWrapper(family.getFont(j))); } } } // Unwrapping font instance for Set<Font> interface. The ArraySet#add won't call // Font#equals function if none of two objects has the same hash, so following // unwrapping won't cause bad performance due to byte-by-byte equality check. ArraySet<Font> result = new ArraySet(set.size()); for (SystemFontHashWrapper wrapper : set) { result.add(wrapper.mFont); } sAvailableFonts = Collections.unmodifiableSet(set); sAvailableFonts = Collections.unmodifiableSet(result); } return sAvailableFonts; } Loading Loading
graphics/java/android/graphics/fonts/Font.java +10 −7 Original line number Diff line number Diff line Loading @@ -801,6 +801,15 @@ public final class Font { return myBuffer.equals(otherBuffer); } /** @hide */ public boolean paramEquals(@NonNull Font f) { return f.getStyle().equals(getStyle()) && f.getTtcIndex() == getTtcIndex() && Arrays.equals(f.getAxes(), getAxes()) && Objects.equals(f.getLocaleList(), getLocaleList()) && Objects.equals(getFile(), f.getFile()); } @Override public boolean equals(@Nullable Object o) { if (o == this) { Loading @@ -818,13 +827,7 @@ public final class Font { return true; } boolean paramEqual = f.getStyle().equals(getStyle()) && f.getTtcIndex() == getTtcIndex() && Arrays.equals(f.getAxes(), getAxes()) && Objects.equals(f.getLocaleList(), getLocaleList()) && Objects.equals(getFile(), f.getFile()); if (!paramEqual) { if (!paramEquals(f)) { return false; } Loading
graphics/java/android/graphics/fonts/SystemFonts.java +42 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** Loading @@ -46,7 +47,6 @@ import java.util.Set; */ public final class SystemFonts { private static final String TAG = "SystemFonts"; private static final String DEFAULT_FAMILY = "sans-serif"; private static final String FONTS_XML = "/system/etc/fonts.xml"; /** @hide */ Loading @@ -59,7 +59,36 @@ public final class SystemFonts { private static final Object LOCK = new Object(); private static @GuardedBy("sLock") Set<Font> sAvailableFonts; private static @GuardedBy("sLock") Map<String, FontFamily[]> sFamilyMap; /** * Helper wrapper class for skipping buffer equality check of Font#equals. * * Due to historical reasons, the Font#equals checks the byte-by-byte buffer equality which * requires heavy IO work in getAvailableFonts. Since the fonts came from system are all regular * file backed font instance and stored in the unique place, just comparing file path should be * good enough for this case. */ private static final class SystemFontHashWrapper { private final Font mFont; SystemFontHashWrapper(Font font) { mFont = font; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; // All system fonts are regular-file backed font instance, so no need to // compare buffers. return mFont.paramEquals(((SystemFontHashWrapper) o).mFont); } @Override public int hashCode() { return Objects.hash(mFont); } } /** * Returns all available font files in the system. Loading @@ -69,17 +98,25 @@ public final class SystemFonts { public static @NonNull Set<Font> getAvailableFonts() { synchronized (LOCK) { if (sAvailableFonts == null) { Set<Font> set = new ArraySet<>(); Set<SystemFontHashWrapper> set = new ArraySet<>(); for (Typeface tf : Typeface.getSystemFontMap().values()) { List<FontFamily> families = tf.getFallback(); for (int i = 0; i < families.size(); ++i) { FontFamily family = families.get(i); for (int j = 0; j < family.getSize(); ++j) { set.add(family.getFont(j)); set.add(new SystemFontHashWrapper(family.getFont(j))); } } } // Unwrapping font instance for Set<Font> interface. The ArraySet#add won't call // Font#equals function if none of two objects has the same hash, so following // unwrapping won't cause bad performance due to byte-by-byte equality check. ArraySet<Font> result = new ArraySet(set.size()); for (SystemFontHashWrapper wrapper : set) { result.add(wrapper.mFont); } sAvailableFonts = Collections.unmodifiableSet(set); sAvailableFonts = Collections.unmodifiableSet(result); } return sAvailableFonts; } Loading