From: <fd...@us...> - 2008-09-30 22:10:17
|
Revision: 4594 http://jnode.svn.sourceforge.net/jnode/?rev=4594&view=rev Author: fduminy Date: 2008-09-30 22:09:24 +0000 (Tue, 30 Sep 2008) Log Message: ----------- - further implementation of BDF fonts & peers related methods - started implementation of missing methods in ttf fonts & peers Modified Paths: -------------- trunk/core/src/classpath/gnu/gnu/java/awt/ClasspathToolkit.java trunk/gui/src/awt/org/jnode/awt/JNodeToolkit.java trunk/gui/src/awt/org/jnode/awt/font/FontManager.java trunk/gui/src/awt/org/jnode/awt/font/FontProvider.java trunk/gui/src/awt/org/jnode/awt/font/JNodeFontPeer.java trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontPeer.java trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontProvider.java trunk/gui/src/awt/org/jnode/awt/font/def/DefaultFontManager.java trunk/gui/src/awt/org/jnode/awt/font/spi/AbstractFontProvider.java trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontDataFile.java trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFMemoryInput.java trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFontProvider.java Added Paths: ----------- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontPeer.java Removed Paths: ------------- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFURLInput.java Modified: trunk/core/src/classpath/gnu/gnu/java/awt/ClasspathToolkit.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/ClasspathToolkit.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/core/src/classpath/gnu/gnu/java/awt/ClasspathToolkit.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -38,36 +38,23 @@ package gnu.java.awt; -import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; import gnu.java.security.action.SetAccessibleAction; import java.awt.AWTException; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.DisplayMode; import java.awt.Font; -import java.awt.FontMetrics; +import java.awt.FontFormatException; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Point; import java.awt.Toolkit; -import java.awt.font.FontRenderContext; -import java.awt.image.ColorModel; -import java.awt.image.ImageProducer; import java.awt.peer.RobotPeer; -import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.AttributedString; -import java.util.HashMap; -import java.util.Map; import java.security.AccessController; +import java.util.Map; import javax.imageio.spi.IIORegistry; @@ -187,7 +174,8 @@ * @throws IOException if a problem occurs while reading in the * contents of <code>stream</code>. */ - public abstract Font createFont(int format, InputStream stream); + // jnode : added "throws FontFormatException, IOException" since Classpath's javadoc mention it + public abstract Font createFont(int format, InputStream stream) throws FontFormatException, IOException; /** * Creates a RobotPeer on a given GraphicsDevice. Modified: trunk/gui/src/awt/org/jnode/awt/JNodeToolkit.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/JNodeToolkit.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/JNodeToolkit.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -37,6 +37,7 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; @@ -80,7 +81,6 @@ import org.apache.log4j.Logger; import org.jnode.awt.font.FontManager; -import org.jnode.awt.font.JNodeFontPeer; import org.jnode.awt.image.BufferedImageSurface; import org.jnode.awt.image.JNodeImage; import org.jnode.driver.DeviceException; @@ -265,7 +265,7 @@ /** * @see gnu.java.awt.ClasspathToolkit#createFont(int, java.io.InputStream) */ - public Font createFont(int format, InputStream stream) { + public Font createFont(int format, InputStream stream) throws FontFormatException, IOException { return getFontManager().createFont(format, stream); } Modified: trunk/gui/src/awt/org/jnode/awt/font/FontManager.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/FontManager.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/FontManager.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -25,9 +25,11 @@ import java.awt.Color; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; import java.awt.Shape; import java.awt.geom.AffineTransform; +import java.io.IOException; import java.io.InputStream; import java.util.Map; @@ -82,18 +84,11 @@ Color color); /** + * @throws IOException + * @throws FontFormatException * */ - public Font createFont(int format, InputStream stream); + public Font createFont(int format, InputStream stream) throws FontFormatException, IOException; public ClasspathFontPeer createFontPeer(String name, Map attrs); - - /** - * Translates the font into a font that is provided by a provider. - * - * @param font - * @param providerName - * @return - */ - public Font getClosestProvidedFont(Font font, String providerName); } Modified: trunk/gui/src/awt/org/jnode/awt/font/FontProvider.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/FontProvider.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/FontProvider.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -22,7 +22,10 @@ package org.jnode.awt.font; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; +import java.io.IOException; +import java.io.InputStream; import java.util.Map; import java.util.Set; @@ -32,7 +35,7 @@ * @author Ewout Prangsma (ep...@us...) * @author Fabien DUMINY (fd...@jn...) */ -public interface FontProvider { +public interface FontProvider<F extends Font> { /** * Give the name of the font (used for setting the first provider to use * among all available ones) @@ -65,7 +68,7 @@ * * @return All fonts this provider can provide */ - public Set<Font> getAllFonts(); + public Set<F> getAllFonts(); /** * Gets a text renderer for the given font. @@ -84,6 +87,14 @@ public FontMetrics getFontMetrics(Font font); /** + * Translates the font into a font that is provided by this provider. + * + * @param font + * @return + */ + public F getCompatibleFont(Font font); + + /** * Creates a font peer from the given name or return null if not supported/provided. * As said in {@link JNodeToolkit#getClasspathFontPeer(String, java.util.Map)} javadoc : * "We don't know what kind of "name" the user requested (logical, face, family)". @@ -92,5 +103,12 @@ * @param attrs * @return */ - public JNodeFontPeer createFontPeer(String name, Map attrs); + public JNodeFontPeer<? extends FontProvider<F>, F> createFontPeer(String name, Map attrs); + + /** + * Read and create a Font from the given InputStream + * @param stream + * @return + */ + public F createFont(InputStream stream) throws FontFormatException, IOException; } Modified: trunk/gui/src/awt/org/jnode/awt/font/JNodeFontPeer.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/JNodeFontPeer.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/JNodeFontPeer.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -39,14 +39,17 @@ * To change the template for this generated type comment go to Window - * Preferences - Java - Code Generation - Code and Comments */ -public abstract class JNodeFontPeer extends ClasspathFontPeer implements FontPeer { - +public abstract class JNodeFontPeer<FP extends FontProvider<F>, F extends Font> + extends ClasspathFontPeer implements FontPeer { + protected final FP provider; + /** * @param name * @param attrs */ - public JNodeFontPeer(String name, Map attrs) { + public JNodeFontPeer(FP provider, String name, Map attrs) { super(name, attrs); + this.provider = provider; } /** @@ -145,4 +148,18 @@ */ public abstract GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags); + + /** + * Convert the given font to a Font whose type is F. + * The font given as input might not be an instance of F + * since {@link Font} class is public, not abstract and has a public constructor. + * If that's the case, then we are trying to find the closest font that + * this peer's provider provides. + * + * @param font any instance of {@link Font} (might not be an instance of F) + * @return + */ + protected final F getCompatibleFont(Font font) { + return provider.getCompatibleFont(font); + } } Modified: trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontPeer.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontPeer.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontPeer.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -10,20 +10,15 @@ import java.util.Locale; import java.util.Map; -import javax.naming.NamingException; - import org.apache.log4j.Logger; -import org.jnode.awt.font.FontManager; import org.jnode.awt.font.JNodeFontPeer; import org.jnode.font.bdf.BDFFontContainer; import org.jnode.font.bdf.BDFGlyph; import org.jnode.font.bdf.BDFMetrics; -import org.jnode.font.bdf.BDFParser; -import org.jnode.naming.InitialNaming; -import org.jnode.vm.Unsafe; import sun.font.CoreMetrics; import sun.font.FontLineMetrics; +import sun.font.StandardGlyphVector; /** * Specific implementation of {@link JNodeFontPeer} for BDF fonts @@ -31,11 +26,16 @@ * @author fabien * */ -public class BDFFontPeer extends JNodeFontPeer { +public class BDFFontPeer extends JNodeFontPeer<BDFFontProvider, BDFFont> { private static final Logger log = Logger.getLogger(BDFFontPeer.class); - public BDFFontPeer(String name, Map attrs) { - super(name, attrs); + /** + * this the char used to replace missing glyphs in BDFFont + */ + private static final char MISSING_GLYPH_CODE = '\u0020'; + + public BDFFontPeer(BDFFontProvider provider, String name, Map attrs) { + super(provider, name, attrs); } /** @@ -43,13 +43,13 @@ */ @Override public boolean canDisplay(Font font, char c) { - BDFFont bdfFont = toBDFFont(font); + BDFFont bdfFont = getCompatibleFont(font); //TODO this is a temporary workaround : we should add a method to BDFFont - BDFGlyph spaceGlyph = bdfFont.getContainer().getGlyph('\u0020'); + BDFGlyph spaceGlyph = bdfFont.getContainer().getGlyph(MISSING_GLYPH_CODE); BDFGlyph characterGlyph = bdfFont.getContainer().getGlyph(c); - return (c == '\u0020') || ((c != '\u0020') && (characterGlyph != spaceGlyph)); + return (c == MISSING_GLYPH_CODE) || ((c != MISSING_GLYPH_CODE) && (characterGlyph != spaceGlyph)); } /** @@ -78,10 +78,7 @@ @Override public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci) { - // TODO implement me - System.out.println("JNodeFontPeer.createGlyphVector(" + - "Font,FontRenderContext,CharacterIterator) not implemented"); - return null; + return new StandardGlyphVector(font, ci, frc); } /** @@ -91,10 +88,7 @@ @Override public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes) { - // TODO implement me - System.out.println("JNodeFontPeer.createGlyphVector(" + - "Font,FontRenderContext,int[]) not implemented"); - return null; + return new StandardGlyphVector(font, glyphCodes, ctx); } /** @@ -103,8 +97,12 @@ */ @Override public byte getBaselineFor(Font font, char c) { - System.out.println("JNodeFontPeer.getBaselineFor not implemented"); // TODO implement me - return 0; + System.out.println("JNodeFontPeer.getBaselineFor not implemented"); + + // TODO find proper value from the BDFFontContainer + // it should be one of Font.CENTER_BASELINE, Font.HANGING_BASELINE, + // Font.ROMAN_BASELINE + return Font.ROMAN_BASELINE; } /** @@ -112,7 +110,7 @@ */ @Override public FontMetrics getFontMetrics(Font font) { - return toBDFFont(font).getFontMetrics(); + return getCompatibleFont(font).getFontMetrics(); } /** @@ -120,7 +118,7 @@ */ @Override public String getGlyphName(Font font, int glyphIndex) { - return toBDFFont(font).getContainer().getGlyphs()[glyphIndex].getName(); + return getCompatibleFont(font).getContainer().getGlyphs()[glyphIndex].getName(); } /** @@ -131,7 +129,7 @@ @Override public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc) { - BDFFont bdfFont = toBDFFont(font); + BDFFont bdfFont = getCompatibleFont(font); BDFMetrics fm = bdfFont.getContainer().getFontMetrics(); float ascent = fm.getAscent(); @@ -163,8 +161,12 @@ */ @Override public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) { - System.out.println("JNodeFontPeer.getMaxCharBounds not implemented"); // TODO implement me - return null; + BDFFont bdfFont = getCompatibleFont(font); + + final Rectangle2D bounds = provider.getMaxCharBounds(bdfFont.getContainer()); + transform(bounds, rc); + + return bounds; } /** @@ -173,7 +175,7 @@ @Override public int getMissingGlyphCode(Font font) { //TODO this is a temporary workaround : we should add a method to BDFFont - return '\u0020'; // this the char used to replace missing glyphs in BDFFont + return MISSING_GLYPH_CODE; // this the char used to replace missing glyphs in BDFFont } /** @@ -181,7 +183,7 @@ */ @Override public int getNumGlyphs(Font font) { - return toBDFFont(font).getContainer().getGlyphs().length; + return getCompatibleFont(font).getContainer().getGlyphs().length; } /** @@ -189,7 +191,7 @@ */ @Override public String getPostScriptName(Font font) { - return toBDFFont(font).getContainer().getName(); + return getCompatibleFont(font).getContainer().getName(); } /** @@ -200,7 +202,7 @@ @Override public Rectangle2D getStringBounds(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext frc) { - BDFFont bdfFont = toBDFFont(font); + BDFFont bdfFont = getCompatibleFont(font); BDFFontContainer container = bdfFont.getContainer(); double width = 0; @@ -213,44 +215,21 @@ } } final Rectangle2D bounds = new Rectangle2D.Double(0, 0, width, height); - - if (frc.getTransform() != null) { - double[] srcPoints = - new double[] {bounds.getMinX(), bounds.getMinY(), - bounds.getMinX(), bounds.getMaxY(), - bounds.getMaxX(), bounds.getMaxY(), - bounds.getMaxX(), bounds.getMinY()}; - double[] dstPoints = new double[srcPoints.length]; - frc.getTransform().transform(srcPoints, 0, dstPoints, 0, srcPoints.length / 2); - - // compute the bounding box of the result - double minX = dstPoints[0]; - double minY = dstPoints[1]; - double maxX = minX; - double maxY = minY; - for (int i = 2; i < dstPoints.length; i += 2) { - double x = dstPoints[i]; - minX = Math.min(minX, x); - maxX = Math.max(maxX, x); - double y = dstPoints[i + 1]; - minY = Math.min(minY, y); - maxY = Math.max(maxY, y); - } - bounds.setRect(minX, minY, maxX - minX + 1, maxY - minY + 1); - } - + transform(bounds, frc); return bounds; } /** + * * @see gnu.java.awt.peer.ClasspathFontPeer#getSubFamilyName(java.awt.Font, * java.util.Locale) */ @Override public String getSubFamilyName(Font font, Locale locale) { - System.out.println("JNodeFontPeer.getSubFamilyName not implemented"); // TODO implement me - return null; + System.out.println("JNodeFontPeer.getSubFamilyName not implemented"); + // TODO not implemented ... remove that while moving to openjdk + return ""; } /** @@ -258,8 +237,9 @@ */ @Override public boolean hasUniformLineMetrics(Font font) { - System.out.println("JNodeFontPeer.hasUniformLineMetrics not implemented"); // TODO implement me - return false; + // We don't have "subfonts" (terms used in GNU Classpath javadoc) + // => returns true + return true; } /** @@ -269,36 +249,36 @@ @Override public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags) { - System.out.println("JNodeFontPeer.layoutGlyphVector not implemented"); // TODO implement me - return null; + //TODO work only for latin fonts but not for hindi, arabic ... fonts + // see GNU Classpath javadoc + return new StandardGlyphVector(font, chars, start, limit, frc); } - /** - * Convert the given font to a BDFFont. - * The font given as input might not be an instance of BDFFont - * since {@link Font} class is public, not abstract and has a public constructor. - * If that's the case, then we are trying to find the closest font that we provide. - * - * @param font any instance of {@link Font} (might not be an instance of BDFFont) - * @return - */ - private BDFFont toBDFFont(Font font) { - if (!(font instanceof BDFFont)) { - // ask the FontManager for a compatible Font that we provide - try { - FontManager mgr = InitialNaming.lookup(FontManager.NAME); - font = mgr.getClosestProvidedFont(font, BDFFontProvider.NAME); - } catch (NamingException ex) { - // it should never happen since font peers are created - // by the FontManager - log.error(ex); + private void transform(Rectangle2D bounds, FontRenderContext frc) { + if (frc.getTransform() != null) { + double[] srcPoints = + new double[] {bounds.getMinX(), bounds.getMinY(), + bounds.getMinX(), bounds.getMaxY(), + bounds.getMaxX(), bounds.getMaxY(), + bounds.getMaxX(), bounds.getMinY()}; + double[] dstPoints = new double[srcPoints.length]; + frc.getTransform().transform(srcPoints, 0, dstPoints, 0, srcPoints.length / 2); + + // compute the bounding box of the result + double minX = dstPoints[0]; + double minY = dstPoints[1]; + double maxX = minX; + double maxY = minY; + for (int i = 2; i < dstPoints.length; i += 2) { + double x = dstPoints[i]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + + double y = dstPoints[i + 1]; + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); } - } - - if (!(font instanceof BDFFont)) { - throw new RuntimeException("unable to convert font " + font + " to a BDFFont"); - } - - return (BDFFont) font; + bounds.setRect(minX, minY, maxX - minX + 1, maxY - minY + 1); + } } } Modified: trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontProvider.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontProvider.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/bdf/BDFFontProvider.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -22,12 +22,16 @@ package org.jnode.awt.font.bdf; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; +import java.awt.geom.Rectangle2D; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +42,7 @@ import org.jnode.awt.font.renderer.RenderCache; import org.jnode.awt.font.spi.AbstractFontProvider; import org.jnode.font.bdf.BDFFontContainer; +import org.jnode.font.bdf.BDFGlyph; import org.jnode.vm.Unsafe; /** @@ -45,9 +50,7 @@ * * @author Fabien DUMINY (fd...@jn...) */ -public class BDFFontProvider extends AbstractFontProvider<BDFFont> { - static final String NAME = "bdf"; - +public class BDFFontProvider extends AbstractFontProvider<BDFFont, BDFFontContainer> { /** * My logger */ @@ -60,21 +63,23 @@ "Vera-10.bdf", "Vera-12.bdf", "Vera-14.bdf", "VeraMono-12-8.bdf", "6x12_FixedMedium-12.bdf" }; - private List<BDFFontContainer> containers; + private List<BDFFontContainer> containers; + private Map<BDFFontContainer, Size> maxCharBounds = new HashMap<BDFFontContainer, Size>(); + public BDFFontProvider() { - super(NAME); + super(BDFFont.class, "bdf"); } protected TextRenderer createTextRenderer(RenderCache renderCache, Font font) { - final BDFFont bdfFont = getBDFFont(font); + final BDFFont bdfFont = getCompatibleFont(font); final TextRenderer renderer = new BDFTextRenderer(bdfFont.getContainer()); return renderer; } protected FontMetrics createFontMetrics(Font font) throws IOException { - final BDFFont bdfFont = getBDFFont(font); + final BDFFont bdfFont = getCompatibleFont(font); return bdfFont.getFontMetrics(); } @@ -91,37 +96,62 @@ public BDFFontPeer createFontPeer(String name, Map attrs) { BDFFontPeer peer = null; + List<BDFFontContainer> datas = getUserFontDatas(); + for (BDFFontContainer container : datas) { + if (match(container, name, attrs)) { + peer = new BDFFontPeer(this, name, attrs); + datas.remove(container); + break; + } + } + for (BDFFontContainer container : getContainers()) { - // it's a temporary workaround taking first font found - //FIXME : find the proper way for matching the font name - //if (container.getFamily().equals(name) || container.getName().equals(name)) { - peer = new BDFFontPeer(name, attrs); - break; - //} + if (match(container, name, attrs)) { + peer = new BDFFontPeer(this, name, attrs); + break; + } } //Unsafe.debug("BDFFontProvider: name=" + name + "fontPeer=" + peer); return peer; } - + + /** + * Read an create a Font from the given InputStream + * @param stream + * @return + */ @Override - protected BDFFont loadFont(URL url) throws IOException { - Reader reader = new InputStreamReader(url.openStream()); + public BDFFont createFont(InputStream stream) throws FontFormatException, IOException { try { + Reader reader = new InputStreamReader(stream); BDFFontContainer container = BDFFontContainer.createFont(reader); + addUserFontData(container); return new BDFFont(container); + } catch (IOException e) { + throw e; } catch (Exception e) { - IOException ioe = new IOException("can't load BDFFont from " + url); - ioe.initCause(e); - throw ioe; + FontFormatException ffe = new FontFormatException("bad bdf format"); + ffe.initCause(e); + throw ffe; } } + + /** + * Load all default fonts. + */ + @Override + protected final void loadFontsImpl() { + for (BDFFontContainer container : getContainers()) { + addFont(new BDFFont(container)); + } + } private List<BDFFontContainer> getContainers() { if (containers == null) { containers = new ArrayList<BDFFontContainer>(); - for (String fontResource : getSystemFonts()) { + for (String fontResource : SYSTEM_FONTS) { try { final ClassLoader cl = Thread.currentThread().getContextClassLoader(); final URL url = cl.getResource(fontResource); @@ -142,23 +172,33 @@ return containers; } - protected String[] getSystemFonts() { - return SYSTEM_FONTS; - } - - private BDFFont getBDFFont(Font font) { - final BDFFont bdfFont; - - if (font instanceof BDFFont) { - bdfFont = (BDFFont) font; - } else { - bdfFont = getCompatibleFont(font); + Rectangle2D getMaxCharBounds(BDFFontContainer container) { + Size size = maxCharBounds.get(container); + + if (size == null) { + size = new Size(); + for (BDFGlyph g : container.getGlyphs()) { + if (g != null) { + size.maxCharWidth += g.getDWidth().width; + size.maxCharHeight = Math.max(g.getDWidth().height, size.maxCharHeight); + } + } + maxCharBounds.put(container, size); } - if (bdfFont == null) { - log.warn("Font not instanceof BDFFont: " + font.getClass().getName()); - } - - return bdfFont; + return new Rectangle2D.Double(0, 0, size.maxCharWidth, size.maxCharHeight); } + + private boolean match(BDFFontContainer container, String name, Map attrs) { + // it's a temporary workaround taking first font found + //FIXME : find the proper way for matching the font name + //if (container.getFamily().equals(name) || container.getName().equals(name)) { + return true; + } + + private static class Size + { + int maxCharWidth = 0; + int maxCharHeight = 0; + } } Modified: trunk/gui/src/awt/org/jnode/awt/font/def/DefaultFontManager.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/def/DefaultFontManager.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/def/DefaultFontManager.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -25,9 +25,11 @@ import java.awt.Color; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; import java.awt.Shape; import java.awt.geom.AffineTransform; +import java.io.IOException; import java.io.InputStream; import java.security.AccessController; import java.util.ArrayList; @@ -35,7 +37,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import javax.naming.NamingException; @@ -64,7 +65,7 @@ * Note : For now, we have only 2 providers (bdf, ttf) and we will probably * never have more than 5 ones. So, a {@link List} is enough for our usage. */ - private final List<FontProvider> providers = new ArrayList<FontProvider>(2); + private final List<FontProvider<?>> providers = new ArrayList<FontProvider<?>>(2); public final Map<Integer, String> fontTypeToProviderName = (Map<Integer, String>) Collections.singletonMap(Font.TRUETYPE_FONT, "ttf"); @@ -121,7 +122,7 @@ */ public synchronized Font[] getAllFonts() { final HashSet<Font> all = new HashSet<Font>(); - for (FontProvider prv : providers) { + for (FontProvider<?> prv : providers) { all.addAll(prv.getAllFonts()); } return (Font[]) all.toArray(new Font[all.size()]); @@ -189,23 +190,23 @@ } } - public Font createFont(int format, InputStream stream) { + public Font createFont(int format, InputStream stream) throws FontFormatException, IOException { String name = fontTypeToProviderName.get(format); if (name == null) throw new IllegalArgumentException("unknown format " + name); - for (FontProvider prv : getProviders()) { + for (FontProvider<?> prv : getProviders()) { if (prv.getName().equals(name)) { - return null; //TODO + return prv.createFont(stream); } } - throw new IllegalArgumentException("can't create font with format " + name); + throw new FontFormatException("can't create font with format " + name); } @Override - public JNodeFontPeer createFontPeer(String name, Map attrs) { - for (FontProvider prv : getProviders()) { - JNodeFontPeer peer = prv.createFontPeer(name, attrs); + public JNodeFontPeer<?, ?> createFontPeer(String name, Map attrs) { + for (FontProvider<?> prv : getProviders()) { + JNodeFontPeer<?, ?> peer = prv.createFontPeer(name, attrs); if (peer != null) { return peer; } @@ -220,8 +221,8 @@ * @param font * @return The provider */ - private FontProvider getProvider(Font font) { - for (FontProvider prv : getProviders()) { + private FontProvider<?> getProvider(Font font) { + for (FontProvider<?> prv : getProviders()) { if (prv.provides(font)) { return prv; } @@ -241,7 +242,7 @@ * * @return */ - private synchronized List<FontProvider> getProviders() { + private synchronized List<FontProvider<?>> getProviders() { // TODO fix true type font // final String firstProviderName = (String)AccessController. // doPrivileged(new GetPropertyAction("jnode.font.renderer", "ttf")); @@ -252,7 +253,7 @@ if (firstProviderName.equals(providers.get(i).getName())) { // exchange the providers so that firstProvider is always at index 0 - FontProvider firstProvider = providers.get(i); + FontProvider<?> firstProvider = providers.get(i); providers.set(i, providers.get(0)); providers.set(0, firstProvider); @@ -273,7 +274,7 @@ Font txFont = font; if (getProvider(font) == null) { - txFont = getClosestProvidedFont(font, null); + txFont = getCompatibleFont(font); } return txFont; @@ -285,18 +286,8 @@ * @param font * @return */ - @Override - public Font getClosestProvidedFont(Font font, String providerName) { - for (FontProvider prv : getProviders()) { - if ((providerName == null) || (prv.getName().equals(providerName))) { - //TODO find the closest possible Font (size, style, ...) among provided ones. - //font = new Font("Luxi Sans", Font.PLAIN, font.getSize()); - font = prv.getAllFonts().iterator().next(); - break; - } - } - - return font; + private Font getCompatibleFont(Font font) { + return getProviders().get(0).getCompatibleFont(font); } private synchronized void updateFontProviders() { @@ -314,7 +305,7 @@ } } - private void configureProvider(List<FontProvider> providers, ConfigurationElement element) { + private void configureProvider(List<FontProvider<?>> providers, ConfigurationElement element) { final String className = element.getAttribute("class"); if (log.isDebugEnabled()) { @@ -325,7 +316,7 @@ try { final Class<?> cls = Thread.currentThread().getContextClassLoader().loadClass(className); - final FontProvider provider = (FontProvider) cls.newInstance(); + final FontProvider<?> provider = (FontProvider<?>) cls.newInstance(); providers.add(provider); } catch (ClassNotFoundException ex) { log.error("Cannot find provider class " + className); @@ -351,13 +342,4 @@ return idx; } - - private static class EmptyFontMetrics extends FontMetrics { - /** - * @param font - */ - public EmptyFontMetrics(Font font) { - super(font); - } - } } Modified: trunk/gui/src/awt/org/jnode/awt/font/spi/AbstractFontProvider.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/spi/AbstractFontProvider.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/spi/AbstractFontProvider.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -24,23 +24,25 @@ import java.awt.Font; import java.awt.FontMetrics; import java.io.IOException; -import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.Vector; + import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.awt.font.FontProvider; import org.jnode.awt.font.TextRenderer; import org.jnode.awt.font.renderer.RenderCache; import org.jnode.awt.font.renderer.RenderContext; -import org.jnode.vm.Unsafe; /** * @author epr * @author Fabien DUMINY (fd...@jn...) */ -public abstract class AbstractFontProvider<T extends Font> implements FontProvider { +public abstract class AbstractFontProvider<F extends Font, FD> implements FontProvider<F> { /** * My logger @@ -62,7 +64,7 @@ /** * All loaded fonts (name, Font) */ - private final HashMap<String, T> fontsByName = new HashMap<String, T>(); + private final HashMap<String, F> fontsByName = new HashMap<String, F>(); /** * Have the system fonts been loaded yet */ @@ -74,9 +76,14 @@ private final RenderCache renderCache = new RenderCache(context); private final String name; + + private final Class<F> fontClass; + + private final List<FD> userFontDatas = new Vector<FD>(); - protected AbstractFontProvider(String name) { + protected AbstractFontProvider(Class<F> fontClass, String name) { this.name = name; + this.fontClass = fontClass; } @@ -98,11 +105,7 @@ public final boolean provides(Font font) { if (font == null) return false; // don't provide default (null) fonts - if (!fontsLoaded) { - log.debug("provides, !fontsLoaded"); - loadFonts(); - } - + loadFonts(); return (getCompatibleFont(font) != null); } @@ -118,11 +121,9 @@ * * @return The set containing all fonts provides by this provider. */ - public final Set<Font> getAllFonts() { - if (!fontsLoaded) { - loadFonts(); - } - return new HashSet<Font>(fontsByName.values()); + public final Set<F> getAllFonts() { + loadFonts(); + return new HashSet<F>(fontsByName.values()); } /** @@ -150,7 +151,7 @@ * @return The metrics */ public final FontMetrics getFontMetrics(Font font) { - FontMetrics fm = (FontMetrics) metrics.get(font); + FontMetrics fm = metrics.get(font); if (fm == null) { try { @@ -163,60 +164,97 @@ return fm; } - - protected abstract FontMetrics createFontMetrics(Font font) throws IOException; - - protected abstract String[] getSystemFonts(); - - protected abstract T loadFont(URL url) throws IOException; - protected final T getCompatibleFont(Font font) { - T f = null; - try { - f = fontsByName.get(font.getFamily()); - if (f == null) { - f = fontsByName.get(font.getName()); - } - - if (f == null) { - f = fontsByName.get(font.getFontName()); - } - - if ((f == null) && (fontsByName.size() > 0)) { - f = fontsByName.values().iterator().next(); - } - } catch (Throwable t) { - log.error("error in getCompatibleFont", t); + /* + * Load all default fonts. + */ + private final void loadFonts() { + if (!fontsLoaded) { + loadFontsImpl(); + fontsLoaded = true; } - return f; } + protected abstract FontMetrics createFontMetrics(Font font) throws IOException; + /** * Load all default fonts. */ - private final void loadFonts() { - for (String font : getSystemFonts()) { - loadFont(font); + protected abstract void loadFontsImpl(); + + /** + * Translates the font into a font that is provided by this provider. + * + * @param font + * @return + */ + @Override + public final F getCompatibleFont(Font font) { + F f = null; + + if (fontClass.isInstance(font)) { + f = fontClass.cast(font); } - fontsLoaded = true; - } + + if (f == null) { + f = fontsByName.get(font.getFamily()); + } + + if (f == null) { + f = fontsByName.get(font.getName()); + } - private final void loadFont(String resName) { - try { - final ClassLoader cl = Thread.currentThread().getContextClassLoader(); - final URL url = cl.getResource(resName); - if (url != null) { - final T font = loadFont(url); - //fontsByName.put(font.getName(), font); - fontsByName.put(font.getFamily(), font); - //fontsByName.put(font.getFontName(), font); - } else { - log.error("Cannot find font resource " + resName); - } - } catch (IOException ex) { - log.error("Cannot find font " + resName + ": " + ex.getMessage()); - } catch (Throwable ex) { - log.error("Cannot find font " + resName, ex); + if (f == null) { + f = fontsByName.get(font.getFontName()); } + + if ((f == null) && (fontsByName.size() > 0)) { + f = fontsByName.values().iterator().next(); + } + + return f; } + + protected void addUserFontData(FD data) { + userFontDatas.add(data); + } + + protected List<FD> getUserFontDatas() { + return userFontDatas; + } + + protected void addFont(F font) { + //fontsByName.put(font.getName(), font); + fontsByName.put(font.getFamily(), font); + //fontsByName.put(font.getFontName(), font); + } + +// /** +// * Load all default fonts. +// */ +// private final void loadFonts() { +// for (String font : getSystemFonts()) { +// loadFont(font); +// } +// fontsLoaded = true; +// } +// +// private final void loadFont(String resName) { +// try { +// final ClassLoader cl = Thread.currentThread().getContextClassLoader(); +// final URL url = cl.getResource(resName); +// if (url != null) { +// final F font = loadFont(url); +// //fontsByName.put(font.getName(), font); +// fontsByName.put(font.getFamily(), font); +// //fontsByName.put(font.getFontName(), font); +// } else { +// log.error("Cannot find font resource " + resName); +// } +// } catch (IOException ex) { +// log.error("Cannot find font " + resName + ": " + ex.getMessage()); +// } catch (Throwable ex) { +// log.error("Cannot find font " + resName, ex); +// } +// } } Modified: trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontDataFile.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontDataFile.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontDataFile.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -56,7 +56,7 @@ } public TTFFontDataFile(URL url) throws IOException { - this(new TTFURLInput(url)); + this(new TTFMemoryInput(url)); } public TTFFontDataFile(TTFInput input) throws IOException { @@ -125,5 +125,4 @@ System.out.println(" entrySelector: " + entrySelector); System.out.println(" rangeShift: " + rangeShift); } - } Added: trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontPeer.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontPeer.java (rev 0) +++ trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFFontPeer.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -0,0 +1,121 @@ +package org.jnode.awt.font.truetype; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.util.Locale; +import java.util.Map; + +import org.jnode.awt.font.JNodeFontPeer; + +public class TTFFontPeer extends JNodeFontPeer<TTFontProvider, TTFFont> { + + public TTFFontPeer(TTFontProvider provider, String name, Map attrs) { + super(provider, name, attrs); + } + + @Override + public boolean canDisplay(Font font, char c) { + TTFFont ttfFont = getCompatibleFont(font); + //ttfFont.getFontData().getGlyph(c); + return false; + } + + @Override + public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci) { + // TODO Auto-generated method stub + return null; + } + + @Override + public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes) { + // TODO Auto-generated method stub + return null; + } + + @Override + public byte getBaselineFor(Font font, char c) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public FontMetrics getFontMetrics(Font font) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getGlyphName(Font font, int glyphIndex) { + // TODO Auto-generated method stub + return null; + } + + @Override + public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, + FontRenderContext rc) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getMissingGlyphCode(Font font) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getNumGlyphs(Font font) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String getPostScriptName(Font font) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Rectangle2D getStringBounds(Font font, CharacterIterator ci, int begin, int limit, + FontRenderContext frc) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSubFamilyName(Font font, Locale locale) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasUniformLineMetrics(Font font) { + // TODO Auto-generated method stub + return false; + } + + @Override + public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, + int limit, int flags) { + // TODO Auto-generated method stub + return null; + } + +} Modified: trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFMemoryInput.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFMemoryInput.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFMemoryInput.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -21,6 +21,11 @@ package org.jnode.awt.font.truetype; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + /** * FIXME: These methods are not really tested yet. * @@ -33,10 +38,30 @@ private final int offset; private int pointer; + public TTFMemoryInput(URL url) throws IOException { + this(url.openStream()); + } + + public TTFMemoryInput(InputStream is) throws IOException { + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + final byte[] buf = new byte[4096]; + int len; + while ((len = is.read(buf)) > 0) { + os.write(buf, 0, len); + } + is.close(); + + this.data = os.toByteArray(); + this.offset = 0; + this.pointer = 0; + } + public TTFMemoryInput(byte[] data, int offset, int length) { this.data = data; this.offset = offset; this.pointer = offset; + + //FIXME more likely to be a bug since we ignore length parameter } public TTFMemoryInput(byte[] data) { @@ -46,6 +71,8 @@ private TTFMemoryInput(TTFMemoryInput src, int offset, int length) { this.data = src.data; this.offset = src.offset + offset; + + //FIXME more likely to be a bug or why is that code disabled ? //this.length = length; } Deleted: trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFURLInput.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFURLInput.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFURLInput.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -1,55 +0,0 @@ -/* - * $Id$ - * - * JNode.org - * Copyright (C) 2003-2006 JNode.org - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; If not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -package org.jnode.awt.font.truetype; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -/** - * @author epr - */ -public class TTFURLInput extends TTFMemoryInput { - - /** - * @param url - * @throws IOException - */ - public TTFURLInput(URL url) - throws IOException { - super(getData(url)); - } - - private static byte[] getData(URL url) - throws IOException { - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - final InputStream is = url.openStream(); - final byte[] buf = new byte[4096]; - int len; - while ((len = is.read(buf)) > 0) { - os.write(buf, 0, len); - } - is.close(); - return os.toByteArray(); - } -} Modified: trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFontProvider.java =================================================================== --- trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFontProvider.java 2008-09-30 21:58:37 UTC (rev 4593) +++ trunk/gui/src/awt/org/jnode/awt/font/truetype/TTFontProvider.java 2008-09-30 22:09:24 UTC (rev 4594) @@ -22,23 +22,29 @@ package org.jnode.awt.font.truetype; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.FontMetrics; import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.jnode.awt.JNodeToolkit; import org.jnode.awt.font.JNodeFontPeer; import org.jnode.awt.font.TextRenderer; +import org.jnode.awt.font.bdf.BDFFont; +import org.jnode.awt.font.bdf.BDFFontPeer; import org.jnode.awt.font.renderer.RenderCache; import org.jnode.awt.font.spi.AbstractFontProvider; +import org.jnode.font.bdf.BDFFontContainer; /** * @author epr * @author Fabien DUMINY (fd...@jn...) */ -public class TTFontProvider extends AbstractFontProvider<TTFFont> { +public class TTFontProvider extends AbstractFontProvider<TTFFont, TTFFontDataFile> { /** * My logger */ @@ -52,7 +58,7 @@ }; public TTFontProvider() { - super("ttf"); + super(TTFFont.class, "ttf"); log.debug("new TTFontProvider"); } @@ -82,11 +88,52 @@ * @return */ @Override - public JNodeFontPeer createFontPeer(String name, Map attrs) { - return null; //TODO + public TTFFontPeer createFontPeer(String name, Map attrs) { + //TODO implement me +// TTFFontPeer peer = null; +// +// List<BDFFontContainer> datas = getUserFontDatas(); +// for (BDFFontContainer container : datas) { +// if (match(container, name, attrs)) { +// peer = new TTFFontPeer(this, name, attrs); +// datas.remove(container); +// break; +// } +// } +// +// for (BDFFontContainer container : getContainers()) { +// if (match(container, name, attrs)) { +// peer = new TTFFontPeer(this, name, attrs); +// break; +// } +// } +// +// return peer; + + return new TTFFontPeer(this, name, attrs); } /** + * Read an create a Font from the given InputStream + * @param stream + * @return + */ + @Override + public TTFFont createFont(InputStream stream) throws FontFormatException, IOException { + try { + TTFFontDataFile data = new TTFFontDataFile(new TTFMemoryInput(stream)); + addUserFontData(data); + return new TTFFont(data, 10); + } catch (IOException e) { + throw e; + } catch (Exception e) { + FontFormatException ffe = new FontFormatException("bad ttf format"); + ffe.initCause(e); + throw ffe; + } + } + + /** * Gets the font data for the given font * * @param font @@ -106,13 +153,23 @@ } } - protected TTFFont loadFont(URL url) throws IOException { - log.debug("<<< loadFont(" + url + ") >>>"); - final TTFFontData fontData = new TTFFontDataFile(url); - return new TTFFont(fontData, 10); + @Override + protected void loadFontsImpl() { + for (String fontResource : SYSTEM_FONTS) { + try { + final ClassLoader cl = Thread.currentThread().getContextClassLoader(); + final URL url = cl.getResource(fontResource); + if (url != null) { + final TTFFontData fontData = new TTFFontDataFile(url); + addFont(new TTFFont(fontData, 10)); + } else { + log.error("Cannot find font resource " + fontResource); + } + } catch (IOException ex) { + log.error("Cannot find font " + fontResource + ": " + ex.getMessage()); + } catch (Throwable ex) { + log.error("Cannot find font " + fontResource, ex); + } + } } - - protected String[] getSystemFonts() { - return SYSTEM_FONTS; - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |