Source Code Cross Referenced for CommonGlyphVector.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » awt » gl » font » 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 » Apache Harmony Java SE » org package » org.apache.harmony.awt.gl.font 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:        /**
0018:         * @author Ilya S. Okomin
0019:         * @version $Revision$
0020:         */package org.apache.harmony.awt.gl.font;
0021:
0022:        import java.awt.Font;
0023:        import java.awt.Rectangle;
0024:        import java.awt.Shape;
0025:        import java.awt.font.FontRenderContext;
0026:        import java.awt.font.GlyphJustificationInfo;
0027:        import java.awt.font.GlyphMetrics;
0028:        import java.awt.font.GlyphVector;
0029:        import java.awt.geom.AffineTransform;
0030:        import java.awt.geom.GeneralPath;
0031:        import java.awt.geom.Point2D;
0032:        import java.awt.geom.Rectangle2D;
0033:
0034:        import org.apache.harmony.awt.internal.nls.Messages;
0035:
0036:        /**
0037:         * GlyphVector implementation
0038:         */
0039:        public class CommonGlyphVector extends GlyphVector {
0040:
0041:            // array of transforms of glyphs in GlyphVector
0042:            protected AffineTransform[] glsTransforms;
0043:
0044:            // array of chars defined in constructor
0045:            public char[] charVector;
0046:
0047:            // array of Glyph objects, that describe information about glyphs
0048:            public Glyph[] vector;
0049:
0050:            // array of default positions of glyphs in GlyphVector
0051:            // without applying GlyphVector's transform
0052:            float[] defaultPositions;
0053:
0054:            // array of logical positions of glyphs in GlyphVector
0055:
0056:            float[] logicalPositions;
0057:
0058:            // array of visual (real) positions of glyphs in GlyphVector
0059:            public float[] visualPositions;
0060:
0061:            // FontRenderContext for this vector.
0062:            protected FontRenderContext vectorFRC;
0063:
0064:            // layout flags mask
0065:            protected int layoutFlags = 0;
0066:
0067:            // array of cached glyph outlines 
0068:            protected Shape[] gvShapes;
0069:
0070:            FontPeerImpl peer;
0071:
0072:            // font corresponding to the GlyphVector 
0073:            Font font;
0074:
0075:            // ascent of the font
0076:            float ascent;
0077:
0078:            // height of the font
0079:            float height;
0080:
0081:            // leading of the font
0082:            float leading;
0083:
0084:            // descent of the font
0085:            float descent;
0086:
0087:            // transform of the GlyphVector
0088:            AffineTransform transform;
0089:
0090:            /**
0091:             * Creates new CommonGlyphVector object from the specified parameters.
0092:             * 
0093:             * @param chars an array of chars
0094:             * @param frc FontRenderContext object
0095:             * @param fnt Font object
0096:             * @param flags layout flags
0097:             */
0098:            @SuppressWarnings("deprecation")
0099:            public CommonGlyphVector(char[] chars, FontRenderContext frc,
0100:                    Font fnt, int flags) {
0101:                int len = chars.length;
0102:
0103:                this .font = fnt;
0104:                this .transform = fnt.getTransform();
0105:                this .peer = (FontPeerImpl) fnt.getPeer();
0106:
0107:                gvShapes = new Shape[len];
0108:
0109:                // !! As pointed in API documentation for the 
0110:                // getGlyphPosisitions(int index,int numEntries, float[] positionReturn) 
0111:                // and getGlyphPosition(int index) methods, if the index is equals to 
0112:                // the number of glyphs the position after the last glyph must be 
0113:                // returned, thus there are n+1 positions and last (n+1) position 
0114:                // points to the end of GlyphVector.
0115:
0116:                logicalPositions = new float[(len + 1) << 1];
0117:                visualPositions = new float[(len + 1) << 1];
0118:                defaultPositions = new float[(len + 1) << 1];
0119:
0120:                //        glsTransforms = new AffineTransform[len];
0121:
0122:                this .charVector = chars;
0123:                this .vectorFRC = frc;
0124:                LineMetricsImpl lmImpl = (LineMetricsImpl) peer
0125:                        .getLineMetrics();
0126:
0127:                this .ascent = lmImpl.getAscent();
0128:                this .height = lmImpl.getHeight();
0129:                this .leading = lmImpl.getLeading();
0130:                this .descent = lmImpl.getDescent();
0131:                this .layoutFlags = flags;
0132:
0133:                if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
0134:                    char vector[] = new char[len];
0135:                    for (int i = 0; i < len; i++) {
0136:                        vector[i] = chars[len - i - 1];
0137:                    }
0138:                    this .vector = peer.getGlyphs(vector);
0139:
0140:                } else {
0141:                    this .vector = peer.getGlyphs(chars);
0142:                }
0143:
0144:                this .glsTransforms = new AffineTransform[len];
0145:
0146:                setDefaultPositions();
0147:                performDefaultLayout();
0148:            }
0149:
0150:            /**
0151:             * Creates new CommonGlyphVector object from the specified parameters. 
0152:             * Layout flags set to default.
0153:             * 
0154:             * @param chars an array of chars
0155:             * @param frc FontRenderContext object
0156:             * @param fnt Font object
0157:             */
0158:            public CommonGlyphVector(char[] chars, FontRenderContext frc,
0159:                    Font fnt) {
0160:                this (chars, frc, fnt, 0);
0161:            }
0162:
0163:            /**
0164:             * Creates new CommonGlyphVector object from the specified parameters. 
0165:             * Layout flags set to default.
0166:             * 
0167:             * @param str specified string
0168:             * @param frc FontRenderContext object
0169:             * @param fnt Font object
0170:             */
0171:            public CommonGlyphVector(String str, FontRenderContext frc, Font fnt) {
0172:                this (str.toCharArray(), frc, fnt, 0);
0173:            }
0174:
0175:            /**
0176:             * Creates new CommonGlyphVector object from the specified parameters.
0177:             * 
0178:             * @param str specified string
0179:             * @param frc FontRenderContext object
0180:             * @param fnt Font object
0181:             * @param flags layout flags
0182:             */
0183:            public CommonGlyphVector(String str, FontRenderContext frc,
0184:                    Font fnt, int flags) {
0185:                this (str.toCharArray(), frc, fnt, flags);
0186:            }
0187:
0188:            /**
0189:             * Set array of logical positions of the glyphs to
0190:             * default with their default advances and height.
0191:             */
0192:            void setDefaultPositions() {
0193:                int len = getNumGlyphs();
0194:
0195:                // First [x,y] is set into [0,0] position
0196:                // for this reason start index is 1
0197:                for (int i = 1; i <= len; i++) {
0198:                    int idx = i << 1;
0199:                    float advanceX = vector[i - 1].getGlyphPointMetrics()
0200:                            .getAdvanceX();
0201:                    float advanceY = vector[i - 1].getGlyphPointMetrics()
0202:                            .getAdvanceY();
0203:
0204:                    defaultPositions[idx] = defaultPositions[idx - 2]
0205:                            + advanceX;
0206:                    defaultPositions[idx + 1] = defaultPositions[idx - 1]
0207:                            + advanceY;
0208:
0209:                }
0210:                transform.transform(defaultPositions, 0, logicalPositions, 0,
0211:                        getNumGlyphs() + 1);
0212:
0213:            }
0214:
0215:            /**
0216:             * Returnes the pixel bounds of this GlyphVector rendered at the 
0217:             * specified x,y location with the given FontRenderContext.
0218:             *  
0219:             * @param frc a FontRenderContext that is used
0220:             * @param x specified x coordinate value
0221:             * @param y specified y coordinate value
0222:             * @return a Rectangle that bounds pixels of this GlyphVector
0223:             */
0224:            @Override
0225:            public Rectangle getPixelBounds(FontRenderContext frc, float x,
0226:                    float y) {
0227:
0228:                double xM, yM, xm, ym;
0229:
0230:                double minX = 0;
0231:                double minY = 0;
0232:                double maxX = 0;
0233:                double maxY = 0;
0234:
0235:                for (int i = 0; i < this .getNumGlyphs(); i++) {
0236:                    Rectangle glyphBounds = this .getGlyphPixelBounds(i, frc, 0,
0237:                            0);
0238:                    xm = glyphBounds.getMinX();
0239:                    ym = glyphBounds.getMinY();
0240:                    xM = glyphBounds.getMaxX();
0241:                    yM = glyphBounds.getMaxY();
0242:
0243:                    if (i == 0) {
0244:                        minX = xm;
0245:                        minY = ym;
0246:                        maxX = xM;
0247:                        maxY = yM;
0248:                    }
0249:
0250:                    if (minX > xm) {
0251:                        minX = xm;
0252:                    }
0253:                    if (minY > ym) {
0254:                        minY = ym;
0255:                    }
0256:                    if (maxX < xM) {
0257:                        maxX = xM;
0258:                    }
0259:                    if (maxY < yM) {
0260:                        maxY = yM;
0261:                    }
0262:                }
0263:                return new Rectangle((int) (minX + x), (int) (minY + y),
0264:                        (int) (maxX - minX), (int) (maxY - minY));
0265:
0266:            }
0267:
0268:            /**
0269:             * Returns the visual bounds of this GlyphVector.
0270:             * The visual bounds is the bounds of the total outline of 
0271:             * this GlyphVector.
0272:             * @return a Rectangle2D that id the visual bounds of this GlyphVector
0273:             */
0274:            @Override
0275:            public Rectangle2D getVisualBounds() {
0276:                float xM, yM, xm, ym;
0277:                float minX = 0;
0278:                float minY = 0;
0279:                float maxX = 0;
0280:                float maxY = 0;
0281:                boolean firstIteration = true;
0282:
0283:                for (int i = 0; i < this .getNumGlyphs(); i++) {
0284:                    Rectangle2D bounds = this .getGlyphVisualBounds(i)
0285:                            .getBounds2D();
0286:                    if (bounds.getWidth() == 0) {
0287:                        continue;
0288:                    }
0289:                    xm = (float) bounds.getX();
0290:                    ym = (float) bounds.getY();
0291:
0292:                    xM = (float) (xm + bounds.getWidth());
0293:
0294:                    yM = ym + (float) bounds.getHeight();
0295:
0296:                    if (firstIteration) {
0297:                        minX = xm;
0298:                        minY = ym;
0299:                        maxX = xM;
0300:                        maxY = yM;
0301:                        firstIteration = false;
0302:                    } else {
0303:                        if (minX > xm) {
0304:                            minX = xm;
0305:                        }
0306:                        if (minY > ym) {
0307:                            minY = ym;
0308:                        }
0309:                        if (maxX < xM) {
0310:                            maxX = xM;
0311:                        }
0312:                        if (maxY < yM) {
0313:                            maxY = yM;
0314:                        }
0315:
0316:                    }
0317:                }
0318:
0319:                return (this .getNumGlyphs() != 0) ? new Rectangle2D.Float(minX,
0320:                        minY, (maxX - minX), (maxY - minY)) : null;
0321:            }
0322:
0323:            /**
0324:             * Sets new position to the specified glyph.
0325:             */
0326:            @Override
0327:            public void setGlyphPosition(int glyphIndex, Point2D newPos) {
0328:                if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
0329:                    // awt.43=glyphIndex is out of vector's limits
0330:                    throw new IndexOutOfBoundsException(Messages
0331:                            .getString("awt.43")); //$NON-NLS-1$
0332:                }
0333:                float x = (float) newPos.getX();
0334:                float y = (float) newPos.getY();
0335:                int index = glyphIndex << 1;
0336:
0337:                if ((x != visualPositions[index])
0338:                        || (y != visualPositions[index + 1])) {
0339:                    visualPositions[index] = x;
0340:                    visualPositions[index + 1] = y;
0341:                    layoutFlags = layoutFlags | FLAG_HAS_POSITION_ADJUSTMENTS;
0342:                }
0343:
0344:            }
0345:
0346:            /**
0347:             * Returns the position of the specified glyph relative to the origin of
0348:             * this GlyphVector
0349:             * @return a Point2D that the origin of the glyph with specified index
0350:             */
0351:            @Override
0352:            public Point2D getGlyphPosition(int glyphIndex) {
0353:                if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
0354:                    // awt.43=glyphIndex is out of vector's limits
0355:                    throw new IndexOutOfBoundsException(Messages
0356:                            .getString("awt.43")); //$NON-NLS-1$
0357:                }
0358:                int index = glyphIndex << 1;
0359:                Point2D pos = new Point2D.Float(visualPositions[index],
0360:                        visualPositions[index + 1]);
0361:
0362:                // For last position we don't have to transform !!
0363:                if (glyphIndex == vector.length) {
0364:                    return pos;
0365:                }
0366:
0367:                AffineTransform at = getGlyphTransform(glyphIndex);
0368:                if ((at == null) || (at.isIdentity())) {
0369:                    return pos;
0370:                }
0371:
0372:                pos.setLocation(pos.getX() + at.getTranslateX(), pos.getY()
0373:                        + at.getTranslateY());
0374:
0375:                return pos;
0376:            }
0377:
0378:            /**
0379:             * Sets new transform to the specified glyph.
0380:             * 
0381:             * @param glyphIndex specified index of the glyph
0382:             * @param trans AffineTransform of the glyph with specified index
0383:             */
0384:            @Override
0385:            public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
0386:                if ((glyphIndex >= vector.length) || (glyphIndex < 0)) {
0387:                    // awt.43=glyphIndex is out of vector's limits
0388:                    throw new IndexOutOfBoundsException(Messages
0389:                            .getString("awt.43")); //$NON-NLS-1$
0390:                }
0391:
0392:                if ((trans == null) || (trans.isIdentity())) {
0393:                    glsTransforms[glyphIndex] = null;
0394:                } else {
0395:                    glsTransforms[glyphIndex] = new AffineTransform(trans);
0396:                    layoutFlags = layoutFlags | FLAG_HAS_TRANSFORMS;
0397:                }
0398:            }
0399:
0400:            /**
0401:             * Returns the affine transform of the specified glyph.
0402:             * 
0403:             * @param glyphIndex specified index of the glyph
0404:             * @return an AffineTransform of the glyph with specified index
0405:             */
0406:            @Override
0407:            public AffineTransform getGlyphTransform(int glyphIndex) {
0408:                if ((glyphIndex >= this .vector.length) || (glyphIndex < 0)) {
0409:                    // awt.43=glyphIndex is out of vector's limits
0410:                    throw new IndexOutOfBoundsException(Messages
0411:                            .getString("awt.43")); //$NON-NLS-1$
0412:                }
0413:                return this .glsTransforms[glyphIndex];
0414:            }
0415:
0416:            /**
0417:             * Returns the metrics of the specified glyph.
0418:             * 
0419:             * @param glyphIndex specified index of the glyph
0420:             */
0421:            @Override
0422:            public GlyphMetrics getGlyphMetrics(int glyphIndex) {
0423:
0424:                if ((glyphIndex < 0) || ((glyphIndex) >= this .getNumGlyphs())) {
0425:                    // awt.43=glyphIndex is out of vector's limits
0426:                    throw new IndexOutOfBoundsException(Messages
0427:                            .getString("awt.43")); //$NON-NLS-1$
0428:                }
0429:                // TODO: is there a sence in GlyphMetrics
0430:                // if certain glyph or Font has a transform??
0431:                return this .vector[glyphIndex].getGlyphMetrics();
0432:            }
0433:
0434:            /**
0435:             * Returns a justification information for the glyph with specified glyph 
0436:             * index.
0437:             * @param glyphIndex index of a glyph which GlyphJustificationInfo is to be 
0438:             * received   
0439:             * @return a GlyphJustificationInfo object that contains glyph justification 
0440:             * properties of the specified glyph
0441:             */
0442:            @Override
0443:            public GlyphJustificationInfo getGlyphJustificationInfo(
0444:                    int glyphIndex) {
0445:                // TODO : Find out the source of Justification info
0446:                if (true) {
0447:                    throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
0448:                }
0449:                return null;
0450:            }
0451:
0452:            /**
0453:             * Returns the FontRenderContext parameter of this GlyphVector.
0454:             */
0455:            @Override
0456:            public FontRenderContext getFontRenderContext() {
0457:                return this .vectorFRC;
0458:            }
0459:
0460:            /**
0461:             * Returns the visual bounds of the specified glyph.
0462:             * 
0463:             * @param glyphIndex specified index of the glyph
0464:             */
0465:            @Override
0466:            public Shape getGlyphVisualBounds(int glyphIndex) {
0467:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0468:                    // awt.43=glyphIndex is out of vector's limits
0469:                    throw new IndexOutOfBoundsException(Messages
0470:                            .getString("awt.43")); //$NON-NLS-1$
0471:                }
0472:
0473:                int idx = glyphIndex << 1;
0474:
0475:                AffineTransform fontTransform = this .transform;
0476:                double xOffs = fontTransform.getTranslateX();
0477:                double yOffs = fontTransform.getTranslateY();
0478:
0479:                if (vector[glyphIndex].getWidth() == 0) {
0480:                    return new Rectangle2D.Float((float) xOffs, (float) yOffs,
0481:                            0, 0);
0482:                }
0483:
0484:                AffineTransform at = AffineTransform.getTranslateInstance(
0485:                        xOffs, yOffs);
0486:                AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
0487:
0488:                if (transform.isIdentity()
0489:                        && ((glyphTransform == null) || glyphTransform
0490:                                .isIdentity())) {
0491:                    Rectangle2D blackBox = vector[glyphIndex].getGlyphMetrics()
0492:                            .getBounds2D();
0493:                    at
0494:                            .translate(visualPositions[idx],
0495:                                    visualPositions[idx + 1]);
0496:                    return (at.createTransformedShape(blackBox));
0497:                }
0498:
0499:                GeneralPath shape = (GeneralPath) this 
0500:                        .getGlyphOutline(glyphIndex);
0501:                shape.transform(at);
0502:                return shape.getBounds2D();
0503:            }
0504:
0505:            /**
0506:             * Returnes the pixel bounds of the specified glyph within GlyphVector 
0507:             * rendered at the specified x,y location.
0508:             *  
0509:             * @param glyphIndex index of the glyph
0510:             * @param frc a FontRenderContext that is used
0511:             * @param x specified x coordinate value
0512:             * @param y specified y coordinate value
0513:             * @return a Rectangle that bounds pixels of the specified glyph
0514:             */
0515:            @Override
0516:            public Rectangle getGlyphPixelBounds(int glyphIndex,
0517:                    FontRenderContext frc, float x, float y) {
0518:
0519:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0520:                    // awt.43=glyphIndex is out of vector's limits
0521:                    throw new IndexOutOfBoundsException(Messages
0522:                            .getString("awt.43")); //$NON-NLS-1$
0523:                }
0524:
0525:                int idx = glyphIndex << 1;
0526:
0527:                if (vector[glyphIndex].getWidth() == 0) {
0528:                    AffineTransform fontTransform = this .transform;
0529:                    double xOffs = x + visualPositions[idx]
0530:                            + fontTransform.getTranslateX();
0531:                    double yOffs = y + visualPositions[idx + 1]
0532:                            + fontTransform.getTranslateY();
0533:                    return new Rectangle((int) xOffs, (int) yOffs, 0, 0);
0534:                }
0535:
0536:                GeneralPath shape = (GeneralPath) this 
0537:                        .getGlyphOutline(glyphIndex);
0538:
0539:                AffineTransform at = AffineTransform.getTranslateInstance(x, y);
0540:
0541:                if (frc != null) {
0542:                    at.concatenate(frc.getTransform());
0543:
0544:                    /*          if (frc.usesFractionalMetrics()){
0545:                     shape.transform(at);
0546:                     Rectangle2D bounds = shape.getBounds2D();
0547:                     Rectangle rect = new Rectangle();
0548:                     rect.setRect(bounds);
0549:                     return rect;
0550:                     }*/
0551:                }
0552:
0553:                shape.transform(at);
0554:
0555:                Rectangle bounds = shape.getBounds();
0556:                return new Rectangle((int) bounds.getX(), (int) bounds.getY(),
0557:                        (int) bounds.getWidth() - 1,
0558:                        (int) bounds.getHeight() - 1);
0559:            }
0560:
0561:            /**
0562:             * Returns a Shape that encloses specified glyph.
0563:             * 
0564:             * @param glyphIndex specified index of the glyph
0565:             */
0566:            @Override
0567:            public Shape getGlyphOutline(int glyphIndex) {
0568:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0569:                    // awt.43=glyphIndex is out of vector's limits
0570:                    throw new IndexOutOfBoundsException(Messages
0571:                            .getString("awt.43")); //$NON-NLS-1$
0572:                }
0573:
0574:                if (gvShapes[glyphIndex] == null) {
0575:                    gvShapes[glyphIndex] = vector[glyphIndex].getShape();
0576:                }
0577:
0578:                GeneralPath gp = (GeneralPath) ((GeneralPath) gvShapes[glyphIndex])
0579:                        .clone();
0580:
0581:                /* Applying GlyphVector font transform */
0582:                AffineTransform at = (AffineTransform) this .transform.clone();
0583:
0584:                /* Applying Glyph transform */
0585:                AffineTransform glyphAT = getGlyphTransform(glyphIndex);
0586:                if (glyphAT != null) {
0587:                    at.preConcatenate(glyphAT);
0588:                }
0589:
0590:                int idx = glyphIndex << 1;
0591:
0592:                gp.transform(at);
0593:                gp.transform(AffineTransform.getTranslateInstance(
0594:                        visualPositions[idx], visualPositions[idx + 1]));
0595:                return gp;
0596:            }
0597:
0598:            /**
0599:             * Returns a Shape that is the outline representation of this GlyphVector 
0600:             * rendered at the specified x,y coordinates.
0601:             * 
0602:             * @param x specified x coordinate value
0603:             * @param y specified y coordinate value
0604:             * @return a Shape object that is the outline of this GlyphVector
0605:             * at the specified coordinates.
0606:             */
0607:            @Override
0608:            public Shape getOutline(float x, float y) {
0609:                GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
0610:                for (int i = 0; i < this .vector.length; i++) {
0611:                    GeneralPath outline = (GeneralPath) getGlyphOutline(i);
0612:
0613:                    /* Applying translation to actual visual bounds */
0614:                    outline.transform(AffineTransform
0615:                            .getTranslateInstance(x, y));
0616:                    gp.append(outline, false);
0617:                }
0618:
0619:                return gp;
0620:            }
0621:
0622:            /**
0623:             * Returns a Shape that is the outline representation of this GlyphVector.
0624:             * 
0625:             * @return a Shape object that is the outline of this GlyphVector
0626:             */
0627:            @Override
0628:            public Shape getOutline() {
0629:                return this .getOutline(0, 0);
0630:            }
0631:
0632:            /**
0633:             * Returns an array of glyphcodes for the specified glyphs.
0634:             * 
0635:             * @param beginGlyphIndex the start index
0636:             * @param numEntries the number of glyph codes to get
0637:             * @param codeReturn the array that receives glyph codes' values
0638:             * @return an array that receives glyph codes' values
0639:             */
0640:            @Override
0641:            public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
0642:                    int[] codeReturn) {
0643:
0644:                if ((beginGlyphIndex < 0)
0645:                        || ((numEntries + beginGlyphIndex) > this 
0646:                                .getNumGlyphs())) {
0647:                    // awt.44=beginGlyphIndex is out of vector's range
0648:                    throw new IndexOutOfBoundsException(Messages
0649:                            .getString("awt.44")); //$NON-NLS-1$
0650:                }
0651:
0652:                if (numEntries < 0) {
0653:                    // awt.45=numEntries is out of vector's range
0654:                    throw new IllegalArgumentException(Messages
0655:                            .getString("awt.45")); //$NON-NLS-1$
0656:                }
0657:
0658:                if (codeReturn == null) {
0659:                    codeReturn = new int[numEntries];
0660:                }
0661:
0662:                for (int i = beginGlyphIndex; i < beginGlyphIndex + numEntries; i++) {
0663:                    codeReturn[i - beginGlyphIndex] = this .vector[i]
0664:                            .getGlyphCode();
0665:                }
0666:
0667:                return codeReturn;
0668:            }
0669:
0670:            /**
0671:             * Returns an array of numEntries character indices for the specified glyphs.
0672:             * 
0673:             * @param beginGlyphIndex the start index
0674:             * @param numEntries the number of glyph codes to get
0675:             * @param codeReturn the array that receives glyph codes' values
0676:             * @return an array that receives glyph char indices
0677:             */
0678:            @Override
0679:            public int[] getGlyphCharIndices(int beginGlyphIndex,
0680:                    int numEntries, int[] codeReturn) {
0681:                if ((beginGlyphIndex < 0)
0682:                        || (beginGlyphIndex >= this .getNumGlyphs())) {
0683:                    // awt.44=beginGlyphIndex is out of vector's range
0684:                    throw new IllegalArgumentException(Messages
0685:                            .getString("awt.44")); //$NON-NLS-1$
0686:                }
0687:
0688:                if ((numEntries < 0)
0689:                        || ((numEntries + beginGlyphIndex) > this 
0690:                                .getNumGlyphs())) {
0691:                    // awt.45=numEntries is out of vector's range
0692:                    throw new IllegalArgumentException(Messages
0693:                            .getString("awt.45")); //$NON-NLS-1$
0694:                }
0695:
0696:                if (codeReturn == null) {
0697:                    codeReturn = new int[numEntries];
0698:                }
0699:
0700:                for (int i = 0; i < numEntries; i++) {
0701:                    codeReturn[i] = this .getGlyphCharIndex(i + beginGlyphIndex);
0702:                }
0703:                return codeReturn;
0704:            }
0705:
0706:            /**
0707:             * Returns an array of numEntries glyphs positions from beginGlyphIndex
0708:             * glyph in Glyph Vector.
0709:             * 
0710:             * @param beginGlyphIndex the start index
0711:             * @param numEntries the number of glyph codes to get
0712:             * @param positionReturn the array that receives glyphs' positions
0713:             * @return an array of floats that receives glyph char indices
0714:             */
0715:            @Override
0716:            public float[] getGlyphPositions(int beginGlyphIndex,
0717:                    int numEntries, float[] positionReturn) {
0718:
0719:                int len = (this .getNumGlyphs() + 1) << 1;
0720:                beginGlyphIndex *= 2;
0721:                numEntries *= 2;
0722:
0723:                if ((beginGlyphIndex < 0)
0724:                        || ((numEntries + beginGlyphIndex) > len)) {
0725:                    // awt.44=beginGlyphIndex is out of vector's range
0726:                    throw new IndexOutOfBoundsException(Messages
0727:                            .getString("awt.44")); //$NON-NLS-1$
0728:                }
0729:
0730:                if (numEntries < 0) {
0731:                    // awt.45=numEntries is out of vector's range
0732:                    throw new IllegalArgumentException(Messages
0733:                            .getString("awt.45")); //$NON-NLS-1$
0734:                }
0735:
0736:                if (positionReturn == null) {
0737:                    positionReturn = new float[numEntries];
0738:                }
0739:
0740:                System.arraycopy(visualPositions, beginGlyphIndex,
0741:                        positionReturn, 0, numEntries);
0742:
0743:                return positionReturn;
0744:            }
0745:
0746:            /**
0747:             * Set numEntries elements of the visualPositions array from beginGlyphIndex
0748:             * of numEntries glyphs positions from beginGlyphIndex glyph in Glyph Vector.
0749:             * 
0750:             * @param beginGlyphIndex the start index
0751:             * @param numEntries the number of glyph codes to get
0752:             * @param setPositions the array of positions to set
0753:             */
0754:            public void setGlyphPositions(int beginGlyphIndex, int numEntries,
0755:                    float[] setPositions) {
0756:
0757:                int len = (this .getNumGlyphs() + 1) << 1;
0758:                beginGlyphIndex *= 2;
0759:                numEntries *= 2;
0760:
0761:                if ((beginGlyphIndex < 0)
0762:                        || ((numEntries + beginGlyphIndex) > len)) {
0763:                    // awt.44=beginGlyphIndex is out of vector's range
0764:                    throw new IndexOutOfBoundsException(Messages
0765:                            .getString("awt.44")); //$NON-NLS-1$
0766:                }
0767:
0768:                if (numEntries < 0) {
0769:                    // awt.45=numEntries is out of vector's range
0770:                    throw new IllegalArgumentException(Messages
0771:                            .getString("awt.45")); //$NON-NLS-1$
0772:                }
0773:
0774:                System.arraycopy(setPositions, 0, visualPositions,
0775:                        beginGlyphIndex, numEntries);
0776:                layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
0777:
0778:            }
0779:
0780:            /**
0781:             * Set elements of the visualPositions array.
0782:             * 
0783:             * @param setPositions the array of positions to set
0784:             */
0785:            public void setGlyphPositions(float[] setPositions) {
0786:
0787:                int len = (this .getNumGlyphs() + 1) << 1;
0788:                if (len != setPositions.length) {
0789:                    // awt.46=length of setPositions array differs from the length of positions array
0790:                    throw new IllegalArgumentException(Messages
0791:                            .getString("awt.46")); //$NON-NLS-1$
0792:                }
0793:
0794:                System.arraycopy(setPositions, 0, visualPositions, 0, len);
0795:                layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
0796:
0797:            }
0798:
0799:            /**
0800:             * Returns glyph code of the specified glyph.
0801:             * 
0802:             * @param glyphIndex specified index of the glyph
0803:             */
0804:            @Override
0805:            public int getGlyphCode(int glyphIndex) {
0806:                if (glyphIndex >= this .vector.length || glyphIndex < 0) {
0807:                    // awt.43=glyphIndex is out of vector's limits
0808:                    throw new IndexOutOfBoundsException(Messages
0809:                            .getString("awt.43")); //$NON-NLS-1$
0810:                }
0811:                return this .vector[glyphIndex].getGlyphCode();
0812:            }
0813:
0814:            /**
0815:             * Returns character index of the specified glyph.
0816:             * 
0817:             * @param glyphIndex specified index of the glyph
0818:             */
0819:            @Override
0820:            public int getGlyphCharIndex(int glyphIndex) {
0821:
0822:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0823:                    // awt.43=glyphIndex is out of vector's limits
0824:                    throw new IllegalArgumentException(Messages
0825:                            .getString("awt.43")); //$NON-NLS-1$
0826:                }
0827:
0828:                if ((this .layoutFlags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
0829:                    return this .charVector.length - glyphIndex - 1;
0830:                }
0831:
0832:                return glyphIndex;
0833:            }
0834:
0835:            /**
0836:             * Returns a character value of the specified glyph.
0837:             * 
0838:             * @param glyphIndex specified index of the glyph
0839:             */
0840:            public char getGlyphChar(int glyphIndex) {
0841:
0842:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0843:                    // awt.43=glyphIndex is out of vector's limits
0844:                    throw new IllegalArgumentException(Messages
0845:                            .getString("awt.43")); //$NON-NLS-1$
0846:                }
0847:                return this .charVector[glyphIndex];
0848:            }
0849:
0850:            /**
0851:             * Assigns default positions to each glyph in this GlyphVector.
0852:             */
0853:            @Override
0854:            public void performDefaultLayout() {
0855:
0856:                System.arraycopy(logicalPositions, 0, visualPositions, 0,
0857:                        logicalPositions.length);
0858:
0859:                // Set position changes flag to zero
0860:                clearLayoutFlags(GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
0861:            }
0862:
0863:            /**
0864:             * Returns the number of glyphs in this Glyph Vector
0865:             */
0866:            @Override
0867:            public int getNumGlyphs() {
0868:                return vector.length;
0869:            }
0870:
0871:            /**
0872:             * Returns the logical bounds of this GlyphVector
0873:             */
0874:            @Override
0875:            public Rectangle2D getLogicalBounds() {
0876:                // XXX: for transforms where an angle between basis vectors is not 90 degrees
0877:                // Rectanlge2D class doesn't fit as Logical bounds. For this reason we use
0878:                // only non-transformed bounds!!
0879:
0880:                float x = visualPositions[0];
0881:                float width = visualPositions[visualPositions.length - 2];
0882:
0883:                double scaleY = transform.getScaleY();
0884:
0885:                Rectangle2D bounds = new Rectangle2D.Float(x,
0886:                        (float) ((-this .ascent - this .leading) * scaleY),
0887:                        width, (float) (this .height * scaleY));
0888:                return bounds;
0889:            }
0890:
0891:            /**
0892:             * Checks whether given GlyphVector equals to this GlyphVector.
0893:             * @param glyphVector GlyphVector object to compare
0894:             */
0895:            @Override
0896:            public boolean equals(GlyphVector glyphVector) {
0897:                if (glyphVector == this ) {
0898:                    return true;
0899:                }
0900:
0901:                if (glyphVector != null) {
0902:
0903:                    if (!(glyphVector.getFontRenderContext().equals(
0904:                            this .vectorFRC) && glyphVector.getFont().equals(
0905:                            this .font))) {
0906:                        return false;
0907:                    }
0908:
0909:                    try {
0910:                        boolean eq = true;
0911:                        for (int i = 0; i < getNumGlyphs(); i++) {
0912:
0913:                            int idx = i * 2;
0914:                            eq = (((CommonGlyphVector) glyphVector).visualPositions[idx] == this .visualPositions[idx])
0915:                                    && (((CommonGlyphVector) glyphVector).visualPositions[idx + 1] == this .visualPositions[idx + 1])
0916:                                    && (glyphVector.getGlyphCharIndex(i) == this 
0917:                                            .getGlyphCharIndex(i));
0918:
0919:                            if (eq) {
0920:                                AffineTransform trans = glyphVector
0921:                                        .getGlyphTransform(i);
0922:                                if (trans == null) {
0923:                                    eq = (this .glsTransforms[i] == null);
0924:                                } else {
0925:                                    eq = this .glsTransforms[i].equals(trans);
0926:                                }
0927:                            }
0928:
0929:                            if (!eq) {
0930:                                return false;
0931:                            }
0932:                        }
0933:
0934:                        return eq;
0935:                    } catch (ClassCastException e) {
0936:                    }
0937:                }
0938:
0939:                return false;
0940:            }
0941:
0942:            /**
0943:             * Returns flags describing the state of the GlyphVector.
0944:             */
0945:            @Override
0946:            public int getLayoutFlags() {
0947:                return layoutFlags;
0948:            }
0949:
0950:            /**
0951:             * Returns char with the specified index.
0952:             * 
0953:             * @param index specified index of the char
0954:             * 
0955:             */
0956:            public char getChar(int index) {
0957:                return this .charVector[index];
0958:
0959:            }
0960:
0961:            /**
0962:             * Clear desired flags in layout flags describing the state. 
0963:             * 
0964:             * @param clearFlags flags mask to clear 
0965:             */
0966:
0967:            private void clearLayoutFlags(int clearFlags) {
0968:                layoutFlags &= ~clearFlags;
0969:            }
0970:
0971:            /**
0972:             * Returns the logical bounds of the specified glyph within this CommonGlyphVector.
0973:             * 
0974:             * @param glyphIndex index of the glyph to get it's logical bounds
0975:             * @return logical bounds of the specified glyph
0976:             */
0977:            @Override
0978:            public Shape getGlyphLogicalBounds(int glyphIndex) {
0979:                if ((glyphIndex < 0) || (glyphIndex >= this .getNumGlyphs())) {
0980:                    // awt.43=glyphIndex is out of vector's limits
0981:                    throw new IndexOutOfBoundsException(Messages
0982:                            .getString("awt.43")); //$NON-NLS-1$
0983:                }
0984:                Glyph glyph = this .vector[glyphIndex];
0985:
0986:                float x0 = visualPositions[glyphIndex * 2];
0987:                float y0 = visualPositions[glyphIndex * 2 + 1];
0988:                float advanceX = glyph.getGlyphPointMetrics().getAdvanceX();
0989:
0990:                GeneralPath gp = new GeneralPath();
0991:                gp.moveTo(0, -ascent - leading);
0992:                gp.lineTo(advanceX, -ascent - leading);
0993:                gp.lineTo(advanceX, descent);
0994:                gp.lineTo(0, descent);
0995:                gp.lineTo(0, -ascent - leading);
0996:                gp.closePath();
0997:
0998:                /* Applying GlyphVector font transform */
0999:                AffineTransform at = (AffineTransform) this .transform.clone();
1000:
1001:                /* Applying Glyph transform */
1002:                AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
1003:                if (glyphTransform != null) {
1004:                    at.concatenate(glyphTransform);
1005:                }
1006:
1007:                /* Applying translation to actual visual bounds */
1008:                at.preConcatenate(AffineTransform.getTranslateInstance(x0, y0));
1009:                gp.transform(at);
1010:                return gp;
1011:            }
1012:
1013:            /**
1014:             * Returns the Font parameter of this GlyphVector
1015:             */
1016:            @Override
1017:            public Font getFont() {
1018:                return this.font;
1019:            }
1020:
1021:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.