Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

CommonBorderPaddingBackground.java 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  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.fo.properties;
  19. import java.awt.Color;
  20. import java.io.FileNotFoundException;
  21. import java.io.IOException;
  22. import java.util.Arrays;
  23. import org.apache.xmlgraphics.image.loader.ImageException;
  24. import org.apache.xmlgraphics.image.loader.ImageInfo;
  25. import org.apache.xmlgraphics.image.loader.ImageManager;
  26. import org.apache.xmlgraphics.image.loader.ImageSessionContext;
  27. import org.apache.fop.ResourceEventProducer;
  28. import org.apache.fop.apps.FOUserAgent;
  29. import org.apache.fop.datatypes.Length;
  30. import org.apache.fop.datatypes.PercentBaseContext;
  31. import org.apache.fop.datatypes.URISpecification;
  32. import org.apache.fop.fo.Constants;
  33. import org.apache.fop.fo.FObj;
  34. import org.apache.fop.fo.PropertyList;
  35. import org.apache.fop.fo.expr.PropertyException;
  36. import org.apache.fop.util.CompareUtil;
  37. /**
  38. * Stores all common border and padding properties.
  39. * See Sec. 7.7 of the XSL-FO Standard.
  40. */
  41. public class CommonBorderPaddingBackground {
  42. /**
  43. * cache holding all canonical instances
  44. * (w/ absolute background-position-* and padding-*)
  45. */
  46. private static final PropertyCache<CommonBorderPaddingBackground> CACHE
  47. = new PropertyCache<CommonBorderPaddingBackground>();
  48. private int hash = -1;
  49. /**
  50. * The "background-attachment" property.
  51. */
  52. public final int backgroundAttachment; // CSOK: VisibilityModifier
  53. /**
  54. * The "background-color" property.
  55. */
  56. public final Color backgroundColor; // CSOK: VisibilityModifier
  57. /**
  58. * The "background-image" property.
  59. */
  60. public final String backgroundImage; // CSOK: VisibilityModifier
  61. /**
  62. * The "background-repeat" property.
  63. */
  64. public final int backgroundRepeat; // CSOK: VisibilityModifier
  65. /**
  66. * The "background-position-horizontal" property.
  67. */
  68. public final Length backgroundPositionHorizontal; // CSOK: VisibilityModifier
  69. /**
  70. * The "background-position-vertical" property.
  71. */
  72. public final Length backgroundPositionVertical; // CSOK: VisibilityModifier
  73. private ImageInfo backgroundImageInfo;
  74. /** the "before" edge */
  75. public static final int BEFORE = 0;
  76. /** the "after" edge */
  77. public static final int AFTER = 1;
  78. /** the "start" edge */
  79. public static final int START = 2;
  80. /** the "end" edge */
  81. public static final int END = 3;
  82. /**
  83. * Utility class to express border info.
  84. */
  85. public static final class BorderInfo {
  86. /** cache holding all canonical instances */
  87. private static final PropertyCache<BorderInfo> CACHE
  88. = new PropertyCache<BorderInfo>();
  89. private int mStyle; // Enum for border style
  90. private Color mColor; // Border color
  91. private CondLengthProperty mWidth;
  92. private int hash = -1;
  93. /**
  94. * Hidden constructor
  95. */
  96. private BorderInfo(int style, CondLengthProperty width, Color color) {
  97. mStyle = style;
  98. mWidth = width;
  99. mColor = color;
  100. }
  101. /**
  102. * Returns a BorderInfo instance corresponding to the given values
  103. *
  104. * @param style the border-style
  105. * @param width the border-width
  106. * @param color the border-color
  107. * @return a cached BorderInfo instance
  108. */
  109. public static BorderInfo getInstance(int style, CondLengthProperty width, Color color) {
  110. return CACHE.fetch(new BorderInfo(style, width, color));
  111. }
  112. /**
  113. * @return the border-style
  114. */
  115. public int getStyle() {
  116. return this.mStyle;
  117. }
  118. /**
  119. * @return the border-color
  120. */
  121. public Color getColor() {
  122. return this.mColor;
  123. }
  124. /**
  125. * @return the border-width
  126. */
  127. public CondLengthProperty getWidth() {
  128. return this.mWidth;
  129. }
  130. /**
  131. * Convenience method returning the border-width,
  132. * taking into account values of "none" and "hidden"
  133. *
  134. * @return the retained border-width
  135. */
  136. public int getRetainedWidth() {
  137. if ((mStyle == Constants.EN_NONE)
  138. || (mStyle == Constants.EN_HIDDEN)) {
  139. return 0;
  140. } else {
  141. return mWidth.getLengthValue();
  142. }
  143. }
  144. @Override
  145. public String toString() {
  146. StringBuffer sb = new StringBuffer("BorderInfo");
  147. sb.append(" {");
  148. sb.append(mStyle);
  149. sb.append(", ");
  150. sb.append(mColor);
  151. sb.append(", ");
  152. sb.append(mWidth);
  153. sb.append("}");
  154. return sb.toString();
  155. }
  156. @Override
  157. public boolean equals(Object obj) {
  158. if (this == obj) {
  159. return true;
  160. }
  161. if (!(obj instanceof BorderInfo)) {
  162. return false;
  163. }
  164. BorderInfo other = (BorderInfo) obj;
  165. return CompareUtil.equal(mColor, other.mColor)
  166. && mStyle == other.mStyle
  167. && CompareUtil.equal(mWidth, other.mWidth);
  168. }
  169. @Override
  170. public int hashCode() {
  171. if (this.hash == -1) {
  172. int hash = 17;
  173. hash = 37 * hash + (mColor == null ? 0 : mColor.hashCode());
  174. hash = 37 * hash + mStyle;
  175. hash = 37 * hash + (mWidth == null ? 0 : mWidth.hashCode());
  176. this.hash = hash;
  177. }
  178. return this.hash;
  179. }
  180. }
  181. /**
  182. * A border info with style "none". Used as a singleton, in the collapsing-border model,
  183. * for elements which don't specify any border on some of their sides.
  184. */
  185. private static final BorderInfo DEFAULT_BORDER_INFO
  186. = BorderInfo.getInstance(Constants.EN_NONE, new ConditionalNullLength(), null);
  187. /**
  188. * A conditional length of value 0. Returned by the
  189. * {@link CommonBorderPaddingBackground#getBorderInfo(int)} method when the
  190. * corresponding border isn't specified, to avoid to callers painful checks for null.
  191. */
  192. private static class ConditionalNullLength extends CondLengthProperty {
  193. @Override
  194. public Property getComponent(int cmpId) {
  195. throw new UnsupportedOperationException();
  196. }
  197. @Override
  198. public Property getConditionality() {
  199. throw new UnsupportedOperationException();
  200. }
  201. @Override
  202. public Length getLength() {
  203. throw new UnsupportedOperationException();
  204. }
  205. @Override
  206. public Property getLengthComponent() {
  207. throw new UnsupportedOperationException();
  208. }
  209. @Override
  210. public int getLengthValue() {
  211. return 0;
  212. }
  213. @Override
  214. public int getLengthValue(PercentBaseContext context) {
  215. return 0;
  216. }
  217. @Override
  218. public boolean isDiscard() {
  219. return true;
  220. }
  221. @Override
  222. public void setComponent(int cmpId, Property cmpnValue, boolean isDefault) {
  223. throw new UnsupportedOperationException();
  224. }
  225. @Override
  226. public String toString() {
  227. return "CondLength[0mpt, discard]";
  228. }
  229. }
  230. /**
  231. * Returns a default BorderInfo of style none.
  232. *
  233. * @return a BorderInfo instance with style set to {@link Constants#EN_NONE}
  234. */
  235. public static BorderInfo getDefaultBorderInfo() {
  236. return DEFAULT_BORDER_INFO;
  237. }
  238. private BorderInfo[] borderInfo = new BorderInfo[4];
  239. private CondLengthProperty[] padding = new CondLengthProperty[4];
  240. /**
  241. * Construct a CommonBorderPaddingBackground object.
  242. *
  243. * @param pList The PropertyList to get properties from.
  244. * @throws PropertyException if there's an error while binding the properties
  245. */
  246. CommonBorderPaddingBackground(PropertyList pList) throws PropertyException {
  247. backgroundAttachment = pList.get(Constants.PR_BACKGROUND_ATTACHMENT).getEnum();
  248. Color bc = pList.get(Constants.PR_BACKGROUND_COLOR).getColor(
  249. pList.getFObj().getUserAgent());
  250. if (bc.getAlpha() == 0) {
  251. backgroundColor = null;
  252. } else {
  253. backgroundColor = bc;
  254. }
  255. String img = pList.get(Constants.PR_BACKGROUND_IMAGE).getString();
  256. if (img == null || "none".equals(img)) {
  257. backgroundImage = "";
  258. backgroundRepeat = -1;
  259. backgroundPositionHorizontal = null;
  260. backgroundPositionVertical = null;
  261. } else {
  262. backgroundImage = img;
  263. backgroundRepeat = pList.get(Constants.PR_BACKGROUND_REPEAT).getEnum();
  264. backgroundPositionHorizontal = pList.get(
  265. Constants.PR_BACKGROUND_POSITION_HORIZONTAL).getLength();
  266. backgroundPositionVertical = pList.get(
  267. Constants.PR_BACKGROUND_POSITION_VERTICAL).getLength();
  268. }
  269. initBorderInfo(pList, BEFORE,
  270. Constants.PR_BORDER_BEFORE_COLOR,
  271. Constants.PR_BORDER_BEFORE_STYLE,
  272. Constants.PR_BORDER_BEFORE_WIDTH,
  273. Constants.PR_PADDING_BEFORE);
  274. initBorderInfo(pList, AFTER,
  275. Constants.PR_BORDER_AFTER_COLOR,
  276. Constants.PR_BORDER_AFTER_STYLE,
  277. Constants.PR_BORDER_AFTER_WIDTH,
  278. Constants.PR_PADDING_AFTER);
  279. initBorderInfo(pList, START,
  280. Constants.PR_BORDER_START_COLOR,
  281. Constants.PR_BORDER_START_STYLE,
  282. Constants.PR_BORDER_START_WIDTH,
  283. Constants.PR_PADDING_START);
  284. initBorderInfo(pList, END,
  285. Constants.PR_BORDER_END_COLOR,
  286. Constants.PR_BORDER_END_STYLE,
  287. Constants.PR_BORDER_END_WIDTH,
  288. Constants.PR_PADDING_END);
  289. }
  290. /**
  291. * Obtain a CommonBorderPaddingBackground instance based on the
  292. * related property valus in the given {@link PropertyList}
  293. *
  294. * @param pList the {@link PropertyList} to use
  295. * @return a CommonBorderPaddingBackground instance (cached if possible)
  296. * @throws PropertyException in case of an error
  297. */
  298. public static CommonBorderPaddingBackground getInstance(PropertyList pList)
  299. throws PropertyException {
  300. CommonBorderPaddingBackground newInstance = new CommonBorderPaddingBackground(pList);
  301. CommonBorderPaddingBackground cachedInstance = null;
  302. /* if padding-* and background-position-* resolve to absolute lengths
  303. * the whole instance can be cached */
  304. if ((newInstance.padding[BEFORE] == null
  305. || newInstance.padding[BEFORE].getLength().isAbsolute())
  306. && (newInstance.padding[AFTER] == null
  307. || newInstance.padding[AFTER].getLength().isAbsolute())
  308. && (newInstance.padding[START] == null
  309. || newInstance.padding[START].getLength().isAbsolute())
  310. && (newInstance.padding[END] == null
  311. || newInstance.padding[END].getLength().isAbsolute())
  312. && (newInstance.backgroundPositionHorizontal == null
  313. || newInstance.backgroundPositionHorizontal.isAbsolute())
  314. && (newInstance.backgroundPositionVertical == null
  315. || newInstance.backgroundPositionVertical.isAbsolute())) {
  316. cachedInstance = CACHE.fetch(newInstance);
  317. }
  318. synchronized (newInstance.backgroundImage.intern()) {
  319. /* for non-cached, or not-yet-cached instances, preload the image */
  320. if ((cachedInstance == null || cachedInstance == newInstance)
  321. && !("".equals(newInstance.backgroundImage))) {
  322. //Additional processing: preload image
  323. String uri = URISpecification.getURL(newInstance.backgroundImage);
  324. FObj fobj = pList.getFObj();
  325. FOUserAgent userAgent = pList.getFObj().getUserAgent();
  326. ImageManager manager = userAgent.getImageManager();
  327. ImageSessionContext sessionContext = userAgent.getImageSessionContext();
  328. ImageInfo info;
  329. try {
  330. info = manager.getImageInfo(uri, sessionContext);
  331. newInstance.backgroundImageInfo = info;
  332. } catch (ImageException e) {
  333. ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
  334. fobj.getUserAgent().getEventBroadcaster());
  335. eventProducer.imageError(fobj, uri, e, fobj.getLocator());
  336. } catch (FileNotFoundException fnfe) {
  337. ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
  338. fobj.getUserAgent().getEventBroadcaster());
  339. eventProducer.imageNotFound(fobj, uri, fnfe, fobj.getLocator());
  340. } catch (IOException ioe) {
  341. ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
  342. fobj.getUserAgent().getEventBroadcaster());
  343. eventProducer.imageIOError(fobj, uri, ioe, fobj.getLocator());
  344. }
  345. }
  346. }
  347. return (cachedInstance != null ? cachedInstance : newInstance);
  348. }
  349. private void initBorderInfo(PropertyList pList, int side,
  350. int colorProp, int styleProp, int widthProp, int paddingProp)
  351. throws PropertyException {
  352. padding[side] = pList.get(paddingProp).getCondLength();
  353. // If style = none, force width to 0, don't get Color (spec 7.7.20)
  354. int style = pList.get(styleProp).getEnum();
  355. if (style != Constants.EN_NONE) {
  356. FOUserAgent ua = pList.getFObj().getUserAgent();
  357. setBorderInfo(BorderInfo.getInstance(style,
  358. pList.get(widthProp).getCondLength(),
  359. pList.get(colorProp).getColor(ua)), side);
  360. }
  361. }
  362. /**
  363. * Sets a border.
  364. * @param info the border information
  365. * @param side the side to apply the info to
  366. */
  367. private void setBorderInfo(BorderInfo info, int side) {
  368. this.borderInfo[side] = info;
  369. }
  370. /**
  371. * @param side the side to retrieve
  372. * @return the border info for a side
  373. */
  374. public BorderInfo getBorderInfo(int side) {
  375. if (this.borderInfo[side] == null) {
  376. return getDefaultBorderInfo();
  377. } else {
  378. return this.borderInfo[side];
  379. }
  380. }
  381. /**
  382. * @return the background image info object, null if there is
  383. * no background image.
  384. */
  385. public ImageInfo getImageInfo() {
  386. return this.backgroundImageInfo;
  387. }
  388. /**
  389. * @param discard indicates whether the .conditionality component should be
  390. * considered (start of a reference-area)
  391. * @return the width of the start-border, taking into account the specified conditionality
  392. */
  393. public int getBorderStartWidth(boolean discard) {
  394. return getBorderWidth(START, discard);
  395. }
  396. /**
  397. * @param discard indicates whether the .conditionality component should be
  398. * considered (end of a reference-area)
  399. * @return the width of the end-border, taking into account the specified conditionality
  400. */
  401. public int getBorderEndWidth(boolean discard) {
  402. return getBorderWidth(END, discard);
  403. }
  404. /**
  405. * @param discard indicates whether the .conditionality component should be
  406. * considered (start of a reference-area)
  407. * @return the width of the before-border, taking into account the specified conditionality
  408. */
  409. public int getBorderBeforeWidth(boolean discard) {
  410. return getBorderWidth(BEFORE, discard);
  411. }
  412. /**
  413. * @param discard indicates whether the .conditionality component should be
  414. * considered (end of a reference-area)
  415. * @return the width of the after-border, taking into account the specified conditionality
  416. */
  417. public int getBorderAfterWidth(boolean discard) {
  418. return getBorderWidth(AFTER, discard);
  419. }
  420. /**
  421. * @param discard indicates whether the .conditionality component should be
  422. * considered (start of a reference-area)
  423. * @param context the context to evaluate percentage values
  424. * @return the width of the start-padding, taking into account the specified conditionality
  425. */
  426. public int getPaddingStart(boolean discard, PercentBaseContext context) {
  427. return getPadding(START, discard, context);
  428. }
  429. /**
  430. * @param discard indicates whether the .conditionality component should be
  431. * considered (start of a reference-area)
  432. * @param context the context to evaluate percentage values
  433. * @return the width of the end-padding, taking into account the specified conditionality
  434. */
  435. public int getPaddingEnd(boolean discard, PercentBaseContext context) {
  436. return getPadding(END, discard, context);
  437. }
  438. /**
  439. * @param discard indicates whether the .conditionality component should be
  440. * considered (start of a reference-area)
  441. * @param context the context to evaluate percentage values
  442. * @return the width of the before-padding, taking into account the specified conditionality
  443. */
  444. public int getPaddingBefore(boolean discard, PercentBaseContext context) {
  445. return getPadding(BEFORE, discard, context);
  446. }
  447. /**
  448. * @param discard indicates whether the .conditionality component should be
  449. * considered (start of a reference-area)
  450. * @param context the context to evaluate percentage values
  451. * @return the width of the after-padding, taking into account the specified conditionality
  452. */
  453. public int getPaddingAfter(boolean discard, PercentBaseContext context) {
  454. return getPadding(AFTER, discard, context);
  455. }
  456. /**
  457. * @param side the side of the border
  458. * @param discard indicates whether the .conditionality component should be considered (end of a
  459. * reference-area)
  460. * @return the width of the start-border, taking into account the specified conditionality
  461. */
  462. public int getBorderWidth(int side, boolean discard) {
  463. if ((borderInfo[side] == null)
  464. || (borderInfo[side].mStyle == Constants.EN_NONE)
  465. || (borderInfo[side].mStyle == Constants.EN_HIDDEN)
  466. || (discard && borderInfo[side].mWidth.isDiscard())) {
  467. return 0;
  468. } else {
  469. return borderInfo[side].mWidth.getLengthValue();
  470. }
  471. }
  472. /**
  473. * The border-color for the given side
  474. *
  475. * @param side one of {@link #BEFORE}, {@link #AFTER}, {@link #START}, {@link #END}
  476. * @return the border-color for the given side
  477. */
  478. public Color getBorderColor(int side) {
  479. if (borderInfo[side] != null) {
  480. return borderInfo[side].getColor();
  481. } else {
  482. return null;
  483. }
  484. }
  485. /**
  486. * The border-style for the given side
  487. *
  488. * @param side one of {@link #BEFORE}, {@link #AFTER}, {@link #START}, {@link #END}
  489. * @return the border-style for the given side
  490. */
  491. public int getBorderStyle(int side) {
  492. if (borderInfo[side] != null) {
  493. return borderInfo[side].mStyle;
  494. } else {
  495. return Constants.EN_NONE;
  496. }
  497. }
  498. /**
  499. * Return the padding for the given side, taking into account
  500. * the conditionality and evaluating any percentages in the given
  501. * context.
  502. *
  503. * @param side one of {@link #BEFORE}, {@link #AFTER}, {@link #START}, {@link #END}
  504. * @param discard true if the conditionality component should be considered
  505. * @param context the context for percentage-resolution
  506. * @return the computed padding for the given side
  507. */
  508. public int getPadding(int side, boolean discard, PercentBaseContext context) {
  509. if ((padding[side] == null) || (discard && padding[side].isDiscard())) {
  510. return 0;
  511. } else {
  512. return padding[side].getLengthValue(context);
  513. }
  514. }
  515. /**
  516. * Returns the CondLengthProperty for the padding on one side.
  517. * @param side the side
  518. * @return the requested CondLengthProperty
  519. */
  520. public CondLengthProperty getPaddingLengthProperty(int side) {
  521. return padding[side];
  522. }
  523. /**
  524. * Return all the border and padding width in the inline progression
  525. * dimension.
  526. * @param discard the discard flag.
  527. * @param context for percentage evaluation.
  528. * @return all the padding and border width.
  529. */
  530. public int getIPPaddingAndBorder(boolean discard, PercentBaseContext context) {
  531. return getPaddingStart(discard, context)
  532. + getPaddingEnd(discard, context)
  533. + getBorderStartWidth(discard)
  534. + getBorderEndWidth(discard);
  535. }
  536. /**
  537. * Return all the border and padding height in the block progression
  538. * dimension.
  539. * @param discard the discard flag.
  540. * @param context for percentage evaluation
  541. * @return all the padding and border height.
  542. */
  543. public int getBPPaddingAndBorder(boolean discard, PercentBaseContext context) {
  544. return getPaddingBefore(discard, context) + getPaddingAfter(discard, context)
  545. + getBorderBeforeWidth(discard) + getBorderAfterWidth(discard);
  546. }
  547. @Override
  548. public String toString() {
  549. return "CommonBordersAndPadding (Before, After, Start, End):\n"
  550. + "Borders: (" + getBorderBeforeWidth(false) + ", " + getBorderAfterWidth(false) + ", "
  551. + getBorderStartWidth(false) + ", " + getBorderEndWidth(false) + ")\n"
  552. + "Border Colors: (" + getBorderColor(BEFORE) + ", " + getBorderColor(AFTER) + ", "
  553. + getBorderColor(START) + ", " + getBorderColor(END) + ")\n"
  554. + "Padding: (" + getPaddingBefore(false, null) + ", " + getPaddingAfter(false, null)
  555. + ", " + getPaddingStart(false, null) + ", " + getPaddingEnd(false, null) + ")\n";
  556. }
  557. /**
  558. * @return true if there is any kind of background to be painted
  559. */
  560. public boolean hasBackground() {
  561. return ((backgroundColor != null || getImageInfo() != null));
  562. }
  563. /** @return true if border is non-zero. */
  564. public boolean hasBorder() {
  565. return ((getBorderBeforeWidth(false) + getBorderAfterWidth(false)
  566. + getBorderStartWidth(false) + getBorderEndWidth(false)) > 0);
  567. }
  568. /**
  569. * @param context for percentage based evaluation.
  570. * @return true if padding is non-zero.
  571. */
  572. public boolean hasPadding(PercentBaseContext context) {
  573. return ((getPaddingBefore(false, context) + getPaddingAfter(false, context)
  574. + getPaddingStart(false, context) + getPaddingEnd(false, context)) > 0);
  575. }
  576. /** @return true if there are any borders defined. */
  577. public boolean hasBorderInfo() {
  578. return (borderInfo[BEFORE] != null || borderInfo[AFTER] != null
  579. || borderInfo[START] != null || borderInfo[END] != null);
  580. }
  581. /**
  582. * Returns the "background-color" property.
  583. * @return the "background-color" property.
  584. */
  585. public Color getBackgroundColor() {
  586. return backgroundColor;
  587. }
  588. /**
  589. * Returns the "background-attachment" property.
  590. * @return the "background-attachment" property.
  591. */
  592. public int getBackgroundAttachment() {
  593. return backgroundAttachment;
  594. }
  595. /**
  596. * Returns the "background-image" property.
  597. * @return the "background-image" property.
  598. */
  599. public String getBackgroundImage() {
  600. return backgroundImage;
  601. }
  602. /**
  603. * Returns the "background-repeat" property.
  604. * @return the "background-repeat" property.
  605. */
  606. public int getBackgroundRepeat() {
  607. return backgroundRepeat;
  608. }
  609. /**
  610. * Returns the "background-position-horizontal" property.
  611. * @return the "background-position-horizontal" property.
  612. */
  613. public Length getBackgroundPositionHorizontal() {
  614. return backgroundPositionHorizontal;
  615. }
  616. /**
  617. * Returns the "background-position-vertical" property.
  618. * @return the "background-position-vertical" property.
  619. */
  620. public Length getBackgroundPositionVertical() {
  621. return backgroundPositionVertical;
  622. }
  623. /**
  624. * Returns the background image info
  625. * @return the background image info
  626. */
  627. public ImageInfo getBackgroundImageInfo() {
  628. return backgroundImageInfo;
  629. }
  630. /**
  631. * Returns the border info
  632. * @return the border info
  633. */
  634. public BorderInfo[] getBorderInfo() {
  635. return borderInfo;
  636. }
  637. /**
  638. * Returns the padding
  639. * @return the padding
  640. */
  641. public CondLengthProperty[] getPadding() {
  642. return padding;
  643. }
  644. @Override
  645. public boolean equals(Object obj) {
  646. if (this == obj) {
  647. return true;
  648. }
  649. if (!(obj instanceof CommonBorderPaddingBackground)) {
  650. return false;
  651. }
  652. CommonBorderPaddingBackground other = (CommonBorderPaddingBackground) obj;
  653. return backgroundAttachment == other.backgroundAttachment
  654. && CompareUtil.equal(backgroundColor, other.backgroundColor)
  655. && CompareUtil.equal(backgroundImage, other.backgroundImage)
  656. && CompareUtil.equal(backgroundPositionHorizontal, backgroundPositionHorizontal)
  657. && CompareUtil.equal(backgroundPositionVertical, other.backgroundPositionVertical)
  658. && backgroundRepeat == other.backgroundRepeat
  659. && Arrays.equals(borderInfo, other.borderInfo)
  660. && Arrays.equals(padding, other.padding);
  661. }
  662. @Override
  663. public int hashCode() {
  664. if (this.hash == -1) {
  665. int hash = getHashCode(backgroundColor,
  666. backgroundImage,
  667. backgroundPositionHorizontal,
  668. backgroundPositionVertical,
  669. borderInfo[BEFORE],
  670. borderInfo[AFTER],
  671. borderInfo[START],
  672. borderInfo[END],
  673. padding[BEFORE],
  674. padding[AFTER],
  675. padding[START],
  676. padding[END]);
  677. hash = 37 * hash + backgroundAttachment;
  678. hash = 37 * hash + backgroundRepeat;
  679. this.hash = hash;
  680. }
  681. return this.hash;
  682. }
  683. private int getHashCode(Object... objects) {
  684. int hash = 17;
  685. for (Object o : objects) {
  686. hash = 37 * hash + (o == null ? 0 : o.hashCode());
  687. }
  688. return hash;
  689. }
  690. }