From f10571ecbd922dcde480566692bfefa93fa161f5 Mon Sep 17 00:00:00 2001 From: benfry Date: Fri, 6 Aug 2010 12:36:35 +0000 Subject: [PATCH] working on how native fonts are handled for better consistency (incomplete) --- core/src/processing/core/PConstants.java | 1 + core/src/processing/core/PFont.java | 38 +++-- core/src/processing/core/PGraphics.java | 10 +- core/src/processing/core/PGraphicsJava2D.java | 146 +++++++++--------- core/todo.txt | 20 +++ 5 files changed, 125 insertions(+), 90 deletions(-) diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index f1eae5882..410a949b5 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -471,6 +471,7 @@ public interface PConstants { static final int ENABLE_OPENGL_4X_SMOOTH = 2; static final int ENABLE_NATIVE_FONTS = 3; + static final int DISABLE_NATIVE_FONTS = -3; static final int DISABLE_DEPTH_TEST = 4; static final int ENABLE_DEPTH_TEST = -4; diff --git a/core/src/processing/core/PFont.java b/core/src/processing/core/PFont.java index e08e650ea..a33fc0e87 100644 --- a/core/src/processing/core/PFont.java +++ b/core/src/processing/core/PFont.java @@ -116,12 +116,16 @@ public class PFont implements PConstants { */ protected Font font; - /** True if this font was loaded from a stream, rather than from the OS. */ + /** + * True if this font was loaded from a stream, rather than from the OS. + * It's always safe to use the native version of a font loaded from a TTF + * file, since that's how it'll look when exported. Otherwise, you'll have + * to use hint(ENABLE_NATIVE_FONTS) to get the native version working with + * renderers that support it. + */ protected boolean stream; - /** - * True if we've already tried to find the native AWT version of this font. - */ + /** True if already tried to find the native AWT version of this font. */ protected boolean fontSearched; /** @@ -132,12 +136,16 @@ public class PFont implements PConstants { static protected Font[] fonts; static protected HashMap fontDifferent; - - // objects to handle creation of font characters only as they're needed - BufferedImage lazyImage; - Graphics2D lazyGraphics; - FontMetrics lazyMetrics; - int[] lazySamples; +// /** +// * 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; public PFont() { } // for subclasses @@ -208,7 +216,8 @@ public class PFont implements PConstants { if (charset == null) { lazy = true; - +// lazyFont = font; + } else { // charset needs to be sorted to make index lookup run more quickly // http://dev.processing.org/bugs/show_bug.cgi?id=494 @@ -345,6 +354,9 @@ public class PFont implements PConstants { if (version == 11) { smooth = is.readBoolean(); } + // See if there's a native version of this font that can be used, + // in case that's of interest later. + findFont(); } @@ -443,7 +455,9 @@ public class PFont implements PConstants { /** - * Set the native complement of this font. + * Set the native complement of this font. Might be set internally via the + * findFont() function, or externally by a deriveFont() call if the font + * is resized by PGraphicsJava2D. */ public void setFont(Font font) { this.font = font; diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index d80b6c735..dee7dd456 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3036,11 +3036,11 @@ public class PGraphics extends PImage implements PConstants { public void textFont(PFont which) { if (which != null) { textFont = which; - if (hints[ENABLE_NATIVE_FONTS]) { - //if (which.font == null) { - which.findFont(); - //} - } +// if (hints[ENABLE_NATIVE_FONTS]) { +// //if (which.font == null) { +// which.findFont(); +// //} +// } /* textFontNative = which.font; diff --git a/core/src/processing/core/PGraphicsJava2D.java b/core/src/processing/core/PGraphicsJava2D.java index f72a566bb..47fb40de5 100644 --- a/core/src/processing/core/PGraphicsJava2D.java +++ b/core/src/processing/core/PGraphicsJava2D.java @@ -970,12 +970,13 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { if (textFont == null) { defaultFontOrDeath("textAscent"); } + Font font = textFont.getFont(); - if (font == null) { - return super.textAscent(); + if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { + FontMetrics metrics = parent.getFontMetrics(font); + return metrics.getAscent(); } - FontMetrics metrics = parent.getFontMetrics(font); - return metrics.getAscent(); + return super.textAscent(); } @@ -984,11 +985,11 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { defaultFontOrDeath("textAscent"); } Font font = textFont.getFont(); - if (font == null) { - return super.textDescent(); + if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { + FontMetrics metrics = parent.getFontMetrics(font); + return metrics.getDescent(); } - FontMetrics metrics = parent.getFontMetrics(font); - return metrics.getDescent(); + return super.textDescent(); } @@ -1027,7 +1028,7 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { // textFontNativeMetrics = g2.getFontMetrics(textFontNative); // } Font font = textFont.getFont(); - if (font != null) { + if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { Font dfont = font.deriveFont(size); g2.setFont(dfont); textFont.setFont(dfont); @@ -1048,13 +1049,13 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { protected float textWidthImpl(char buffer[], int start, int stop) { Font font = textFont.getFont(); - if (font == null) { - return super.textWidthImpl(buffer, start, stop); + if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { + // maybe should use one of the newer/fancier functions for this? + int length = stop - start; + FontMetrics metrics = g2.getFontMetrics(font); + return metrics.charsWidth(buffer, start, length); } - // maybe should use one of the newer/fancier functions for this? - int length = stop - start; - FontMetrics metrics = g2.getFontMetrics(font); - return metrics.charsWidth(buffer, start, length); + return super.textWidthImpl(buffer, start, stop); } @@ -1079,66 +1080,65 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { Font font = textFont.getFont(); - if (font == null) { + if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { + /* + // save the current setting for text smoothing. note that this is + // different from the smooth() function, because the font smoothing + // is controlled when the font is created, not now as it's drawn. + // fixed a bug in 0116 that handled this incorrectly. + Object textAntialias = + g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + + // override the current text smoothing setting based on the font + // (don't change the global smoothing settings) + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + textFont.smooth ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + */ + Object antialias = + g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + if (antialias == null) { + // if smooth() and noSmooth() not called, this will be null (0120) + antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT; + } + + // override the current smoothing setting based on the font + // also changes global setting for antialiasing, but this is because it's + // not possible to enable/disable them independently in some situations. + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + textFont.smooth ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + + //System.out.println("setting frac metrics"); + //g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + // RenderingHints.VALUE_FRACTIONALMETRICS_ON); + + g2.setColor(fillColorObject); + int length = stop - start; + g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f)); + // better to use drawString() with floats? (nope, draws the same) + //g2.drawString(new String(buffer, start, length), x, y); + + // this didn't seem to help the scaling issue + // and creates garbage because of the new temporary object + //java.awt.font.GlyphVector gv = textFontNative.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop)); + //g2.drawGlyphVector(gv, x, y); + + // System.out.println("text() " + new String(buffer, start, stop)); + + // return to previous smoothing state if it was changed + //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias); + + textX = x + textWidthImpl(buffer, start, stop); + textY = y; + textZ = 0; // this will get set by the caller if non-zero + + } else { // otherwise just do the default super.textLineImpl(buffer, start, stop, x, y); - return; } - - /* - // save the current setting for text smoothing. note that this is - // different from the smooth() function, because the font smoothing - // is controlled when the font is created, not now as it's drawn. - // fixed a bug in 0116 that handled this incorrectly. - Object textAntialias = - g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - - // override the current text smoothing setting based on the font - // (don't change the global smoothing settings) - g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - textFont.smooth ? - RenderingHints.VALUE_ANTIALIAS_ON : - RenderingHints.VALUE_ANTIALIAS_OFF); - */ - - Object antialias = - g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - if (antialias == null) { - // if smooth() and noSmooth() not called, this will be null (0120) - antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT; - } - - // override the current smoothing setting based on the font - // also changes global setting for antialiasing, but this is because it's - // not possible to enable/disable them independently in some situations. - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - textFont.smooth ? - RenderingHints.VALUE_ANTIALIAS_ON : - RenderingHints.VALUE_ANTIALIAS_OFF); - - //System.out.println("setting frac metrics"); - //g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, - // RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - g2.setColor(fillColorObject); - int length = stop - start; - g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f)); - // better to use drawString() with floats? (nope, draws the same) - //g2.drawString(new String(buffer, start, length), x, y); - - // this didn't seem to help the scaling issue - // and creates garbage because of the new temporary object - //java.awt.font.GlyphVector gv = textFontNative.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop)); - //g2.drawGlyphVector(gv, x, y); - -// System.out.println("text() " + new String(buffer, start, stop)); - - // return to previous smoothing state if it was changed - //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias); - - textX = x + textWidthImpl(buffer, start, stop); - textY = y; - textZ = 0; // this will get set by the caller if non-zero } diff --git a/core/todo.txt b/core/todo.txt index bdf535175..dc7542a90 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,24 @@ 0190 core X change skewX/Y to shearX/Y _ need reference update for this +X ENABLE_NATIVE_FONTS was being ignored, native fonts were used no matter what +X fix the behavior +_ need to finish font changes wrt native fonts before any release +_ right now not in a good place--default font will be bitmapped and ugly + +_ image resizing is ugly (just use java2d?) +_ http://code.google.com/p/processing/issues/detail?id=332 + +_ show an error when using a font character that isn't available +_ maybe fall back on other characters instead? + +_ nfc() is a problem on intl systems when subsetting fonts + +_ OpenGL noSmooth() problems +_ http://code.google.com/p/processing/issues/detail?id=328 + +_ color() problem with alpha +_ http://code.google.com/p/processing/issues/detail?id=327 _ setAttribute? setString/Int/Float or just set? @@ -25,6 +43,7 @@ X or make the call that it's read-only, and remove the saving code _ document save() and write(), and their differences X adding write() method? X need to handle how save() works inside xml lib +_ constructor has changed to .parse(...) instead of new XMLElement(str) _ possible addition for 'implementation' variable @@ -112,6 +131,7 @@ Oct 6 15:49:18 Shiny [0x0-0x12d12d].com.apple.Safari[3059]: Start called. big ones _ ortho() behaving differently in P3D vs OPENGL _ http://dev.processing.org/bugs/show_bug.cgi?id=100 +_ http://code.google.com/p/processing/issues/detail?id=37 _ shows a blank canvas _ (was only happening once b/c was drawing first in perspective) _ seems to be mapping to 0, 0 - width/2, height/2