001 /* 002 * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 /* $Id: ElementListSupport.java,v d02878fc1d01 2009/09/08 12:35:02 max $ */ 018 019 package net.sourceforge.jeuclid.elements.support; 020 021 import java.awt.Color; 022 import java.awt.geom.Dimension2D; 023 import java.util.ArrayList; 024 import java.util.List; 025 026 import net.sourceforge.jeuclid.layout.FillRectObject; 027 import net.sourceforge.jeuclid.layout.GraphicsObject; 028 import net.sourceforge.jeuclid.layout.LayoutInfo; 029 import net.sourceforge.jeuclid.layout.LayoutStage; 030 import net.sourceforge.jeuclid.layout.LayoutView; 031 import net.sourceforge.jeuclid.layout.LayoutableNode; 032 033 import org.w3c.dom.Node; 034 035 /** 036 * Class to support Lists of MathElements. 037 * <p> 038 * This class can be used by all elements that have some kind of a list of 039 * children that they need to handle in a row-like manner. 040 * 041 * @version $Revision: d02878fc1d01 $ 042 */ 043 public final class ElementListSupport { 044 045 private ElementListSupport() { 046 // Utility class. 047 } 048 049 /** 050 * Creates a list of children for the given Element. 051 * 052 * @param parent 053 * the parent element. 054 * @return list of Children. 055 */ 056 public static List<Node> createListOfChildren(final Node parent) { 057 final org.w3c.dom.NodeList childList = parent.getChildNodes(); 058 final int len = childList.getLength(); 059 final List<Node> children = new ArrayList<Node>(len); 060 for (int i = 0; i < len; i++) { 061 final Node child = childList.item(i); 062 children.add(child); 063 } 064 return children; 065 066 } 067 068 /** 069 * Creates a list of layoutable children for the given Element. 070 * 071 * @param parent 072 * the parent element. 073 * @return list of Children. 074 */ 075 public static List<LayoutableNode> createListOfLayoutChildren( 076 final Node parent) { 077 final org.w3c.dom.NodeList childList = parent.getChildNodes(); 078 final int len = childList.getLength(); 079 final List<LayoutableNode> children = new ArrayList<LayoutableNode>(len); 080 for (int i = 0; i < len; i++) { 081 final Node child = childList.item(i); 082 if (child instanceof LayoutableNode) { 083 children.add((LayoutableNode) child); 084 } 085 } 086 return children; 087 088 } 089 090 /** 091 * @param view 092 * View Object 093 * @param info 094 * Info to fill 095 * @param parent 096 * Current Node 097 * @param stage 098 * Stage to load Info From 099 * @param borderLeftTop 100 * border around element. 101 * @param borderRightBottom 102 * border around element. 103 */ 104 public static void fillInfoFromChildren(final LayoutView view, 105 final LayoutInfo info, final Node parent, final LayoutStage stage, 106 final Dimension2D borderLeftTop, final Dimension2D borderRightBottom) { 107 float ascentHeight = (float) borderLeftTop.getHeight(); 108 float descentHeight = (float) borderRightBottom.getHeight(); 109 final float startX = (float) borderLeftTop.getWidth(); 110 float width = startX; 111 for (final LayoutableNode child : ElementListSupport 112 .createListOfLayoutChildren(parent)) { 113 final LayoutInfo childInfo = view.getInfo(child); 114 ascentHeight = Math.max(ascentHeight, -childInfo.getPosY(stage) 115 + childInfo.getAscentHeight(stage)); 116 descentHeight = Math.max(descentHeight, childInfo.getPosY(stage) 117 + childInfo.getDescentHeight(stage)); 118 width = Math.max(width, childInfo.getPosX(stage) 119 + childInfo.getWidth(stage)); 120 } 121 info.setAscentHeight(ascentHeight + (float) borderLeftTop.getHeight(), 122 stage); 123 info.setDescentHeight(descentHeight 124 + (float) borderRightBottom.getHeight(), stage); 125 info.setHorizontalCenterOffset((width + startX) / 2.0f, stage); 126 info.setWidth(width + (float) borderRightBottom.getWidth(), stage); 127 } 128 129 /** 130 * @param view 131 * View Object 132 * @param info 133 * Info to fill 134 * @param children 135 * Children to layout 136 * @param stage 137 * Stage to load Info From 138 */ 139 public static void layoutSequential(final LayoutView view, 140 final LayoutInfo info, final List<LayoutableNode> children, 141 final LayoutStage stage) { 142 float ascentHeight = 0.0f; 143 float descentHeight = 0.0f; 144 float posX = 0.0f; 145 float stretchAscent = 0.0f; 146 float stretchDescent = 0.0f; 147 148 for (final LayoutableNode child : children) { 149 final LayoutInfo childInfo = view.getInfo(child); 150 ascentHeight = Math.max(ascentHeight, childInfo 151 .getAscentHeight(stage)); 152 descentHeight = Math.max(descentHeight, childInfo 153 .getDescentHeight(stage)); 154 stretchAscent = Math.max(stretchAscent, childInfo 155 .getStretchAscent()); 156 stretchDescent = Math.max(stretchDescent, childInfo 157 .getStretchDescent()); 158 childInfo.moveTo(posX, 0.0f, stage); 159 posX += childInfo.getWidth(stage); 160 } 161 info.setAscentHeight(ascentHeight, stage); 162 info.setDescentHeight(descentHeight, stage); 163 info.setStretchAscent(stretchAscent); 164 info.setStretchDescent(stretchDescent); 165 info.setHorizontalCenterOffset(posX / 2.0f, stage); 166 info.setWidth(posX, stage); 167 } 168 169 /** 170 * Add a background Rectangle for the given background color. 171 * 172 * @param backgroundColor 173 * background color (may be null) 174 * @param info 175 * LayoutInfo object to add to. Must already be completely 176 * rendered (stage 2) 177 * @param useCeil 178 * if true, the {@link Math#ceil(double)} will be used to avoid 179 * anti-aliasing artifacts. 180 */ 181 public static void addBackground(final Color backgroundColor, 182 final LayoutInfo info, final boolean useCeil) { 183 if (backgroundColor != null) { 184 final GraphicsObject fillObject; 185 if (useCeil) { 186 fillObject = new FillRectObject(backgroundColor, (float) Math 187 .ceil(info.getAscentHeight(LayoutStage.STAGE2)), 188 (float) Math.ceil(info 189 .getDescentHeight(LayoutStage.STAGE2)), 190 (float) Math.ceil(info.getWidth(LayoutStage.STAGE2))); 191 } else { 192 fillObject = new FillRectObject(backgroundColor, info 193 .getAscentHeight(LayoutStage.STAGE2), info 194 .getDescentHeight(LayoutStage.STAGE2), info 195 .getWidth(LayoutStage.STAGE2)); 196 197 } 198 199 info.getGraphicObjects().add(0, fillObject); 200 } 201 202 } 203 }