aboutsummaryrefslogtreecommitdiffstats
pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>jQuery UI Datepicker - Restrict date range</title>
	<link rel="stylesheet" href="../../themes/base/all.css">
	<script src="../../external/jquery/jquery.js"></script>
	<script src="../../ui/core.js"></script>
	<script src="../../ui/widget.js"></script>
	<script src="../../ui/datepicker.js"></script>
	<link rel="stylesheet" href="../demos.css">
	<script>
	$(function() {
		$( "#datepicker" ).datepicker({ minDate: -20, maxDate: "+1M +10D" });
	});
	</script>
</head>
<body>

<p>Date: <input type="text" id="datepicker"></p>

<div class="demo-description">
<p>Restrict the range of selectable dates with the <code>minDate</code> and <code>maxDate</code> options.  Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D').  For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.</p>
</div>
</body>
</html>
n264'>264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
/*
 * Copyright 2005 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.layoutmgr.inline;

import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.datatypes.SimplePercentBaseContext;
import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.Font;

/**
 * The alignment context is carried within a LayoutContext and as
 * part of the Knuth Inline elements to facilitate proper line building.
 * All measurements are in mpt.
 */
public class AlignmentContext implements Constants {

    /** The height or BPD of this context */
    private int areaHeight;
    /** The computed line-height property value applicable */
    private int lineHeight;
    /** The distance in BPD from the top of the box to the alignmentPoint */
    private int alignmentPoint;
    /** The baseline shift value in effect */
    private int baselineShiftValue;
    /** The computed alignment baseline identifier */
    private int alignmentBaselineIdentifier;
    /** The x height */
    private int xHeight;
    private ScaledBaselineTable scaledBaselineTable = null;
    private ScaledBaselineTable actualBaselineTable = null;
    private AlignmentContext parentAlignmentContext = null;
    
    /**
     * Creates a new instance of AlignmentContext 
     * for graphics areas.
     * @param height the total height of the area
     * @param alignmentAdjust the alignment-adjust property
     * @param alignmentBaseline the alignment-baseline property
     * @param baselineShift the baseline-shift property
     * @param dominantBaseline the dominant-baseline property
     * @param parentAlignmentContext the parent alignment context
     */
    public AlignmentContext(int height
                            , Length alignmentAdjust
                            , int alignmentBaseline
                            , Length baselineShift
                            , int dominantBaseline
                            , AlignmentContext parentAlignmentContext) {
        
        this.areaHeight = height;
        this.lineHeight = height;
        this.xHeight = height;
        this.parentAlignmentContext = parentAlignmentContext;
        this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable();
        setAlignmentBaselineIdentifier(alignmentBaseline
                                       , parentAlignmentContext.getDominantBaselineIdentifier());
        setBaselineShift(baselineShift);
        int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier();
        boolean newScaledBaselineTableRequired = false;
        if (baselineShiftValue != 0) {
            newScaledBaselineTableRequired = true;
        }
        switch (dominantBaseline) {
            case EN_AUTO:
                newScaledBaselineTableRequired = baselineShiftValue != 0;
                break;
            case EN_USE_SCRIPT: // TODO
                break;
            case EN_NO_CHANGE:
                break;
            case EN_RESET_SIZE:
                newScaledBaselineTableRequired = true;
                break;
            default:
                newScaledBaselineTableRequired = true;
                dominantBaselineIdentifier = dominantBaseline;
                break;
        }
        actualBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable(
                                                            height, 
                                                            dominantBaselineIdentifier, 
                                                            scaledBaselineTable.getWritingMode());
        if (newScaledBaselineTableRequired) {
            scaledBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable(
                                                            height, 
                                                            dominantBaselineIdentifier, 
                                                            scaledBaselineTable.getWritingMode());
        }
        setAlignmentAdjust(alignmentAdjust);
    }
    
