1 21 24 package org.lobobrowser.html.style; 25 import java.awt.*; 26 import java.util.*; 27 28 import org.lobobrowser.html.domimpl.*; 29 import org.lobobrowser.util.gui.ColorFactory; 30 import org.lobobrowser.util.gui.FontFactory; 31 import org.w3c.dom.css.CSS2Properties; 32 import org.w3c.dom.html2.*; 33 34 37 public class StyleSheetRenderState implements RenderState { 38 private static final FontFactory FONT_FACTORY = FontFactory.getInstance(); 39 private static final String DEFAULT_FONT_FAMILY = "Times New Roman"; 40 private static final Font DEFAULT_FONT = FONT_FACTORY.getFont(DEFAULT_FONT_FAMILY, null, null, null, HtmlValues.DEFAULT_FONT_SIZE); 41 protected static final Insets INVALID_INSETS = new Insets(0, 0, 0, 0); 42 protected static final BackgroundInfo INVALID_BACKGROUND_INFO = new BackgroundInfo(); 43 protected static final Color INVALID_COLOR = new Color(100, 0, 100); 44 45 protected final HTMLElementImpl element; 46 protected final RenderState prevRenderState; 47 48 private Font iFont; 49 private FontMetrics iFontMetrics; 50 private Color iColor; 51 private Color iBackgroundColor = INVALID_COLOR; 52 private Color iTextBackgroundColor = INVALID_COLOR; 53 private Color iOverlayColor = INVALID_COLOR; 54 private BackgroundInfo iBackgroundInfo = INVALID_BACKGROUND_INFO; 55 private int iTextDecoration = -1; 56 private int iBlankWidth = -1; 57 private boolean iHighlight; 58 59 static { 60 } 61 62 public StyleSheetRenderState(RenderState prevRenderState, HTMLElementImpl element) { 63 this.prevRenderState = prevRenderState; 64 this.element = element; 65 } 66 67 72 protected int getDefaultDisplay() { 73 return DISPLAY_INLINE; 74 } 75 76 private Integer iDisplay; 77 78 public int getDisplay() { 79 Integer d = this.iDisplay; 80 if(d != null) { 81 return d.intValue(); 82 } 83 CSS2Properties props = this.getCssProperties(); 84 String displayText = props == null ? null : props.getDisplay(); 85 int displayInt; 86 if(displayText != null) { 87 String displayTextTL = displayText.toLowerCase(); 88 if("block".equals(displayTextTL)) { 89 displayInt = DISPLAY_BLOCK; 90 } 91 else if("inline".equals(displayTextTL)) { 92 displayInt = DISPLAY_INLINE; 93 } 94 else if("none".equals(displayTextTL)) { 95 displayInt = DISPLAY_NONE; 96 } 97 else if("list-item".equals(displayTextTL)) { 98 displayInt = DISPLAY_LIST_ITEM; 99 } 100 else if("table".equals(displayTextTL)) { 101 displayInt = DISPLAY_TABLE; 102 } 103 else if("table-cell".equals(displayTextTL)) { 104 displayInt = DISPLAY_TABLE_CELL; 105 } 106 else if("table-row".equals(displayTextTL)) { 107 displayInt = DISPLAY_TABLE_ROW; 108 } 109 else { 110 displayInt = this.getDefaultDisplay(); 111 } 112 } 113 else { 114 displayInt = this.getDefaultDisplay(); 115 } 116 d = new Integer (displayInt); 117 this.iDisplay = d; 118 return displayInt; 119 } 120 121 public RenderState getPreviousRenderState() { 122 return this.prevRenderState; 123 } 124 125 public int getFontBase() { 126 RenderState prs = this.prevRenderState; 127 return prs == null ? 3 : prs.getFontBase(); 128 } 129 130 public void repaint() { 131 } 133 134 protected final CSS2PropertiesImpl getCssProperties() { 135 HTMLElementImpl element = this.element; 136 return element == null ? null : element.getCurrentStyle(); 137 } 138 139 public StyleSheetRenderState() { 140 this.element = null; 143 this.prevRenderState = null; 144 } 145 146 public void invalidate() { 147 Map map = this.iWordInfoMap; 148 if(map != null) { 149 map.clear(); 150 } 151 this.iFont = null; 152 this.iFontMetrics = null; 153 this.iColor = null; 154 this.iTextDecoration = -1; 155 this.iBlankWidth = -1; 156 this.alignXPercent = -1; 157 this.iBackgroundColor = INVALID_COLOR; 158 this.iTextBackgroundColor = INVALID_COLOR; 159 this.iOverlayColor = INVALID_COLOR; 160 this.iBackgroundInfo = INVALID_BACKGROUND_INFO; 161 this.iDisplay = null; 162 this.iTextIndentText = null; 163 this.iWhiteSpace = null; 164 this.marginInsets = INVALID_INSETS; 165 this.paddingInsets = INVALID_INSETS; 166 } 168 169 217 218 public Font getFont() { 219 Font f = this.iFont; 220 if(f != null) { 221 return f; 222 } 223 CSS2PropertiesImpl style = this.getCssProperties(); 224 RenderState prs = this.prevRenderState; 225 if(style == null) { 226 if(prs != null) { 227 f = prs.getFont(); 228 this.iFont = f; 229 return f; 230 } 231 f = DEFAULT_FONT; 232 this.iFont = f; 233 return f; 234 } 235 Float fontSize = null; 236 String fontStyle = null; 237 String fontVariant = null; 238 String fontWeight = null; 239 String fontFamily = null; 240 241 String fontSpec = style == null ? null : style.getFont(); 242 if(fontSpec != null) { 243 FontInfo fontInfo = HtmlValues.createFontInfo(fontSpec, this.prevRenderState); 244 fontSize = fontInfo.fontSize; 245 fontStyle = fontInfo.fontStyle; 246 fontVariant = fontInfo.fontVariant; 247 fontWeight = fontInfo.fontWeight; 248 fontFamily = fontInfo.fontFamily; 249 } 250 String newFontSize = style == null ? null : style.getFontSize(); 251 String newFontFamily = style == null ? null : style.getFontFamily(); 252 String newFontStyle = style == null ? null : style.getFontStyle(); 253 String newFontVariant = style == null ? null : style.getFontVariant(); 254 String newFontWeight = style == null ? null : style.getFontWeight(); 255 if(fontSpec == null && newFontSize == null && newFontWeight == null && newFontStyle == null && newFontFamily == null && newFontVariant == null) { 256 if(prs != null) { 257 f = prs.getFont(); 258 this.iFont = f; 259 return f; 260 } 261 f = DEFAULT_FONT; 262 this.iFont = f; 263 return f; 264 } 265 if(newFontSize != null) { 266 try { 267 fontSize = new Float (HtmlValues.getFontSize(newFontSize, prs)); 268 } catch(Exception err) { 269 fontSize = HtmlValues.DEFAULT_FONT_SIZE_BOX; 270 } 271 } 272 else if(fontSize == null) { 273 if(prs != null) { 274 fontSize = new Float (prs.getFont().getSize()); 275 } else { 276 fontSize = HtmlValues.DEFAULT_FONT_SIZE_BOX; 277 } 278 } 279 if(newFontFamily != null) { 280 fontFamily = newFontFamily; 281 } 282 else if(fontFamily == null && prs != null) { 283 fontFamily = prs.getFont().getFamily(); 284 } 285 if(fontFamily == null) { 286 fontFamily = DEFAULT_FONT_FAMILY; 287 } 288 if(newFontStyle != null) { 289 fontStyle = newFontStyle; 290 } 291 else if(fontStyle == null && prs != null) { 292 int fstyle = prs.getFont().getStyle(); 293 if((fstyle & Font.ITALIC) != 0) { 294 fontStyle = "italic"; 295 } 296 } 297 if(newFontVariant != null) { 298 fontVariant = newFontVariant; 299 } 300 else if(prs != null) { 301 } 303 if(newFontWeight != null) { 304 fontWeight = newFontWeight; 305 } 306 else if(fontWeight == null && prs != null) { 307 int fstyle = prs.getFont().getStyle(); 308 if((fstyle & Font.BOLD) != 0) { 309 fontWeight = "bold"; 310 } 311 } 312 f = FONT_FACTORY.getFont(fontFamily, fontStyle, fontVariant, fontWeight, fontSize.floatValue()); 313 this.iFont = f; 314 return f; 315 } 316 317 public Color getColor() { 318 Color c = this.iColor; 319 if(c != null) { 320 return c; 321 } 322 CSS2PropertiesImpl props = this.getCssProperties(); 323 String colorValue = props == null ? null : props.getColor(); 324 if(colorValue == null || "".equals(colorValue)) { 325 RenderState prs = this.prevRenderState; 326 if(prs != null) { 327 c = prs.getColor(); 328 this.iColor = c; 329 return c; 330 } 331 else { 332 colorValue = "black"; 333 } 334 } 335 c = ColorFactory.getInstance().getColor(colorValue); 336 this.iColor = c; 337 return c; 338 } 339 340 public Color getBackgroundColor() { 341 Color c = this.iBackgroundColor; 342 if(c != INVALID_COLOR) { 343 return c; 344 } 345 Color localColor; 346 BackgroundInfo binfo = this.getBackgroundInfo(); 347 localColor = binfo == null ? null : binfo.backgroundColor; 348 if(localColor == null && this.getDisplay() == DISPLAY_INLINE) { 349 RenderState prs = this.prevRenderState; 350 if(prs != null) { 351 Color ancestorColor = prs.getBackgroundColor(); 352 if(ancestorColor != null) { 353 this.iBackgroundColor = ancestorColor; 354 return ancestorColor; 355 } 356 } 357 } 358 this.iBackgroundColor = localColor; 359 return localColor; 360 } 361 362 public Color getTextBackgroundColor() { 363 Color c = this.iTextBackgroundColor; 364 if(c != INVALID_COLOR) { 365 return c; 366 } 367 Color localColor; 368 if(this.getDisplay() != DISPLAY_INLINE) { 369 localColor = null; 371 } 372 else { 373 BackgroundInfo binfo = this.getBackgroundInfo(); 374 localColor = binfo == null ? null : binfo.backgroundColor; 375 if(localColor == null) { 376 RenderState prs = this.prevRenderState; 377 if(prs != null) { 378 Color ancestorColor = prs.getTextBackgroundColor(); 379 if(ancestorColor != null) { 380 this.iTextBackgroundColor = ancestorColor; 381 return ancestorColor; 382 } 383 } 384 } 385 } 386 this.iTextBackgroundColor = localColor; 387 return localColor; 388 } 389 390 public Color getOverlayColor() { 391 Color c = this.iOverlayColor; 392 if(c != INVALID_COLOR) { 393 return c; 394 } 395 CSS2PropertiesImpl props = this.getCssProperties(); 396 String colorValue = props == null ? null : props.getOverlayColor(); 397 if(colorValue == null || colorValue.length() == 0) { 398 RenderState prs = this.prevRenderState; 399 if(prs != null) { 400 c = prs.getOverlayColor(); 401 this.iOverlayColor = c; 402 return c; 403 } 404 else { 405 colorValue = null; 406 } 407 } 408 c = colorValue == null ? null : ColorFactory.getInstance().getColor(colorValue); 409 this.iOverlayColor = c; 410 return c; 411 } 412 413 public int getTextDecorationMask() { 414 int td = this.iTextDecoration; 415 if(td != -1) { 416 return td; 417 } 418 CSS2PropertiesImpl props = this.getCssProperties(); 419 String tdText = props == null ? null : props.getTextDecoration(); 420 if(tdText == null) { 421 RenderState prs = this.prevRenderState; 422 if(prs != null) { 423 td = prs.getTextDecorationMask(); 424 this.iTextDecoration = td; 425 return td; 426 } 427 } 428 td = 0; 429 if(tdText != null) { 430 StringTokenizer tok = new StringTokenizer(tdText.toLowerCase(), ", \t\n\r"); 431 while(tok.hasMoreTokens()) { 432 String token = tok.nextToken(); 433 if("none".equals(token)) { 434 } 436 else if("underline".equals(token)) { 437 td |= StyleSheetRenderState.MASK_TEXTDECORATION_UNDERLINE; 438 } 439 else if("line-through".equals(token)) { 440 td |= StyleSheetRenderState.MASK_TEXTDECORATION_LINE_THROUGH; 441 } 442 else if("blink".equals(token)) { 443 td |= StyleSheetRenderState.MASK_TEXTDECORATION_BLINK; 444 } 445 else if("overline".equals(token)) { 446 td |= StyleSheetRenderState.MASK_TEXTDECORATION_OVERLINE; 447 } 448 } 449 } 450 this.iTextDecoration = td; 451 return td; 452 } 453 454 public final FontMetrics getFontMetrics() { 455 FontMetrics fm = this.iFontMetrics; 456 if(fm == null) { 457 fm = Toolkit.getDefaultToolkit().getFontMetrics(this.getFont()); 459 this.iFontMetrics = fm; 460 } 461 return fm; 462 } 463 464 public int getBlankWidth() { 465 int bw = this.iBlankWidth; 466 if(bw == -1) { 467 bw = this.getFontMetrics().charWidth(' '); 468 this.iBlankWidth = bw; 469 } 470 return bw; 471 } 472 473 476 public boolean isHighlight() { 477 return this.iHighlight; 478 } 479 480 483 public void setHighlight(boolean highlight) { 484 this.iHighlight = highlight; 485 } 486 487 Map iWordInfoMap = null; 488 489 public final WordInfo getWordInfo(String word) { 490 Map map = this.iWordInfoMap; 493 if(map == null) { 494 map = new HashMap(1); 495 this.iWordInfoMap = map; 496 } 497 WordInfo wi = (WordInfo) map.get(word); 498 if(wi != null) { 499 return wi; 500 } 501 wi = new WordInfo(); 502 FontMetrics fm = this.getFontMetrics(); 503 wi.fontMetrics = fm; 504 wi.ascentPlusLeading = fm.getAscent() + fm.getLeading(); 505 wi.descent = fm.getDescent(); 506 wi.height = fm.getHeight(); 507 wi.width = fm.stringWidth(word); 508 map.put(word, wi); 509 return wi; 510 } 511 512 private int alignXPercent = -1; 513 514 public int getAlignXPercent() { 515 int axp = this.alignXPercent; 516 if(axp != -1) { 517 return axp; 518 } 519 CSS2Properties props = this.getCssProperties(); 520 String textAlign = props == null ? null : props.getTextAlign(); 521 if(textAlign == null || textAlign.length() == 0) { 522 HTMLElement element = this.element; 524 if(element != null) { 525 textAlign = element.getAttribute("align"); 526 if(textAlign == null || textAlign.length() == 0) { 527 RenderState prs = this.prevRenderState; 528 if(prs != null) { 529 return prs.getAlignXPercent(); 530 } 531 textAlign = null; 532 } 533 } 534 } 535 if(textAlign == null) { 536 axp = 0; 537 } 538 else if("center".equalsIgnoreCase(textAlign)) { 539 axp = 50; 540 } 541 else if("right".equalsIgnoreCase(textAlign)) { 542 axp = 100; 543 } 544 else { 545 axp = 0; 547 } 548 this.alignXPercent = axp; 549 return axp; 550 } 551 552 public int getAlignYPercent() { 553 return 0; 556 } 557 558 private Map counters = null; 559 560 public int getCount(String counter, int nesting) { 561 RenderState prs = this.prevRenderState; 563 if(prs != null) { 564 return prs.getCount(counter, nesting); 565 } 566 Map counters = this.counters; 567 if(counters == null) { 568 return 0; 569 } 570 ArrayList counterArray = (ArrayList) counters.get(counter); 571 if(nesting < 0 || nesting >= counterArray.size()) { 572 return 0; 573 } 574 Integer integer = (Integer ) counterArray.get(nesting); 575 return integer == null ? 0 : integer.intValue(); 576 } 577 578 public void resetCount(String counter, int nesting, int value) { 579 RenderState prs = this.prevRenderState; 581 if(prs != null) { 582 prs.resetCount(counter, nesting, value); 583 } 584 Map counters = this.counters; 585 if(counters == null) { 586 counters = new HashMap(2); 587 this.counters = counters; 588 counters.put(counter, new ArrayList(0)); 589 } 590 ArrayList counterArray = (ArrayList) counters.get(counter); 591 while(counterArray.size() <= nesting) { 592 counterArray.add(null); 593 } 594 counterArray.set(nesting, new Integer (value)); 595 } 596 597 public int incrementCount(String counter, int nesting) { 598 RenderState prs = this.prevRenderState; 600 if(prs != null) { 601 return prs.incrementCount(counter, nesting); 602 } 603 Map counters = this.counters; 604 if(counters == null) { 605 counters = new HashMap(2); 606 this.counters = counters; 607 counters.put(counter, new ArrayList(0)); 608 } 609 ArrayList counterArray = (ArrayList) counters.get(counter); 610 while(counterArray.size() <= nesting) { 611 counterArray.add(null); 612 } 613 Integer integer = (Integer ) counterArray.get(nesting); 614 int prevValue = integer == null ? 0 : integer.intValue(); 615 counterArray.set(nesting, new Integer (prevValue + 1)); 616 return prevValue; 617 } 618 619 public BackgroundInfo getBackgroundInfo() { 620 BackgroundInfo binfo = this.iBackgroundInfo; 621 if(binfo != INVALID_BACKGROUND_INFO) { 622 return binfo; 623 } 624 binfo = null; 625 CSS2PropertiesImpl props = this.getCssProperties(); 626 if(props != null) { 627 String background = props.getBackground(); 628 if(background != null) { 629 if(binfo == null) { 630 binfo = new BackgroundInfo(); 631 } 632 this.applyBackground(binfo, background); 633 } 634 String backgroundColorText = props.getBackgroundColor(); 635 if(backgroundColorText != null) { 636 if(binfo == null) { 637 binfo = new BackgroundInfo(); 638 } 639 binfo.backgroundColor = ColorFactory.getInstance().getColor(backgroundColorText); 640 } 641 String backgroundImageText = props.getBackgroundImage(); 642 if(backgroundImageText != null) { 643 String backgroundImage = HtmlValues.getURIFromStyleValue(backgroundImageText); 644 if(backgroundImage != null) { 645 if(binfo == null) { 646 binfo = new BackgroundInfo(); 647 } 648 binfo.backgroundImage = backgroundImage; 649 } 650 } 651 String backgroundRepeatText = props.getBackgroundRepeat(); 652 if(backgroundRepeatText != null) { 653 if(binfo == null) { 654 binfo = new BackgroundInfo(); 655 } 656 this.applyBackgroundRepeat(binfo, backgroundRepeatText); 657 } 658 String backgroundPositionText = props.getBackgroundPosition(); 659 if(backgroundPositionText != null) { 660 if(binfo == null) { 661 binfo = new BackgroundInfo(); 662 } 663 this.applyBackgroundPosition(binfo, backgroundPositionText); 664 } 665 } 666 this.iBackgroundInfo = binfo; 667 return binfo; 668 } 669 670 private String iTextIndentText = null; 671 672 public String getTextIndentText() { 673 String tiText = this.iTextIndentText; 674 if(tiText != null) { 675 return tiText; 676 } 677 CSS2PropertiesImpl props = this.getCssProperties(); 678 tiText = props == null ? null : props.getTextIndent(); 679 if(tiText == null) { 680 RenderState prs = this.prevRenderState; 681 if(prs != null) { 682 String parentText = prs.getTextIndentText(); 683 this.iTextIndentText = parentText; 684 return parentText; 685 } 686 else { 687 tiText = ""; 688 } 689 } 690 return tiText; 691 } 692 693 public int getTextIndent(int availSize) { 694 String tiText = this.getTextIndentText(); 696 if(tiText.length() == 0) { 697 return 0; 698 } 699 else { 700 return HtmlValues.getPixelSize(tiText, this, 0, availSize); 701 } 702 } 703 704 protected Integer iWhiteSpace; 705 706 public int getWhiteSpace() { 707 if(RenderThreadState.getState().overrideNoWrap) { 708 return WS_NOWRAP; 709 } 710 Integer ws = this.iWhiteSpace; 711 if(ws != null) { 712 return ws.intValue(); 713 } 714 CSS2PropertiesImpl props = this.getCssProperties(); 715 String whiteSpaceText = props == null ? null : props.getWhiteSpace(); 716 int wsValue; 717 if(whiteSpaceText == null) { 718 HTMLElementImpl element = this.element; 719 if(element != null && element.getAttributeAsBoolean("nowrap")) { 720 wsValue = WS_NOWRAP; 721 } 722 else { 723 RenderState prs = this.prevRenderState; 724 if(prs != null) { 725 wsValue = prs.getWhiteSpace(); 726 } 727 else { 728 wsValue = WS_NORMAL; 729 } 730 } 731 } 732 else { 733 String whiteSpaceTextTL = whiteSpaceText.toLowerCase(); 734 if("nowrap".equals(whiteSpaceTextTL)) { 735 wsValue = WS_NOWRAP; 736 } 737 else if("pre".equals(whiteSpaceTextTL)) { 738 wsValue = WS_PRE; 739 } 740 else { 741 wsValue = WS_NORMAL; 742 } 743 } 744 this.iWhiteSpace = new Integer (wsValue); 745 return wsValue; 746 } 747 748 private java.awt.Insets marginInsets = INVALID_INSETS; 749 private java.awt.Insets paddingInsets = INVALID_INSETS; 750 751 public java.awt.Insets getMarginInsets() { 752 Insets mi = this.marginInsets; 753 if(mi != INVALID_INSETS) { 754 return mi; 755 } 756 CSS2PropertiesImpl props = this.getCssProperties(); 757 if(props == null) { 758 mi = null; 759 } 760 else { 761 mi = HtmlValues.getMarginInsets(props, this); 762 } 763 this.marginInsets = mi; 764 return mi; 765 } 766 767 public java.awt.Insets getPaddingInsets() { 768 Insets mi = this.paddingInsets; 769 if(mi != INVALID_INSETS) { 770 return mi; 771 } 772 CSS2PropertiesImpl props = this.getCssProperties(); 773 if(props == null) { 774 mi = null; 775 } 776 else { 777 mi = HtmlValues.getPaddingInsets(props, this); 778 this.paddingInsets = mi; 779 } 780 return mi; 781 } 782 783 private void applyBackgroundHorizontalPositon(BackgroundInfo binfo, String xposition) { 784 if(xposition.endsWith("%")) { 785 binfo.backgroundXPositionAbsolute = false; 786 try { 787 binfo.backgroundXPosition = (int) Double.parseDouble(xposition.substring(0, xposition.length() - 1).trim()); 788 } catch(NumberFormatException nfe) { 789 binfo.backgroundXPosition = 0; 790 } 791 } 792 else if("center".equalsIgnoreCase(xposition)) { 793 binfo.backgroundXPositionAbsolute = false; 794 binfo.backgroundXPosition = 50; 795 } 796 else if("right".equalsIgnoreCase(xposition)) { 797 binfo.backgroundXPositionAbsolute = false; 798 binfo.backgroundXPosition = 100; 799 } 800 else if("left".equalsIgnoreCase(xposition)) { 801 binfo.backgroundXPositionAbsolute = false; 802 binfo.backgroundXPosition = 0; 803 } 804 else { 805 binfo.backgroundXPositionAbsolute = true; 806 binfo.backgroundXPosition = HtmlValues.getPixelSize(xposition, this, 0); 807 } 808 } 809 810 private void applyBackgroundVerticalPosition(BackgroundInfo binfo, String yposition) { 811 if(yposition.endsWith("%")) { 812 binfo.backgroundYPositionAbsolute = false; 813 try { 814 binfo.backgroundYPosition = (int) Double.parseDouble(yposition.substring(0, yposition.length() - 1).trim()); 815 } catch(NumberFormatException nfe) { 816 binfo.backgroundYPosition = 0; 817 } 818 } 819 else if("center".equalsIgnoreCase(yposition)) { 820 binfo.backgroundYPositionAbsolute = false; 821 binfo.backgroundYPosition = 50; 822 } 823 else if("bottom".equalsIgnoreCase(yposition)) { 824 binfo.backgroundYPositionAbsolute = false; 825 binfo.backgroundYPosition = 100; 826 } 827 else if("top".equalsIgnoreCase(yposition)) { 828 binfo.backgroundYPositionAbsolute = false; 829 binfo.backgroundYPosition = 0; 830 } 831 else { 832 binfo.backgroundYPositionAbsolute = true; 833 binfo.backgroundYPosition = HtmlValues.getPixelSize(yposition, this, 0); 834 } 835 } 836 837 private void applyBackgroundPosition(BackgroundInfo binfo, String position) { 838 StringTokenizer tok = new StringTokenizer(position, " \t\r\n"); 839 if(tok.hasMoreTokens()) { 840 String xposition = tok.nextToken(); 841 this.applyBackgroundHorizontalPositon(binfo, xposition); 842 if(tok.hasMoreTokens()) { 843 String yposition = tok.nextToken(); 844 this.applyBackgroundVerticalPosition(binfo, yposition); 845 } 846 } 847 } 848 849 private void applyBackground(BackgroundInfo binfo, String background) { 850 String [] tokens = HtmlValues.splitCssValue(background); 851 boolean hasXPosition = false; 852 for(int i = 0; i < tokens.length; i++) { 853 String token = tokens[i]; 854 if(ColorFactory.getInstance().isColor(token)) { 855 binfo.backgroundColor = ColorFactory.getInstance().getColor(token); 856 } 857 else if(HtmlValues.isUrl(token)) { 858 binfo.backgroundImage = HtmlValues.getURIFromStyleValue(token); 859 } 860 else if(isBackgroundRepeat(token)) { 861 this.applyBackgroundRepeat(binfo, token); 862 } 863 else if(isBackgroundPosition(token)) { 864 if(hasXPosition) { 865 this.applyBackgroundVerticalPosition(binfo, token); 866 } 867 else { 868 hasXPosition = true; 869 this.applyBackgroundHorizontalPositon(binfo, token); 870 } 871 } 872 } 873 } 874 875 private boolean isBackgroundPosition(String token) { 876 return HtmlValues.isLength(token) || 877 token.endsWith("%") || 878 token.equalsIgnoreCase("top") || 879 token.equalsIgnoreCase("center") || 880 token.equalsIgnoreCase("bottom") || 881 token.equalsIgnoreCase("left") || 882 token.equalsIgnoreCase("right"); 883 } 884 885 private boolean isBackgroundRepeat(String repeat) { 886 String repeatTL = repeat.toLowerCase(); 887 return repeatTL.indexOf("repeat") != -1; 888 } 889 890 private void applyBackgroundRepeat(BackgroundInfo binfo, String backgroundRepeatText) { 891 String brtl = backgroundRepeatText.toLowerCase(); 892 if("repeat".equals(brtl)) { 893 binfo.backgroundRepeat = BackgroundInfo.BR_REPEAT; 894 } 895 else if("repeat-x".equals(brtl)) { 896 binfo.backgroundRepeat = BackgroundInfo.BR_REPEAT_X; 897 } 898 else if("repeat-y".equals(brtl)) { 899 binfo.backgroundRepeat = BackgroundInfo.BR_REPEAT_Y; 900 } 901 else if("no-repeat".equals(brtl)) { 902 binfo.backgroundRepeat = BackgroundInfo.BR_NO_REPEAT; 903 } 904 } 905 906 907 public String toString() { 908 return "StyleSheetRenderState[font=" + this.getFont() + ",textDecoration=" + this.getTextDecorationMask() + "]"; 909 } 910 } 911 | Popular Tags |