1 17 18 19 20 package org.apache.fop.layoutmgr; 21 22 import java.util.LinkedList ; 23 import java.util.List ; 24 import java.util.ListIterator ; 25 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 import org.apache.fop.fo.Constants; 29 import org.apache.fop.traits.MinOptMax; 30 31 34 public abstract class AbstractBreaker { 35 36 37 protected static Log log = LogFactory.getLog(AbstractBreaker.class); 38 39 public static class PageBreakPosition extends LeafPosition { 40 double bpdAdjust; int difference; 42 int footnoteFirstListIndex; 43 int footnoteFirstElementIndex; 44 int footnoteLastListIndex; 45 int footnoteLastElementIndex; 46 47 PageBreakPosition(LayoutManager lm, int iBreakIndex, 48 int ffli, int ffei, int flli, int flei, 49 double bpdA, int diff) { 50 super(lm, iBreakIndex); 51 bpdAdjust = bpdA; 52 difference = diff; 53 footnoteFirstListIndex = ffli; 54 footnoteFirstElementIndex = ffei; 55 footnoteLastListIndex = flli; 56 footnoteLastElementIndex = flei; 57 } 58 } 59 60 public class BlockSequence extends BlockKnuthSequence { 61 62 63 public int ignoreAtStart = 0; 64 65 public int ignoreAtEnd = 0; 66 67 74 private int startOn; 75 76 private int displayAlign; 77 78 84 public BlockSequence(int iStartOn, int displayAlign) { 85 super(); 86 startOn = iStartOn; 87 this.displayAlign = displayAlign; 88 } 89 90 94 public int getStartOn() { 95 return this.startOn; 96 } 97 98 99 public int getDisplayAlign() { 100 return this.displayAlign; 101 } 102 106 public KnuthSequence endSequence() { 107 return endSequence(null); 108 } 109 110 115 public KnuthSequence endSequence(Position breakPosition) { 116 while (this.size() > ignoreAtStart 118 && !((KnuthElement)this.get(this.size() - 1)).isBox()) { 119 this.remove(this.size() - 1); 120 } 121 if (this.size() > ignoreAtStart) { 122 if (getDisplayAlign() == Constants.EN_X_DISTRIBUTE && isSinglePartFavored()) { 125 this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, 126 false, breakPosition, false)); 127 ignoreAtEnd = 1; 128 } else { 129 this.add(new KnuthPenalty(0, KnuthElement.INFINITE, 130 false, null, false)); 131 this.add(new KnuthGlue(0, 10000000, 0, null, false)); 132 this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, 133 false, breakPosition, false)); 134 ignoreAtEnd = 3; 135 } 136 return this; 137 } else { 138 this.clear(); 139 return null; 140 } 141 } 142 143 public BlockSequence endBlockSequence(Position breakPosition) { 144 KnuthSequence temp = endSequence(breakPosition); 145 if (temp != null) { 146 BlockSequence returnSequence = new BlockSequence(startOn, displayAlign); 147 returnSequence.addAll(temp); 148 returnSequence.ignoreAtEnd = this.ignoreAtEnd; 149 return returnSequence; 150 } else { 151 return null; 152 } 153 } 154 155 } 156 157 158 private int blockListIndex = 0; 159 160 private List blockLists = null; 161 162 protected int alignment; 163 private int alignmentLast; 164 165 protected MinOptMax footnoteSeparatorLength = new MinOptMax(0); 166 167 protected abstract int getCurrentDisplayAlign(); 168 protected abstract boolean hasMoreContent(); 169 protected abstract void addAreas(PositionIterator posIter, LayoutContext context); 170 protected abstract LayoutManager getTopLevelLM(); 171 protected abstract LayoutManager getCurrentChildLM(); 172 173 178 protected boolean isPartOverflowRecoveryActivated() { 179 return true; 180 } 181 182 185 protected boolean isSinglePartFavored() { 186 return false; 187 } 188 189 195 protected PageSequenceLayoutManager.PageProvider getPageProvider() { 196 return null; 197 } 198 199 204 protected PageBreakingAlgorithm.PageBreakingLayoutListener getLayoutListener() { 205 return null; 206 } 207 208 213 protected abstract LinkedList getNextKnuthElements(LayoutContext context, int alignment); 214 215 216 public boolean isEmpty() { 217 return (blockLists.size() == 0); 218 } 219 220 protected void startPart(BlockSequence list, int breakClass) { 221 } 223 224 227 protected void handleEmptyContent() { 228 } 230 231 protected abstract void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp); 232 233 237 protected LayoutContext createLayoutContext() { 238 return new LayoutContext(0); 239 } 240 241 245 protected void updateLayoutContext(LayoutContext context) { 246 } 248 249 254 protected void observeElementList(List elementList) { 255 ElementListObserver.observe(elementList, "breaker", null); 256 } 257 258 262 public void doLayout(int flowBPD) { 263 doLayout(flowBPD, false); 264 } 265 266 272 public void doLayout(int flowBPD, boolean autoHeight) { 273 LayoutContext childLC = createLayoutContext(); 274 childLC.setStackLimit(new MinOptMax(flowBPD)); 275 276 if (getCurrentDisplayAlign() == Constants.EN_X_FILL) { 277 alignment = Constants.EN_JUSTIFY; 279 } else if (getCurrentDisplayAlign() == Constants.EN_X_DISTRIBUTE) { 280 alignment = Constants.EN_JUSTIFY; 282 } else { 283 alignment = Constants.EN_START; 284 } 285 alignmentLast = Constants.EN_START; 286 if (isSinglePartFavored() && alignment == Constants.EN_JUSTIFY) { 287 alignmentLast = Constants.EN_JUSTIFY; 288 } 289 childLC.setBPAlignment(alignment); 290 291 BlockSequence blockList; 292 blockLists = new java.util.ArrayList (); 293 294 log.debug("PLM> flow BPD =" + flowBPD); 295 296 int nextSequenceStartsOn = Constants.EN_ANY; 298 while (hasMoreContent()) { 299 blockLists.clear(); 300 301 nextSequenceStartsOn = getNextBlockList(childLC, nextSequenceStartsOn, blockLists); 302 303 log.debug("PLM> blockLists.size() = " + blockLists.size()); 305 for (blockListIndex = 0; blockListIndex < blockLists.size(); blockListIndex++) { 306 blockList = (BlockSequence) blockLists.get(blockListIndex); 307 308 if (log.isDebugEnabled()) { 310 log.debug(" blockListIndex = " + blockListIndex); 311 String pagina = (blockList.startOn == Constants.EN_ANY) ? "any page" 312 : (blockList.startOn == Constants.EN_ODD_PAGE) ? "odd page" 313 : "even page"; 314 log.debug(" sequence starts on " + pagina); 315 } 316 observeElementList(blockList); 317 319 log.debug("PLM> start of algorithm (" + this.getClass().getName() 320 + "), flow BPD =" + flowBPD); 321 PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(), 322 getPageProvider(), getLayoutListener(), 323 alignment, alignmentLast, footnoteSeparatorLength, 324 isPartOverflowRecoveryActivated(), autoHeight, isSinglePartFavored()); 325 int iOptPageCount; 326 327 BlockSequence effectiveList; 328 if (getCurrentDisplayAlign() == Constants.EN_X_FILL) { 329 330 effectiveList = justifyBoxes(blockList, alg, flowBPD); 331 } else { 332 333 effectiveList = blockList; 334 } 335 336 alg.setConstantLineWidth(flowBPD); 338 iOptPageCount = alg.findBreakingPoints(effectiveList, 339 1, true, BreakingAlgorithm.ALL_BREAKS); 340 log.debug("PLM> iOptPageCount= " + iOptPageCount 341 + " pageBreaks.size()= " + alg.getPageBreaks().size()); 342 343 344 doPhase3(alg, iOptPageCount, blockList, effectiveList); 346 } 347 } 348 349 } 350 351 358 protected abstract void doPhase3(PageBreakingAlgorithm alg, int partCount, 359 BlockSequence originalList, BlockSequence effectiveList); 360 361 368 protected void addAreas(PageBreakingAlgorithm alg, int partCount, 369 BlockSequence originalList, BlockSequence effectiveList) { 370 addAreas(alg, 0, partCount, originalList, effectiveList); 371 } 372 373 381 protected void addAreas(PageBreakingAlgorithm alg, int startPart, int partCount, 382 BlockSequence originalList, BlockSequence effectiveList) { 383 LayoutContext childLC; 384 ListIterator effectiveListIterator = effectiveList.listIterator(); 386 int startElementIndex = 0; 387 int endElementIndex = 0; 388 int lastBreak = -1; 389 for (int p = startPart; p < startPart + partCount; p++) { 390 PageBreakPosition pbp = (PageBreakPosition) alg.getPageBreaks().get(p); 391 392 int lastBreakClass; 394 if (p == 0) { 395 lastBreakClass = effectiveList.getStartOn(); 396 } else { 397 ListElement lastBreakElement = effectiveList.getElement(endElementIndex); 398 if (lastBreakElement.isPenalty()) { 399 KnuthPenalty pen = (KnuthPenalty)lastBreakElement; 400 lastBreakClass = pen.getBreakClass(); 401 } else { 402 lastBreakClass = Constants.EN_COLUMN; 403 } 404 } 405 406 endElementIndex = pbp.getLeafPos(); 408 409 startElementIndex += (startElementIndex == 0) 412 ? effectiveList.ignoreAtStart 413 : 0; 414 415 log.debug("PLM> part: " + (p + 1) 416 + ", start at pos " + startElementIndex 417 + ", break at pos " + endElementIndex 418 + ", break class = " + lastBreakClass); 419 420 startPart(effectiveList, lastBreakClass); 421 422 int displayAlign = getCurrentDisplayAlign(); 423 424 int notificationEndElementIndex = endElementIndex; 427 428 endElementIndex -= (endElementIndex == (originalList.size() - 1)) 431 ? effectiveList.ignoreAtEnd 432 : 0; 433 434 if (((KnuthElement) effectiveList.get(endElementIndex)) 437 .isGlue()) { 438 endElementIndex--; 439 } 440 441 effectiveListIterator = effectiveList 444 .listIterator(startElementIndex); 445 KnuthElement firstElement; 446 while (effectiveListIterator.hasNext() 447 && !(firstElement = (KnuthElement) effectiveListIterator.next()) 448 .isBox()) { 449 456 startElementIndex++; 457 } 458 459 if (startElementIndex <= endElementIndex) { 460 if (log.isDebugEnabled()) { 461 log.debug(" addAreas from " + startElementIndex 462 + " to " + endElementIndex); 463 } 464 childLC = new LayoutContext(0); 465 childLC.setSpaceAdjust(pbp.bpdAdjust); 467 if (pbp.difference != 0 && displayAlign == Constants.EN_CENTER) { 471 childLC.setSpaceBefore(pbp.difference / 2); 472 } else if (pbp.difference != 0 && displayAlign == Constants.EN_AFTER) { 473 childLC.setSpaceBefore(pbp.difference); 474 } else if (pbp.difference != 0 && displayAlign == Constants.EN_X_DISTRIBUTE 475 && p < (partCount - 1)) { 476 int boxCount = 0; 478 effectiveListIterator = effectiveList 479 .listIterator(startElementIndex); 480 while (effectiveListIterator.nextIndex() <= endElementIndex) { 481 KnuthElement tempEl = (KnuthElement)effectiveListIterator.next(); 482 if (tempEl.isBox() && tempEl.getW() > 0) { 483 boxCount++; 484 } 485 } 486 if (boxCount >= 2) { 488 childLC.setSpaceAfter(pbp.difference / (boxCount - 1)); 489 } 490 } 491 492 493 if (displayAlign == Constants.EN_X_FILL) { 494 int averageLineLength = optimizeLineLength(effectiveList, 495 startElementIndex, endElementIndex); 496 if (averageLineLength != 0) { 497 childLC.setStackLimit(new MinOptMax(averageLineLength)); 498 } 499 } 500 501 502 SpaceResolver.performConditionalsNotification(effectiveList, 504 startElementIndex, notificationEndElementIndex, lastBreak); 505 506 addAreas(new KnuthPossPosIter(effectiveList, 508 startElementIndex, endElementIndex + 1), childLC); 509 } else { 510 handleEmptyContent(); 512 } 513 514 finishPart(alg, pbp); 515 516 lastBreak = endElementIndex; 517 startElementIndex = pbp.getLeafPos() + 1; 518 } 519 } 520 528 535 protected int handleSpanChange(LayoutContext childLC, int nextSequenceStartsOn) { 536 return nextSequenceStartsOn; 537 } 538 545 protected int getNextBlockList(LayoutContext childLC, 546 int nextSequenceStartsOn, 547 List blockLists) { 548 updateLayoutContext(childLC); 549 childLC.signalSpanChange(Constants.NOT_SET); 551 552 LinkedList returnedList; 553 BlockSequence blockList; 554 if ((returnedList = getNextKnuthElements(childLC, alignment)) != null) { 555 if (returnedList.size() == 0) { 556 nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn); 557 return nextSequenceStartsOn; 558 } 559 blockList = new BlockSequence(nextSequenceStartsOn, getCurrentDisplayAlign()); 560 561 nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn); 563 564 Position breakPosition = null; 565 if (((KnuthElement) returnedList.getLast()).isPenalty() 566 && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) { 567 KnuthPenalty breakPenalty = (KnuthPenalty) returnedList 568 .removeLast(); 569 breakPosition = breakPenalty.getPosition(); 570 switch (breakPenalty.getBreakClass()) { 571 case Constants.EN_PAGE: 572 log.debug("PLM> break - PAGE"); 573 nextSequenceStartsOn = Constants.EN_ANY; 574 break; 575 case Constants.EN_COLUMN: 576 log.debug("PLM> break - COLUMN"); 577 nextSequenceStartsOn = Constants.EN_COLUMN; 579 break; 580 case Constants.EN_ODD_PAGE: 581 log.debug("PLM> break - ODD PAGE"); 582 nextSequenceStartsOn = Constants.EN_ODD_PAGE; 583 break; 584 case Constants.EN_EVEN_PAGE: 585 log.debug("PLM> break - EVEN PAGE"); 586 nextSequenceStartsOn = Constants.EN_EVEN_PAGE; 587 break; 588 default: 589 throw new IllegalStateException ("Invalid break class: " 590 + breakPenalty.getBreakClass()); 591 } 592 } 593 blockList.addAll(returnedList); 594 BlockSequence seq = null; 595 seq = blockList.endBlockSequence(breakPosition); 596 if (seq != null) { 597 blockLists.add(seq); 598 } 599 } 600 return nextSequenceStartsOn; 601 } 602 603 610 private int optimizeLineLength(KnuthSequence effectiveList, int startElementIndex, int endElementIndex) { 611 ListIterator effectiveListIterator; 612 int boxCount = 0; 614 int accumulatedLineLength = 0; 615 int greatestMinimumLength = 0; 616 effectiveListIterator = effectiveList 617 .listIterator(startElementIndex); 618 while (effectiveListIterator.nextIndex() <= endElementIndex) { 619 KnuthElement tempEl = (KnuthElement) effectiveListIterator 620 .next(); 621 if (tempEl instanceof KnuthBlockBox) { 622 KnuthBlockBox blockBox = (KnuthBlockBox) tempEl; 623 if (blockBox.getBPD() > 0) { 624 log.debug("PSLM> nominal length of line = " + blockBox.getBPD()); 625 log.debug(" range = " 626 + blockBox.getIPDRange()); 627 boxCount++; 628 accumulatedLineLength += ((KnuthBlockBox) tempEl) 629 .getBPD(); 630 } 631 if (blockBox.getIPDRange().min > greatestMinimumLength) { 632 greatestMinimumLength = blockBox 633 .getIPDRange().min; 634 } 635 } 636 } 637 int averageLineLength = 0; 638 if (accumulatedLineLength > 0 && boxCount > 0) { 639 averageLineLength = (int) (accumulatedLineLength / boxCount); 640 log.debug("Average line length = " + averageLineLength); 641 if (averageLineLength < greatestMinimumLength) { 642 averageLineLength = greatestMinimumLength; 643 log.debug(" Correction to: " + averageLineLength); 644 } 645 } 646 return averageLineLength; 647 } 648 649 656 private BlockSequence justifyBoxes(BlockSequence blockList, PageBreakingAlgorithm alg, int availableBPD) { 657 int iOptPageNumber; 658 alg.setConstantLineWidth(availableBPD); 659 iOptPageNumber = alg.findBreakingPoints(blockList, 660 1, true, BreakingAlgorithm.ALL_BREAKS); 661 log.debug("PLM> iOptPageNumber= " + iOptPageNumber); 662 663 ListIterator sequenceIterator = blockList.listIterator(); 665 ListIterator breakIterator = alg.getPageBreaks().listIterator(); 666 KnuthElement thisElement = null; 667 PageBreakPosition thisBreak; 668 int accumulatedS; int adjustedDiff; int firstElementIndex; 671 672 while (breakIterator.hasNext()) { 673 thisBreak = (PageBreakPosition) breakIterator.next(); 674 if (log.isDebugEnabled()) { 675 log.debug("| first page: break= " 676 + thisBreak.getLeafPos() + " difference= " 677 + thisBreak.difference + " ratio= " 678 + thisBreak.bpdAdjust); 679 } 680 accumulatedS = 0; 681 adjustedDiff = 0; 682 683 KnuthElement firstElement; 689 while (!(firstElement = (KnuthElement) sequenceIterator 690 .next()).isBox()) { 691 log.debug("PLM> ignoring glue or penalty element " 693 + "at the beginning of the sequence"); 694 if (firstElement.isGlue()) { 695 ((BlockLevelLayoutManager) firstElement 696 .getLayoutManager()) 697 .discardSpace((KnuthGlue) firstElement); 698 } 699 } 700 firstElementIndex = sequenceIterator.previousIndex(); 701 sequenceIterator.previous(); 702 703 MinOptMax lineNumberMaxAdjustment = new MinOptMax(0); 706 MinOptMax spaceMaxAdjustment = new MinOptMax(0); 707 double spaceAdjustmentRatio = 0.0; 708 LinkedList blockSpacesList = new LinkedList (); 709 LinkedList unconfirmedList = new LinkedList (); 710 LinkedList adjustableLinesList = new LinkedList (); 711 boolean bBoxSeen = false; 712 while (sequenceIterator.hasNext() 713 && sequenceIterator.nextIndex() <= thisBreak 714 .getLeafPos()) { 715 thisElement = (KnuthElement) sequenceIterator.next(); 716 if (thisElement.isGlue()) { 717 switch (((KnuthGlue) thisElement) 721 .getAdjustmentClass()) { 722 case BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT: 723 case BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT: 725 unconfirmedList.add(thisElement); 730 break; 731 case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT: 732 lineNumberMaxAdjustment.max += ((KnuthGlue) thisElement) 734 .getY(); 735 lineNumberMaxAdjustment.min -= ((KnuthGlue) thisElement) 736 .getZ(); 737 adjustableLinesList.add(thisElement); 738 break; 739 case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT: 740 break; 742 default: 743 } 745 } else if (thisElement.isBox()) { 746 if (!bBoxSeen) { 747 bBoxSeen = true; 749 } else if (unconfirmedList.size() > 0) { 750 while (unconfirmedList.size() > 0) { 755 KnuthGlue blockSpace = (KnuthGlue) unconfirmedList 756 .removeFirst(); 757 spaceMaxAdjustment.max += ((KnuthGlue) blockSpace) 758 .getY(); 759 spaceMaxAdjustment.min -= ((KnuthGlue) blockSpace) 760 .getZ(); 761 blockSpacesList.add(blockSpace); 762 } 763 } 764 } 765 } 766 log.debug("| line number adj= " 767 + lineNumberMaxAdjustment); 768 log.debug("| space adj = " 769 + spaceMaxAdjustment); 770 771 if (thisElement.isPenalty() && thisElement.getW() > 0) { 772 log.debug(" mandatory variation to the number of lines!"); 773 ((BlockLevelLayoutManager) thisElement 774 .getLayoutManager()).negotiateBPDAdjustment( 775 thisElement.getW(), thisElement); 776 } 777 778 if (thisBreak.bpdAdjust != 0 779 && (thisBreak.difference > 0 && thisBreak.difference <= spaceMaxAdjustment.max) 780 || (thisBreak.difference < 0 && thisBreak.difference >= spaceMaxAdjustment.min)) { 781 spaceAdjustmentRatio = ((double) thisBreak.difference / (thisBreak.difference > 0 ? spaceMaxAdjustment.max 783 : spaceMaxAdjustment.min)); 784 adjustedDiff += adjustBlockSpaces( 785 blockSpacesList, 786 thisBreak.difference, 787 (thisBreak.difference > 0 ? spaceMaxAdjustment.max 788 : -spaceMaxAdjustment.min)); 789 log.debug("single space: " 790 + (adjustedDiff == thisBreak.difference 791 || thisBreak.bpdAdjust == 0 ? "ok" 792 : "ERROR")); 793 } else if (thisBreak.bpdAdjust != 0) { 794 adjustedDiff += adjustLineNumbers( 795 adjustableLinesList, 796 thisBreak.difference, 797 (thisBreak.difference > 0 ? lineNumberMaxAdjustment.max 798 : -lineNumberMaxAdjustment.min)); 799 adjustedDiff += adjustBlockSpaces( 800 blockSpacesList, 801 thisBreak.difference - adjustedDiff, 802 ((thisBreak.difference - adjustedDiff) > 0 ? spaceMaxAdjustment.max 803 : -spaceMaxAdjustment.min)); 804 log.debug("lines and space: " 805 + (adjustedDiff == thisBreak.difference 806 || thisBreak.bpdAdjust == 0 ? "ok" 807 : "ERROR")); 808 809 } 810 } 811 812 BlockSequence effectiveList = new BlockSequence(blockList.getStartOn(), 816 blockList.getDisplayAlign()); 817 effectiveList.addAll(getCurrentChildLM().getChangedKnuthElements( 818 blockList.subList(0, blockList.size() - blockList.ignoreAtEnd), 819 0)); 820 effectiveList.endSequence(); 823 824 ElementListObserver.observe(effectiveList, "breaker-effective", null); 825 826 alg.getPageBreaks().clear(); return effectiveList; 828 } 829 830 private int adjustBlockSpaces(LinkedList spaceList, int difference, int total) { 831 if (log.isDebugEnabled()) { 832 log.debug("AdjustBlockSpaces: difference " + difference + " / " + total 833 + " on " + spaceList.size() + " spaces in block"); 834 } 835 ListIterator spaceListIterator = spaceList.listIterator(); 836 int adjustedDiff = 0; 837 int partial = 0; 838 while (spaceListIterator.hasNext()) { 839 KnuthGlue blockSpace = (KnuthGlue)spaceListIterator.next(); 840 partial += (difference > 0 ? blockSpace.getY() : blockSpace.getZ()); 841 if (log.isDebugEnabled()) { 842 log.debug("available = " + partial + " / " + total); 843 log.debug("competenza = " 844 + (((int)((float) partial * difference / total)) - adjustedDiff) 845 + " / " + difference); 846 } 847 int newAdjust = ((BlockLevelLayoutManager) blockSpace.getLayoutManager()).negotiateBPDAdjustment(((int) ((float) partial * difference / total)) - adjustedDiff, blockSpace); 848 adjustedDiff += newAdjust; 849 } 850 return adjustedDiff; 851 } 852 853 private int adjustLineNumbers(LinkedList lineList, int difference, int total) { 854 if (log.isDebugEnabled()) { 855 log.debug("AdjustLineNumbers: difference " + difference + " / " + total + " on " + lineList.size() + " elements"); 856 } 857 858 881 ListIterator lineListIterator = lineList.listIterator(); 882 int adjustedDiff = 0; 883 int partial = 0; 884 while (lineListIterator.hasNext()) { 885 KnuthGlue line = (KnuthGlue)lineListIterator.next(); 886 partial += (difference > 0 ? line.getY() : line.getZ()); 887 int newAdjust = ((BlockLevelLayoutManager) line.getLayoutManager()).negotiateBPDAdjustment(((int) ((float) partial * difference / total)) - adjustedDiff, line); 888 adjustedDiff += newAdjust; 889 } 890 return adjustedDiff; 891 } 892 893 } 894 | Popular Tags |