📄 stylesheet.java
字号:
} } } } /** * A temporary class used to hold a Vector, a StringBuffer and a * Hashtable. This is used to avoid allocing a lot of garbage when * searching for rules. Use the static method obtainSearchBuffer and * releaseSearchBuffer to get a SearchBuffer, and release it when * done. */ private static class SearchBuffer { /** A stack containing instances of SearchBuffer. Used in getting * rules. */ static Stack searchBuffers = new Stack(); // A set of temporary variables that can be used in whatever way. Vector vector = null; StringBuffer stringBuffer = null; Hashtable hashtable = null; /** * Returns an instance of SearchBuffer. Be sure and issue * a releaseSearchBuffer when done with it. */ static SearchBuffer obtainSearchBuffer() { SearchBuffer sb; try { sb = (SearchBuffer)searchBuffers.pop(); } catch (EmptyStackException ese) { sb = new SearchBuffer(); } return sb; } /** * Adds <code>sb</code> to the stack of SearchBuffers that can * be used. */ static void releaseSearchBuffer(SearchBuffer sb) { sb.empty(); searchBuffers.push(sb); } StringBuffer getStringBuffer() { if (stringBuffer == null) { stringBuffer = new StringBuffer(); } return stringBuffer; } Vector getVector() { if (vector == null) { vector = new Vector(); } return vector; } Hashtable getHashtable() { if (hashtable == null) { hashtable = new Hashtable(); } return hashtable; } void empty() { if (stringBuffer != null) { stringBuffer.setLength(0); } if (vector != null) { vector.removeAllElements(); } if (hashtable != null) { hashtable.clear(); } } } static final Border noBorder = new EmptyBorder(0,0,0,0); /** * Class to carry out some of the duties of * CSS formatting. Implementations of this * class enable views to present the CSS formatting * while not knowing anything about how the CSS values * are being cached. * <p> * As a delegate of Views, this object is responsible for * the insets of a View and making sure the background * is maintained according to the CSS attributes. */ public static class BoxPainter implements Serializable { BoxPainter(AttributeSet a, CSS css, StyleSheet ss) { this.ss = ss; this.css = css; border = getBorder(a); binsets = border.getBorderInsets(null); topMargin = getLength(CSS.Attribute.MARGIN_TOP, a); bottomMargin = getLength(CSS.Attribute.MARGIN_BOTTOM, a); leftMargin = getLength(CSS.Attribute.MARGIN_LEFT, a); rightMargin = getLength(CSS.Attribute.MARGIN_RIGHT, a); bg = ss.getBackground(a); if (ss.getBackgroundImage(a) != null) { bgPainter = new BackgroundImagePainter(a, css, ss); } } /** * Fetches a border to render for the given attributes. * PENDING(prinz) This is pretty badly hacked at the * moment. */ Border getBorder(AttributeSet a) { Border b = noBorder; Object o = a.getAttribute(CSS.Attribute.BORDER_STYLE); if (o != null) { String bstyle = o.toString(); int bw = (int) getLength(CSS.Attribute.BORDER_TOP_WIDTH, a); if (bw > 0) { if (bstyle.equals("inset")) { Color c = getBorderColor(a); b = new BevelBorder(BevelBorder.LOWERED, c.brighter(), c.darker()); } else if (bstyle.equals("outset")) { Color c = getBorderColor(a); b = new BevelBorder(BevelBorder.RAISED, c.brighter(), c.darker()); } else if (bstyle.equals("solid")) { Color c = getBorderColor(a); b = new LineBorder(c); } } } return b; } /** * Fetches the color to use for borders. This will either be * the value specified by the border-color attribute (which * is not inherited), or it will default to the color attribute * (which is inherited). */ Color getBorderColor(AttributeSet a) { Color color = css.getColor(a, CSS.Attribute.BORDER_COLOR); if (color == null) { color = css.getColor(a, CSS.Attribute.COLOR); if (color == null) { return Color.black; } } return color; } /** * Fetches the inset needed on a given side to * account for the margin, border, and padding. * * @param side The size of the box to fetch the * inset for. This can be View.TOP, * View.LEFT, View.BOTTOM, or View.RIGHT. * @param v the view making the request. This is * used to get the AttributeSet, and may be used to * resolve percentage arguments. * @exception IllegalArgumentException for an invalid direction */ public float getInset(int side, View v) { AttributeSet a = v.getAttributes(); float inset = 0; switch(side) { case View.LEFT: inset += leftMargin; inset += binsets.left; inset += getLength(CSS.Attribute.PADDING_LEFT, a); break; case View.RIGHT: inset += rightMargin; inset += binsets.right; inset += getLength(CSS.Attribute.PADDING_RIGHT, a); break; case View.TOP: inset += topMargin; inset += binsets.top; inset += getLength(CSS.Attribute.PADDING_TOP, a); break; case View.BOTTOM: inset += bottomMargin; inset += binsets.bottom; inset += getLength(CSS.Attribute.PADDING_BOTTOM, a); break; default: throw new IllegalArgumentException("Invalid side: " + side); } return inset; } /** * Paints the CSS box according to the attributes * given. This should paint the border, padding, * and background. * * @param g the rendering surface. * @param x the x coordinate of the allocated area to * render into. * @param y the y coordinate of the allocated area to * render into. * @param w the width of the allocated area to render into. * @param h the height of the allocated area to render into. * @param v the view making the request. This is * used to get the AttributeSet, and may be used to * resolve percentage arguments. */ public void paint(Graphics g, float x, float y, float w, float h, View v) { // PENDING(prinz) implement real rendering... which would // do full set of border and background capabilities. // remove margin x += leftMargin; y += topMargin; w -= leftMargin + rightMargin; h -= topMargin + bottomMargin; if (bg != null) { g.setColor(bg); g.fillRect((int) x, (int) y, (int) w, (int) h); } if (bgPainter != null) { bgPainter.paint(g, x, y, w, h, v); } border.paintBorder(null, g, (int) x, (int) y, (int) w, (int) h); } float getLength(CSS.Attribute key, AttributeSet a) { return css.getLength(a, key); } float topMargin; float bottomMargin; float leftMargin; float rightMargin; // Bitmask, used to indicate what margins are relative: // bit 0 for top, 1 for bottom, 2 for left and 3 for right. short marginFlags; Border border; Insets binsets; CSS css; StyleSheet ss; Color bg; BackgroundImagePainter bgPainter; } /** * Class to carry out some of the duties of CSS list * formatting. Implementations of this * class enable views to present the CSS formatting * while not knowing anything about how the CSS values * are being cached. */ public static class ListPainter implements Serializable { ListPainter(AttributeSet attr, StyleSheet ss) { /* Get the image to use as a list bullet */ String imgstr = (String)attr.getAttribute(CSS.Attribute. LIST_STYLE_IMAGE); type = null; if (imgstr != null && !imgstr.equals("none")) { String tmpstr = null; try { StringTokenizer st = new StringTokenizer(imgstr, "()"); if (st.hasMoreTokens()) tmpstr = st.nextToken(); if (st.hasMoreTokens()) tmpstr = st.nextToken(); URL u = new URL(tmpstr); img = new ImageIcon(u); } catch (MalformedURLException e) { if (tmpstr != null && ss != null && ss.getBase() != null) { try { URL u = new URL(ss.getBase(), tmpstr); img = new ImageIcon(u); } catch (MalformedURLException murle) { img = null; } } else { img = null; } } } /* Get the type of bullet to use in the list */ if (img == null) { type = (CSS.Value)attr.getAttribute(CSS.Attribute. LIST_STYLE_TYPE); } start = 1; paintRect = new Rectangle(); } /** * Returns a string that represents the value * of the HTML.Attribute.TYPE attribute. * If this attributes is not defined, then * then the type defaults to "disc" unless * the tag is on Ordered list. In the case * of the latter, the default type is "decimal". */ private CSS.Value getChildType(View childView) { CSS.Value childtype = (CSS.Value)childView.getAttributes(). getAttribute(CSS.Attribute.LIST_STYLE_TYPE); if (childtype == null) { if (type == null) { // Parent view. View v = childView.getParent(); HTMLDocument doc = (HTMLDocument)v.getDocument(); if (doc.matchNameAttribute(v.getElement().getAttributes(), HTML.Tag.OL)) { childtype = CSS.Value.DECIMAL; } else { childtype = CSS.Value.DISC; } } else { childtype = type; } } return childtype; } /** * Obtains the starting index from <code>parent</code>. */ private void getStart(View parent) { checkedForStart = true; Element element = parent.getElement(); if (element != null) { AttributeSet attr = element.getAttributes(); Object startValue; if (attr != null && attr.isDefined(HTML.Attribute.START) && (startValue = attr.getAttribute (HTML.Attribute.START)) != null && (startValue instanceof String)) { try { start = Integer.parseInt((String)startValue); } catch (NumberFormatException nfe) {} } } } /** * Returns an integer that should be used to render the child at * <code>childIndex</code> with. The retValue will usually be * <code>childIndex</code> + 1, unless <code>parentView</code> * has some Views that do not represent LI's, or one of the views * has a HTML.Attribute.START specified. */ private int getRenderIndex(View parentView, int childIndex) { if (!checkedForStart) { getStart(parentView); } int retIndex = childIndex; for (int counter = childIndex; counter >= 0; counter--) { AttributeSet as = parentView.getElement().getElement(counter). getAttributes(); if (as.getAttribute(StyleConstants.NameAttribute) != HTML.Tag.LI) { retIndex--; } else { Object value = as.getAttribute(HTML.Attribute.VALUE); if (value != null && (value instanceof String)) { try { int iValue = Integer.parseInt((String)value); return retIndex - counter + iValue; } catch (NumberFormatException nfe) {} } } } return retIndex + start; } /** * Paints the CSS list decoration according to the * attributes given. * * @param g the rendering surface. * @param x the x coordinate of the list item allocation * @param y the y coordinate of the list item allocation * @param w the width of the list item allocation * @param h the height of the list item allocation * @param v the allocated area to paint into. * @param item which list item is being painted. This * is a number greater than or equal to 0. */ public void paint(Graphics g, float x, float y, float w, float h, View v, int item) { View cv = v.getView(item); Object name = cv.getElement().getAttributes().getAttribute (StyleConstants.NameAttribute); // Only draw something if the View is a list item. This won't // be the case for comments. if (!(name instanceof HTML.Tag) || name != HTM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -