1 |
// Jericho HTML Parser - Java based library for analysing and manipulating HTML
|
2 |
// Version 3.2
|
3 |
// Copyright (C) 2004-2009 Martin Jericho
|
4 |
// http://jericho.htmlparser.net/
|
5 |
//
|
6 |
// This library is free software; you can redistribute it and/or
|
7 |
// modify it under the terms of either one of the following licences:
|
8 |
//
|
9 |
// 1. The Eclipse Public License (EPL) version 1.0,
|
10 |
// included in this distribution in the file licence-epl-1.0.html
|
11 |
// or available at http://www.eclipse.org/legal/epl-v10.html
|
12 |
//
|
13 |
// 2. The GNU Lesser General Public License (LGPL) version 2.1 or later,
|
14 |
// included in this distribution in the file licence-lgpl-2.1.txt
|
15 |
// or available at http://www.gnu.org/licenses/lgpl.txt
|
16 |
//
|
17 |
// This library is distributed on an "AS IS" basis,
|
18 |
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
19 |
// See the individual licence texts for more details.
|
20 |
|
21 |
package net.htmlparser.jericho;
|
22 |
|
23 |
import java.util.*;
|
24 |
|
25 |
final class RendererCSS {
|
26 |
private static enum Side {
|
27 |
top, right, bottom, left
|
28 |
}
|
29 |
|
30 |
private static Map<String,Float> UNIT_FACTOR=new HashMap<String,Float>();
|
31 |
static {
|
32 |
UNIT_FACTOR.put("em",1.0F);
|
33 |
UNIT_FACTOR.put("ex",1.0F);
|
34 |
UNIT_FACTOR.put("px",0.125F);
|
35 |
UNIT_FACTOR.put("in",8F);
|
36 |
UNIT_FACTOR.put("cm",3F);
|
37 |
UNIT_FACTOR.put("mm",0.3F);
|
38 |
UNIT_FACTOR.put("pt",0.1F);
|
39 |
UNIT_FACTOR.put("pc",1.2F);
|
40 |
}
|
41 |
|
42 |
public static int getTopMargin(final Element element, int defaultValue) {
|
43 |
return getMargin(get(element),Side.top,defaultValue);
|
44 |
}
|
45 |
|
46 |
public static int getBottomMargin(final Element element, int defaultValue) {
|
47 |
return getMargin(get(element),Side.bottom,defaultValue);
|
48 |
}
|
49 |
|
50 |
public static int getLeftMargin(final Element element, int defaultValue) {
|
51 |
return getMargin(get(element),Side.left,defaultValue);
|
52 |
}
|
53 |
|
54 |
public static int getRightMargin(final Element element, int defaultValue) {
|
55 |
return getMargin(get(element),Side.right,defaultValue);
|
56 |
}
|
57 |
|
58 |
private static String get(final Element element) {
|
59 |
return element.getAttributeValue("style");
|
60 |
}
|
61 |
|
62 |
private static int getMargin(final String css, final Side side, final int defaultValue) {
|
63 |
if (css==null) return defaultValue;
|
64 |
String[] styles=css.split(";");
|
65 |
for (int i=0; i<styles.length; i++) styles[i]=styles[i].toLowerCase().trim();
|
66 |
int margin=getStyleValue(styles,side,"margin");
|
67 |
int padding=getStyleValue(styles,side,"padding");
|
68 |
if (margin==-1) return padding!=-1 ? padding : defaultValue;
|
69 |
return padding!=-1 ? margin+padding : margin;
|
70 |
}
|
71 |
|
72 |
private static int getStyleValue(final String[] styles, final Side side, final String styleName) {
|
73 |
int combinedStyleValue=-1;
|
74 |
for (int i=0; i<styles.length; i++) {
|
75 |
final String style=styles[i];
|
76 |
if (style.length()<=styleName.length()+1 || !style.startsWith(styleName)) continue;
|
77 |
int colonPos=style.indexOf(':');
|
78 |
if (colonPos==-1) continue;
|
79 |
String styleValue=style.substring(colonPos+1).trim();
|
80 |
if (styleValue.length()==0) continue;
|
81 |
boolean explicitSide=false;
|
82 |
int styleNameEnd=styleName.length();
|
83 |
if (style.charAt(styleName.length())=='-' && style.startsWith(side.name(),styleName.length()+1)) {
|
84 |
// eg margin-top: 1em
|
85 |
explicitSide=true;
|
86 |
styleNameEnd=styleName.length()+1+side.name().length();
|
87 |
if (style.length()<=styleNameEnd+1) continue;
|
88 |
}
|
89 |
if (styleNameEnd!=colonPos && !Segment.isWhiteSpace(style.charAt(styleNameEnd))) continue;
|
90 |
if (!explicitSide) {
|
91 |
// eg margin: 1em 0 2px 0
|
92 |
final String[] styleValueItems=styleValue.split("\\s+");
|
93 |
int itemIndex=side.ordinal();
|
94 |
final int itemCount=styleValueItems.length;
|
95 |
if (itemCount==0) continue;
|
96 |
if (itemCount==1) {
|
97 |
// top/right/bottom/left all in one item
|
98 |
itemIndex=0;
|
99 |
} else if (itemCount==2) {
|
100 |
// top/bottom, left/right
|
101 |
itemIndex=side.ordinal()%2;
|
102 |
} else if (itemCount==3) {
|
103 |
// top, left/right, bottom
|
104 |
if (side==Side.left) itemIndex=1;
|
105 |
}
|
106 |
styleValue=styleValueItems[itemIndex].trim();
|
107 |
}
|
108 |
int value=0;
|
109 |
if (styleValue.length()==0) continue;
|
110 |
if (styleValue.charAt(styleValue.length()-1)=='%') continue;
|
111 |
if (styleValue.equals("auto") || styleValue.equals("inherit")) continue;
|
112 |
if (styleValue.length()<3) {
|
113 |
if (!styleValue.equals("0")) continue;
|
114 |
} else {
|
115 |
Float unitFactor=UNIT_FACTOR.get(styleValue.substring(styleValue.length()-2));
|
116 |
if (unitFactor==null) continue;
|
117 |
float rawValue;
|
118 |
try {
|
119 |
rawValue=Float.parseFloat(styleValue.substring(0,styleValue.length()-2));
|
120 |
} catch (NumberFormatException ex) {
|
121 |
continue;
|
122 |
}
|
123 |
value=Math.round(rawValue*unitFactor);
|
124 |
}
|
125 |
if (explicitSide) return value;
|
126 |
combinedStyleValue=value;
|
127 |
}
|
128 |
return combinedStyleValue;
|
129 |
}
|
130 |
}
|