diff options
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/font/TextDecorator.java')
-rw-r--r-- | awt/org/apache/harmony/awt/gl/font/TextDecorator.java | 433 |
1 files changed, 0 insertions, 433 deletions
diff --git a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java deleted file mode 100644 index 81905fd..0000000 --- a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * @author Oleg V. Khaschansky - * @version $Revision$ - */ - -package org.apache.harmony.awt.gl.font; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.TextAttribute; -import java.awt.geom.Area; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.text.AttributedCharacterIterator.Attribute; -import java.util.Map; - -/** - * This class is responsible for rendering text decorations like - * underline, strikethrough, text with background, etc. - */ -public class TextDecorator { - private static final TextDecorator inst = new TextDecorator(); - private TextDecorator() {} - static TextDecorator getInstance() { - return inst; - } - - /** - * This class encapsulates a set of decoration attributes for a single text run. - */ - static class Decoration { - private static final BasicStroke UNDERLINE_LOW_ONE_PIXEL_STROKE = - new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10); - - private static final BasicStroke UNDERLINE_LOW_TWO_PIXEL_STROKE = - new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10); - - private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE = - new BasicStroke( - 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, - new float[] { 1, 1 }, 0 - ); - - private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE2 = - new BasicStroke( - 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, - new float[] { 1, 1 }, 1 - ); - - private static final BasicStroke UNDERLINE_LOW_DASHED_STROKE = - new BasicStroke( - 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, - new float[] { 4, 4 }, 0 - ); - - boolean ulOn = false; // Have standard underline? - BasicStroke ulStroke; - - BasicStroke imUlStroke; // Stroke for INPUT_METHOD_UNDERLINE - BasicStroke imUlStroke2; // Specially for UNDERLINE_LOW_GRAY - - boolean strikeThrough; - BasicStroke strikeThroughStroke; - - boolean haveStrokes = false; // Strokes already created? - - boolean swapBfFg; - Paint bg; // background color - Paint fg; // foreground color - - Paint graphicsPaint; // Slot for saving current paint - - Decoration( - Integer imUl, - boolean swap, - boolean sth, - Paint bg, Paint fg, - boolean ulOn) { - - if (imUl != null) { - // Determine which stroke to use - if (imUl == TextAttribute.UNDERLINE_LOW_ONE_PIXEL) { - this.imUlStroke = Decoration.UNDERLINE_LOW_ONE_PIXEL_STROKE; - } else if (imUl == TextAttribute.UNDERLINE_LOW_TWO_PIXEL) { - this.imUlStroke = Decoration.UNDERLINE_LOW_TWO_PIXEL_STROKE; - } else if (imUl == TextAttribute.UNDERLINE_LOW_DOTTED) { - this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE; - } else if (imUl == TextAttribute.UNDERLINE_LOW_GRAY) { - this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE; - this.imUlStroke2 = Decoration.UNDERLINE_LOW_DOTTED_STROKE2; - } else if (imUl == TextAttribute.UNDERLINE_LOW_DASHED) { - this.imUlStroke = Decoration.UNDERLINE_LOW_DASHED_STROKE; - } - } - - this.ulOn = ulOn; // Has underline - this.swapBfFg = swap; - this.strikeThrough = sth; - this.bg = bg; - this.fg = fg; - } - - /** - * Creates strokes of proper width according to the info - * stored in the BasicMetrics - * @param metrics - basic metrics - */ - private void getStrokes(BasicMetrics metrics) { - if (!haveStrokes) { - if (strikeThrough) { - strikeThroughStroke = - new BasicStroke( - metrics.strikethroughThickness, - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_MITER, - 10 - ); - } - - if (ulOn) { - ulStroke = - new BasicStroke( - metrics.underlineThickness, - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_MITER, - 10 - ); - } - - haveStrokes = true; - } - } - } - - /** - * Creates Decoration object from the set of text attributes - * @param attributes - text attributes - * @return Decoration object - */ - static Decoration getDecoration(Map<? extends Attribute, ?> attributes) { - if (attributes == null) { - return null; // It is for plain text - } - - Object underline = attributes.get(TextAttribute.UNDERLINE); - boolean hasStandardUnderline = underline == TextAttribute.UNDERLINE_ON; - - Object imUnderline = attributes.get(TextAttribute.INPUT_METHOD_UNDERLINE); - Integer imUl = (Integer) imUnderline; - - boolean swapBgFg = - TextAttribute.SWAP_COLORS_ON.equals( - attributes.get(TextAttribute.SWAP_COLORS) - ); - - boolean strikeThrough = - TextAttribute.STRIKETHROUGH_ON.equals( - attributes.get(TextAttribute.STRIKETHROUGH) - ); - - Paint fg = (Paint) attributes.get(TextAttribute.FOREGROUND); - Paint bg = (Paint) attributes.get(TextAttribute.BACKGROUND); - - if ( - !hasStandardUnderline && - imUnderline == null && - fg == null && - bg == null && - !swapBgFg && - !strikeThrough - ) { - return null; - } - return new Decoration(imUl, swapBgFg, strikeThrough, bg, fg, hasStandardUnderline); - } - - /** - * Fills the background before drawing if needed. - * - * @param trs - text segment - * @param g2d - graphics to draw to - * @param xOffset - offset in X direction to the upper left corner of the - * layout from the origin of the graphics - * @param yOffset - offset in Y direction to the upper left corner of the - * layout from the origin of the graphics - */ - static void prepareGraphics( - TextRunSegment trs, Graphics2D g2d, - float xOffset, float yOffset - ) { - Decoration d = trs.decoration; - - if (d.fg == null && d.bg == null && d.swapBfFg == false) { - return; // Nothing to do - } - - d.graphicsPaint = g2d.getPaint(); - - if (d.fg == null) { - d.fg = d.graphicsPaint; - } - - if (d.swapBfFg) { - // Fill background area - g2d.setPaint(d.fg); - Rectangle2D bgArea = trs.getLogicalBounds(); - Rectangle2D toFill = - new Rectangle2D.Double( - bgArea.getX() + xOffset, - bgArea.getY() + yOffset, - bgArea.getWidth(), - bgArea.getHeight() - ); - g2d.fill(toFill); - - // Set foreground color - g2d.setPaint(d.bg == null ? Color.WHITE : d.bg); - } else { - if (d.bg != null) { // Fill background area - g2d.setPaint(d.bg); - Rectangle2D bgArea = trs.getLogicalBounds(); - Rectangle2D toFill = - new Rectangle2D.Double( - bgArea.getX() + xOffset, - bgArea.getY() + yOffset, - bgArea.getWidth(), - bgArea.getHeight() - ); - g2d.fill(toFill); - } - - // Set foreground color - g2d.setPaint(d.fg); - } - } - - /** - * Restores the original state of the graphics if needed - * @param d - decoration - * @param g2d - graphics - */ - static void restoreGraphics(Decoration d, Graphics2D g2d) { - if (d.fg == null && d.bg == null && d.swapBfFg == false) { - return; // Nothing to do - } - - g2d.setPaint(d.graphicsPaint); - } - - /** - * Renders the text decorations - * @param trs - text run segment - * @param g2d - graphics to render to - * @param xOffset - offset in X direction to the upper left corner - * of the layout from the origin of the graphics - * @param yOffset - offset in Y direction to the upper left corner - * of the layout from the origin of the graphics - */ - static void drawTextDecorations( - TextRunSegment trs, Graphics2D g2d, - float xOffset, float yOffset - ) { - Decoration d = trs.decoration; - - if (!d.ulOn && d.imUlStroke == null && !d.strikeThrough) { - return; // Nothing to do - } - - float left = xOffset + (float) trs.getLogicalBounds().getMinX(); - float right = xOffset + (float) trs.getLogicalBounds().getMaxX(); - - Stroke savedStroke = g2d.getStroke(); - - d.getStrokes(trs.metrics); - - if (d.strikeThrough) { - float y = trs.y + yOffset + trs.metrics.strikethroughOffset; - g2d.setStroke(d.strikeThroughStroke); - g2d.draw(new Line2D.Float(left, y, right, y)); - } - - if (d.ulOn) { - float y = trs.y + yOffset + trs.metrics.underlineOffset; - g2d.setStroke(d.ulStroke); - g2d.draw(new Line2D.Float(left, y, right, y)); - } - - if (d.imUlStroke != null) { - float y = trs.y + yOffset + trs.metrics.underlineOffset; - g2d.setStroke(d.imUlStroke); - g2d.draw(new Line2D.Float(left, y, right, y)); - if (d.imUlStroke2 != null) { - y++; - g2d.setStroke(d.imUlStroke2); - g2d.draw(new Line2D.Float(left, y, right, y)); - } - } - - g2d.setStroke(savedStroke); - } - - /** - * Extends the visual bounds of the text run segment to - * include text decorations. - * @param trs - text segment - * @param segmentBounds - bounds of the undecorated text - * @param d - decoration - * @return extended bounds - */ - static Rectangle2D extendVisualBounds( - TextRunSegment trs, - Rectangle2D segmentBounds, - Decoration d - ) { - if (d == null) { - return segmentBounds; - } - double minx = segmentBounds.getMinX(); - double miny = segmentBounds.getMinY(); - double maxx = segmentBounds.getMaxX(); - double maxy = segmentBounds.getMaxY(); - - Rectangle2D lb = trs.getLogicalBounds(); - - if (d.swapBfFg || d.bg != null) { - minx = Math.min(lb.getMinX() - trs.x, minx); - miny = Math.min(lb.getMinY() - trs.y, miny); - maxx = Math.max(lb.getMaxX() - trs.x, maxx); - maxy = Math.max(lb.getMaxY() - trs.y, maxy); - } - - if (d.ulOn || d.imUlStroke != null || d.strikeThrough) { - minx = Math.min(lb.getMinX() - trs.x, minx); - maxx = Math.max(lb.getMaxX() - trs.x, maxx); - - d.getStrokes(trs.metrics); - - if (d.ulStroke != null) { - maxy = Math.max( - maxy, - trs.metrics.underlineOffset + - d.ulStroke.getLineWidth() - ); - } - - if (d.imUlStroke != null) { - maxy = Math.max( - maxy, - trs.metrics.underlineOffset + - d.imUlStroke.getLineWidth() + - (d.imUlStroke2 == null ? 0 : d.imUlStroke2.getLineWidth()) - ); - } - } - - return new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny); - } - - /** - * Extends the outline of the text run segment to - * include text decorations. - * @param trs - text segment - * @param segmentOutline - outline of the undecorated text - * @param d - decoration - * @return extended outline - */ - static Shape extendOutline( - TextRunSegment trs, - Shape segmentOutline, - Decoration d - ) { - if (d == null || !d.ulOn && d.imUlStroke == null && !d.strikeThrough) { - return segmentOutline; // Nothing to do - } - - Area res = new Area(segmentOutline); - - float left = (float) trs.getLogicalBounds().getMinX() - trs.x; - float right = (float) trs.getLogicalBounds().getMaxX() - trs.x; - - d.getStrokes(trs.metrics); - - if (d.strikeThrough) { - float y = trs.metrics.strikethroughOffset; - res.add(new Area(d.strikeThroughStroke.createStrokedShape( - new Line2D.Float(left, y, right, y) - ))); - } - - if (d.ulOn) { - float y = trs.metrics.underlineOffset; - res.add(new Area(d.ulStroke.createStrokedShape( - new Line2D.Float(left, y, right, y) - ))); - } - - if (d.imUlStroke != null) { - float y = trs.metrics.underlineOffset; - res.add(new Area(d.imUlStroke.createStrokedShape( - new Line2D.Float(left, y, right, y) - ))); - - if (d.imUlStroke2 != null) { - y++; - res.add(new Area(d.imUlStroke2.createStrokedShape( - new Line2D.Float(left, y, right, y) - ))); - } - } - - return res; - } -} |