⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fstextconstructor.java

📁 利用opensource的开源jar实现生成flash文件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            char currentChar = (char) characterCode;

            if (font.canDisplay(currentChar)) 
            {
                GlyphVector glyphVector = font.createGlyphVector(fontContext,
                    new char[] { currentChar });
                Rectangle2D bounds = glyphVector.getGlyphOutline(0).getBounds2D();
    
                x = Math.min(bounds.getX(), x);
                y = Math.min(bounds.getY(), y);
    
                w = Math.max(bounds.getWidth(), w);
                h = Math.max(bounds.getHeight(), h);
    
                glyphIndex++;
            }
            characterCode++;
        }
        return new Rectangle2D.Double(x, y, w, h);
    }
    /*
     * Convert the outline of the glyph into a Flash shape.
     *
     * Values returned are expressed in pixels.
     */
    private FSShape convertShape(Shape glyph)
    {
        PathIterator pathIter = glyph.getPathIterator(null);
        FSShapeConstructor path = new FSShapeConstructor();
        
        double[] coords = new double[6];

        int xOrigin = 0;
        int yOrigin = 0;

        int currentX = 0;
        int currentY = 0;

        while (!pathIter.isDone())
        {
            int segmentType = pathIter.currentSegment(coords);

            int p1 = (int) (coords[0]);
            int p2 = (int) (coords[1]);
            int p3 = (int) (coords[2]);
            int p4 = (int) (coords[3]);
            int p5 = (int) (coords[4]);
            int p6 = (int) (coords[5]);

            switch (segmentType)
            {
                case PathIterator.SEG_MOVETO:
                    path.closePath();
                    path.move(p1, p2);
                    break;
                case PathIterator.SEG_LINETO:
                    path.line(p1, p2);
                    break;
                case PathIterator.SEG_QUADTO:
                    path.curve(p1, p2, p3, p4);
                    break;
                case PathIterator.SEG_CUBICTO:
                    path.curve(p1, p2, p3, p4, p5, p6);
                    break;
                case PathIterator.SEG_CLOSE:
                    path.closePath();
                    break;
            }
            pathIter.next();
        }
                
        if (path.objects.size() > 0)
        {
            FSShapeStyle style = (FSShapeStyle)path.objects.get(0);
            style.setLineStyle(0);
            style.setAltFillStyle(1);
        }
        return path.shape();
    }
    /*
     Generate the bounding rectangle for the text. 
     */
    private FSBounds boundsForText(int[] glyphIndices, int[] advances, int fontSize)
    {
        float scaleEMSquare = fontSize / 1024.0f;

        int minX = 0;
        int maxX = 0;
        int minY = 0;
        int maxY = 0;
        boolean any = false;
        
        int advance = 0;

        for (int i = 0; i < glyphIndices.length; i++)
        {
           ArrayList array = null;

      /* Patch added as there are null Glyphs decoded from the font. */
      if (glyphTable[orderTable[glyphIndices[i]]] == null)
          array = glyphTable[missingGlyph].shape.getObjects();
      else
          array = glyphTable[orderTable[glyphIndices[i]]].shape.getObjects();
      /* end of patch */

            int x = advance;
            int y = 0;

            for (Iterator j = array.iterator(); j.hasNext();)
            {
                FSTransformObject currentObject = (FSTransformObject) j.next();

                if (currentObject instanceof FSShapeStyle)
                {
                    FSShapeStyle style = (FSShapeStyle) currentObject;

                    x = advance + style.getMoveX();
                    y = style.getMoveY();
                }
                else if (currentObject instanceof FSLine)
                {
                    FSLine line = (FSLine) currentObject;

                    x += line.getX();
                    y += line.getY();
                }
                else if (currentObject instanceof FSCurve)
                {
                    FSCurve curve = (FSCurve) currentObject;

                    x += (curve.getControlX() + curve.getAnchorX());
                    y += (curve.getControlY() + curve.getAnchorY());
                }
                
                if (any) {
                    minX = Math.min(minX, x);
                    maxX = Math.max(maxX, x);
                    minY = Math.min(minY, y);
                    maxY = Math.max(maxY, y);
                } else {
                    minX = maxX = x;
                    minY = maxY = y;
                    any = true;
                }
            }
            advance += advances[i] / scaleEMSquare;
        }

        minX = (int) (minX * scaleEMSquare);
        maxX = (int) (maxX * scaleEMSquare);
        minY = (int) (minY * scaleEMSquare) + scaleBaseline(scaleEMSquare);
        maxY = (int) (maxY * scaleEMSquare) + scaleBaseline(scaleEMSquare);
        return new FSBounds(minX, minY, maxX, maxY);
    }
    /*
     Generate and array of FSCharacter objects from the glyph codes and advances.
     */
    private ArrayList charactersForGlyphs(int[] codes, int[] advances)
    {
        ArrayList characters = new ArrayList(codes.length);

        for (int i = 0; i < codes.length; i++)
            characters.add(new FSCharacter(codes[i], advances[i]));

        return characters;
    }
    /*
     Indicates whether or not this FSTextConstructor can display a specified Unicode character. 
     This method returns true if the character can be displayed, false if not.
     */
    private boolean canDisplay(char c)
    {
        boolean canDisplay = false;

        if (c < characterTable.length && characterTable[c] != 0)
           canDisplay = true;

        return canDisplay;
    }
    /*
     Return an array of indexes into the array of glyphs that represent each of the characters 
     in the string.
     */
    private int[] glyphIndicesForString(String aString)
    {
        int[] glyphCodes = new int[aString.length()];
        
        for (int i = 0; i < aString.length(); i++)
        {
            char character = aString.charAt(i);
            int glyphIndex = characterTable[character];
            int index = 0;
            
            for (index=0; index<65536; index++)
            {
                if (orderTable[index] == glyphIndex)
                    break;
                else if (orderTable[index] == -1)
                {
                    orderTable[index] = (short)glyphIndex;
                    break;
                }
            }
            glyphCodes[i] = index;
        }
        return glyphCodes;
    }
    /*
     Return an array of advances for the glyphs that represent each of the characters in the string
     */
    private int[] advancesForGlyphIndices(int[] glyphCodes, float scaleFactor)
    {
        int[] glyphAdvances = new int[glyphCodes.length];

        for (int i=0; i<glyphCodes.length; i++)
        {
            int index = orderTable[glyphCodes[i]];
            
            glyphAdvances[i] = (int) (glyphTable[index].advance * scaleFactor);
        }

        return glyphAdvances;
    }
    /*
     Return a new baseline scaled according to the new font size.
     */
    private int scaleBaseline(float scaleFactor)
    {
        int newBaseline = (int) (baseline * scaleFactor);
        newBaseline += (20 - (newBaseline % 20));

        return newBaseline;
    }
    private byte[] dataFromFile(String filename) throws FileNotFoundException, IOException
    {
        File aFile = new File(filename);
        FileInputStream imageContents = null;
        
        byte[] bytes = new byte[(int)aFile.length()];
        
        imageContents = new FileInputStream(aFile);            
        imageContents.read(bytes);
        imageContents.close();

        return bytes;
    }
    private void decodeOpenTypeFont(String fontName) throws IOException, DataFormatException
    {
        FSCoder coder = new FSCoder(FSCoder.BIG_ENDIAN, dataFromFile(fontName));
        
        float version = coder.readFixedBits(32, 16);

        int tableCount = coder.readWord(2, false);
        int searchRange = coder.readWord(2, false);
        int entrySelector = coder.readWord(2, false);
        int rangeShift = coder.readWord(2, false);
        
        int os_2Offset = 0;
        int headOffset = 0;
        int hheaOffset = 0;
        int maxpOffset = 0;
        int locaOffset = 0;
        int cmapOffset = 0;
        int glyfOffset = 0;
        int hmtxOffset = 0;
        int nameOffset = 0;
        
        int os_2Length = 0;
        int headLength = 0;
        int hheaLength = 0;
        int maxpLength = 0;
        int locaLength = 0;
        int cmapLength = 0;
        int hmtxLength = 0;
        int nameLength = 0;
        int glyfLength = 0;

        int chunkType = 0;
        int checksum = 0;
        int offset = 0;
        int length = 0;
        
        for (int i=0; i<tableCount; i++) 
        {
            chunkType = coder.readWord(4, false);
            checksum = coder.readWord(4, false);
            offset = coder.readWord(4, false) << 3;
            length = coder.readWord(4, false);
            
            /* 
             * Chunks are encoded in ascending alphabetical order so
             * the location of the tables is mapped before they are 
             * decoded since the glyphs come before the loca or maxp
             * table which identify how many glyphs are encoded.
             */
            switch (chunkType)
            {
                case OS_2: os_2Offset = offset; os_2Length = length; break;
                case CMAP: cmapOffset = offset; cmapLength = length; break;
                case GLYF: glyfOffset = offset; glyfLength = length; break;
                case HEAD: headOffset = offset; headLength = length; break;
                case HHEA: hheaOffset = offset; hheaLength = length; break;
                case HMTX: hmtxOffset = offset; hmtxLength = length; break;
                case LOCA: locaOffset = offset; locaLength = length; break;
                case MAXP: maxpOffset = offset; maxpLength = length; break;
                case NAME: nameOffset = offset; nameLength = length; break;
                default: break;
            }
        }
        
        int bytesRead = 0;

        if (maxpOffset != 0) { coder.setPointer(maxpOffset); decodeMAXP(coder); bytesRead = (coder.getPointer() - maxpOffset) >> 3; }
        if (os_2Offset != 0) { coder.setPointer(os_2Offset); decodeOS_2(coder); bytesRead = (coder.getPointer() - os_2Offset) >> 3; }
        if (headOffset != 0) { coder.setPointer(headOffset); decodeHEAD(coder); bytesRead = (coder.getPointer() - headOffset) >> 3; }
        if (hheaOffset != 0) { coder.setPointer(hheaOffset); decodeHHEA(coder); bytesRead = (coder.getPointer() - hheaOffset) >> 3; }
        if (nameOffset != 0) { coder.setPointer(nameOffset); decodeNAME(coder); bytesRead = (coder.getPointer() - nameOffset) >> 3; }
        
        glyphTable = new FSGlyph[numberOfGlyphs];
        
        // Decode glyphs first so objects will be created.
        if (locaOffset != 0) { coder.setPointer(locaOffset); decodeGlyphs(coder, glyfOffset); bytesRead = (coder.getPointer() - locaOffset) >> 3; }
        if (hmtxOffset != 0) { coder.setPointer(hmtxOffset); decodeHMTX(coder); bytesRead = (coder.getPointer() - hmtxOffset) >> 3; }
        if (cmapOffset != 0) { coder.setPointer(cmapOffset); decodeCMAP(coder); bytesRead = (coder.getPointer() - cmapOffset) >> 3; }

        orderTable[0] = characterTable[(short)' '];
        
        for (int i=0; i<characterTable.length; i++)
        {
            if (characterTable[i] >= glyphTable.length)
                characterTable[i] = (short)missingGlyph;
        }
        /*
         * Change the space character so no shape is drawn.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -