From 419b204a9970ef93163e39f0824a994e29b3d6df Mon Sep 17 00:00:00 2001 From: benfry Date: Wed, 29 Sep 2004 06:06:51 +0000 Subject: [PATCH] fixing several font issues.. PFont2 now works properly.. --- processing/core/PApplet.java | 15 +++-- processing/core/PFont.java | 106 +++++++++-------------------------- processing/core/PFont2.java | 70 ++++++++++++++++------- processing/core/todo.txt | 34 +++++++++++ processing/todo.txt | 36 ++---------- 5 files changed, 129 insertions(+), 132 deletions(-) diff --git a/processing/core/PApplet.java b/processing/core/PApplet.java index a93eed8aa..fc4e00109 100644 --- a/processing/core/PApplet.java +++ b/processing/core/PApplet.java @@ -1428,10 +1428,10 @@ public class PApplet extends Applet System.out.flush(); } - //static public void println(Object what[]) { - //for (int i = 0; i < what.length; i++) System.out.println(what[i]); - //System.out.flush(); - //} + static public void printarr(Object what[]) { + for (int i = 0; i < what.length; i++) System.out.println(what[i]); + System.out.flush(); + } @@ -2190,6 +2190,13 @@ public class PApplet extends Applet } catch (Exception e) { } // ignored + try { + File file = new File(folder, filename); + stream = new FileInputStream(file); + if (stream != null) return stream; + + } catch (Exception e) { } // ignored + try { stream = new FileInputStream(new File("data", filename)); if (stream != null) return stream; diff --git a/processing/core/PFont.java b/processing/core/PFont.java index 9a998f5b3..e5af2a456 100644 --- a/processing/core/PFont.java +++ b/processing/core/PFont.java @@ -1,11 +1,11 @@ /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* - BFont - font object for text rendering + PFont - font object for text rendering Part of the Processing project - http://processing.org - Copyright (c) 2001-04 Massachusetts Institute of Technology - (Except where noted that the author is not Ben Fry) + Copyright (c) 2004 Ben Fry & Casey Reas + Portions Copyright (c) 2001-04 Massachusetts Institute of Technology This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -29,15 +29,6 @@ import java.io.*; import java.util.*; -// where is the font point size embedded in the font? -// not sizing properly relative to how the platforms work - -// ascent = height of lowercase d -// descent = depth of lowercase p -// get the leading calculation in there properly - -// how do we handle kerning - /* awful ascii (non)art for how this works | @@ -65,9 +56,9 @@ public class PFont implements PConstants { // image width, a power of 2 // note! these will always be the same - public int iwidth, iheight; + public int twidth, theight; // float versions of the above - //float iwidthf, iheightf; + //float twidthf, theightf; // formerly iwidthf, iheightf.. but that's wrong // actually should be mbox, the font size @@ -113,44 +104,19 @@ public class PFont implements PConstants { // this will make new fonts downward compatible mbox2 = is.readInt(); - //System.out.println("boxes " + mbox + " " + mbox2); - - //int mboxX = is.readInt(); // not used, just fontsize (48) - //int mboxY = is.readInt(); // also just fontsize (48) - - // only store this one for leading calc - //mbox = mboxY; fwidth = mbox; fheight = mbox; // size for image ("texture") is next power of 2 // over the font size. for most vlw fonts, the size is 48 // so the next power of 2 is 64. - // (actually that wasn't quite right, since mboxX/Y were both 64, - // and the font builder was already setting it as the next pow of 2) - /* - iwidth = (int) - Math.pow(2, Math.ceil(Math.log(mboxX) / Math.log(2))); - iheight = (int) - Math.pow(2, Math.ceil(Math.log(mboxY) / Math.log(2))); - */ - // double-check to make sure that mbox2 is a power of 2 // there was a bug in the old font generator that broke this mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2))); // size for the texture is stored in the font - iwidth = iheight = mbox2; + twidth = theight = mbox2; - //iwidthf = (float) iwidth; - //iheightf = (float) iheight; - - // font size is 48, so default leading is 48 * 1.2 - // this is same as what illustrator uses for the default - //defaultLeading = ((float)mboxY / iheightf) * 1.2f; - - //int baseHt = is.readInt(); // zero, ignored - //is.readInt(); // ignore 4 for struct padding - ascent = is.readInt(); // formerly zero/ignored + ascent = is.readInt(); // formerly baseHt (zero/ignored) descent = is.readInt(); // formerly ignored struct padding //System.out.println("found mbox = " + mbox); @@ -182,53 +148,30 @@ public class PFont implements PConstants { // cache locations of the ascii charset if (value[i] < 128) ascii[value[i]] = i; - //if (value[i] == 'd') - //System.out.println("calc ascent is " + topExtent[i]); - //if (value[i] == 'p') - //System.out.println("calc descent is " + (-topExtent[i] + height[i])); - // the values for getAscent() and getDescent() from FontMetrics // seem to be way too large.. perhaps they're the max? // as such, use a more traditional marker for ascent/descent if (value[i] == 'd') { - ascent = topExtent[i]; + if (ascent == 0) ascent = topExtent[i]; } if (value[i] == 'p') { - descent = -topExtent[i] + height[i]; + if (descent == 0) descent = -topExtent[i] + height[i]; } } - // foreign font, so just make ascent the max topExtent - // or maybe just throw an exception and say to re-export? + // not a roman font, so throw an error and ask to re-build. + // that way can avoid a bunch of error checking hacks in here. if ((ascent == 0) && (descent == 0)) { - for (int i = 0; i < charCount; i++) { - char cc = (char) value[i]; - if (Character.isWhitespace(cc) || - (cc == '\u00A0') || (cc == '\u2007') || (cc == '\u202F')) { - continue; - } - - if (topExtent[i] > ascent) { - ascent = topExtent[i]; - } - int d = -topExtent[i] + height[i]; - if (d > descent) { - descent = d; - //System.out.println("big d is on " + PApplet.hex(value[i]) - // + " " + ((char) value[i])); - } - //System.out.println("max top now: " + ascent + - // " for " + PApplet.hex(value[i]) + " "); - } - } - //System.out.println("a/d = " + ascent + " " + descent); + throw new RuntimeException("Please use \"Create Font\" to " + + "re-create this font."); + } images = new PImage[charCount]; for (int i = 0; i < charCount; i++) { //int pixels[] = new int[64 * 64]; - int pixels[] = new int[iwidth * iheight]; + int pixels[] = new int[twidth * theight]; //images[i] = new PImage(pixels, 64, 64, ALPHA); - images[i] = new PImage(pixels, iwidth, iheight, ALPHA); + images[i] = new PImage(pixels, twidth, theight, ALPHA); int bitmapSize = height[i] * width[i]; byte temp[] = new byte[bitmapSize]; @@ -241,7 +184,7 @@ public class PFont implements PConstants { for (int x = 0; x < w; x++) { int valu = temp[y*w + x] & 0xff; //images[i].pixels[y*64 + x] = valu; - images[i].pixels[y * iwidth + x] = valu; + images[i].pixels[y * twidth + x] = valu; // the following makes javagl more happy.. // not sure what's going on //(valu << 24) | (valu << 16) | (valu << 8) | valu; //0xffffff; @@ -288,7 +231,8 @@ public class PFont implements PConstants { for (int y = 0; y < height[i]; y++) { for (int x = 0; x < width[i]; x++) { - os.write(images[i].pixels[y * width[i] + x] & 0xff); + //os.write(images[i].pixels[y * width[i] + x] & 0xff); + os.write(images[i].pixels[y * mbox2 + x] & 0xff); } } } @@ -352,7 +296,10 @@ public class PFont implements PConstants { public void resetLeading() { - leading = size * ((float)mbox / fheight) * 1.2f; + //leading = size * ((float)mbox / fheight) * 1.2f; + + // by trial & error, this seems close to illustrator + leading = (ascent() + descent()) * 1.275f; } @@ -372,7 +319,7 @@ public class PFont implements PConstants { // supposedly this should be ok even in SCREEN_SPACE mode - // since the applet will set the 'size' of the font to iwidth + // since the applet will set the 'size' of the font to twidth // (though this prolly breaks any sort of 'height' measurements) public float width(char c) { if (c == 32) return width('i'); @@ -513,7 +460,7 @@ public class PFont implements PConstants { for (int row = y0; row < y0 + h0; row++) { for (int col = x0; col < x0 + w0; col++) { - int a1 = (fa * pixels1[row * iwidth + col]) >> 8; + int a1 = (fa * pixels1[row * twidth + col]) >> 8; int a2 = a1 ^ 0xff; int p1 = pixels1[row * width[glyph] + col]; int p2 = pixels2[(yy + row-y0)*parent.width + (xx+col-x0)]; @@ -598,7 +545,8 @@ public class PFont implements PConstants { if (xx + size > right) { // this goes on the next line xx = x; - yy += ascent() + descent(); //leading; + yy += leading; + //yy += ascent() * 1.2f; if (yy > h) return; // too big for box } text(words[j], xx, yy, z, parent); diff --git a/processing/core/PFont2.java b/processing/core/PFont2.java index e799ab637..51bd97fd9 100644 --- a/processing/core/PFont2.java +++ b/processing/core/PFont2.java @@ -67,15 +67,15 @@ public class PFont2 extends PFont { }; - public PFont2(String name, int size) throws IOException { + public PFont2(String name, int size) { this(new Font(name, Font.PLAIN, size), false, true); } - public PFont2(String name, int size, boolean smooth) throws IOException { + public PFont2(String name, int size, boolean smooth) { this(new Font(name, Font.PLAIN, size), false, smooth); } - public PFont2(Font font, boolean all, boolean smooth) throws IOException { + public PFont2(Font font, boolean all, boolean smooth) { //int firstChar = 33; //int lastChar = 126; @@ -83,6 +83,8 @@ public class PFont2 extends PFont { this.charCount = all ? 65536 : charset.length; this.mbox = font.getSize(); + fwidth = fheight = mbox; + /* // size for image/texture is next power of 2 over font size iwidth = iheight = (int) @@ -91,7 +93,7 @@ public class PFont2 extends PFont { iwidthf = iheightf = (float) iwidth; */ - images = new PImage[charCount]; + PImage bitmaps[] = new PImage[charCount]; // allocate enough space for the character info value = new int[charCount]; @@ -118,8 +120,8 @@ public class PFont2 extends PFont { g.setFont(font); FontMetrics metrics = g.getFontMetrics(); - ascent = metrics.getAscent(); - descent = metrics.getDescent(); + //ascent = metrics.getAscent(); + //descent = metrics.getDescent(); //System.out.println("descent found was " + descent); int maxWidthHeight = 0; @@ -177,7 +179,8 @@ public class PFont2 extends PFont { setWidth[index] = metrics.charWidth(c); // cache locations of the ascii charset - if (value[i] < 128) ascii[value[i]] = i; + //if (value[i] < 128) ascii[value[i]] = i; + if (c < 128) ascii[c] = index; // offset from vertical location of baseline // of where the char was drawn (mbox*2) @@ -186,35 +189,64 @@ public class PFont2 extends PFont { // offset from left of where coord was drawn leftExtent[index] = minX - mbox; - //System.out.println(height[index] + " " + width[index] + " " + - // setWidth[index] + " " + - // topExtent[index] + " " + leftExtent[index]); + if (c == 'd') { + ascent = topExtent[index]; + } + if (c == 'p') { + descent = -topExtent[index] + height[index]; + } if (width[index] > maxWidthHeight) maxWidthHeight = width[index]; if (height[index] > maxWidthHeight) maxWidthHeight = height[index]; - images[index] = new PImage(new int[width[index] * height[index]], - width[index], height[index], ALPHA); + bitmaps[index] = new PImage(new int[width[index] * height[index]], + width[index], height[index], ALPHA); for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { - //System.out.println("getting pixel " + x + " " + y); int value = 255 - raster.getSample(x, y, 0); int pindex = (y - minY) * width[index] + (x - minX); - images[index].pixels[pindex] = value; - //System.out.print(BApplet.nf(value, 3) + " "); + bitmaps[index].pixels[pindex] = value; } - //System.out.println(); } - //System.out.println(); index++; } charCount = index; + // foreign font, so just make ascent the max topExtent + if ((ascent == 0) && (descent == 0)) { + for (int i = 0; i < charCount; i++) { + char cc = (char) value[i]; + if (Character.isWhitespace(cc) || + (cc == '\u00A0') || (cc == '\u2007') || (cc == '\u202F')) { + continue; + } + if (topExtent[i] > ascent) { + ascent = topExtent[i]; + } + int d = -topExtent[i] + height[i]; + if (d > descent) { + descent = d; + } + } + } // size for image/texture is next power of 2 over largest char mbox2 = (int) Math.pow(2, Math.ceil(Math.log(maxWidthHeight) / Math.log(2))); - //System.out.println("mbox is " + mbox); - //System.out.println("found " + charCount + " chars + twidth = theight = mbox2; + + //images = bitmaps; + //System.out.println("Mbox 2 is " + mbox2); + images = new PImage[charCount]; + // copy from bitmaps into actual image pixels + for (int i = 0; i < charCount; i++) { + images[i] = new PImage(new int[mbox2*mbox2], mbox2, mbox2, ALPHA); + for (int y = 0; y < height[i]; y++) { + System.arraycopy(bitmaps[i].pixels, y*width[i], + images[i].pixels, y*mbox2, + width[i]); + } + bitmaps[i] = null; + } } } diff --git a/processing/core/todo.txt b/processing/core/todo.txt index 1b3d5c784..0c2587f97 100644 --- a/processing/core/todo.txt +++ b/processing/core/todo.txt @@ -205,6 +205,40 @@ X make savePath() and createPath() accessible to the outside world X useful for libraries saving files etc. +0070p8 +_ need to try jogl to make sure no further changes +_ and the illustrator stuff + +X sizing bug fix to fonts, they now match platform standards +X however, *this will break people's code* +X text in a box not written +_ make sure to note in the docs that text/textrect position differently +o for this reason, should it be called textrect()? +_ if a word (no spaces) is too long to fit, insert a 'space' +_ move left/center/right aligning into the font class +_ otherwise text with alignment has problems with returns +_ could PFont2 be done entirely with reflection? +_ that way other font types can properly extend PFont +X font heights and leading are bad +X get good values for ascent and descent +X if ScreenFont subclasses PFont.. can that be used in textFont()? +_ move SCREEN_SPACE into ScreenFont() class? +_ that way can clear up some of the general confusion in the code +_ also handle things like rotation +_ not having kerning really blows +_ could this be pulled from the OpenType font stuff? +_ it could be placed at the end of the file +_ simple way to just use java text in p5 applets? +_ the current text support is just so hokey +X check to make sure the tops of fonts not getting chopped in font builder +_ look into fixing the texture mapping to not squash fonts +_ NEW_GRAPHICS totally smashes everything + +_ 404 error because first searches applet directory on zipdecode + +_ image(String name) and textFont(String name) + + ............................................................ diff --git a/processing/todo.txt b/processing/todo.txt index 96f8c79ff..4e81052a3 100644 --- a/processing/todo.txt +++ b/processing/todo.txt @@ -248,44 +248,20 @@ X update with other examples 0070p8 X height for applets wasn't working properly - X debug font stuff in processing.core X mbox wasn't set properly (not a power of 2) X debug framerate() stuff with noLoop() +X re-enabled printarr(Object[]) -_ strange hangs, errors that don't come up: -_ watch out for loadFont() outside of setup -_ or other things that can cause errors +-> most stuff is over in core.. argh _ remove SystemOutSiphon: i just died message -_ need to try jogl to make sure no further changes +_ nanoxml problems with manifest -X sizing bug fix to fonts, they now match platform standards -X however, *this will break people's code* -_ text in a box not written -_ make sure to note in the docs that it positions differently -o for this reason, should it be called textrect()? -_ if a word (no spaces) is too long to fit, insert a 'space' -_ text with alignment has problems with returns -_ could PFont2 be done entirely with reflection? -_ that way other font types can properly extend PFont -_ font heights and leading are bad -_ get good values for ascent and descent -_ if ScreenFont subclasses PFont.. can that be used in textFont()? -_ move left/center/right aligning into the font class -_ not having kerning really blows -_ could this be pulled from the OpenType font stuff? -_ it could be placed at the end of the file -_ simple way to just use java text in p5 applets? -_ the current text support is just so hokey -_ move SCREEN_SPACE into ScreenFont() class? -_ that way can clear up some of the general confusion in the code -_ also handle things like rotation - -_ image(String name) and textFont(String name) - -_ nanoxml crash +_ readme.txt/bugs.txt: strange hangs, errors that don't come up: +_ watch out for loadFont() outside of setup +_ or other things that can cause errors