]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
add small-caps support.
authoreschaeffer <eschaeffer@unknown>
Tue, 23 Jan 2001 16:01:48 +0000 (16:01 +0000)
committereschaeffer <eschaeffer@unknown>
Tue, 23 Jan 2001 16:01:48 +0000 (16:01 +0000)
PR:
Obtained from:
Submitted by:
Reviewed by:

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193977 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/fo/FOText.java
src/org/apache/fop/fo/flow/Block.java
src/org/apache/fop/layout/BlockArea.java
src/org/apache/fop/layout/FontState.java

index 19210c03e383ed57462730ec60056b71f5e81f78..debc06e1479b7c744bf5de0587eb150537940da8 100644 (file)
@@ -1,35 +1,35 @@
 /*-- $Id$ --
 
  ============================================================================
-                   The Apache Software License, Version 1.1
+                                                                        The Apache Software License, Version 1.1
  ============================================================================
 
-    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+               Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
 
  1. Redistributions of  source code must  retain the above copyright  notice,
-    this list of conditions and the following disclaimer.
+               this list of conditions and the following disclaimer.
 
  2. Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
+               this list of conditions and the following disclaimer in the documentation
+               and/or other materials provided with the distribution.
 
  3. The end-user documentation included with the redistribution, if any, must
-    include  the following  acknowledgment:  "This product includes  software
-    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
-    Alternately, this  acknowledgment may  appear in the software itself,  if
-    and wherever such third-party acknowledgments normally appear.
+               include  the following  acknowledgment:  "This product includes  software
+               developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+               Alternately, this  acknowledgment may  appear in the software itself,  if
+               and wherever such third-party acknowledgments normally appear.
 
  4. The names "FOP" and  "Apache Software Foundation"  must not be used to
-    endorse  or promote  products derived  from this  software without  prior
-    written permission. For written permission, please contact
-    apache@apache.org.
+               endorse  or promote  products derived  from this  software without  prior
+               written permission. For written permission, please contact
+               apache@apache.org.
 
  5. Products  derived from this software may not  be called "Apache", nor may
-    "Apache" appear  in their name,  without prior written permission  of the
-    Apache Software Foundation.
+               "Apache" appear  in their name,  without prior written permission  of the
+               Apache Software Foundation.
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -65,92 +65,95 @@ import org.apache.fop.apps.FOPException;
  */
 public class FOText extends FONode {
 
-    protected char[] ca;
-    protected int start;
-    protected int length;
-
-    FontState fs;
-    float red;
-    float green;
-    float blue;
-    int wrapOption;
-    int whiteSpaceCollapse;
-
-    // Textdecoration
-    protected boolean underlined = false;
-    protected boolean overlined = false;
-    protected boolean lineThrough = false;
-
-
-    public FOText(char[] chars, int s, int e, FObj parent) {
-        super(parent);
-        this.start = 0;
-        this.ca = new char[e - s];
-        for (int i = s; i < e; i++)
-            this.ca[i - s] = chars[i];
-        this.length = e - s;
-    }
-
-    public void setUnderlined(boolean ul) {
-        this.underlined = ul;
-    }
-
-    public boolean willCreateArea()
-    {
-        this.whiteSpaceCollapse = this.parent.properties.get(
-                                    "white-space-collapse").getEnum();
-        if(this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE && length > 0) {
-            return true;
-        }
-        for (int i = start; i < start + length; i++) {
-            char ch = ca[i];
-            if (!((ch == ' ') || (ch == '\n') || (ch == '\r') ||
-                    (ch == '\t'))) { // whitespace
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public Status layout(Area area) throws FOPException {
-        if (!(area instanceof BlockArea)) {
-            MessageHandler.errorln("WARNING: text outside block area" +
-                                   new String(ca, start, length));
-            return new Status(Status.OK);
-        }
-        if (this.marker == START) {
-            String fontFamily =
-              this.parent.properties.get("font-family").getString();
-            String fontStyle =
-              this.parent.properties.get("font-style").getString();
-            String fontWeight =
-              this.parent.properties.get("font-weight").getString();
-            int fontSize = this.parent.properties.get(
-                             "font-size").getLength().mvalue();
-
-            this.fs = new FontState(area.getFontInfo(), fontFamily,
-                                    fontStyle, fontWeight, fontSize);
-
-            ColorType c =
-              this.parent.properties.get("color").getColorType();
-            this.red = c.red();
-            this.green = c.green();
-            this.blue = c.blue();
-
-            this.wrapOption =
-              this.parent.properties.get("wrap-option").getEnum();
-            this.whiteSpaceCollapse = this.parent.properties.get(
-                                        "white-space-collapse").getEnum();
-
-            this.marker = this.start;
-        }
-        int orig_start = this.marker;
-        this.marker = ((BlockArea) area).addText(fs, red, green, blue,
-                      wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca,
-                      this.marker, length, underlined);
-        if (this.marker == -1) {
-
-                       
+               protected char[] ca;
+               protected int start;
+               protected int length;
+
+               FontState fs;
+               float red;
+               float green;
+               float blue;
+               int wrapOption;
+               int whiteSpaceCollapse;
+
+               // Textdecoration
+               protected boolean underlined = false;
+               protected boolean overlined = false;
+               protected boolean lineThrough = false;
+
+
+               public FOText(char[] chars, int s, int e, FObj parent) {
+                               super(parent);
+                               this.start = 0;
+                               this.ca = new char[e - s];
+                               for (int i = s; i < e; i++)
+                                               this.ca[i - s] = chars[i];
+                               this.length = e - s;
+               }
+
+               public void setUnderlined(boolean ul) {
+                               this.underlined = ul;
+               }
+
+               public boolean willCreateArea()
+               {
+                               this.whiteSpaceCollapse = this.parent.properties.get(
+                                                                                                                                               "white-space-collapse").getEnum();
+                               if(this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE && length > 0) {
+                                               return true;
+                               }
+                               for (int i = start; i < start + length; i++) {
+                                               char ch = ca[i];
+                                               if (!((ch == ' ') || (ch == '\n') || (ch == '\r') ||
+                                                                               (ch == '\t'))) { // whitespace
+                                                               return true;
+                                               }
+                               }
+                               return false;
+               }
+
+               public Status layout(Area area) throws FOPException {
+                               if (!(area instanceof BlockArea)) {
+                                               MessageHandler.errorln("WARNING: text outside block area" +
+                                                                                                                                        new String(ca, start, length));
+                                               return new Status(Status.OK);
+                               }
+                               if (this.marker == START) {
+                                               String fontFamily =
+                                                       this.parent.properties.get("font-family").getString();
+                                               String fontStyle =
+                                                       this.parent.properties.get("font-style").getString();
+                                               String fontWeight =
+                                                       this.parent.properties.get("font-weight").getString();
+                                               int fontSize = this.parent.properties.get(
+                                                                                                                "font-size").getLength().mvalue();
+                                               // font-variant support
+                                               // added by Eric SCHAEFFER
+                                               int fontVariant = this.parent.properties.get("font-variant").getEnum();
+
+                                               this.fs = new FontState(area.getFontInfo(), fontFamily,
+                                                                                                                                               fontStyle, fontWeight, fontSize, fontVariant);
+
+                                               ColorType c =
+                                                       this.parent.properties.get("color").getColorType();
+                                               this.red = c.red();
+                                               this.green = c.green();
+                                               this.blue = c.blue();
+
+                                               this.wrapOption =
+                                                       this.parent.properties.get("wrap-option").getEnum();
+                                               this.whiteSpaceCollapse = this.parent.properties.get(
+                                                                                                                                                               "white-space-collapse").getEnum();
+
+                                               this.marker = this.start;
+                               }
+                               int orig_start = this.marker;
+                               this.marker = ((BlockArea) area).addText(fs, red, green, blue,
+                                                                                       wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca,
+                                                                                       this.marker, length, underlined);
+                               if (this.marker == -1) {
+
+
                                // commented out by Hani Elabed, 11/28/2000
                                // if this object has been laid out
                                // successfully, leave it alone....
@@ -161,11 +164,11 @@ public class FOText extends FONode {
                                // see LineArea.addText()
 
                        //this.marker = 0;
-            return new Status(Status.OK);
-        } else if (this.marker != orig_start) {
-            return new Status(Status.AREA_FULL_SOME);
-        } else {
-            return new Status(Status.AREA_FULL_NONE);
-        }
-    }
+                                               return new Status(Status.OK);
+                               } else if (this.marker != orig_start) {
+                                               return new Status(Status.AREA_FULL_SOME);
+                               } else {
+                                               return new Status(Status.AREA_FULL_NONE);
+                               }
+               }
 }
index b4c10d10929e62a48d542fb2cf9198ab31e4cc28..f5f5f04171cdab7bb03f12902b6dec1b56468e46 100644 (file)
@@ -1,35 +1,35 @@
 /*-- $Id$ --
 
  ============================================================================
-                   The Apache Software License, Version 1.1
+                                                                        The Apache Software License, Version 1.1
  ============================================================================
 
-    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+               Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
 
  1. Redistributions of  source code must  retain the above copyright  notice,
-    this list of conditions and the following disclaimer.
+               this list of conditions and the following disclaimer.
 
  2. Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
+               this list of conditions and the following disclaimer in the documentation
+               and/or other materials provided with the distribution.
 
  3. The end-user documentation included with the redistribution, if any, must
-    include  the following  acknowledgment:  "This product includes  software
-    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
-    Alternately, this  acknowledgment may  appear in the software itself,  if
-    and wherever such third-party acknowledgments normally appear.
+               include  the following  acknowledgment:  "This product includes  software
+               developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+               Alternately, this  acknowledgment may  appear in the software itself,  if
+               and wherever such third-party acknowledgments normally appear.
 
  4. The names "FOP" and  "Apache Software Foundation"  must not be used to
-    endorse  or promote  products derived  from this  software without  prior
-    written permission. For written permission, please contact
-    apache@apache.org.
+               endorse  or promote  products derived  from this  software without  prior
+               written permission. For written permission, please contact
+               apache@apache.org.
 
  5. Products  derived from this software may not  be called "Apache", nor may
-    "Apache" appear  in their name,  without prior written permission  of the
-    Apache Software Foundation.
+               "Apache" appear  in their name,  without prior written permission  of the
+               Apache Software Foundation.
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -61,402 +61,407 @@ import org.apache.fop.apps.FOPException;
 
 public class Block extends FObjMixed {
 
-    public static class Maker extends FObj.Maker {
-        public FObj make(FObj parent,
-                         PropertyList propertyList) throws FOPException {
-            return new Block(parent, propertyList);
-        }
-    }
-
-    public static FObj.Maker maker() {
-        return new Block.Maker();
-    }
-
-    FontState fs;
-    int align;
-    int alignLast;
-    int breakBefore;
-    int breakAfter;
-    int lineHeight;
-    int startIndent;
-    int endIndent;
-    int spaceBefore;
-    int spaceAfter;
-    int textIndent;
-    int keepWithNext;
-    ColorType backgroundColor;
-    int paddingTop;
-    int paddingBottom;
-    int paddingLeft;
-    int paddingRight;
-    int blockWidows;
-    int blockOrphans;
-
-    String id;
-
-    ColorType borderTopColor;
-    int borderTopWidth;
-    int borderTopStyle;
-    ColorType borderBottomColor;
-    int borderBottomWidth;
-    int borderBottomStyle;
-    ColorType borderLeftColor;
-    int borderLeftWidth;
-    int borderLeftStyle;
-    ColorType borderRightColor;
-    int borderRightWidth;
-    int borderRightStyle;
-
-    int hyphenate;
-    char hyphenationChar;
-    int hyphenationPushCharacterCount;
-    int hyphenationRemainCharacterCount;
-    String language;
-    String country;
+               public static class Maker extends FObj.Maker {
+                               public FObj make(FObj parent,
+                                                                                                PropertyList propertyList) throws FOPException {
+                                               return new Block(parent, propertyList);
+                               }
+               }
+
+               public static FObj.Maker maker() {
+                               return new Block.Maker();
+               }
+
+               FontState fs;
+               int align;
+               int alignLast;
+               int breakBefore;
+               int breakAfter;
+               int lineHeight;
+               int startIndent;
+               int endIndent;
+               int spaceBefore;
+               int spaceAfter;
+               int textIndent;
+               int keepWithNext;
+               ColorType backgroundColor;
+               int paddingTop;
+               int paddingBottom;
+               int paddingLeft;
+               int paddingRight;
+               int blockWidows;
+               int blockOrphans;
+
+               String id;
+
+               ColorType borderTopColor;
+               int borderTopWidth;
+               int borderTopStyle;
+               ColorType borderBottomColor;
+               int borderBottomWidth;
+               int borderBottomStyle;
+               ColorType borderLeftColor;
+               int borderLeftWidth;
+               int borderLeftStyle;
+               ColorType borderRightColor;
+               int borderRightWidth;
+               int borderRightStyle;
+
+               int hyphenate;
+               char hyphenationChar;
+               int hyphenationPushCharacterCount;
+               int hyphenationRemainCharacterCount;
+               String language;
+               String country;
        int span;
-       
-    BlockArea blockArea;
-
-    // this may be helpful on other FOs too
-    boolean anythingLaidOut = false;
-
-    public Block(FObj parent, PropertyList propertyList) {
-        super(parent, propertyList);
-        this.name = "fo:block";
-        this.span = this.properties.get("span").getEnum();
-    }
-
-    public Status layout(Area area) throws FOPException {
-        // MessageHandler.error(" b:LAY[" + marker + "] ");
-
-
-        if (this.marker == BREAK_AFTER) {
-            return new Status(Status.OK);
-        }
-
-        if (this.marker == START) {
-            String fontFamily =
-              this.properties.get("font-family").getString();
-            String fontStyle =
-              this.properties.get("font-style").getString();
-            String fontWeight =
-              this.properties.get("font-weight").getString();
-            int fontSize =
-              this.properties.get("font-size").getLength().mvalue();
-
-            this.fs = new FontState(area.getFontInfo(), fontFamily,
-                                    fontStyle, fontWeight, fontSize);
-            this.align = this.properties.get("text-align").getEnum();
-            this.alignLast =
-              this.properties.get("text-align-last").getEnum();
-            this.breakBefore =
-              this.properties.get("break-before").getEnum();
-            this.breakAfter = this.properties.get("break-after").getEnum();
-            this.lineHeight = this.properties.get(
-                                "line-height").getLength().mvalue();
-            this.startIndent = this.properties.get(
-                                 "start-indent").getLength().mvalue();
-            this.endIndent = this.properties.get(
-                               "end-indent").getLength().mvalue();
-            this.spaceBefore = this.properties.get(
-                                 "space-before.optimum").getLength().mvalue();
-            this.spaceAfter = this.properties.get(
-                                "space-after.optimum").getLength().mvalue();
-            this.textIndent = this.properties.get(
-                                "text-indent").getLength().mvalue();
-            this.keepWithNext =
-              this.properties.get("keep-with-next").getEnum();
-            this.backgroundColor = this.properties.get(
-                                     "background-color").getColorType();
-            this.paddingTop =
-              this.properties.get("padding").getLength().mvalue();
-
-            this.paddingLeft = this.paddingTop;
-            this.paddingRight = this.paddingTop;
-            this.paddingBottom = this.paddingTop;
-            if (this.paddingTop == 0) {
-                this.paddingTop = this.properties.get(
-                                    "padding-top").getLength().mvalue();
-                this.paddingLeft = this.properties.get(
-                                     "padding-left").getLength().mvalue();
-                this.paddingBottom = this.properties.get(
-                                       "padding-bottom").getLength().mvalue();
-                this.paddingRight = this.properties.get(
-                                      "padding-right").getLength().mvalue();
-            }
-            this.borderTopColor =
-              this.properties.get("border-color").getColorType();
-            this.borderBottomColor = this.borderTopColor;
-            this.borderLeftColor = this.borderTopColor;
-            this.borderRightColor = this.borderTopColor;
-            if (this.borderTopColor == null) {
-                this.borderTopColor = this.properties.get(
-                                        "border-top-color").getColorType();
-                this.borderBottomColor = this.properties.get(
-                                           "border-bottom-color").getColorType();
-                this.borderLeftColor = this.properties.get(
-                                         "border-left-color").getColorType();
-                this.borderRightColor = this.properties.get(
-                                          "border-right-color").getColorType();
-            }
-            this.borderTopWidth = this.properties.get(
-                                    "border-width").getLength().mvalue();
-            this.borderBottomWidth = this.borderTopWidth;
-            this.borderLeftWidth = this.borderTopWidth;
-            this.borderRightWidth = this.borderTopWidth;
-            if (this.borderTopWidth == 0) {
-                this.borderTopWidth = this.properties.get(
-                                        "border-top-width").getLength().mvalue();
-                this.borderBottomWidth = this.properties.get(
-                                           "border-bottom-width").getLength().mvalue();
-                this.borderLeftWidth = this.properties.get(
-                                         "border-left-width").getLength().mvalue();
-                this.borderRightWidth = this.properties.get(
-                                          "border-right-width").getLength().mvalue();
-            }
-            this.borderTopStyle =
-              this.properties.get("border-style").getEnum();
-            this.borderBottomStyle = this.borderTopStyle;
-            this.borderLeftStyle = this.borderTopStyle;
-            this.borderRightStyle = this.borderTopStyle;
-            if (this.borderTopStyle == 0) {
-                this.borderTopStyle =
-                  this.properties.get("border-top-style").getEnum();
-                this.borderBottomStyle = this.properties.get(
-                                           "border-bottom-style").getEnum();
-                this.borderLeftStyle = this.properties.get(
-                                         "border-left-style").getEnum();
-                this.borderRightStyle = this.properties.get(
-                                          "border-right-style").getEnum();
-            }
-            this.blockWidows =
-              this.properties.get("widows").getNumber().intValue();
-            this.blockOrphans =
-              this.properties.get("orphans").getNumber().intValue();
-
-            this.hyphenate = this.properties.get("hyphenate").getEnum();
-            this.hyphenationChar = this.properties.get("hyphenation-character").getCharacter();
-            this.hyphenationPushCharacterCount = this.properties.get(
-                                                   "hyphenation-push-character-count").getNumber().
-                                                 intValue();
-            this.hyphenationRemainCharacterCount = this.properties.get(
-                                                     "hyphenation-remain-character-count").getNumber().
-                                                   intValue();
-            this.language = this.properties.get("language").getString();
-            this.country = this.properties.get("country").getString();
-
-            this.id = this.properties.get("id").getString();
-
-            if (area instanceof BlockArea) {
-                area.end();
-            }
-            if (this.isInLabel) {
-                startIndent += bodyIndent;
-                endIndent += (area.getAllocationWidth() -
-                              distanceBetweenStarts - startIndent) +
-                             labelSeparation;
-            } else if (this.isInListBody) {
-                startIndent += bodyIndent + distanceBetweenStarts;
-            }
-
-            if(area.getIDReferences() != null)
-                area.getIDReferences().createID(id);
-
-            this.marker = 0;
-
-            if (breakBefore == BreakBefore.PAGE) {
-                return new Status(Status.FORCE_PAGE_BREAK);
-            }
-
-            if (breakBefore == BreakBefore.ODD_PAGE) {
-                return new Status(Status.FORCE_PAGE_BREAK_ODD);
-            }
-
-            if (breakBefore == BreakBefore.EVEN_PAGE) {
-                return new Status(Status.FORCE_PAGE_BREAK_EVEN);
-            }
-
-            if (breakBefore == BreakBefore.COLUMN) {
-                return new Status(Status.FORCE_COLUMN_BREAK);
-            }
-
-            int numChildren = this.children.size();
-            for (int i = 0; i < numChildren; i++) {
-                FONode fo = (FONode) children.elementAt(i);
-                if (fo instanceof FOText) {
-                    if (((FOText) fo).willCreateArea()) {
-                        fo.setWidows(blockWidows);
-                        break;
-                    } else {
-                        children.removeElementAt(i);
-                        numChildren = this.children.size();
-                        i--;
-                    }
-                } else {
-                    fo.setWidows(blockWidows);
-                    break;
-                }
-            }
-
-            for (int i = numChildren - 1; i >= 0; i--) {
-                FONode fo = (FONode) children.elementAt(i);
-                if (fo instanceof FOText) {
-                    if (((FOText) fo).willCreateArea()) {
-                        fo.setOrphans(blockOrphans);
-                        break;
-                    }
-                } else {
-                    fo.setOrphans(blockOrphans);
-                    break;
-                }
-            }
-        }
-
-        if ((spaceBefore != 0) && (this.marker == 0)) {
-            area.addDisplaySpace(spaceBefore);
-        }
-
-        if (anythingLaidOut) {
-            this.textIndent = 0;
-        }
-
-        if (marker == 0 && area.getIDReferences() != null) {
-            area.getIDReferences().configureID(id, area);
-        }
-
-        int spaceLeft = area.spaceLeft();
-        this.blockArea = new BlockArea(fs, area.getAllocationWidth(),
-                                       area.spaceLeft(), startIndent, endIndent, textIndent,
-                                       align, alignLast, lineHeight);
-        blockArea.setPage(area.getPage());
-        blockArea.setBackgroundColor(backgroundColor);
-        blockArea.setPadding(paddingTop, paddingLeft, paddingBottom,
-                             paddingRight);
-        blockArea.setBorderStyle(borderTopStyle, borderLeftStyle,
-                                 borderBottomStyle, borderRightStyle);
-        blockArea.setBorderWidth(borderTopWidth, borderLeftWidth,
-                                 borderBottomWidth, borderRightWidth);
-        blockArea.setBorderColor(borderTopColor, borderLeftColor,
-                                 borderBottomColor, borderRightColor);
-        blockArea.setHyphenation(language, country, hyphenate,
-                                 hyphenationChar, hyphenationPushCharacterCount,
-                                 hyphenationRemainCharacterCount);
-        blockArea.start();
-
-        blockArea.setAbsoluteHeight(area.getAbsoluteHeight());
-        blockArea.setIDReferences(area.getIDReferences());
-
-        blockArea.setTableCellXOffset(area.getTableCellXOffset());
-
-        int numChildren = this.children.size();
-        for (int i = this.marker; i < numChildren; i++) {
-            FONode fo = (FONode) children.elementAt(i);
-            if (this.isInListBody) {
-                fo.setIsInListBody();
-                fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
-                fo.setBodyIndent(this.bodyIndent);
-            }
-            Status status;
-            if ((status = fo.layout(blockArea)).isIncomplete()) {
-                this.marker = i;
-                // this block was modified by
-                // Hani Elabed 11/27/2000
-                //if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE))
-                //{
-                //    status = new Status(Status.AREA_FULL_SOME);
-                //}
-
-                // new block to replace the one above
-                // Hani Elabed 11/27/2000
-                if (status.getCode() == Status.AREA_FULL_NONE) {
-                    // something has already been laid out
-                    if ((i != 0)) {
-                        status = new Status(Status.AREA_FULL_SOME);
-                        area.addChild(blockArea);
-                        area.setMaxHeight(area.getMaxHeight() - spaceLeft + blockArea.getMaxHeight());
-                        area.increaseHeight(blockArea.getHeight());
-                        area.setAbsoluteHeight(
-                          blockArea.getAbsoluteHeight());
-                        anythingLaidOut = true;
-
-                        return status;
-                    } else // i == 0 nothing was laid out..
-                    {
-                        anythingLaidOut = false;
-                        return status;
-                    }
-                }
-
-                //blockArea.end();
-                area.addChild(blockArea);
-                area.setMaxHeight(area.getMaxHeight() - spaceLeft + blockArea.getMaxHeight());
-                area.increaseHeight(blockArea.getHeight());
-                area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
-                anythingLaidOut = true;
-                return status;
-            }
-            anythingLaidOut = true;
-        }
-
-        blockArea.end();
-        area.addChild(blockArea);
-
-        /* should this be combined into above? */
-        area.increaseHeight(blockArea.getHeight());
-
-        area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
-
-        if (spaceAfter != 0) {
-            area.addDisplaySpace(spaceAfter);
-        }
-
-        if (area instanceof BlockArea) {
-            area.start();
-        }
-
-        if (breakAfter == BreakAfter.PAGE) {
-            this.marker = BREAK_AFTER;
-            return new Status(Status.FORCE_PAGE_BREAK);
-        }
-
-        if (breakAfter == BreakAfter.ODD_PAGE) {
-            this.marker = BREAK_AFTER;
-            return new Status(Status.FORCE_PAGE_BREAK_ODD);
-        }
-
-        if (breakAfter == BreakAfter.EVEN_PAGE) {
-            this.marker = BREAK_AFTER;
-            return new Status(Status.FORCE_PAGE_BREAK_EVEN);
-        }
-
-        if (breakAfter == BreakAfter.COLUMN) {
-            this.marker = BREAK_AFTER;
-            return new Status(Status.FORCE_COLUMN_BREAK);
-        }
-
-        if (keepWithNext != 0) {
-            return new Status(Status.KEEP_WITH_NEXT);
-        }
-
-        //MessageHandler.error(" b:OK" + marker + " ");
-        return new Status(Status.OK);
-    }
-
-    public int getAreaHeight() {
-        return blockArea.getHeight();
-    }
-
-
-  /**
-   * Return the content width of the boxes generated by this FO.
-   */
-  public int getContentWidth() {
-    if (blockArea != null)
-      return blockArea.getContentWidth(); //getAllocationWidth()??
-    else return 0;  // not laid out yet
-  }
-  
-  public int getSpan() {
-         return this.span;
-  }
+
+               BlockArea blockArea;
+
+               // this may be helpful on other FOs too
+               boolean anythingLaidOut = false;
+
+               public Block(FObj parent, PropertyList propertyList) {
+                               super(parent, propertyList);
+                               this.name = "fo:block";
+                               this.span = this.properties.get("span").getEnum();
+               }
+
+               public Status layout(Area area) throws FOPException {
+                               // MessageHandler.error(" b:LAY[" + marker + "] ");
+
+
+                               if (this.marker == BREAK_AFTER) {
+                                               return new Status(Status.OK);
+                               }
+
+                               if (this.marker == START) {
+                                               String fontFamily =
+                                                       this.properties.get("font-family").getString();
+                                               String fontStyle =
+                                                       this.properties.get("font-style").getString();
+                                               String fontWeight =
+                                                       this.properties.get("font-weight").getString();
+                                               int fontSize =
+                                                       this.properties.get("font-size").getLength().mvalue();
+
+                                               // font-variant support
+                                               // added by Eric SCHAEFFER
+                                               int fontVariant =
+                                                       this.properties.get("font-variant").getEnum();
+
+                                               this.fs = new FontState(area.getFontInfo(), fontFamily,
+                                                                                                                                               fontStyle, fontWeight, fontSize, fontVariant);
+                                               this.align = this.properties.get("text-align").getEnum();
+                                               this.alignLast =
+                                                       this.properties.get("text-align-last").getEnum();
+                                               this.breakBefore =
+                                                       this.properties.get("break-before").getEnum();
+                                               this.breakAfter = this.properties.get("break-after").getEnum();
+                                               this.lineHeight = this.properties.get(
+                                                                                                                               "line-height").getLength().mvalue();
+                                               this.startIndent = this.properties.get(
+                                                                                                                                "start-indent").getLength().mvalue();
+                                               this.endIndent = this.properties.get(
+                                                                                                                        "end-indent").getLength().mvalue();
+                                               this.spaceBefore = this.properties.get(
+                                                                                                                                "space-before.optimum").getLength().mvalue();
+                                               this.spaceAfter = this.properties.get(
+                                                                                                                               "space-after.optimum").getLength().mvalue();
+                                               this.textIndent = this.properties.get(
+                                                                                                                               "text-indent").getLength().mvalue();
+                                               this.keepWithNext =
+                                                       this.properties.get("keep-with-next").getEnum();
+                                               this.backgroundColor = this.properties.get(
+                                                                                                                                                "background-color").getColorType();
+                                               this.paddingTop =
+                                                       this.properties.get("padding").getLength().mvalue();
+
+                                               this.paddingLeft = this.paddingTop;
+                                               this.paddingRight = this.paddingTop;
+                                               this.paddingBottom = this.paddingTop;
+                                               if (this.paddingTop == 0) {
+                                                               this.paddingTop = this.properties.get(
+                                                                                                                                               "padding-top").getLength().mvalue();
+                                                               this.paddingLeft = this.properties.get(
+                                                                                                                                                "padding-left").getLength().mvalue();
+                                                               this.paddingBottom = this.properties.get(
+                                                                                                                                                        "padding-bottom").getLength().mvalue();
+                                                               this.paddingRight = this.properties.get(
+                                                                                                                                                       "padding-right").getLength().mvalue();
+                                               }
+                                               this.borderTopColor =
+                                                       this.properties.get("border-color").getColorType();
+                                               this.borderBottomColor = this.borderTopColor;
+                                               this.borderLeftColor = this.borderTopColor;
+                                               this.borderRightColor = this.borderTopColor;
+                                               if (this.borderTopColor == null) {
+                                                               this.borderTopColor = this.properties.get(
+                                                                                                                                                               "border-top-color").getColorType();
+                                                               this.borderBottomColor = this.properties.get(
+                                                                                                                                                                        "border-bottom-color").getColorType();
+                                                               this.borderLeftColor = this.properties.get(
+                                                                                                                                                                "border-left-color").getColorType();
+                                                               this.borderRightColor = this.properties.get(
+                                                                                                                                                                       "border-right-color").getColorType();
+                                               }
+                                               this.borderTopWidth = this.properties.get(
+                                                                                                                                               "border-width").getLength().mvalue();
+                                               this.borderBottomWidth = this.borderTopWidth;
+                                               this.borderLeftWidth = this.borderTopWidth;
+                                               this.borderRightWidth = this.borderTopWidth;
+                                               if (this.borderTopWidth == 0) {
+                                                               this.borderTopWidth = this.properties.get(
+                                                                                                                                                               "border-top-width").getLength().mvalue();
+                                                               this.borderBottomWidth = this.properties.get(
+                                                                                                                                                                        "border-bottom-width").getLength().mvalue();
+                                                               this.borderLeftWidth = this.properties.get(
+                                                                                                                                                                "border-left-width").getLength().mvalue();
+                                                               this.borderRightWidth = this.properties.get(
+                                                                                                                                                                       "border-right-width").getLength().mvalue();
+                                               }
+                                               this.borderTopStyle =
+                                                       this.properties.get("border-style").getEnum();
+                                               this.borderBottomStyle = this.borderTopStyle;
+                                               this.borderLeftStyle = this.borderTopStyle;
+                                               this.borderRightStyle = this.borderTopStyle;
+                                               if (this.borderTopStyle == 0) {
+                                                               this.borderTopStyle =
+                                                                       this.properties.get("border-top-style").getEnum();
+                                                               this.borderBottomStyle = this.properties.get(
+                                                                                                                                                                        "border-bottom-style").getEnum();
+                                                               this.borderLeftStyle = this.properties.get(
+                                                                                                                                                                "border-left-style").getEnum();
+                                                               this.borderRightStyle = this.properties.get(
+                                                                                                                                                                       "border-right-style").getEnum();
+                                               }
+                                               this.blockWidows =
+                                                       this.properties.get("widows").getNumber().intValue();
+                                               this.blockOrphans =
+                                                       this.properties.get("orphans").getNumber().intValue();
+
+                                               this.hyphenate = this.properties.get("hyphenate").getEnum();
+                                               this.hyphenationChar = this.properties.get("hyphenation-character").getCharacter();
+                                               this.hyphenationPushCharacterCount = this.properties.get(
+                                                                                                                                                                                                        "hyphenation-push-character-count").getNumber().
+                                                                                                                                                                                                intValue();
+                                               this.hyphenationRemainCharacterCount = this.properties.get(
+                                                                                                                                                                                                                "hyphenation-remain-character-count").getNumber().
+                                                                                                                                                                                                        intValue();
+                                               this.language = this.properties.get("language").getString();
+                                               this.country = this.properties.get("country").getString();
+
+                                               this.id = this.properties.get("id").getString();
+
+                                               if (area instanceof BlockArea) {
+                                                               area.end();
+                                               }
+                                               if (this.isInLabel) {
+                                                               startIndent += bodyIndent;
+                                                               endIndent += (area.getAllocationWidth() -
+                                                                                                                       distanceBetweenStarts - startIndent) +
+                                                                                                                labelSeparation;
+                                               } else if (this.isInListBody) {
+                                                               startIndent += bodyIndent + distanceBetweenStarts;
+                                               }
+
+                                               if(area.getIDReferences() != null)
+                                                               area.getIDReferences().createID(id);
+
+                                               this.marker = 0;
+
+                                               if (breakBefore == BreakBefore.PAGE) {
+                                                               return new Status(Status.FORCE_PAGE_BREAK);
+                                               }
+
+                                               if (breakBefore == BreakBefore.ODD_PAGE) {
+                                                               return new Status(Status.FORCE_PAGE_BREAK_ODD);
+                                               }
+
+                                               if (breakBefore == BreakBefore.EVEN_PAGE) {
+                                                               return new Status(Status.FORCE_PAGE_BREAK_EVEN);
+                                               }
+
+                                               if (breakBefore == BreakBefore.COLUMN) {
+                                                               return new Status(Status.FORCE_COLUMN_BREAK);
+                                               }
+
+                                               int numChildren = this.children.size();
+                                               for (int i = 0; i < numChildren; i++) {
+                                                               FONode fo = (FONode) children.elementAt(i);
+                                                               if (fo instanceof FOText) {
+                                                                               if (((FOText) fo).willCreateArea()) {
+                                                                                               fo.setWidows(blockWidows);
+                                                                                               break;
+                                                                               } else {
+                                                                                               children.removeElementAt(i);
+                                                                                               numChildren = this.children.size();
+                                                                                               i--;
+                                                                               }
+                                                               } else {
+                                                                               fo.setWidows(blockWidows);
+                                                                               break;
+                                                               }
+                                               }
+
+                                               for (int i = numChildren - 1; i >= 0; i--) {
+                                                               FONode fo = (FONode) children.elementAt(i);
+                                                               if (fo instanceof FOText) {
+                                                                               if (((FOText) fo).willCreateArea()) {
+                                                                                               fo.setOrphans(blockOrphans);
+                                                                                               break;
+                                                                               }
+                                                               } else {
+                                                                               fo.setOrphans(blockOrphans);
+                                                                               break;
+                                                               }
+                                               }
+                               }
+
+                               if ((spaceBefore != 0) && (this.marker == 0)) {
+                                               area.addDisplaySpace(spaceBefore);
+                               }
+
+                               if (anythingLaidOut) {
+                                               this.textIndent = 0;
+                               }
+
+                               if (marker == 0 && area.getIDReferences() != null) {
+                                               area.getIDReferences().configureID(id, area);
+                               }
+
+                               int spaceLeft = area.spaceLeft();
+                               this.blockArea = new BlockArea(fs, area.getAllocationWidth(),
+                                                                                                                                                        area.spaceLeft(), startIndent, endIndent, textIndent,
+                                                                                                                                                        align, alignLast, lineHeight);
+                               blockArea.setPage(area.getPage());
+                               blockArea.setBackgroundColor(backgroundColor);
+                               blockArea.setPadding(paddingTop, paddingLeft, paddingBottom,
+                                                                                                                paddingRight);
+                               blockArea.setBorderStyle(borderTopStyle, borderLeftStyle,
+                                                                                                                                borderBottomStyle, borderRightStyle);
+                               blockArea.setBorderWidth(borderTopWidth, borderLeftWidth,
+                                                                                                                                borderBottomWidth, borderRightWidth);
+                               blockArea.setBorderColor(borderTopColor, borderLeftColor,
+                                                                                                                                borderBottomColor, borderRightColor);
+                               blockArea.setHyphenation(language, country, hyphenate,
+                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
+                                                                                                                                hyphenationRemainCharacterCount);
+                               blockArea.start();
+
+                               blockArea.setAbsoluteHeight(area.getAbsoluteHeight());
+                               blockArea.setIDReferences(area.getIDReferences());
+
+                               blockArea.setTableCellXOffset(area.getTableCellXOffset());
+
+                               int numChildren = this.children.size();
+                               for (int i = this.marker; i < numChildren; i++) {
+                                               FONode fo = (FONode) children.elementAt(i);
+                                               if (this.isInListBody) {
+                                                               fo.setIsInListBody();
+                                                               fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+                                                               fo.setBodyIndent(this.bodyIndent);
+                                               }
+                                               Status status;
+                                               if ((status = fo.layout(blockArea)).isIncomplete()) {
+                                                               this.marker = i;
+                                                               // this block was modified by
+                                                               // Hani Elabed 11/27/2000
+                                                               //if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE))
+                                                               //{
+                                                               //    status = new Status(Status.AREA_FULL_SOME);
+                                                               //}
+
+                                                               // new block to replace the one above
+                                                               // Hani Elabed 11/27/2000
+                                                               if (status.getCode() == Status.AREA_FULL_NONE) {
+                                                                               // something has already been laid out
+                                                                               if ((i != 0)) {
+                                                                                               status = new Status(Status.AREA_FULL_SOME);
+                                                                                               area.addChild(blockArea);
+                                                                                               area.setMaxHeight(area.getMaxHeight() - spaceLeft + blockArea.getMaxHeight());
+                                                                                               area.increaseHeight(blockArea.getHeight());
+                                                                                               area.setAbsoluteHeight(
+                                                                                                       blockArea.getAbsoluteHeight());
+                                                                                               anythingLaidOut = true;
+
+                                                                                               return status;
+                                                                               } else // i == 0 nothing was laid out..
+                                                                               {
+                                                                                               anythingLaidOut = false;
+                                                                                               return status;
+                                                                               }
+                                                               }
+
+                                                               //blockArea.end();
+                                                               area.addChild(blockArea);
+                                                               area.setMaxHeight(area.getMaxHeight() - spaceLeft + blockArea.getMaxHeight());
+                                                               area.increaseHeight(blockArea.getHeight());
+                                                               area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
+                                                               anythingLaidOut = true;
+                                                               return status;
+                                               }
+                                               anythingLaidOut = true;
+                               }
+
+                               blockArea.end();
+                               area.addChild(blockArea);
+
+                               /* should this be combined into above? */
+                               area.increaseHeight(blockArea.getHeight());
+
+                               area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
+
+                               if (spaceAfter != 0) {
+                                               area.addDisplaySpace(spaceAfter);
+                               }
+
+                               if (area instanceof BlockArea) {
+                                               area.start();
+                               }
+
+                               if (breakAfter == BreakAfter.PAGE) {
+                                               this.marker = BREAK_AFTER;
+                                               return new Status(Status.FORCE_PAGE_BREAK);
+                               }
+
+                               if (breakAfter == BreakAfter.ODD_PAGE) {
+                                               this.marker = BREAK_AFTER;
+                                               return new Status(Status.FORCE_PAGE_BREAK_ODD);
+                               }
+
+                               if (breakAfter == BreakAfter.EVEN_PAGE) {
+                                               this.marker = BREAK_AFTER;
+                                               return new Status(Status.FORCE_PAGE_BREAK_EVEN);
+                               }
+
+                               if (breakAfter == BreakAfter.COLUMN) {
+                                               this.marker = BREAK_AFTER;
+                                               return new Status(Status.FORCE_COLUMN_BREAK);
+                               }
+
+                               if (keepWithNext != 0) {
+                                               return new Status(Status.KEEP_WITH_NEXT);
+                               }
+
+                               //MessageHandler.error(" b:OK" + marker + " ");
+                               return new Status(Status.OK);
+               }
+
+               public int getAreaHeight() {
+                               return blockArea.getHeight();
+               }
+
+
+       /**
+        * Return the content width of the boxes generated by this FO.
+        */
+       public int getContentWidth() {
+               if (blockArea != null)
+                       return blockArea.getContentWidth(); //getAllocationWidth()??
+               else return 0;  // not laid out yet
+       }
+
+       public int getSpan() {
+               return this.span;
+       }
 }
index 20e877f9be7acba2c9091350b33757186f6acf75..e114cee5268e6e0754adf331958aca0497057a69 100644 (file)
@@ -1,35 +1,35 @@
 /*-- $Id$ --
 
  ============================================================================
-                   The Apache Software License, Version 1.1
+                                                                        The Apache Software License, Version 1.1
  ============================================================================
 
-    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+               Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
 
  1. Redistributions of  source code must  retain the above copyright  notice,
-    this list of conditions and the following disclaimer.
+               this list of conditions and the following disclaimer.
 
  2. Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
+               this list of conditions and the following disclaimer in the documentation
+               and/or other materials provided with the distribution.
 
  3. The end-user documentation included with the redistribution, if any, must
-    include  the following  acknowledgment:  "This product includes  software
-    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
-    Alternately, this  acknowledgment may  appear in the software itself,  if
-    and wherever such third-party acknowledgments normally appear.
+               include  the following  acknowledgment:  "This product includes  software
+               developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+               Alternately, this  acknowledgment may  appear in the software itself,  if
+               and wherever such third-party acknowledgments normally appear.
 
  4. The names "Fop" and  "Apache Software Foundation"  must not be used to
-    endorse  or promote  products derived  from this  software without  prior
-    written permission. For written permission, please contact
-    apache@apache.org.
+               endorse  or promote  products derived  from this  software without  prior
+               written permission. For written permission, please contact
+               apache@apache.org.
 
  5. Products  derived from this software may not  be called "Apache", nor may
-    "Apache" appear  in their name,  without prior written permission  of the
-    Apache Software Foundation.
+               "Apache" appear  in their name,  without prior written permission  of the
+               Apache Software Foundation.
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -55,6 +55,7 @@ import org.apache.fop.render.Renderer;
 import org.apache.fop.fo.flow.*;
 import org.apache.fop.fo.*;
 import org.apache.fop.apps.*;
+import org.apache.fop.fo.properties.*;
 
 // Java
 import java.util.Vector;
@@ -63,332 +64,392 @@ import org.apache.fop.messaging.MessageHandler;
 
 public class BlockArea extends Area {
 
-    /* relative to area container */
-    protected int startIndent;
-    protected int endIndent;
-
-    /* first line startIndent modifier */
-    protected int textIndent;
-
-    protected int lineHeight;
-
-    protected int halfLeading;
-
-
-    /* text-align of all but the last line */
-    protected int align;
-
-    /* text-align of the last line */
-    protected int alignLastLine;
-
-    protected LineArea currentLineArea;
-    protected LinkSet currentLinkSet;
-
-    /* have any line areas been used? */
-    protected boolean hasLines = false;
-
-    /*hyphenation*/
-    protected int hyphenate;
-    protected char hyphenationChar;
-    protected int hyphenationPushCharacterCount;
-    protected int hyphenationRemainCharacterCount;
-    protected String language;
-    protected String country;
-
-    protected Vector pendingFootnotes = null;
-
-    public BlockArea(FontState fontState, int allocationWidth,
-                     int maxHeight, int startIndent, int endIndent,
-                     int textIndent, int align, int alignLastLine, int lineHeight) {
-        super(fontState, allocationWidth, maxHeight);
-
-        this.startIndent = startIndent;
-        this.endIndent = endIndent;
-        this.textIndent = textIndent;
-        this.contentRectangleWidth =
-          allocationWidth - startIndent - endIndent;
-        this.align = align;
-        this.alignLastLine = alignLastLine;
-        this.lineHeight = lineHeight;
-
-        if (fontState != null)
-            this.halfLeading = (lineHeight - fontState.getFontSize()) / 2;
-    }
-
-    public void render(Renderer renderer) {
-        renderer.renderBlockArea(this);
-    }
-
-    public void addLineArea(LineArea la) {
-        if (!la.isEmpty()) {
-            this.addDisplaySpace(this.halfLeading);
-            int size = la.getHeight();
-            this.addChild(la);
-            this.increaseHeight(size);
-            this.addDisplaySpace(this.halfLeading);
-        }
-        // add pending footnotes
-        if(pendingFootnotes != null) {
-            for(Enumeration e = pendingFootnotes.elements(); e.hasMoreElements(); ) {
-                FootnoteBody fb = (FootnoteBody)e.nextElement();
-                Page page = getPage();
-                if(!Footnote.layoutFootnote(page, fb, this)) {
-                    page.addPendingFootnote(fb);
-                }
-            }
-            pendingFootnotes = null;
-        }
-    }
-
-    public int addPageNumberCitation(FontState fontState, float red,
-                                     float green, float blue, int wrapOption, LinkSet ls,
-                                     int whiteSpaceCollapse, String refid) {
-
-        this.currentLineArea.changeFont(fontState);
-        this.currentLineArea.changeColor(red, green, blue);
-        this.currentLineArea.changeWrapOption(wrapOption);
-        this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
-        this.currentLineArea.changeHyphenation(language, country, hyphenate,
-                                 hyphenationChar, hyphenationPushCharacterCount,
-                                 hyphenationRemainCharacterCount);
-
-
-        if (ls != null) {
-            this.currentLinkSet = ls;
-            ls.setYOffset(currentHeight);
-        }
-
-        this.currentLineArea.addPageNumberCitation(refid, ls);
-        this.hasLines = true;
-
-        return -1;
-
-    }
-
-    public int addText(FontState fontState, float red, float green,
-                       float blue, int wrapOption, LinkSet ls,
-                       int whiteSpaceCollapse, char data[], int start, int end,
-                       boolean ul) {
-        int ts, te;
-        char[] ca;
-
-        ts = start;
-        te = end;
-        ca = data;
-
-        if (currentHeight + currentLineArea.getHeight() > maxHeight) {
-            return start;
-        }
-
-        this.currentLineArea.changeFont(fontState);
-        this.currentLineArea.changeColor(red, green, blue);
-        this.currentLineArea.changeWrapOption(wrapOption);
-        this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
-        this.currentLineArea.changeHyphenation(language, country, hyphenate,
-                                 hyphenationChar, hyphenationPushCharacterCount,
-                                 hyphenationRemainCharacterCount);
-        if (ls != null) {
-            this.currentLinkSet = ls;
-            ls.setYOffset(currentHeight);
-        }
-
-        ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
-        this.hasLines = true;
-
-        while (ts != -1) {
-            this.currentLineArea.align(this.align);
-            this.addLineArea(this.currentLineArea);
-
-            this.currentLineArea =
-              new LineArea(fontState, lineHeight, halfLeading,
-                           allocationWidth, startIndent, endIndent,
-                           currentLineArea);
-            if (currentHeight + currentLineArea.getHeight() >
-                    this.maxHeight) {
-                return ts;
-            }
-            this.currentLineArea.changeFont(fontState);
-            this.currentLineArea.changeColor(red, green, blue);
-            this.currentLineArea.changeWrapOption(wrapOption);
-            this.currentLineArea.changeWhiteSpaceCollapse(
-              whiteSpaceCollapse);
-            this.currentLineArea.changeHyphenation(language, country, hyphenate,
-                                     hyphenationChar, hyphenationPushCharacterCount,
-                                     hyphenationRemainCharacterCount);
-            if (ls != null) {
-                ls.setYOffset(currentHeight);
-            }
-
-            ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
-        }
-        return -1;
-    }
-
-
-    /**
-      * adds a leader to current line area of containing block area
-      * the actual leader area is created in the line area
-      *
-      * @return int +1 for success and -1 for none
-      */
-    public int addLeader(FontState fontState, float red, float green,
-                         float blue, int leaderPattern, int leaderLengthMinimum,
-                         int leaderLengthOptimum, int leaderLengthMaximum,
-                         int ruleThickness, int ruleStyle, int leaderPatternWidth,
-                         int leaderAlignment) {
-
-        //this should start a new page
-        if (currentHeight + currentLineArea.getHeight() > maxHeight) {
-            return -1;
-        }
-
-        this.currentLineArea.changeFont(fontState);
-        this.currentLineArea.changeColor(red, green, blue);
-
-        //check whether leader fits into the (rest of the) line
-        //using length.optimum to determine where to break the line as defined 
-        // in the xsl:fo spec: "User agents may choose to use the value of 'leader-length.optimum'
-        // to determine where to break the line" (7.20.4)
-        //if leader is longer then create a new LineArea and put leader there
-        if (leaderLengthOptimum <= (this.getContentWidth() -
-                                    this.currentLineArea.finalWidth -
-                                    this.currentLineArea.pendingWidth)) {
-            this.currentLineArea.addLeader(leaderPattern,
-                                           leaderLengthMinimum, leaderLengthOptimum,
-                                           leaderLengthMaximum, ruleStyle, ruleThickness,
-                                           leaderPatternWidth, leaderAlignment);
-        } else {
-            //finish current line area and put it into children vector
-            this.currentLineArea.align(this.align);
-            this.addLineArea(this.currentLineArea);
-
-            //create new line area
-            this.currentLineArea =
-              new LineArea(fontState, lineHeight, halfLeading,
-                           allocationWidth, startIndent, endIndent,
-                           currentLineArea);
-            this.currentLineArea.changeFont(fontState);
-            this.currentLineArea.changeColor(red, green, blue);
-
-            if (currentHeight + currentLineArea.getHeight() >
-                    this.maxHeight) {
-                return -1;
-            }
-
-            //check whether leader fits into LineArea at all, otherwise
-            //clip it (should honor the clip option of containing area)
-            if (leaderLengthMinimum <=
-                      this.currentLineArea.getContentWidth()) {
-                this.currentLineArea.addLeader(leaderPattern,
-                                               leaderLengthMinimum, leaderLengthOptimum,
-                                               leaderLengthMaximum, ruleStyle, ruleThickness,
-                                               leaderPatternWidth, leaderAlignment);
-            } else {
-                MessageHandler.errorln("Leader doesn't fit into line, it will be clipped to fit.");
-                this.currentLineArea.addLeader(leaderPattern,
-                                               this.currentLineArea.getContentWidth() -
-                                               this.currentLineArea.finalWidth -
-                                               this.currentLineArea.pendingWidth,
-                                               leaderLengthOptimum, leaderLengthMaximum,
-                                               ruleStyle, ruleThickness, leaderPatternWidth,
-                                               leaderAlignment);
-            }
-        }
-        this.hasLines = true;
-        return 1;
-    }
-
-    public void addCharacter(FontState fontState, float red, float green,
-                       float blue, int wrapOption, LinkSet ls,
-                       int whiteSpaceCollapse, char data, boolean ul) {
-
-        this.currentLineArea.changeFont(fontState);
-        this.currentLineArea.changeColor(red, green, blue);
-        this.currentLineArea.changeWrapOption(wrapOption);
-        this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
-
-        if (ls != null) {
-            this.currentLinkSet = ls;
-            ls.setYOffset(currentHeight);
-        }
-
-        int marker = this.currentLineArea.addCharacter(data, ls, ul);
-        //if character didn't fit into line, open a new one
-        if (marker == org.apache.fop.fo.flow.Character.DOESNOT_FIT) {
-            this.currentLineArea.align(this.align);
-            this.addLineArea(this.currentLineArea);
-
-            this.currentLineArea =
-              new LineArea(fontState, lineHeight, halfLeading,
-                           allocationWidth, startIndent, endIndent,
-                           currentLineArea);
-            this.currentLineArea.changeFont(fontState);
-            this.currentLineArea.changeColor(red, green, blue);
-            this.currentLineArea.changeWrapOption(wrapOption);
-            this.currentLineArea.changeWhiteSpaceCollapse(
-              whiteSpaceCollapse);
-            if (ls != null) {
-                this.currentLinkSet = ls;
-                ls.setYOffset(currentHeight);
-            }
-
-            this.currentLineArea.addCharacter(data, ls, ul);
-        }
-        this.hasLines = true;
-    }
-
-
-    public void end() {
-        if (this.hasLines) {
-            this.currentLineArea.addPending();
-            this.currentLineArea.align(this.alignLastLine);
-            this.addLineArea(this.currentLineArea);
-        }
-    }
-
-    public void start() {
-        currentLineArea = new LineArea(fontState, lineHeight, halfLeading,
-                                       allocationWidth, startIndent + textIndent, endIndent, null);
-    }
-
-    public int getEndIndent() {
-        return endIndent;
-    }
-
-    public int getStartIndent() {
-        return startIndent + paddingLeft + borderWidthLeft;
-    }
-
-    public void setIndents(int startIndent, int endIndent) {
-        this.startIndent = startIndent;
-        this.endIndent = endIndent;
-        this.contentRectangleWidth =
-          allocationWidth - startIndent - endIndent;
-    }
-
-    public int spaceLeft() {
-        return maxHeight - currentHeight;
-    }
-
-    public int getHalfLeading() {
-        return halfLeading;
-    }
-
-    public void setHyphenation(String language, String country, int hyphenate, char hyphenationChar,
-                                 int hyphenationPushCharacterCount,
-                                 int hyphenationRemainCharacterCount) {
-      this.language = language;
-      this.country = country;
-      this.hyphenate =  hyphenate;
-      this.hyphenationChar = hyphenationChar;
-      this.hyphenationPushCharacterCount = hyphenationPushCharacterCount;
-      this.hyphenationRemainCharacterCount = hyphenationRemainCharacterCount;
-    }
-
-    public void addFootnote(FootnoteBody fb) {
-        if(pendingFootnotes == null) {
-            pendingFootnotes = new Vector();
-        }
-        pendingFootnotes.addElement(fb);
-    }
+               /* relative to area container */
+               protected int startIndent;
+               protected int endIndent;
+
+               /* first line startIndent modifier */
+               protected int textIndent;
+
+               protected int lineHeight;
+
+               protected int halfLeading;
+
+
+               /* text-align of all but the last line */
+               protected int align;
+
+               /* text-align of the last line */
+               protected int alignLastLine;
+
+               protected LineArea currentLineArea;
+               protected LinkSet currentLinkSet;
+
+               /* have any line areas been used? */
+               protected boolean hasLines = false;
+
+               /*hyphenation*/
+               protected int hyphenate;
+               protected char hyphenationChar;
+               protected int hyphenationPushCharacterCount;
+               protected int hyphenationRemainCharacterCount;
+               protected String language;
+               protected String country;
+
+               protected Vector pendingFootnotes = null;
+
+               public BlockArea(FontState fontState, int allocationWidth,
+                                                                                int maxHeight, int startIndent, int endIndent,
+                                                                                int textIndent, int align, int alignLastLine, int lineHeight) {
+                               super(fontState, allocationWidth, maxHeight);
+
+                               this.startIndent = startIndent;
+                               this.endIndent = endIndent;
+                               this.textIndent = textIndent;
+                               this.contentRectangleWidth =
+                                       allocationWidth - startIndent - endIndent;
+                               this.align = align;
+                               this.alignLastLine = alignLastLine;
+                               this.lineHeight = lineHeight;
+
+                               if (fontState != null)
+                                               this.halfLeading = (lineHeight - fontState.getFontSize()) / 2;
+               }
+
+               public void render(Renderer renderer) {
+                               renderer.renderBlockArea(this);
+               }
+
+               public void addLineArea(LineArea la) {
+                               if (!la.isEmpty()) {
+                                               this.addDisplaySpace(this.halfLeading);
+                                               int size = la.getHeight();
+                                               this.addChild(la);
+                                               this.increaseHeight(size);
+                                               this.addDisplaySpace(this.halfLeading);
+                               }
+                               // add pending footnotes
+                               if(pendingFootnotes != null) {
+                                               for(Enumeration e = pendingFootnotes.elements(); e.hasMoreElements(); ) {
+                                                               FootnoteBody fb = (FootnoteBody)e.nextElement();
+                                                               Page page = getPage();
+                                                               if(!Footnote.layoutFootnote(page, fb, this)) {
+                                                                               page.addPendingFootnote(fb);
+                                                               }
+                                               }
+                                               pendingFootnotes = null;
+                               }
+               }
+
+               public int addPageNumberCitation(FontState fontState, float red,
+                                                                                                                                                float green, float blue, int wrapOption, LinkSet ls,
+                                                                                                                                                int whiteSpaceCollapse, String refid) {
+
+                               this.currentLineArea.changeFont(fontState);
+                               this.currentLineArea.changeColor(red, green, blue);
+                               this.currentLineArea.changeWrapOption(wrapOption);
+                               this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
+                               this.currentLineArea.changeHyphenation(language, country, hyphenate,
+                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
+                                                                                                                                hyphenationRemainCharacterCount);
+
+
+                               if (ls != null) {
+                                               this.currentLinkSet = ls;
+                                               ls.setYOffset(currentHeight);
+                               }
+
+                               this.currentLineArea.addPageNumberCitation(refid, ls);
+                               this.hasLines = true;
+
+                               return -1;
+
+               }
+
+               // font-variant support : addText is a wrapper for addRealText
+               // added by Eric SCHAEFFER
+               public int addText(FontState fontState, float red, float green,
+                                                                                        float blue, int wrapOption, LinkSet ls,
+                                                                                        int whiteSpaceCollapse, char data[], int start, int end,
+                                                                                        boolean ul) {
+                       if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) {
+                               FontState smallCapsFontState;
+                               try {
+                                       int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d);
+                                       smallCapsFontState = new FontState(
+                                               fontState.getFontInfo(),
+                                               fontState.getFontFamily(),
+                                               fontState.getFontStyle(),
+                                               fontState.getFontWeight(),
+                                               smallCapsFontHeight,
+                                               FontVariant.NORMAL);
+                               } catch (FOPException ex) {
+                                       smallCapsFontState = fontState;
+                                       MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage());
+                               }
+
+                               // parse text for upper/lower case and call addRealText
+                               char c;
+                               boolean isLowerCase;
+                               int caseStart;
+                               FontState fontStateToUse;
+                               for (int i = start; i < end; ) {
+                                       caseStart = i;
+                                       c = data[i];
+                                       isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c));
+                                       while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) {
+                                               if (isLowerCase) {
+                                                       data[i] = java.lang.Character.toUpperCase(c);
+                                               }
+                                               i++;
+                                               if (i == end)
+                                                       break;
+                                               c = data[i];
+                                       }
+                                       if (isLowerCase) {
+                                               fontStateToUse = smallCapsFontState;
+                                       } else {
+                                               fontStateToUse = fontState;
+                                       }
+                                       int index = this.addRealText(fontStateToUse, red, green, blue, wrapOption, ls,
+                                               whiteSpaceCollapse, data, caseStart, i, ul);
+                                       if (index != -1) {
+                                               return index;
+                                       }
+                               }
+
+                               return -1;
+                       }
+
+                       // font-variant normal
+                       return this.addRealText(fontState, red, green, blue, wrapOption, ls,
+                               whiteSpaceCollapse, data, start, end, ul);
+               }
+
+               protected int addRealText(FontState fontState, float red, float green,
+                                                                                        float blue, int wrapOption, LinkSet ls,
+                                                                                        int whiteSpaceCollapse, char data[], int start, int end,
+                                                                                        boolean ul) {
+                               int ts, te;
+                               char[] ca;
+
+                               ts = start;
+                               te = end;
+                               ca = data;
+
+                               if (currentHeight + currentLineArea.getHeight() > maxHeight) {
+                                               return start;
+                               }
+
+                               this.currentLineArea.changeFont(fontState);
+                               this.currentLineArea.changeColor(red, green, blue);
+                               this.currentLineArea.changeWrapOption(wrapOption);
+                               this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
+                               this.currentLineArea.changeHyphenation(language, country, hyphenate,
+                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
+                                                                                                                                hyphenationRemainCharacterCount);
+                               if (ls != null) {
+                                               this.currentLinkSet = ls;
+                                               ls.setYOffset(currentHeight);
+                               }
+
+                               ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
+                               this.hasLines = true;
+
+                               while (ts != -1) {
+                                               this.currentLineArea.align(this.align);
+                                               this.addLineArea(this.currentLineArea);
+
+                                               this.currentLineArea =
+                                                       new LineArea(fontState, lineHeight, halfLeading,
+                                                                                                        allocationWidth, startIndent, endIndent,
+                                                                                                        currentLineArea);
+                                               if (currentHeight + currentLineArea.getHeight() >
+                                                                               this.maxHeight) {
+                                                               return ts;
+                                               }
+                                               this.currentLineArea.changeFont(fontState);
+                                               this.currentLineArea.changeColor(red, green, blue);
+                                               this.currentLineArea.changeWrapOption(wrapOption);
+                                               this.currentLineArea.changeWhiteSpaceCollapse(
+                                                       whiteSpaceCollapse);
+                                               this.currentLineArea.changeHyphenation(language, country, hyphenate,
+                                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
+                                                                                                                                                hyphenationRemainCharacterCount);
+                                               if (ls != null) {
+                                                               ls.setYOffset(currentHeight);
+                                               }
+
+                                               ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
+                               }
+                               return -1;
+               }
+
+
+               /**
+                       * adds a leader to current line area of containing block area
+                       * the actual leader area is created in the line area
+                       *
+                       * @return int +1 for success and -1 for none
+                       */
+               public int addLeader(FontState fontState, float red, float green,
+                                                                                                float blue, int leaderPattern, int leaderLengthMinimum,
+                                                                                                int leaderLengthOptimum, int leaderLengthMaximum,
+                                                                                                int ruleThickness, int ruleStyle, int leaderPatternWidth,
+                                                                                                int leaderAlignment) {
+
+                               //this should start a new page
+                               if (currentHeight + currentLineArea.getHeight() > maxHeight) {
+                                               return -1;
+                               }
+
+                               this.currentLineArea.changeFont(fontState);
+                               this.currentLineArea.changeColor(red, green, blue);
+
+                               //check whether leader fits into the (rest of the) line
+                               //using length.optimum to determine where to break the line as defined
+                               // in the xsl:fo spec: "User agents may choose to use the value of 'leader-length.optimum'
+                               // to determine where to break the line" (7.20.4)
+                               //if leader is longer then create a new LineArea and put leader there
+                               if (leaderLengthOptimum <= (this.getContentWidth() -
+                                                                                                                                               this.currentLineArea.finalWidth -
+                                                                                                                                               this.currentLineArea.pendingWidth)) {
+                                               this.currentLineArea.addLeader(leaderPattern,
+                                                                                                                                                                        leaderLengthMinimum, leaderLengthOptimum,
+                                                                                                                                                                        leaderLengthMaximum, ruleStyle, ruleThickness,
+                                                                                                                                                                        leaderPatternWidth, leaderAlignment);
+                               } else {
+                                               //finish current line area and put it into children vector
+                                               this.currentLineArea.align(this.align);
+                                               this.addLineArea(this.currentLineArea);
+
+                                               //create new line area
+                                               this.currentLineArea =
+                                                       new LineArea(fontState, lineHeight, halfLeading,
+                                                                                                        allocationWidth, startIndent, endIndent,
+                                                                                                        currentLineArea);
+                                               this.currentLineArea.changeFont(fontState);
+                                               this.currentLineArea.changeColor(red, green, blue);
+
+                                               if (currentHeight + currentLineArea.getHeight() >
+                                                                               this.maxHeight) {
+                                                               return -1;
+                                               }
+
+                                               //check whether leader fits into LineArea at all, otherwise
+                                               //clip it (should honor the clip option of containing area)
+                                               if (leaderLengthMinimum <=
+                                                                                       this.currentLineArea.getContentWidth()) {
+                                                               this.currentLineArea.addLeader(leaderPattern,
+                                                                                                                                                                                        leaderLengthMinimum, leaderLengthOptimum,
+                                                                                                                                                                                        leaderLengthMaximum, ruleStyle, ruleThickness,
+                                                                                                                                                                                        leaderPatternWidth, leaderAlignment);
+                                               } else {
+                                                               MessageHandler.errorln("Leader doesn't fit into line, it will be clipped to fit.");
+                                                               this.currentLineArea.addLeader(leaderPattern,
+                                                                                                                                                                                        this.currentLineArea.getContentWidth() -
+                                                                                                                                                                                        this.currentLineArea.finalWidth -
+                                                                                                                                                                                        this.currentLineArea.pendingWidth,
+                                                                                                                                                                                        leaderLengthOptimum, leaderLengthMaximum,
+                                                                                                                                                                                        ruleStyle, ruleThickness, leaderPatternWidth,
+                                                                                                                                                                                        leaderAlignment);
+                                               }
+                               }
+                               this.hasLines = true;
+                               return 1;
+               }
+
+               public void addCharacter(FontState fontState, float red, float green,
+                                                                                        float blue, int wrapOption, LinkSet ls,
+                                                                                        int whiteSpaceCollapse, char data, boolean ul) {
+
+                               this.currentLineArea.changeFont(fontState);
+                               this.currentLineArea.changeColor(red, green, blue);
+                               this.currentLineArea.changeWrapOption(wrapOption);
+                               this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
+
+                               if (ls != null) {
+                                               this.currentLinkSet = ls;
+                                               ls.setYOffset(currentHeight);
+                               }
+
+                               int marker = this.currentLineArea.addCharacter(data, ls, ul);
+                               //if character didn't fit into line, open a new one
+                               if (marker == org.apache.fop.fo.flow.Character.DOESNOT_FIT) {
+                                               this.currentLineArea.align(this.align);
+                                               this.addLineArea(this.currentLineArea);
+
+                                               this.currentLineArea =
+                                                       new LineArea(fontState, lineHeight, halfLeading,
+                                                                                                        allocationWidth, startIndent, endIndent,
+                                                                                                        currentLineArea);
+                                               this.currentLineArea.changeFont(fontState);
+                                               this.currentLineArea.changeColor(red, green, blue);
+                                               this.currentLineArea.changeWrapOption(wrapOption);
+                                               this.currentLineArea.changeWhiteSpaceCollapse(
+                                                       whiteSpaceCollapse);
+                                               if (ls != null) {
+                                                               this.currentLinkSet = ls;
+                                                               ls.setYOffset(currentHeight);
+                                               }
+
+                                               this.currentLineArea.addCharacter(data, ls, ul);
+                               }
+                               this.hasLines = true;
+               }
+
+
+               public void end() {
+                               if (this.hasLines) {
+                                               this.currentLineArea.addPending();
+                                               this.currentLineArea.align(this.alignLastLine);
+                                               this.addLineArea(this.currentLineArea);
+                               }
+               }
+
+               public void start() {
+                               currentLineArea = new LineArea(fontState, lineHeight, halfLeading,
+                                                                                                                                                        allocationWidth, startIndent + textIndent, endIndent, null);
+               }
+
+               public int getEndIndent() {
+                               return endIndent;
+               }
+
+               public int getStartIndent() {
+                               return startIndent + paddingLeft + borderWidthLeft;
+               }
+
+               public void setIndents(int startIndent, int endIndent) {
+                               this.startIndent = startIndent;
+                               this.endIndent = endIndent;
+                               this.contentRectangleWidth =
+                                       allocationWidth - startIndent - endIndent;
+               }
+
+               public int spaceLeft() {
+                               return maxHeight - currentHeight;
+               }
+
+               public int getHalfLeading() {
+                               return halfLeading;
+               }
+
+               public void setHyphenation(String language, String country, int hyphenate, char hyphenationChar,
+                                                                                                                                int hyphenationPushCharacterCount,
+                                                                                                                                int hyphenationRemainCharacterCount) {
+                       this.language = language;
+                       this.country = country;
+                       this.hyphenate =  hyphenate;
+                       this.hyphenationChar = hyphenationChar;
+                       this.hyphenationPushCharacterCount = hyphenationPushCharacterCount;
+                       this.hyphenationRemainCharacterCount = hyphenationRemainCharacterCount;
+               }
+
+               public void addFootnote(FootnoteBody fb) {
+                               if(pendingFootnotes == null) {
+                                               pendingFootnotes = new Vector();
+                               }
+                               pendingFootnotes.addElement(fb);
+               }
 }