    /**
     * Creates a new instance of AlignmentContext
     * @param font the font
     * @param lineHeight the computed value of the lineHeight property
     * @param alignmentAdjust the alignment-adjust property
     * @param alignmentBaseline the alignment-baseline property
     * @param baselineShift the baseline-shift property
     * @param dominantBaseline the dominant-baseline property
     * @param parentAlignmentContext the parent alignment context
     */
    public AlignmentContext(Font font
                            , int lineHeight
                            , Length alignmentAdjust
                            , int alignmentBaseline
                            , Length baselineShift
                            , int dominantBaseline
                            , AlignmentContext parentAlignmentContext) {
        this.areaHeight = font.getAscender() - font.getDescender();
        this.lineHeight = lineHeight;
        this.parentAlignmentContext = parentAlignmentContext;
        this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable();
        this.xHeight = font.getXHeight();
        setAlignmentBaselineIdentifier(alignmentBaseline
                                       , parentAlignmentContext.getDominantBaselineIdentifier());
        setBaselineShift(baselineShift);
        int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier();
        boolean newScaledBaselineTableRequired = false;
        if (baselineShiftValue != 0) {
            newScaledBaselineTableRequired = true;
        }
        switch (dominantBaseline) {
            case EN_AUTO:
                newScaledBaselineTableRequired = baselineShiftValue != 0;
                break;
            case EN_USE_SCRIPT: // TODO
                break;
            case EN_NO_CHANGE:
                break;
            case EN_RESET_SIZE:
                newScaledBaselineTableRequired = true;
                break;
            default:
                newScaledBaselineTableRequired = true;
                dominantBaselineIdentifier = dominantBaseline;
                break;
        }
        actualBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, 
                                                            dominantBaselineIdentifier, 
                                                            scaledBaselineTable.getWritingMode());
        if (newScaledBaselineTableRequired) {
            scaledBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, 
                                    dominantBaselineIdentifier, 
                                    scaledBaselineTable.getWritingMode());
        }
        setAlignmentAdjust(alignmentAdjust);
    }
    
    /**
     * Creates a new instance of AlignmentContext based simply
     * on the font and the writing mode.
     * @param font the font
     * @param lineHeight the computed value of the lineHeight property
     * @param writingMode the current writing mode
     */
    public AlignmentContext(Font font, int lineHeight, int writingMode) {
        this.areaHeight = font.getAscender() - font.getDescender();
        this.lineHeight = lineHeight;
        this.xHeight = font.getXHeight();
        this.parentAlignmentContext = null;
        this.scaledBaselineTable 
                    = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, writingMode);
        this.actualBaselineTable = scaledBaselineTable;
        this.alignmentBaselineIdentifier = getDominantBaselineIdentifier();
        this.alignmentPoint = font.getAscender();
        this.baselineShiftValue = 0;
    }
    
    /**
     * Returns the alignment point for this context.
     * This is the point on the start edge of the area this context
     * applies to measured from the before edge of the area.
     * @return the default alignment point
     */
    public int getAlignmentPoint() {
        return alignmentPoint;
    }

    /**
     * Returns the current value of baseline shift in effect.
     * @return the baseline shift
     */
    public int getBaselineShiftValue() {
        return baselineShiftValue;
    }

    /**
     * Returns the current alignment baseline identifier
     * @return the alignment baseline identifier
     */
    public int getAlignmentBaselineIdentifier() {
        return alignmentBaselineIdentifier;
    }

    /**
     * Sets the current alignment baseline identifer. For
     * alignment-baseline values of "auto" and "baseline" this
     * method does the conversion into the appropriate computed
     * value assuming script is "auto" and the fo is not fo:character.
     * @param alignmentBaseline the alignment-baseline property
     * @param parentDominantBaselineIdentifier the dominant baseline of the parent fo
     */
    private void setAlignmentBaselineIdentifier(int alignmentBaseline
                                               , int parentDominantBaselineIdentifier) {
        switch (alignmentBaseline) {
            case EN_AUTO: // fall through
            case EN_BASELINE:
                this.alignmentBaselineIdentifier = parentDominantBaselineIdentifier;
                break;
            case EN_BEFORE_EDGE:
            case EN_TEXT_BEFORE_EDGE:
            case EN_CENTRAL:
            case EN_MIDDLE:
            case EN_AFTER_EDGE:
            case EN_TEXT_AFTER_EDGE:
            case EN_IDEOGRAPHIC:
            case EN_ALPHABETIC:
            case EN_HANGING:
            case EN_MATHEMATICAL:
                this.alignmentBaselineIdentifier = alignmentBaseline;
                break;
        }
    }

    /**
     * Sets the current alignment baseline identifer. For
     * alignment-baseline values of "auto" and "baseline" this
     * method does the conversion into the appropriate computed
     * value assuming script is "auto" and the fo is not fo:character.
     * @param alignmentAdjust the alignment-adjust property
     */
    private void setAlignmentAdjust(Length alignmentAdjust) {
        int beforeEdge = actualBaselineTable.getBaseline(EN_BEFORE_EDGE);
        switch (alignmentAdjust.getEnum()) {
            case EN_AUTO:
                alignmentPoint = beforeEdge 
                                    - actualBaselineTable.getBaseline(alignmentBaselineIdentifier);
                break;
            case EN_BASELINE:
                alignmentPoint = beforeEdge;
                break;
            case EN_BEFORE_EDGE:
            case EN_TEXT_BEFORE_EDGE:
            case EN_CENTRAL:
            case EN_MIDDLE:
            case EN_AFTER_EDGE:
            case EN_TEXT_AFTER_EDGE:
            case EN_IDEOGRAPHIC:
            case EN_ALPHABETIC:
            case EN_HANGING:
            case EN_MATHEMATICAL:
                alignmentPoint = beforeEdge 
                                    - actualBaselineTable.getBaseline(alignmentAdjust.getEnum());
                break;
            default:
                alignmentPoint = beforeEdge
                    + alignmentAdjust.getValue(new SimplePercentBaseContext(null
                                                        , LengthBase.ALIGNMENT_ADJUST
                                                        , lineHeight));
                break;
        }
    }

    /**
     * Return the scaled baseline table for this context.
     * @return the scaled baseline table
     */
    public ScaledBaselineTable getScaledBaselineTable() {
        return this.scaledBaselineTable;
    }

    /**
     * Return the dominant baseline identifier.
     * @return the dominant baseline identifier
     */
    public int getDominantBaselineIdentifier() {
        return scaledBaselineTable.getDominantBaselineIdentifier();
    }
    
    /**
     * Return the writing mode.
     * @return the writing mode
     */
    public int getWritingMode() {
        return scaledBaselineTable.getWritingMode();
    }
    
    /**
     * Calculates the baseline shift value based on the baseline-shift
     * property value.
     * @param baselineShift the baseline shift property value
     * @return the computed baseline shift value
     */
    private void setBaselineShift(Length baselineShift) {
        baselineShiftValue = 0;
        ScaledBaselineTable sbt = null;
        switch (baselineShift.getEnum()) {
            case EN_BASELINE: //Nothing to do
                break;
            case EN_SUB:
                baselineShiftValue = Math.round(-(xHeight / 2)
                                + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
                                );
                break;
            case EN_SUPER:
                baselineShiftValue = Math.round(parentAlignmentContext.getXHeight()
                                + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
                                );
                break;
            case 0: // A <length> or <percentage> value
                baselineShiftValue = baselineShift.getValue(
                    new SimplePercentBaseContext(null
                                                , LengthBase.CUSTOM_BASE
                                                , parentAlignmentContext.getLineHeight()));
                break;
        }
    }

    /**
     * Return the parent alignment context.
     * @return the parent alignment context
     */
    public AlignmentContext getParentAlignmentContext() {
        return parentAlignmentContext;
    }

    /**
     * Return the offset between the current dominant baseline and
     * the parent dominant baseline.
     * @return the offset in shift direction
     */
    public int getBaselineOffset() {
        if (parentAlignmentContext == null) {
            return 0;
        }
        return parentAlignmentContext.getScaledBaselineTable()
                                    .getBaseline(alignmentBaselineIdentifier)
                - scaledBaselineTable
                    .deriveScaledBaselineTable(parentAlignmentContext.getDominantBaselineIdentifier())
                    .getBaseline(alignmentBaselineIdentifier)
                - scaledBaselineTable
                    .getBaseline(parentAlignmentContext.getDominantBaselineIdentifier())
                + baselineShiftValue;
    }

    /**
     * Return the offset between the current dominant baseline and
     * the outermost parent dominant baseline.
     * @return the offet in shift direction
     */
    public int getTotalBaselineOffset() {
        int offset = 0;
        if (parentAlignmentContext != null) {
            offset = getBaselineOffset() + parentAlignmentContext.getTotalBaselineOffset();
        }
        return offset;
    }

    /**
     * Return the offset between the alignment baseline and
     * the outermost parent dominant baseline.
     * @return the offset in shift direction
     */
    public int getTotalAlignmentBaselineOffset() {
        return getTotalAlignmentBaselineOffset(alignmentBaselineIdentifier);
    }

    /**
     * Return the offset between the given alignment baseline and
     * the outermost parent dominant baseline.
     * @param alignmentBaselineId the alignment baseline
     * @return the offset
     */
    public int getTotalAlignmentBaselineOffset(int alignmentBaselineId) {
        int offset = baselineShiftValue;
        if (parentAlignmentContext != null) {
            offset = parentAlignmentContext.getTotalBaselineOffset() 
                    + parentAlignmentContext.getScaledBaselineTable()
                        .getBaseline(alignmentBaselineId)
                    + baselineShiftValue;
        } 
        return offset;
    }

    /**
     * Return the offset between the dominant baseline and
     * the given actual baseline
     * @param baselineIdentifier the baseline
     * @return the offset
     */
    public int getActualBaselineOffset(int baselineIdentifier) {
        // This is the offset from the dominant baseline to the alignment baseline
        int offset = getTotalAlignmentBaselineOffset() - getTotalBaselineOffset();
        // Add the offset to the actual baseline we want
        offset += actualBaselineTable.deriveScaledBaselineTable(alignmentBaselineIdentifier)
                    .getBaseline(baselineIdentifier);
        return offset;
    }

    /**
     * Return the offset the outermost parent dominant baseline
     * and the top of this box.
     * @return the offset
     */
    private int getTotalTopOffset() {
        int offset = getTotalAlignmentBaselineOffset() + getAltitude();
        return offset;
    }

    /**
     * Return the total height of the context.
     * @return the height
     */
    public int getHeight() {
        return areaHeight;
    }
    
    /**
     * Return the line height of the context.
     * @return the height
     */
    public int getLineHeight() {
        return lineHeight;
    }
    
    /**
     * The altitude of the context that is the height above the
     * alignment point.
     * @return the altitude
     */
    public int getAltitude() {
        return alignmentPoint;
    }

    /**
     * The depth of the context that is the height below
     * alignment point.
     * @return the altitude
     */
    public int getDepth() {
        return getHeight() - alignmentPoint;
    }
    
    /**
     * The x height of the context.
     * @return the x height
     */
    public int getXHeight() {
        return this.xHeight;
    }
    
    /**
     * Resizes the line as specified. Assumes that the new alignment point
     * is on the dominant baseline, that is this function should be called for
     * line areas only.
     * @param newLineHeight the new height of the line
     * @param newAlignmentPoint the new alignment point
     */
    public void resizeLine(int newLineHeight, int newAlignmentPoint) {
        areaHeight = newLineHeight;
        alignmentPoint = newAlignmentPoint;
        scaledBaselineTable.setBeforeAndAfterBaselines(alignmentPoint
                                                        , alignmentPoint - areaHeight);
    }
    
    /**
     * Returns the offset from the before-edge of the parent to
     * this context.
     * @return the offset for rendering
     */
    public int getOffset() {
        int offset = 0;
        if (parentAlignmentContext != null) {
            offset = parentAlignmentContext.getTotalTopOffset() - getTotalTopOffset();
        } else {
            offset = getAltitude() - scaledBaselineTable.getBaseline(EN_TEXT_BEFORE_EDGE);
        }
        return offset;
    }
    
    /**
     * Returns an indication if we still use the initial baseline table.
     * The initial baseline table is the table generated by the Line LM.
     * @return true if this is still the initial baseline table
     */
    public boolean usesInitialBaselineTable() {
        return parentAlignmentContext == null
               || (scaledBaselineTable == parentAlignmentContext.getScaledBaselineTable()
                    && parentAlignmentContext.usesInitialBaselineTable());
    }
    
    private boolean isHorizontalWritingMode() {
        return (getWritingMode() == EN_LR_TB || getWritingMode() == EN_RL_TB);
    }
    
    /** @see java.lang.Object#toString() */
    public String toString() {
        StringBuffer sb = new StringBuffer(64);
        sb.append("ah=" + areaHeight);
        sb.append(" lp=" + lineHeight);
        sb.append(" ap=" + alignmentPoint);
        sb.append(" ab=" + alignmentBaselineIdentifier);
        sb.append(" bs=" + baselineShiftValue);
        return sb.toString();
    }
    
}