float doJustification()

in modules/awt/src/main/java/common/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java [602:789]


        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
            int lastPriority =
                    jInfos[jInfos.length-1] == null ?
                    -1 : jInfos[jInfos.length-1].priority;

            // Get the highest priority
            int highestPriority = 0;
            for (; highestPriority<jInfos.length; highestPriority++) {
                if (jInfos[highestPriority] != null) {
                    break;
                }
            }

            if (highestPriority == jInfos.length) {
                return 0;
            }

            TextRunBreaker.JustificationInfo firstInfo = jInfos[highestPriority];
            TextRunBreaker.JustificationInfo lastInfo =
                    lastPriority > 0 ? jInfos[lastPriority] : null;

            boolean haveFirst = info.start <= firstInfo.firstIdx;
            boolean haveLast = info.end >= (firstInfo.lastIdx + 1);

            // Here we suppose that GLYPHS are ordered LEFT TO RIGHT
            int firstGlyph = haveFirst ?
                    getChar2Glyph()[firstInfo.firstIdx - info.start] :
                    getChar2Glyph()[0];

            int lastGlyph = haveLast ?
                    getChar2Glyph()[firstInfo.lastIdx - info.start] :
                    getChar2Glyph()[info.length - 1];
            if (haveLast) {
                lastGlyph--;
            }

            TextRunBreaker.JustificationInfo currInfo;
            float glyphOffset = 0;
            float positionIncrement = 0;
            float sideIncrement = 0;

            if (haveFirst) {  // Don't add padding before first char
                GlyphJustificationInfo gji = getGlyphJustificationInfos()[firstGlyph];
                currInfo = jInfos[gji.growPriority];
                if (currInfo != null) {
                    if (currInfo.useLimits) {
                        if (currInfo.absorb) {
                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
                        } else if (
                                lastInfo != null &&
                                lastInfo.priority == currInfo.priority
                        ) {
                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
                        }
                        glyphOffset +=
                                firstInfo.grow ?
                                gji.growRightLimit :
                                -gji.shrinkRightLimit;
                    } else {
                        glyphOffset += gji.weight * currInfo.gapPerUnit;
                    }
                }

                firstGlyph++;
            }

            if (firstInfo.grow) {
                for (int i=firstGlyph; i<=lastGlyph; i++) {
                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
                    currInfo = jInfos[gji.growPriority];
                    if (currInfo == null) {
                        // We still have to increment glyph position
                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
                        getGlyphVector().setGlyphPosition(i, glyphPos);

                        continue;
                    }

                    if (currInfo.useLimits) {
                        glyphOffset += gji.growLeftLimit;
                        if (currInfo.absorb) {
                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
                            glyphOffset += sideIncrement;
                            positionIncrement = glyphOffset;
                            glyphOffset += sideIncrement;
                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
                            glyphOffset += sideIncrement;
                            positionIncrement = glyphOffset;
                            glyphOffset += sideIncrement;
                        } else {
                            positionIncrement = glyphOffset;
                        }
                        glyphOffset += gji.growRightLimit;
                    } else {
                        sideIncrement = gji.weight * currInfo.gapPerUnit;
                        glyphOffset += sideIncrement;
                        positionIncrement = glyphOffset;
                        glyphOffset += sideIncrement;
                    }

                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
                    getGlyphVector().setGlyphPosition(i, glyphPos);
                }
            } else {
                for (int i=firstGlyph; i<=lastGlyph; i++) {
                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
                    currInfo = jInfos[gji.shrinkPriority];
                    if (currInfo == null) {
                        // We still have to increment glyph position
                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
                        getGlyphVector().setGlyphPosition(i, glyphPos);

                        continue;
                    }

                    if (currInfo.useLimits) {
                        glyphOffset -= gji.shrinkLeftLimit;
                        if (currInfo.absorb) {
                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
                            glyphOffset += sideIncrement;
                            positionIncrement = glyphOffset;
                            glyphOffset += sideIncrement;
                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
                            glyphOffset += sideIncrement;
                            positionIncrement = glyphOffset;
                            glyphOffset += sideIncrement;
                        } else {
                            positionIncrement = glyphOffset;
                        }
                        glyphOffset -= gji.shrinkRightLimit;
                    } else {
                        sideIncrement =  gji.weight * currInfo.gapPerUnit;
                        glyphOffset += sideIncrement;
                        positionIncrement = glyphOffset;
                        glyphOffset += sideIncrement;
                    }

                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
                    getGlyphVector().setGlyphPosition(i, glyphPos);
                }
            }


            if (haveLast) {   // Don't add padding after last char
                lastGlyph++;

                GlyphJustificationInfo gji = getGlyphJustificationInfos()[lastGlyph];
                currInfo = jInfos[gji.growPriority];

                if (currInfo != null) {
                    if (currInfo.useLimits) {
                        glyphOffset += firstInfo.grow ? gji.growLeftLimit : -gji.shrinkLeftLimit;
                        if (currInfo.absorb) {
                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
                        }
                    } else {
                        glyphOffset += gji.weight * currInfo.gapPerUnit;
                    }
                }

                // Ajust positions of all glyphs after last glyph
                for (int i=lastGlyph; i<getGlyphVector().getNumGlyphs()+1; i++) {
                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
                    glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
                    getGlyphVector().setGlyphPosition(i, glyphPos);
                }
            } else { // Update position after last glyph in glyph vector -
                // to get correct advance for it
                Point2D glyphPos = getGlyphVector().getGlyphPosition(lastGlyph+1);
                glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
                getGlyphVector().setGlyphPosition(lastGlyph+1, glyphPos);
            }

            gjis = null; // We don't need justification infos any more
            // Also we have to reset cached bounds and metrics
            this.visualBounds = null;
            this.logicalBounds = null;

            return glyphOffset; // How much our segment grown or shrunk
        }