private void alignLineAreas(BlockArea b, LayoutState ls) {
   BlockAlignment alignment = ls.getReferenceAlignment();
   ReferenceArea r = ls.getReferenceArea();
   double measure = r.isVertical() ? r.getWidth() : r.getHeight();
   double consumed = 0;
   int numChildren = 0;
   for (AreaNode c : b.getChildren()) {
     consumed += c.getBPD();
     ++numChildren;
   }
   double available = measure - consumed;
   if (available > 0) {
     if (alignment == BlockAlignment.BEFORE) {
       // no-op
     } else if (alignment == BlockAlignment.AFTER) {
       // no-op
     } else if (alignment == BlockAlignment.CENTER) {
       // no-op
     } else {
       justifyLineAreas(b, measure, consumed, numChildren, alignment);
     }
   } else if (available < 0) {
     b.setOverflow(-available);
   }
 }
 protected void layoutBody(Element e, LayoutState ls) {
   ls.pushBlock(e);
   for (Element c : getChildElements(e)) {
     if (isElement(c, ttDivisionElementName)) layoutDivision(c, ls);
   }
   ls.pop();
 }
 protected List<Area> layoutISDInstance(Element e, LayoutState ls) {
   List<Area> areas = new java.util.ArrayList<Area>();
   try {
     double begin = Double.parseDouble(e.getAttribute("begin"));
     double end = Double.parseDouble(e.getAttribute("end"));
     Extent cellResolution =
         parseCellResolution(Documents.getAttribute(e, ttpCellResolutionAttrName, null));
     if (cellResolution == null) cellResolution = defaults.getCellResolution();
     ls.pushCanvas(e, begin, end, cellResolution);
     Extent extent = ls.getExternalExtent();
     double w = extent.getWidth();
     double h = extent.getHeight();
     boolean clip = ls.getExternalOverflow().clips();
     ls.pushViewport(e, w, h, clip);
     WritingMode wm = ls.getExternalWritingMode();
     TransformMatrix ctm = ls.getExternalTransform();
     ls.pushReference(e, 0, 0, w, h, wm, ctm);
     for (Element c : getChildElements(e)) {
       if (isElement(c, isdRegionElementName)) layoutRegion(c, ls);
       else if (isElement(c, isdComputedStyleSetElementName)) ls.saveStyles(c);
     }
     ls.pop();
     ls.pop();
     areas.add(ls.pop());
   } catch (NumberFormatException x) {
   }
   return areas;
 }
 protected void layoutParagraph(Paragraph p, LayoutState ls) {
   ls.pushBlock(p.getElement());
   for (LineArea l : new ParagraphLayout(p, ls).layout()) {
     ls.addLine(l);
   }
   AreaNode b = ls.peek();
   if (b instanceof BlockArea) alignLineAreas((BlockArea) b, ls);
   ls.pop();
 }
 protected void layoutDivision(Element e, LayoutState ls) {
   ls.pushBlock(e);
   for (Element c : getChildElements(e)) {
     if (isElement(c, ttDivisionElementName)) {
       layoutDivision(c, ls);
     } else if (isElement(c, ttParagraphElementName)) {
       layoutParagraph(c, ls);
     }
   }
   ls.pop();
 }
 private StyleCollector newStyleCollector(LayoutState ls) {
   return new StyleCollector(
       context,
       ls.getFontCache(),
       defaults,
       ls.getExternalExtent(),
       ls.getReferenceExtent(),
       ls.getCellResolution(),
       ls.getWritingMode(),
       ls.getLanguage(),
       ls.getFont(),
       ls.getStyles());
 }
 protected void layoutRegion(Element e, LayoutState ls) {
   Extent extent = ls.getExtent(e);
   double w = extent.getWidth();
   double h = extent.getHeight();
   Point origin = ls.getPosition(e, extent);
   double x = origin.getX();
   double y = origin.getY();
   boolean clip = ls.getOverflow(e).clips();
   ls.pushViewport(e, w, h, clip);
   WritingMode wm = ls.getWritingMode(e);
   TransformMatrix ctm = ls.getTransform(e);
   ls.pushReference(e, x, y, w, h, wm, ctm);
   for (Element c : getChildElements(e)) {
     if (isElement(c, ttBodyElementName)) layoutBody(c, ls);
   }
   AreaNode r = ls.peek();
   if (r instanceof ReferenceArea) alignBlockAreas((ReferenceArea) r, ls.getReferenceAlignment());
   ls.pop();
   ls.pop();
 }
 private void warnOnCounterViolations(LayoutState ls) {
   Reporter reporter = context.getReporter();
   ls.finalizeCounters();
   int regions = ls.getCounter(LayoutState.Counter.REGIONS_IN_CANVAS);
   if ((maxRegions >= 0) && (regions > maxRegions))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Regions per canvas limit exceeded, {0} present, must not exceed {1}.",
             regions,
             maxRegions));
   int lines = ls.getCounter(LayoutState.Counter.LINES_IN_CANVAS);
   if ((maxLines >= 0) && (lines > maxLines))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Lines per canvas limit exceeded, {0} present, must not exceed {1}.",
             lines,
             maxLines));
   int linesPerRegion = ls.getCounter(LayoutState.Counter.MAX_LINES_IN_REGION);
   if ((maxLinesPerRegion >= 0) && (linesPerRegion > maxLinesPerRegion))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Lines per region limit exceeded, {0} present, must not exceed {1}.",
             linesPerRegion,
             maxLinesPerRegion));
   int chars = ls.getCounter(LayoutState.Counter.CHARS_IN_CANVAS);
   if ((maxChars >= 0) && (chars > maxChars))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Characters per canvas limit exceeded, {0} present, must not exceed {1}.",
             chars,
             maxChars));
   int charsPerRegion = ls.getCounter(LayoutState.Counter.MAX_CHARS_IN_REGION);
   if ((maxCharsPerRegion >= 0) && (charsPerRegion > maxCharsPerRegion))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Characters per region limit exceeded, {0} present, must not exceed {1}.",
             charsPerRegion,
             maxCharsPerRegion));
   int charsPerLine = ls.getCounter(LayoutState.Counter.MAX_CHARS_IN_LINE);
   if ((maxCharsPerLine >= 0) && (charsPerLine > maxCharsPerLine))
     reporter.logWarning(
         reporter.message(
             "*KEY*",
             "Characters per line limit exceeded, {0} present, must not exceed {1}.",
             charsPerLine,
             maxCharsPerLine));
 }
 protected LayoutState initializeLayoutState(LayoutState ls) {
   return ls.initialize(
       fontCache, getLineBreakIterator(), getCharacterBreakIterator(), getDefaults());
 }