vfont.java
来自「Hecl编程语言是一个高层次的脚本语言的Java实现。其用意是要小」· Java 代码 · 共 1,008 行 · 第 1/2 页
JAVA
1,008 行
for(int i=0; i<hf.charactersInSet; ++i) { char thechar = (char)(' ' + i); StringBuffer all = new StringBuffer(); StringBuffer sb = new StringBuffer(); int minx = hf.characterMinX[i]; int maxx = hf.characterMaxX[i]; int cw = maxx - minx; // Remind widest character if(cw > fontcwidth) fontcwidth = cw; char n = 0; int hfnpts = hf.numberOfPoints[i]; for(int k=1; k<hfnpts; ++k) { char[] xvals = hf.characterVectors[i][HersheyFont.X]; char[] yvals = hf.characterVectors[i][HersheyFont.Y]; if(xvals[k] == (int)' ') { if(n > 0) { if(n > 2) all.append('V').append(n).append(sb.toString()); else all.append('v').append(sb.toString()); n = 0; sb = new StringBuffer(); } } else { sb.append((char)(((int)xvals[k])-minx)); sb.append((char)(fontheight-(((int)yvals[k])-miny))); ++n; } } if(n > 0) { if(n > 2) all.append('V').append((char)n).append(sb.toString()); else all.append('v').append(sb.toString()); } setGlyph(thechar,new Glyph(thechar,cw, all.toString().toCharArray())); } makeDefaultGlyph(); }//#endif public int getFontBaseLine() { return fontbaseline; } public int getFontCapLine() { return fontcapline; } public int getFontCharWidth() { return fontcwidth; } public int getFontHeight() { return fontheight; } public int getFontXLine() { return fontxline; } public void setFontBaseLine(int v) { fontbaseline = v; } public void setFontCapLine(int v) { fontcapline = v; } public void setFontCharWidth(int v) { fontcwidth = v; } public void setFontHeight(int v) { fontheight = v; } public void setFontXLine(int v) { fontxline = v; } public void setDefaultGlyph(Glyph glyph) { // Silently ignore null default glyph! if(glyph != null) defaultglyph = glyph; }//#endif public String getName() { return fontname; } public int getHeight() { return round(scaling); } public void setGlyph(char thechar,Glyph glyph) { // Tricky: make sure the Glyph really describes the character for // which it is stored! glyph.ch = thechar; if(thechar >= 0 && thechar < 256) isoglyphs[thechar] = glyph; else { glyphtab.put(new Character(thechar),glyph); } } public Glyph getDefaultGlyph() { return defaultglyph; } public Glyph getGlyph(char thechar) { Glyph glyph = null; if(thechar >= 0 && thechar < 256) glyph = isoglyphs[thechar]; else { glyph = (Glyph)glyphtab.get(new Character(thechar)); } if(glyph == null) glyph = defaultglyph; //System.out.println("thechar="+thechar+", glyph="+glyph); //glyph.printOn(System.out); return glyph; } public int glyphWidth(char thechar) { return getGlyph(thechar).getWidth(); } public void drawString(String text, int xc, int yc, Rectangle r,Graphics g) { drawString(text,xc,yc,new DrawParams(BOTTOM|LEFT,1.0,1.0,.0,.0),r,g); } public void drawString(String text, int xc, int yc,int anchor, Rectangle r,Graphics g) { drawString(text,xc,yc,new DrawParams(anchor,1.0,1.0,.0,.0),r,g); } public void drawString(String text, int xc, int yc, int anchor, double width, double height, Rectangle r, Graphics g) { drawString(text,xc,yc,new DrawParams(anchor,width,height,.0,.0),r,g); } public void drawString(String text, int xc, int yc, int anchor, double width, double height, double theta, double slant, Rectangle r, Graphics g) { drawString(text,xc,yc,new DrawParams(anchor,width,height,theta,slant),r,g); } public void drawString(String text,int xc,int yc,DrawParams dp, Rectangle r,Graphics g) { // starting position int xp = xc, yp = yc; // set the position to do all rotations about int rotpx = xc, rotpy = yc; // set the flag to true if the angle is not 0.0 double verticalOffsetFactor = .0; // if we are to do a rotation dp.setup(fontheight); // if we are not going to actually draw the string if(r != null) { // set up to initialize the bounding rectangle r.x = r.width = xp; r.y = r.height = yp; } if((dp.anchor & BASELINE) == BASELINE) { verticalOffsetFactor = .0f; yp -= round(dp.yscale/*dp.height*/ * fontbaseline); } else { if((dp.anchor & TOP) == TOP) { verticalOffsetFactor = 1.0; } if((dp.anchor & VCENTER) == VCENTER) { verticalOffsetFactor = 0.5; } if((dp.anchor & BOTTOM) == BOTTOM) { verticalOffsetFactor = .0; } // move the y position based on the vertical alignment yp -= round(verticalOffsetFactor * dp.yscale/*dp.height*/ * fontheight); } char[] chars = text.toCharArray(); if(chars.length > 0) { // if we have a non-standard horizontal alignment if((dp.anchor & LEFT) != LEFT) { // find the length of the string in pixels ... int len = 0; for(int j = 0; j < chars.length; j++) { // the character's number in the array ... len += glyphWidth(chars[j]); } len = round(dp.xscale/*dp.width*/ * len); // if we are center aligned if((dp.anchor & HCENTER) == HCENTER) { // move the starting point half to the left xp -= len / 2; } else { // alignment is right, move the start all the way to the left xp -= len; } } // loop through each character in the string ... for(int j = 0; j < chars.length; j++) { // advance the starting coordinate xp += getGlyph(chars[j]).draw(xp, yp, rotpx, rotpy, dp, r, g); } } // Correct rectangle dimension if(r != null) { r.width = r.width - r.x + 1; r.height = r.height - r.y + 1; } } public Rectangle extent(String text, int xc, int yc,int anchor,Rectangle r) { return extent(text,xc,yc,new DrawParams(anchor,1.0,1.0,.0,.0),r); } public Rectangle extent(String text, int xc, int yc, int anchor, double width, double height, Rectangle r) { return extent(text,xc,yc,new DrawParams(anchor,width,height,.0,.0),r); } public Rectangle extent(String text, int xc, int yc, int anchor, double width, double height, double theta, double slant,Rectangle r) { return extent(text,xc,yc,new DrawParams(anchor,width,height,theta,slant),r); } public Rectangle extent(String text, int xc, int yc,DrawParams dp,Rectangle r) { if(r == null) r = new Rectangle(); drawString(text,xc,yc,dp,r,null); return r; } //#ifndef ISMIDLET public int getNumberOfGlyphs() { int numglyphs = 0; for(int i=0; i<isoglyphs.length; ++i) { if(isoglyphs[i] != null) ++numglyphs; } Enumeration e = glyphtab.elements(); while(e.hasMoreElements()) { e.nextElement(); ++numglyphs; } return numglyphs; } public boolean hasGlyph(char thechar) { if(thechar >= 0 && thechar < 256) return isoglyphs[thechar] != null; return null != glyphtab.get(new Character(thechar)); } public PrintStream storeOn(PrintStream s) { StringBuffer sb = new StringBuffer(); sb.append("AX\n{\n"); // number of glyphs sb.append("\tn ").append(getNumberOfGlyphs()).append('\n'); // font height sb.append("\th ").append(fontheight).append('\n'); // font baseline position sb.append("\tb ").append(fontbaseline).append('\n'); // font Xline sb.append("\tx ").append(fontxline).append('\n'); // font capline sb.append("\tc ").append(fontcapline).append('\n'); // font character width (average??) sb.append("\tw ").append(fontcwidth).append('\n'); s.print(sb.toString()); for(int i=0; i<isoglyphs.length; ++i) { if(isoglyphs[i] != null) { s.print('\t'); isoglyphs[i].storeOn(s).println(); } } Enumeration e = glyphtab.elements(); while(e.hasMoreElements()) { s.print('\t'); ((Glyph)e.nextElement()).storeOn(s).println(); } s.println("}"); return s; }//#endif protected void makeDefaultGlyph() { StringBuffer sb = new StringBuffer(); int w = fontcwidth/2; // make sure character has some extent... if(w < 3) w = 3; // generate a glyph that is a box sb.append('V').append((char)5); sb.append((char)1).append((char)1); sb.append((char)(w-2)).append((char)1); sb.append((char)(w-2)).append((char)(fontheight-2)); sb.append((char)(1)).append((char)(fontheight-2)); sb.append((char)1).append((char)1); defaultglyph = new Glyph((char)0,w, sb.toString().toCharArray()); } protected int getc(InputStreamReader is) throws IOException { int ch; if(is.markSupported()) { is.mark(1); ch = lastchar = is.read(); } else { if(pushback) { pushback = false; ch = lastchar; } else { ch = lastchar = is.read(); } } return ch; } protected void ungetc(InputStreamReader is,int ch) throws IOException { if(is.markSupported()) is.reset(); else { pushback = true; lastchar = ch; } } protected void skipWS(InputStreamReader is) throws IOException { // skip whitespace int ch; do { ch = getc(is); } while(ch == ' ' || ch == '\t' || ch == '\n'); if(ch != ' ' && ch != '\t' && ch != '\n' && ch != -1) ungetc(is,ch); } protected int readInt(InputStreamReader is) throws IOException { int ch; int val = 0; boolean neg = false; int numdigits = 0; skipWS(is); ch = getc(is); if(ch == '+') ch = getc(is); else if(ch == '-') { neg = true; ch = getc(is); } while(ch != -1 && Character.isDigit((char)ch)) { ++numdigits; val = 10 * val + Character.digit((char)ch,10); ch = getc(is); } if(neg) val = -val; if(ch != -1 && numdigits > 0) ungetc(is,ch); return val; } protected void readStrokes(char thechar,InputStreamReader is) throws IOException { StringBuffer sb = new StringBuffer(); int i = 0; int c; int cwidth = fontcwidth; int midline = 0; while ((c = getc(is)) != ';' && c != '}' && c != -1) { switch (c) { case 'w': // character width cwidth = readInt(is); break; case 'm': // font character centerline/midline midline = readInt(is); break; case 'l': case 'v': // draw lline (with thickness) sb.append((char)c); /* insert the opcode */ /* read first argument */ sb.append((char)readInt(is)); sb.append((char)readInt(is)); /* read second argument */ sb.append((char)readInt(is)); sb.append((char)readInt(is)); break; case 'V': case 'p': case 'P': case 'B': sb.append((char)c); /* insert the opcode */ i = readInt(is); sb.append((char)i); for (int j = 0; j < i; j++) { sb.append((char)readInt(is)); sb.append((char)readInt(is)); } break; case ' ': /* space between input chars, ignore */ case '\t': default: break; } } if (c == -1 || c == '}') throw new IOException("EOF or format error in font file."); setGlyph(thechar,new Glyph(thechar,cwidth, midline,sb.toString().toCharArray())); } private static InputStream checkis(InputStream is,String name) throws IOException { if(is == null) throw new IOException("Font '"+name+"' not found."); return is; } //#ifndef ISMIDLET private static InputStream makeis(File file) throws IOException { return checkis(new FileInputStream(file),file.getCanonicalPath()); }//#endif private static int round(double x) { return (int)Math.floor(.5+x); } protected String fontname; protected int fontheight = 1; protected int fontbaseline = 0; protected int fontcwidth = 0; protected int fontcapline = 0; // unused protected int fontxline = 0; // unused protected int fontthickness = 0; // unused protected Hashtable glyphtab = new Hashtable(); protected Glyph[] isoglyphs = new Glyph[256]; protected Glyph defaultglyph; protected boolean pushback = false; protected int lastchar = 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?