greatly improve startup slowness on systems that have a lot of fonts installed

This commit is contained in:
Ben Fry
2019-01-18 14:32:22 -08:00
parent fca49356b3
commit 75efd1a212
4 changed files with 56 additions and 38 deletions
-12
View File
@@ -6319,18 +6319,6 @@ public class PApplet implements PConstants {
}
/**
* Used by PGraphics to remove the requirement for loading a font!
*/
protected PFont createDefaultFont(float size) {
// Font f = new Font("SansSerif", Font.PLAIN, 12);
// println("n: " + f.getName());
// println("fn: " + f.getFontName());
// println("ps: " + f.getPSName());
return createFont("Lucida Sans", size, true, null);
}
public PFont createFont(String name, float size) {
return createFont(name, size, true, null);
}
+29 -20
View File
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2012-15 The Processing Foundation
Copyright (c) 2012-19 The Processing Foundation
Copyright (c) 2004-12 Ben Fry & Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
@@ -159,21 +159,12 @@ public class PFont implements PConstants {
static protected Font[] fonts;
static protected HashMap<String, Font> fontDifferent;
// /**
// * If not null, this font is set to load dynamically. This is the default
// * when createFont() method is called without a character set. Bitmap
// * versions of characters are only created when prompted by an index() call.
// */
// protected Font lazyFont;
protected BufferedImage lazyImage;
protected Graphics2D lazyGraphics;
protected FontMetrics lazyMetrics;
protected int[] lazySamples;
/** for subclasses that need to store metadata about the font */
// protected HashMap<PGraphics, Object> cacheMap;
/**
* @nowebref
*/
@@ -902,21 +893,29 @@ public class PFont implements PConstants {
}
/**
* Make an internal list of all installed fonts. This can take a while with
* a lot of fonts installed, but running it on a separate thread may not
* help much. As of the commit that's adding this note, loadFonts() will
* only be called by PFont.list() and when loading a font by name, both of
* which are occasions when we'd need to block until this was finished
* anyway. It's also possible that running getAllFonts() on a non-EDT thread
* could cause graphics system issues. Further, the first fonts are usually
* loaded at the beginning of a sketch, meaning that sketch startup time
* will still be affected, even with threading (and blocking) in place.
*/
static public void loadFonts() {
if (fonts == null) {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
fonts = ge.getAllFonts();
// Figure out what the font is named when things fail
systemFontName = new Font("", Font.PLAIN, 1).getFontName();
if (PApplet.platform == PConstants.MACOSX) {
fontDifferent = new HashMap<>();
for (Font font : fonts) {
// getName() returns the PostScript name on OS X 10.6 w/ Java 6.
// No need to use getPSName() anymore because getName()
// returns the PostScript name on OS X 10.6 w/ Java 6.
fontDifferent.put(font.getName(), font);
//fontDifferent.put(font.getPSName(), font);
}
}
}
@@ -928,22 +927,32 @@ public class PFont implements PConstants {
* This bug was filed years ago as #4769141 at bugreporter.apple.com. More:
* <a href="http://dev.processing.org/bugs/show_bug.cgi?id=407">Bug 407</a>.
* <br>
* This function displays a warning when the font isn't found and
* Java's system font is used.
* This function displays a warning when the font is not found
* and Java's system font is used.
* See: <a href="https://github.com/processing/processing/issues/5481">issue #5481</a>
*/
static public Font findFont(String name) {
loadFonts();
if (PApplet.platform == PConstants.MACOSX) {
loadFonts();
Font maybe = fontDifferent.get(name);
if (maybe != null) {
return maybe;
}
}
Font font = new Font(name, Font.PLAIN, 1);
// make sure we have the name of the system fallback font
if (systemFontName == null) {
// Figure out what the font is named when things fail
systemFontName = new Font("", Font.PLAIN, 1).getFontName();
}
// warn the user if they didn't get the font they want
if (!name.equals(systemFontName) &&
font.getFontName().equals(systemFontName)) {
PGraphics.showWarning("Default font being used because \"" + name + "\" is not available.");
font.getFontName().equals(systemFontName)) {
PGraphics.showWarning("\"" + name + "\" is not available, " +
"so another font will be used. " +
"Use PFont.list() to show available fonts.");
}
return font;
}
+19 -4
View File
@@ -4062,6 +4062,15 @@ public class PGraphics extends PImage implements PConstants {
// TEXT/FONTS
/**
* Used by PGraphics to remove the requirement for loading a font.
*/
protected PFont createDefaultFont(float size) {
Font baseFont = new Font("Lucida Sans", Font.PLAIN, 1);
return createFont(baseFont, size, true, null, false);
}
protected PFont createFont(String name, float size,
boolean smooth, char[] charset) {
String lowerName = name.toLowerCase();
@@ -4083,9 +4092,7 @@ public class PGraphics extends PImage implements PConstants {
} else {
baseFont = PFont.findFont(name);
}
return new PFont(baseFont.deriveFont(size * parent.pixelDensity),
smooth, charset, stream != null,
parent.pixelDensity);
return createFont(baseFont, size, smooth, charset, stream != null);
} catch (Exception e) {
System.err.println("Problem with createFont(\"" + name + "\")");
@@ -4095,6 +4102,14 @@ public class PGraphics extends PImage implements PConstants {
}
private PFont createFont(Font baseFont, float size,
boolean smooth, char[] charset, boolean stream) {
return new PFont(baseFont.deriveFont(size * parent.pixelDensity),
smooth, charset, stream,
parent.pixelDensity);
}
public void textAlign(int alignX) {
textAlign(alignX, BASELINE);
}
@@ -8217,7 +8232,7 @@ public class PGraphics extends PImage implements PConstants {
*/
protected void defaultFontOrDeath(String method, float size) {
if (parent != null) {
textFont = parent.createDefaultFont(size);
textFont = createDefaultFont(size);
} else {
throw new RuntimeException("Use textFont() before " + method + "()");
}
+8 -2
View File
@@ -2,6 +2,13 @@
X make JSONObject.quote() (both versions) public
X fix javaPlatform variable for newer JDK versions
X https://github.com/processing/processing/pull/5626
o many fonts installed causes slow startup on macos
o run that on a thread, and make sure default font doesn't need the list loaded
X can't be done, notes in the code for PFont.loadFonts()
X greatly improve startup time when user-specified fonts are not used
X default font will be faster, using ttf/otf is fine
X only createFont("The Font Name") is still slow on macOS
X and PFont.list()
contrib
o make tabs into spaces, fixes pixelDensity(2) issue with tabs
@@ -55,6 +62,7 @@ o is this coming from us? if so, need to provide actions
X haven't seen for a while, maybe fixed
_ NullPointerException at java.awt.Window.init(Window.java:497) when using Airplay
_ https://github.com/processing/processing/issues/5620
_ try to catch the NPE and warn the user about what's happening
@@ -78,7 +86,6 @@ _ need to make this work behind the scenes instead
_ create icon.png or have an 'icons' folder with multiple sizes
_ Implement blendMode() for PDF
_ https://github.com/processing/processing/issues/5438
@@ -89,7 +96,6 @@ _ Switch to getModifiersEx() and fix the AWT modifiers used in PSurfaceAWT
_ this is an easy fix, but need to check impact elsewhere
_ does anything else rely on these modifiers?
_ when doing createFont, can we add it to the os fonts available?
_ add separator option to loadTable()