You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Keep.java 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.layoutmgr;
  19. import org.apache.fop.fo.Constants;
  20. import org.apache.fop.fo.properties.KeepProperty;
  21. import org.apache.fop.fo.properties.Property;
  22. /**
  23. * Object representing a keep constraint, corresponding
  24. * to the XSL-FO <a href="http://www.w3.org/TR/xsl/#d0e26492">keep properties</a>.
  25. */
  26. public final class Keep {
  27. /** The integer value for "auto" keep strength. */
  28. private static final int STRENGTH_AUTO = Integer.MIN_VALUE;
  29. /** The integer value for "always" keep strength. */
  30. private static final int STRENGTH_ALWAYS = Integer.MAX_VALUE;
  31. /** keep auto */
  32. public static final Keep KEEP_AUTO = new Keep(STRENGTH_AUTO, Constants.EN_AUTO);
  33. /** keep always */
  34. public static final Keep KEEP_ALWAYS = new Keep(STRENGTH_ALWAYS, Constants.EN_LINE);
  35. private int strength;
  36. private int context;
  37. private Keep(int strength, int context) {
  38. this.strength = strength;
  39. this.context = context;
  40. }
  41. private static int getKeepStrength(Property keep) {
  42. if (keep.isAuto()) {
  43. return STRENGTH_AUTO;
  44. } else if (keep.getEnum() == Constants.EN_ALWAYS) {
  45. return STRENGTH_ALWAYS;
  46. } else {
  47. return keep.getNumber().intValue();
  48. }
  49. }
  50. /**
  51. * Obtain a Keep instance corresponding to the given {@link KeepProperty}
  52. *
  53. * @param keepProperty the {@link KeepProperty}
  54. * @return a new instance corresponding to the given property
  55. */
  56. public static Keep getKeep(KeepProperty keepProperty) {
  57. Keep keep = new Keep(STRENGTH_AUTO, Constants.EN_AUTO);
  58. keep.update(keepProperty.getWithinPage(), Constants.EN_PAGE);
  59. keep.update(keepProperty.getWithinColumn(), Constants.EN_COLUMN);
  60. keep.update(keepProperty.getWithinLine(), Constants.EN_LINE);
  61. return keep;
  62. }
  63. private void update(Property keep, int context) {
  64. if (!keep.isAuto()) {
  65. this.strength = getKeepStrength(keep);
  66. this.context = context;
  67. }
  68. }
  69. /** @return {@code true} if the keep property was specified as "auto" */
  70. public boolean isAuto() {
  71. return strength == STRENGTH_AUTO;
  72. }
  73. /**
  74. * Returns the context of this keep.
  75. *
  76. * @return one of {@link Constants#EN_LINE}, {@link Constants#EN_COLUMN} or
  77. * {@link Constants#EN_PAGE}
  78. */
  79. public int getContext() {
  80. return context;
  81. }
  82. /** @return the penalty value corresponding to the strength of this Keep */
  83. public int getPenalty() {
  84. if (strength == STRENGTH_AUTO) {
  85. return 0;
  86. } else if (strength == STRENGTH_ALWAYS) {
  87. return KnuthElement.INFINITE;
  88. } else {
  89. return KnuthElement.INFINITE - 1;
  90. }
  91. }
  92. private static int getKeepContextPriority(int context) {
  93. switch (context) {
  94. case Constants.EN_LINE: return 0;
  95. case Constants.EN_COLUMN: return 1;
  96. case Constants.EN_PAGE: return 2;
  97. case Constants.EN_AUTO: return 3;
  98. default: throw new IllegalArgumentException();
  99. }
  100. }
  101. /**
  102. * Compare this Keep instance to another one, and return the
  103. * stronger one if the context is the same
  104. *
  105. * @param other the instance to compare to
  106. * @return the winning Keep instance
  107. */
  108. public Keep compare(Keep other) {
  109. /* check strength "always" first, regardless of priority */
  110. if (this.strength == STRENGTH_ALWAYS
  111. && this.strength > other.strength) {
  112. return this;
  113. } else if (other.strength == STRENGTH_ALWAYS
  114. && other.strength > this.strength) {
  115. return other;
  116. }
  117. int pThis = getKeepContextPriority(this.context);
  118. int pOther = getKeepContextPriority(other.context);
  119. /* equal priority: strongest wins */
  120. if (pThis == pOther) {
  121. return (strength >= other.strength) ? this : other;
  122. }
  123. /* different priority: lowest priority wins */
  124. return (pThis < pOther) ? this : other;
  125. }
  126. /** {@inheritDoc} */
  127. public String toString() {
  128. return (strength == STRENGTH_AUTO) ? "auto"
  129. : (strength == STRENGTH_ALWAYS) ? "always"
  130. : Integer.toString(strength);
  131. }
  132. }