index 55508dc705fa76be7ec84b9449a79cb73f513a9e..3794db88a32b04b04f1299c143d43c2a95ddff87 100644 (file)
@@ -1,36 +1,36 @@
-/*-- $Id$ -- 
+/*-- $Id$ --
 
  ============================================================================
-                   The Apache Software License, Version 1.1
+                                                                        The Apache Software License, Version 1.1
  ============================================================================
-    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+               Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
+
  1. Redistributions of  source code must  retain the above copyright  notice,
-    this list of conditions and the following disclaimer.
+               this list of conditions and the following disclaimer.
+
  2. Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
+               this list of conditions and the following disclaimer in the documentation
+               and/or other materials provided with the distribution.
+
  3. The end-user documentation included with the redistribution, if any, must
-    include  the following  acknowledgment:  "This product includes  software
-    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
-    Alternately, this  acknowledgment may  appear in the software itself,  if
-    and wherever such third-party acknowledgments normally appear.
+               include  the following  acknowledgment:  "This product includes  software
+               developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+               Alternately, this  acknowledgment may  appear in the software itself,  if
+               and wherever such third-party acknowledgments normally appear.
+
  4. The names "Fop" and  "Apache Software Foundation"  must not be used to
-    endorse  or promote  products derived  from this  software without  prior
-    written permission. For written permission, please contact
-    apache@apache.org.
+               endorse  or promote  products derived  from this  software without  prior
+               written permission. For written permission, please contact
+               apache@apache.org.
+
  5. Products  derived from this software may not  be called "Apache", nor may
-    "Apache" appear  in their name,  without prior written permission  of the
-    Apache Software Foundation.
+               "Apache" appear  in their name,  without prior written permission  of the
+               Apache Software Foundation.
+
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
  This software  consists of voluntary contributions made  by many individuals
  on  behalf of the Apache Software  Foundation and was  originally created by
- James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache
  Software Foundation, please see <http://www.apache.org/>.
+
  */
 package org.apache.fop.layout;
 
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.properties.FontVariant;
 
 public class FontState {
-       
-    protected FontInfo fontInfo;
-    private String fontName;
-    private int fontSize;
-    private String fontFamily;
-    private String fontStyle;
-    private String fontWeight;
-    private FontMetric metric;
-    
-    public FontState(FontInfo fontInfo, String fontFamily, String fontStyle, String fontWeight, int fontSize) throws FOPException {
+
+               protected FontInfo fontInfo;
+               private String fontName;
+               private int fontSize;
+               private String fontFamily;
+               private String fontStyle;
+               private String fontWeight;
+               private FontMetric metric;
+               private int fontVariant;
+
+               public FontState(FontInfo fontInfo, String fontFamily, String fontStyle, String fontWeight, int fontSize) throws FOPException {
+                       this(fontInfo, fontFamily, fontStyle, fontWeight, fontSize, FontVariant.NORMAL);
+               }
+               public FontState(FontInfo fontInfo, String fontFamily, String fontStyle, String fontWeight, int fontSize, int fontVariant) throws FOPException {
        this.fontInfo = fontInfo;
        this.fontFamily = fontFamily;
        this.fontStyle = fontStyle;
@@ -70,50 +75,55 @@ public class FontState {
        this.fontSize = fontSize;
        this.fontName = fontInfo.fontLookup(fontFamily,fontStyle,fontWeight);
        this.metric = fontInfo.getMetricsFor(fontName);
-    }
+       this.fontVariant = fontVariant;
+               }
 
-    public int getAscender() {
+               public int getAscender() {
        return  metric.getAscender(fontSize) / 1000;
-    }
+               }
 
-    public int getCapHeight() {
+               public int getCapHeight() {
        return metric.getCapHeight(fontSize) / 1000;
-    }
+               }
 
-    public int getDescender() {
+               public int getDescender() {
        return metric.getDescender(fontSize) / 1000;
-    }
+               }
 
-    public String getFontName() {
+               public String getFontName() {
        return this.fontName;
-    }
+               }
 
-    public int getFontSize() {
+               public int getFontSize() {
        return this.fontSize;
-    }
+               }
 
-    public String getFontWeight() {
+               public String getFontWeight() {
        return this.fontWeight;
-    }
+               }
 
-    public String getFontFamily() {
+               public String getFontFamily() {
        return this.fontFamily;
-    }
+               }
 
-    public String getFontStyle() {
+               public String getFontStyle() {
        return this.fontStyle;
-    }
+               }
+
+               public int getFontVariant() {
+       return this.fontVariant;
+               }
 
-    public FontInfo getFontInfo() {
+               public FontInfo getFontInfo() {
        return this.fontInfo;
-    }
+               }
 
-    public int getXHeight() {
+               public int getXHeight() {
        return metric.getXHeight(fontSize) / 1000;
-    }
+               }
 
-    public int width(int charnum) {
+               public int width(int charnum) {
        // returns width of given character number in millipoints
        return (metric.width(charnum, fontSize) / 1000);
-    }
+               }
 }