Source Code Cross Referenced for VFont.java in  » Scripting » hecl » org » graphics » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » hecl » org.graphics 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) 2005, 2006 data2c GmbH (www.data2c.com)
003:         *
004:         * Author: Wolfgang S. Kechel - wolfgang.kechel@data2c.com
005:         *
006:         */
007:
008:        package org.graphics;
009:
010:        import java.io.EOFException;
011:        import java.io.InputStream;
012:        import java.io.InputStreamReader;
013:        import java.io.IOException;
014:
015:        import java.util.Hashtable;
016:
017:        /*
018:         * Set internal define to make module widely independant of build environment
019:         */
020:        //#ifndef j2se
021:        //#define ISMIDLET
022:        //#endif
023:        //#ifndef ISMIDLET
024:        /*
025:         * Control usage of HERSHEY font stuff. Comment next line to disable
026:         * creation of vector font from hershey font.
027:         */
028:        //#define USEHERSHEY
029:        import java.io.File;
030:        import java.io.FileInputStream;
031:        import java.io.FileNotFoundException;
032:        import java.io.PrintStream;
033:
034:        import java.awt.Graphics;
035:        import java.awt.Point;
036:        import java.awt.Polygon;
037:        import java.awt.Rectangle;
038:
039:        import java.net.URL;
040:
041:        import java.util.Enumeration;
042:
043:        //#ifdef USEHERSHEY
044:        import org.hershey.HersheyFont; //#endif
045:
046:        //#else
047:        import javax.microedition.lcdui.Graphics;
048:
049:        import org.awt.Point;
050:        import org.awt.Rectangle;
051:
052:        //#endif
053:
054:        public class VFont {
055:            public final static double ITALICS = 0.75;
056:
057:            //#ifndef ISMIDLET
058:            public final static int HCENTER = 1;
059:            public final static int VCENTER = 2;
060:            public final static int LEFT = 4;
061:            public final static int RIGHT = 8;
062:            public final static int TOP = 16;
063:            public final static int BOTTOM = 32;
064:            public final static int BASELINE = 64;
065:            //public final static int CAP = 0x80;
066:            protected static double dpi = 100;
067:            //#else
068:            public final static int HCENTER = Graphics.HCENTER;
069:            public final static int LEFT = Graphics.LEFT;
070:            public final static int RIGHT = Graphics.RIGHT;
071:            public final static int TOP = Graphics.TOP;
072:            public final static int VCENTER = Graphics.VCENTER;
073:            public final static int BOTTOM = Graphics.BOTTOM;
074:            public final static int BASELINE = Graphics.BASELINE;
075:            //public final static int CAP = 2;
076:            protected static double dpi = 125;
077:            //#endif
078:
079:            // Target size of font in point (default: 12pt)
080:            protected static double normsize = 12.0;
081:            // Hold precalculated value to scale font to normsize
082:            // accoring to display resolution in dpi.
083:            protected static double scaling = (normsize * dpi) / 72.0;
084:
085:            public static int getDPI() {
086:                return (int) dpi;
087:            }
088:
089:            public static void setDPI(int dotsperinch) {
090:                dpi = dotsperinch;
091:                scaling = (normsize * dpi) / 72.0;
092:            }
093:
094:            // Class to hold all parameters needed for drawing a string
095:            public static class DrawParams {
096:                public DrawParams() {
097:                    this (BOTTOM | LEFT, 1, 1, 0, 0);
098:                }
099:
100:                public DrawParams(int anchorspec, double w, double h,
101:                        double rot, double italics) {
102:                    anchor = anchorspec;
103:                    width = w;
104:                    height = h;
105:                    theta = rot;
106:                    slant = italics;
107:                }
108:
109:                void setup(double fontheight) {
110:                    scale = scaling / fontheight;
111:                    xscale = width * scale;
112:                    yscale = height * scale;
113:                    if (theta != .0) {
114:                        double tmp = (double) (-Math.PI / 180.0 * theta);
115:                        costheta = (double) Math.cos(tmp);
116:                        sintheta = (double) Math.sin(tmp);
117:                    } else {
118:                        costheta = 1.0;
119:                        sintheta = .0;
120:                    }
121:                    finalslant = slant * yscale;
122:                    /*
123:                     System.err.println("fh="+fontheight
124:                     +", w="+width +" / xs="+xscale
125:                     +", h="+height +" / ys="+yscale
126:                     +", sl="+slant +" / fsl="+finalslant);
127:                     */
128:                }
129:
130:                public int anchor;
131:                public double width;
132:                public double height;
133:                public double theta; // rotation in degrees
134:                public double slant; // slant as tan(slantangle)
135:                double costheta = 1.0;
136:                double sintheta = .0;
137:                double finalslant = .0;
138:                double scale;
139:                double xscale;
140:                double yscale;
141:            }
142:
143:            public static class Glyph
144:            //#ifndef ISMIDLET
145:                    implements  Cloneable
146:            //#endif
147:            {
148:                // A glyph describes a character.
149:                // The coordinate system has (0,0) in the lower left corner increasing
150:                // to the left (x) and upwards (y).
151:                public Glyph(char ch, int cwidth, char[] strokes) {
152:                    this (ch, cwidth, 0, strokes);
153:                }
154:
155:                public Glyph(char ch, int cwidth, int ml, char[] strokes) {
156:                    this .ch = ch;
157:                    this .cwidth = (short) cwidth;
158:                    this .midline = (short) ml;
159:                    this .strokes = strokes;
160:                }
161:
162:                public int draw(int xp, int yp, int rotpx, int rotpy,
163:                        DrawParams dp, Rectangle r, Graphics g) {
164:                    int npts = 0;
165:                    Point[] pts = null;
166:                    for (int i = 0; i < strokes.length;) {
167:                        int what = (int) strokes[i++];
168:                        switch (what) {
169:                        case 'v':
170:                        case 'l':
171:                            npts = 2;
172:                            //System.out.println("ex v 2");
173:                            pts = getPoints(npts, i, xp, yp, rotpx, rotpy, dp,
174:                                    r);
175:                            line(pts[0].x, pts[0].y, pts[1].x, pts[1].y, g);
176:                            i += 2 * npts;
177:                            break;
178:                        case 'V':
179:                        case 'p':
180:                        case 'P':
181:                            npts = (int) strokes[i++];
182:                            //System.out.println("ex p "+npts);
183:                            pts = getPoints(npts, i, xp, yp, rotpx, rotpy, dp,
184:                                    r);
185:                            switch (what) {
186:                            case 'V':
187:                                lines(pts, g);
188:                                break;
189:                            case 'p':
190:                                if (g != null)
191:                                    Draw.drawPolygon(g, npts, pts, false);
192:                                break;
193:                            case 'P':
194:                                if (g != null)
195:                                    Draw.drawPolygon(g, npts, pts, true);
196:                                break;
197:                            }
198:                            i += 2 * npts;
199:                            break;
200:                        default:
201:                            i = strokes.length;
202:                            break;
203:                        }
204:                    }
205:                    return round(dp.xscale/*dp.width*/* cwidth);
206:                }
207:
208:                protected Point[] getPoints(int npts, int startat, int xp,
209:                        int yp, int rotpx, int rotpy, DrawParams dp, Rectangle r) {
210:                    int x;
211:                    int y;
212:                    Point[] p = new Point[npts];
213:                    for (int i = 0; i < npts; ++i, startat += 2) {
214:                        x = xform(xp, strokes[startat], dp.xscale);
215:                        if (0.0 != dp.finalslant) {
216:                            //System.out.println("y="+(int)strokes[startat+1] +"corr="+(strokes[startat+1]*finalslant));
217:                            // add italics offset to the "normal" point transformation
218:                            x += strokes[startat + 1] * dp.finalslant;
219:                        }
220:                        // calculate the y coordinate
221:                        y = xform(yp, -strokes[startat + 1], dp.yscale);
222:
223:                        if (dp.theta != .0) {
224:                            // apply the rotation matrix ...
225:                            // transform the coordinate to the rotation center point
226:                            double xd = x - rotpx;
227:                            double yd = y - rotpy;
228:
229:                            // rotate
230:                            double xd2 = xd * dp.costheta - yd * dp.sintheta;
231:                            double yd2 = xd * dp.sintheta + yd * dp.costheta;
232:
233:                            // transform back
234:                            x = round(xd2) + rotpx;
235:                            y = round(yd2) + rotpy;
236:                        }
237:                        if (r != null) {
238:                            if (x < r.x) {
239:                                r.x = x;
240:                            }
241:                            if (y < r.y) {
242:                                r.y = y;
243:                            }
244:                            if (x > r.width) {
245:                                r.width = x;
246:                            }
247:                            if (y > r.height) {
248:                                r.height = y;
249:                            }
250:                        }
251:                        p[i] = new Point(x, y);
252:                    }
253:                    return p;
254:                }
255:
256:                protected void lines(Point[] points, Graphics g) {
257:                    if (points == null || g == null)
258:                        return;
259:                    for (int i = 0; i < points.length - 1; ++i) {
260:                        line(points[i].x, points[i].y, points[i + 1].x,
261:                                points[i + 1].y, g);
262:                    }
263:                }
264:
265:                protected void line(int x1, int y1, int x2, int y2, Graphics g) {
266:                    if (g == null)
267:                        return;
268:
269:                    //#ifdef notdef
270:                    if (width > 1) {
271:                        //#ifndef ISMIDLET
272:                        // if the width is greater than one
273:                        Polygon filledPolygon = new Polygon();
274:
275:                        int offset = width / 2;
276:
277:                        // this does not generate a true "wide line" but it seems to
278:                        // look OK for font lines
279:                        filledPolygon.addPoint(x1 - offset, y1 + offset);
280:                        filledPolygon.addPoint(x1 + offset, y1 - offset);
281:                        filledPolygon.addPoint(x2 + offset, y2 - offset);
282:                        filledPolygon.addPoint(x2 - offset, y2 + offset);
283:                        // draw a polygon
284:                        g.fillPolygon(filledPolygon);
285:                        //#else
286:                        System.out.println("NO THICK LINES!!!");
287:                        //#endif
288:                    }
289:                    //#endif
290:                    // draw a line
291:                    //#ifdef ISMIDLET
292:                    int oldstroke = g.getStrokeStyle();
293:                    g.setStrokeStyle(Graphics.SOLID);
294:                    //#endif
295:                    g.drawLine(x1, y1, x2, y2);
296:                    //#ifdef ISMIDLET
297:                    g.setStrokeStyle(oldstroke);
298:                    //#endif
299:                }
300:
301:                //#ifndef ISMIDLET
302:                public Glyph(Glyph g) {
303:                    this (g.ch, g.cwidth, g.midline, copyStrokes(g.strokes));
304:                }
305:
306:                public Object clone() {
307:                    return new Glyph(this );
308:                }
309:
310:                public char[] getStrokes() {
311:                    return strokes;
312:                }
313:
314:                public void setStrokes(char[] newstrokes) {
315:                    strokes = newstrokes;
316:                }
317:
318:                public PrintStream storeOn(PrintStream s) {
319:                    s.print("# " + Integer.toString(ch) + " w " + cwidth);
320:                    if (midline != 0 && midline != cwidth / 2)
321:                        s.print(" m " + midline);
322:                    if (strokes != null) {
323:                        for (int i = 0; i < strokes.length;) {
324:                            char ch = strokes[i++];
325:                            s.print(' ');
326:                            s.print(ch);
327:                            switch (ch) {
328:                            case 'v':
329:                            case 'l':
330:                                s.print(" " + ((int) strokes[i++]));
331:                                s.print(" " + ((int) strokes[i++]));
332:                                s.print(" " + ((int) strokes[i++]));
333:                                s.print(" " + ((int) strokes[i++]));
334:                                break;
335:                            case 'V':
336:                            case 'p':
337:                            case 'P':
338:                                int n = (int) strokes[i++];
339:                                s.print(" " + String.valueOf(n));
340:                                while (n-- > 0) {
341:                                    s.print(" " + ((int) strokes[i++]));
342:                                    s.print(" " + ((int) strokes[i++]));
343:                                }
344:                                break;
345:                            default:
346:                                i = strokes.length;
347:                                break;
348:                            }
349:                        }
350:                    }
351:                    s.print(";");
352:                    return s;
353:                }
354:
355:                public int getMidLine() {
356:                    return midline;
357:                }
358:
359:                public void setWidth(int val) {
360:                    if (val >= 0)
361:                        cwidth = (short) val;
362:                }
363:
364:                public void setMidLine(int val) {
365:                    if (val >= 0)
366:                        midline = (short) val;
367:                }
368:
369:                private static char[] copyStrokes(char[] strokes) {
370:                    char[] newstrokes = new char[strokes.length];
371:                    System.arraycopy(strokes, 0, newstrokes, 0, strokes.length);
372:                    return newstrokes;
373:                }
374:
375:                //#endif
376:
377:                public int getWidth() {
378:                    return cwidth;
379:                }
380:
381:                static protected final int xform(int offset, int val, double mag) {
382:                    return round(offset + val * mag);
383:                }
384:
385:                char ch;
386:                short cwidth;
387:                short midline = 0;
388:                char[] strokes = null;
389:            }
390:
391:            public VFont(String name, String resourcename) throws IOException {
392:                this (name, new InputStreamReader(checkis(resourcename
393:                        .getClass().getResourceAsStream(resourcename),
394:                        resourcename)));
395:            }
396:
397:            public VFont(String name, InputStreamReader is) throws IOException {
398:                fontname = name;
399:
400:                // read format
401:                int format = getc(is);
402:                int unused = getc(is);
403:                int ch;
404:
405:                while ((ch = getc(is)) != '{' && ch != -1)
406:                    ;
407:                if (ch == -1)
408:                    // error: premature eof
409:                    throw new EOFException("Premature EOF in font file.");
410:                if (format != 'A' || unused != 'X')
411:                    // error: unknown format
412:                    throw new IOException("Font file format error.");
413:
414:                while ((ch = getc(is)) != '#' && ch != -1) {
415:                    switch (ch) {
416:                    case 'n':
417:                        // ignore
418:                        readInt(is);
419:                        //h.numchars = readInt(is);
420:                        /* note that number of characters is one more than max characters */
421:                        break;
422:                    case 'h':
423:                        fontheight = readInt(is);
424:                        break;
425:                    case 'b':
426:                        fontbaseline = readInt(is);
427:                        break;
428:                    case 'x':
429:                        fontxline = readInt(is);
430:                        break;
431:                    case 'c':
432:                        fontcapline = readInt(is);
433:                        break;
434:                    case 'w':
435:                        fontcwidth = readInt(is);
436:                        break;
437:                    case 'T':
438:                        fontthickness = readInt(is);
439:                        break;
440:                    case ' ':
441:                    default:
442:                        break;
443:                    }
444:                }
445:                if (ch == -1) {
446:                    // error: premature eof
447:                    throw new EOFException("Premature EOF in font file header.");
448:                }
449:                ungetc(is, ch);
450:
451:                boolean done = false;
452:                while (!done) {
453:                    while ((ch = getc(is)) != '#' && ch != '}' && ch != -1) {
454:                        //skip to #
455:                        ;
456:                    }
457:
458:                    if (ch == '#') {
459:                        readStrokes((char) readInt(is), is);
460:                    } else {
461:                        done = true;
462:                    }
463:                }
464:                //if(fontcwidth
465:                makeDefaultGlyph();
466:            }
467:
468:            //#ifndef ISMIDLET
469:            public VFont(File file) throws IOException {
470:                this (file.getName(), new InputStreamReader(makeis(file)));
471:            }
472:
473:            public VFont(String name, File filename) throws IOException {
474:                this (name, new InputStreamReader(makeis(filename)));
475:            }
476:
477:            //#ifdef USEHERSHEY
478:            public VFont(String name, HersheyFont hf) {
479:                fontname = name;
480:
481:                int miny = hf.characterSetMinY;
482:                int maxy = hf.characterSetMaxY;
483:
484:                fontheight = maxy - miny;
485:                fontcwidth = 0;
486:                fontcapline = fontxline = fontthickness = 0;
487:
488:                for (int i = 0; i < hf.charactersInSet; ++i) {
489:                    char thechar = (char) (' ' + i);
490:                    StringBuffer all = new StringBuffer();
491:                    StringBuffer sb = new StringBuffer();
492:                    int minx = hf.characterMinX[i];
493:                    int maxx = hf.characterMaxX[i];
494:                    int cw = maxx - minx;
495:
496:                    // Remind widest character
497:                    if (cw > fontcwidth)
498:                        fontcwidth = cw;
499:
500:                    char n = 0;
501:                    int hfnpts = hf.numberOfPoints[i];
502:                    for (int k = 1; k < hfnpts; ++k) {
503:                        char[] xvals = hf.characterVectors[i][HersheyFont.X];
504:                        char[] yvals = hf.characterVectors[i][HersheyFont.Y];
505:
506:                        if (xvals[k] == (int) ' ') {
507:                            if (n > 0) {
508:                                if (n > 2)
509:                                    all.append('V').append(n).append(
510:                                            sb.toString());
511:                                else
512:                                    all.append('v').append(sb.toString());
513:                                n = 0;
514:                                sb = new StringBuffer();
515:                            }
516:                        } else {
517:                            sb.append((char) (((int) xvals[k]) - minx));
518:                            sb
519:                                    .append((char) (fontheight - (((int) yvals[k]) - miny)));
520:                            ++n;
521:                        }
522:                    }
523:                    if (n > 0) {
524:                        if (n > 2)
525:                            all.append('V').append((char) n).append(
526:                                    sb.toString());
527:                        else
528:                            all.append('v').append(sb.toString());
529:                    }
530:                    setGlyph(thechar, new Glyph(thechar, cw, all.toString()
531:                            .toCharArray()));
532:                }
533:                makeDefaultGlyph();
534:            }
535:
536:            //#endif
537:
538:            public int getFontBaseLine() {
539:                return fontbaseline;
540:            }
541:
542:            public int getFontCapLine() {
543:                return fontcapline;
544:            }
545:
546:            public int getFontCharWidth() {
547:                return fontcwidth;
548:            }
549:
550:            public int getFontHeight() {
551:                return fontheight;
552:            }
553:
554:            public int getFontXLine() {
555:                return fontxline;
556:            }
557:
558:            public void setFontBaseLine(int v) {
559:                fontbaseline = v;
560:            }
561:
562:            public void setFontCapLine(int v) {
563:                fontcapline = v;
564:            }
565:
566:            public void setFontCharWidth(int v) {
567:                fontcwidth = v;
568:            }
569:
570:            public void setFontHeight(int v) {
571:                fontheight = v;
572:            }
573:
574:            public void setFontXLine(int v) {
575:                fontxline = v;
576:            }
577:
578:            public void setDefaultGlyph(Glyph glyph) {
579:                // Silently ignore null default glyph!
580:                if (glyph != null)
581:                    defaultglyph = glyph;
582:            }
583:
584:            //#endif
585:
586:            public String getName() {
587:                return fontname;
588:            }
589:
590:            public int getHeight() {
591:                return round(scaling);
592:            }
593:
594:            public void setGlyph(char thechar, Glyph glyph) {
595:                // Tricky: make sure the Glyph really describes the character for
596:                // which it is stored!
597:                glyph.ch = thechar;
598:                if (thechar >= 0 && thechar < 256)
599:                    isoglyphs[thechar] = glyph;
600:                else {
601:                    glyphtab.put(new Character(thechar), glyph);
602:                }
603:            }
604:
605:            public Glyph getDefaultGlyph() {
606:                return defaultglyph;
607:            }
608:
609:            public Glyph getGlyph(char thechar) {
610:                Glyph glyph = null;
611:
612:                if (thechar >= 0 && thechar < 256)
613:                    glyph = isoglyphs[thechar];
614:                else {
615:                    glyph = (Glyph) glyphtab.get(new Character(thechar));
616:                }
617:                if (glyph == null)
618:                    glyph = defaultglyph;
619:                //System.out.println("thechar="+thechar+", glyph="+glyph);
620:                //glyph.printOn(System.out);
621:                return glyph;
622:            }
623:
624:            public int glyphWidth(char thechar) {
625:                return getGlyph(thechar).getWidth();
626:            }
627:
628:            public void drawString(String text, int xc, int yc, Rectangle r,
629:                    Graphics g) {
630:                drawString(text, xc, yc, new DrawParams(BOTTOM | LEFT, 1.0,
631:                        1.0, .0, .0), r, g);
632:            }
633:
634:            public void drawString(String text, int xc, int yc, int anchor,
635:                    Rectangle r, Graphics g) {
636:                drawString(text, xc, yc, new DrawParams(anchor, 1.0, 1.0, .0,
637:                        .0), r, g);
638:            }
639:
640:            public void drawString(String text, int xc, int yc, int anchor,
641:                    double width, double height, Rectangle r, Graphics g) {
642:                drawString(text, xc, yc, new DrawParams(anchor, width, height,
643:                        .0, .0), r, g);
644:            }
645:
646:            public void drawString(String text, int xc, int yc, int anchor,
647:                    double width, double height, double theta, double slant,
648:                    Rectangle r, Graphics g) {
649:                drawString(text, xc, yc, new DrawParams(anchor, width, height,
650:                        theta, slant), r, g);
651:            }
652:
653:            public void drawString(String text, int xc, int yc, DrawParams dp,
654:                    Rectangle r, Graphics g) {
655:
656:                // starting position
657:                int xp = xc, yp = yc;
658:                // set the position to do all rotations about
659:                int rotpx = xc, rotpy = yc;
660:                // set the flag to true if the angle is not 0.0
661:                double verticalOffsetFactor = .0;
662:
663:                // if we are to do a rotation
664:                dp.setup(fontheight);
665:
666:                // if we are not going to actually draw the string
667:                if (r != null) {
668:                    // set up to initialize the bounding rectangle
669:                    r.x = r.width = xp;
670:                    r.y = r.height = yp;
671:                }
672:
673:                if ((dp.anchor & BASELINE) == BASELINE) {
674:                    verticalOffsetFactor = .0f;
675:                    yp -= round(dp.yscale/*dp.height*/* fontbaseline);
676:                } else {
677:                    if ((dp.anchor & TOP) == TOP) {
678:                        verticalOffsetFactor = 1.0;
679:                    }
680:                    if ((dp.anchor & VCENTER) == VCENTER) {
681:                        verticalOffsetFactor = 0.5;
682:                    }
683:                    if ((dp.anchor & BOTTOM) == BOTTOM) {
684:                        verticalOffsetFactor = .0;
685:                    }
686:                    // move the y position based on the vertical alignment
687:                    yp -= round(verticalOffsetFactor * dp.yscale/*dp.height*/
688:                            * fontheight);
689:                }
690:
691:                char[] chars = text.toCharArray();
692:                if (chars.length > 0) {
693:                    // if we have a non-standard horizontal alignment
694:                    if ((dp.anchor & LEFT) != LEFT) {
695:                        // find the length of the string in pixels ...
696:                        int len = 0;
697:
698:                        for (int j = 0; j < chars.length; j++) {
699:                            // the character's number in the array ...
700:                            len += glyphWidth(chars[j]);
701:                        }
702:                        len = round(dp.xscale/*dp.width*/* len);
703:
704:                        // if we are center aligned
705:                        if ((dp.anchor & HCENTER) == HCENTER) {
706:                            // move the starting point half to the left
707:                            xp -= len / 2;
708:                        } else {
709:                            // alignment is right, move the start all the way to the left
710:                            xp -= len;
711:                        }
712:                    }
713:
714:                    // loop through each character in the string ...
715:                    for (int j = 0; j < chars.length; j++) {
716:                        // advance the starting coordinate
717:                        xp += getGlyph(chars[j]).draw(xp, yp, rotpx, rotpy, dp,
718:                                r, g);
719:                    }
720:                }
721:
722:                // Correct rectangle dimension
723:                if (r != null) {
724:                    r.width = r.width - r.x + 1;
725:                    r.height = r.height - r.y + 1;
726:                }
727:            }
728:
729:            public Rectangle extent(String text, int xc, int yc, int anchor,
730:                    Rectangle r) {
731:                return extent(text, xc, yc, new DrawParams(anchor, 1.0, 1.0,
732:                        .0, .0), r);
733:            }
734:
735:            public Rectangle extent(String text, int xc, int yc, int anchor,
736:                    double width, double height, Rectangle r) {
737:                return extent(text, xc, yc, new DrawParams(anchor, width,
738:                        height, .0, .0), r);
739:            }
740:
741:            public Rectangle extent(String text, int xc, int yc, int anchor,
742:                    double width, double height, double theta, double slant,
743:                    Rectangle r) {
744:                return extent(text, xc, yc, new DrawParams(anchor, width,
745:                        height, theta, slant), r);
746:            }
747:
748:            public Rectangle extent(String text, int xc, int yc, DrawParams dp,
749:                    Rectangle r) {
750:                if (r == null)
751:                    r = new Rectangle();
752:                drawString(text, xc, yc, dp, r, null);
753:                return r;
754:            }
755:
756:            //#ifndef ISMIDLET
757:            public int getNumberOfGlyphs() {
758:                int numglyphs = 0;
759:
760:                for (int i = 0; i < isoglyphs.length; ++i) {
761:                    if (isoglyphs[i] != null)
762:                        ++numglyphs;
763:                }
764:                Enumeration e = glyphtab.elements();
765:                while (e.hasMoreElements()) {
766:                    e.nextElement();
767:                    ++numglyphs;
768:                }
769:                return numglyphs;
770:            }
771:
772:            public boolean hasGlyph(char thechar) {
773:                if (thechar >= 0 && thechar < 256)
774:                    return isoglyphs[thechar] != null;
775:                return null != glyphtab.get(new Character(thechar));
776:            }
777:
778:            public PrintStream storeOn(PrintStream s) {
779:                StringBuffer sb = new StringBuffer();
780:
781:                sb.append("AX\n{\n");
782:                // number of glyphs
783:                sb.append("\tn ").append(getNumberOfGlyphs()).append('\n');
784:                // font height
785:                sb.append("\th ").append(fontheight).append('\n');
786:                // font baseline position
787:                sb.append("\tb ").append(fontbaseline).append('\n');
788:                // font Xline
789:                sb.append("\tx ").append(fontxline).append('\n');
790:                // font capline
791:                sb.append("\tc ").append(fontcapline).append('\n');
792:                // font character width (average??)
793:                sb.append("\tw ").append(fontcwidth).append('\n');
794:                s.print(sb.toString());
795:                for (int i = 0; i < isoglyphs.length; ++i) {
796:                    if (isoglyphs[i] != null) {
797:                        s.print('\t');
798:                        isoglyphs[i].storeOn(s).println();
799:                    }
800:                }
801:                Enumeration e = glyphtab.elements();
802:                while (e.hasMoreElements()) {
803:                    s.print('\t');
804:                    ((Glyph) e.nextElement()).storeOn(s).println();
805:                }
806:                s.println("}");
807:                return s;
808:            }
809:
810:            //#endif
811:
812:            protected void makeDefaultGlyph() {
813:                StringBuffer sb = new StringBuffer();
814:                int w = fontcwidth / 2;
815:
816:                // make sure character has some extent...
817:                if (w < 3)
818:                    w = 3;
819:
820:                // generate a glyph that is a box
821:                sb.append('V').append((char) 5);
822:                sb.append((char) 1).append((char) 1);
823:                sb.append((char) (w - 2)).append((char) 1);
824:                sb.append((char) (w - 2)).append((char) (fontheight - 2));
825:                sb.append((char) (1)).append((char) (fontheight - 2));
826:                sb.append((char) 1).append((char) 1);
827:                defaultglyph = new Glyph((char) 0, w, sb.toString()
828:                        .toCharArray());
829:            }
830:
831:            protected int getc(InputStreamReader is) throws IOException {
832:                int ch;
833:
834:                if (is.markSupported()) {
835:                    is.mark(1);
836:                    ch = lastchar = is.read();
837:                } else {
838:                    if (pushback) {
839:                        pushback = false;
840:                        ch = lastchar;
841:                    } else {
842:                        ch = lastchar = is.read();
843:                    }
844:                }
845:                return ch;
846:            }
847:
848:            protected void ungetc(InputStreamReader is, int ch)
849:                    throws IOException {
850:                if (is.markSupported())
851:                    is.reset();
852:                else {
853:                    pushback = true;
854:                    lastchar = ch;
855:                }
856:            }
857:
858:            protected void skipWS(InputStreamReader is) throws IOException {
859:                // skip whitespace
860:                int ch;
861:                do {
862:                    ch = getc(is);
863:                } while (ch == ' ' || ch == '\t' || ch == '\n');
864:                if (ch != ' ' && ch != '\t' && ch != '\n' && ch != -1)
865:                    ungetc(is, ch);
866:            }
867:
868:            protected int readInt(InputStreamReader is) throws IOException {
869:                int ch;
870:                int val = 0;
871:                boolean neg = false;
872:                int numdigits = 0;
873:
874:                skipWS(is);
875:                ch = getc(is);
876:                if (ch == '+')
877:                    ch = getc(is);
878:                else if (ch == '-') {
879:                    neg = true;
880:                    ch = getc(is);
881:                }
882:                while (ch != -1 && Character.isDigit((char) ch)) {
883:                    ++numdigits;
884:                    val = 10 * val + Character.digit((char) ch, 10);
885:                    ch = getc(is);
886:                }
887:                if (neg)
888:                    val = -val;
889:                if (ch != -1 && numdigits > 0)
890:                    ungetc(is, ch);
891:                return val;
892:            }
893:
894:            protected void readStrokes(char thechar, InputStreamReader is)
895:                    throws IOException {
896:                StringBuffer sb = new StringBuffer();
897:                int i = 0;
898:                int c;
899:                int cwidth = fontcwidth;
900:                int midline = 0;
901:
902:                while ((c = getc(is)) != ';' && c != '}' && c != -1) {
903:                    switch (c) {
904:                    case 'w':
905:                        // character width
906:                        cwidth = readInt(is);
907:                        break;
908:                    case 'm':
909:                        // font character centerline/midline
910:                        midline = readInt(is);
911:                        break;
912:                    case 'l':
913:                    case 'v':
914:                        // draw lline (with thickness)
915:                        sb.append((char) c); /* insert the opcode */
916:                        /* read first argument */
917:                        sb.append((char) readInt(is));
918:                        sb.append((char) readInt(is));
919:                        /* read second argument */
920:                        sb.append((char) readInt(is));
921:                        sb.append((char) readInt(is));
922:                        break;
923:                    case 'V':
924:                    case 'p':
925:                    case 'P':
926:                    case 'B':
927:                        sb.append((char) c); /* insert the opcode */
928:                        i = readInt(is);
929:                        sb.append((char) i);
930:                        for (int j = 0; j < i; j++) {
931:                            sb.append((char) readInt(is));
932:                            sb.append((char) readInt(is));
933:                        }
934:                        break;
935:                    case ' ': /* space between input chars, ignore */
936:                    case '\t':
937:                    default:
938:                        break;
939:                    }
940:                }
941:                if (c == -1 || c == '}')
942:                    throw new IOException("EOF or format error in font file.");
943:                setGlyph(thechar, new Glyph(thechar, cwidth, midline, sb
944:                        .toString().toCharArray()));
945:            }
946:
947:            private static InputStream checkis(InputStream is, String name)
948:                    throws IOException {
949:                if (is == null)
950:                    throw new IOException("Font '" + name + "' not found.");
951:                return is;
952:            }
953:
954:            //#ifndef ISMIDLET
955:            private static InputStream makeis(File file) throws IOException {
956:                return checkis(new FileInputStream(file), file
957:                        .getCanonicalPath());
958:            }
959:
960:            //#endif
961:
962:            private static int round(double x) {
963:                return (int) Math.floor(.5 + x);
964:            }
965:
966:            protected String fontname;
967:            protected int fontheight = 1;
968:            protected int fontbaseline = 0;
969:            protected int fontcwidth = 0;
970:            protected int fontcapline = 0; // unused
971:            protected int fontxline = 0; // unused
972:            protected int fontthickness = 0; // unused
973:
974:            protected Hashtable glyphtab = new Hashtable();
975:            protected Glyph[] isoglyphs = new Glyph[256];
976:            protected Glyph defaultglyph;
977:            protected boolean pushback = false;
978:            protected int lastchar = 0;
979:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.