summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/font
diff options
context:
space:
mode:
Diffstat (limited to 'awt/java/awt/font')
-rw-r--r--awt/java/awt/font/FontRenderContext.java178
-rw-r--r--awt/java/awt/font/GlyphJustificationInfo.java197
-rw-r--r--awt/java/awt/font/GlyphMetrics.java266
-rw-r--r--awt/java/awt/font/GlyphVector.java403
-rw-r--r--awt/java/awt/font/GraphicAttribute.java179
-rw-r--r--awt/java/awt/font/ImageGraphicAttribute.java185
-rw-r--r--awt/java/awt/font/LineBreakMeasurer.java238
-rw-r--r--awt/java/awt/font/LineMetrics.java116
-rw-r--r--awt/java/awt/font/MultipleMaster.java91
-rw-r--r--awt/java/awt/font/OpenType.java418
-rw-r--r--awt/java/awt/font/ShapeGraphicAttribute.java206
-rw-r--r--awt/java/awt/font/TextHitInfo.java215
-rw-r--r--awt/java/awt/font/TextLayout.java927
-rw-r--r--awt/java/awt/font/TextMeasurer.java182
-rw-r--r--awt/java/awt/font/TransformAttribute.java86
-rw-r--r--awt/java/awt/font/package.html8
16 files changed, 3895 insertions, 0 deletions
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..d7de00f
--- /dev/null
+++ b/awt/java/awt/font/FontRenderContext.java
@@ -0,0 +1,178 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * The FontRenderContext class contains the information about text measurement.
+ * Anti-aliasing and fractional-metrics modes are defined by an application and
+ * affect the size of a character.
+ *
+ * @since Android 1.0
+ */
+public class FontRenderContext {
+
+ // Affine transform of this mode
+ /**
+ * The transform.
+ */
+ private AffineTransform transform;
+
+ // Is the anti-aliased mode used
+ /**
+ * The anti aliased.
+ */
+ private boolean fAntiAliased;
+
+ // Is the fractional metrics used
+ /**
+ * The fractional metrics.
+ */
+ private boolean fFractionalMetrics;
+
+
+ /**
+ * Instantiates a new FontRenderContext object with the specified
+ * AffineTransform, anti-aliasing and fractional metrics flags.
+ *
+ * @param trans
+ * the AffineTransform.
+ * @param antiAliased
+ * the anti-aliasing flag.
+ * @param usesFractionalMetrics
+ * the fractional metrics flag.
+ */
+ public FontRenderContext(AffineTransform trans, boolean antiAliased,
+ boolean usesFractionalMetrics) {
+ if (trans != null){
+ transform = new AffineTransform(trans);
+ }
+ fAntiAliased = antiAliased;
+ fFractionalMetrics = usesFractionalMetrics;
+ }
+
+ /**
+ * Instantiates a new FontRenderContext object.
+ */
+ protected FontRenderContext() {
+ }
+
+ /**
+ * Compares the specified Object with current FontRenderContext object.
+ *
+ * @param obj
+ * the Object to be compared.
+ * @return true, if the specified Object is equal to current
+ * FontRenderContext object.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj != null) {
+ try {
+ return equals((FontRenderContext) obj);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ return false;
+
+ }
+
+ /**
+ * Gets the transform which is used for scaling typographical points to
+ * pixels in this FontRenderContext.
+ *
+ * @return the AffineTransform which is used for scaling typographical
+ * points to pixels in this FontRenderContext.
+ */
+ public AffineTransform getTransform() {
+ if (transform != null){
+ return new AffineTransform(transform);
+ }
+ return new AffineTransform();
+ }
+
+ /**
+ * Compares the specified FontRenderContext object with current
+ * FontRenderContext.
+ *
+ * @param frc
+ * the FontRenderContext object to be compared.
+ * @return true, if the specified FontRenderContext object is equal to
+ * current FontRenderContext.
+ */
+ public boolean equals(FontRenderContext frc) {
+ if (this == frc){
+ return true;
+ }
+
+ if (frc == null){
+ return false;
+ }
+
+ if (!frc.getTransform().equals(this.getTransform()) &&
+ !frc.isAntiAliased() == this.fAntiAliased &&
+ !frc.usesFractionalMetrics() == this.fFractionalMetrics){
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns true if the text fractional metrics are used in this
+ * FontRenderContext.
+ *
+ * @return true, if the text fractional metrics are used in this
+ * FontRenderContext, false otherwise.
+ */
+ public boolean usesFractionalMetrics() {
+ return this.fFractionalMetrics;
+ }
+
+ /**
+ * Returns true if anti-aliasing is used in this FontRenderContext.
+ *
+ * @return true, if is anti-aliasing is used in this FontRenderContext,
+ * false otherwise.
+ */
+ public boolean isAntiAliased() {
+ return this.fAntiAliased;
+ }
+
+ /**
+ * Returns hash code of the FontRenderContext object.
+ *
+ * @return the hash code of the FontRenderContext object.
+ */
+ @Override
+ public int hashCode() {
+ return this.getTransform().hashCode() ^
+ new Boolean(this.fFractionalMetrics).hashCode() ^
+ new Boolean(this.fAntiAliased).hashCode();
+ }
+
+}
+
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..b03de0a
--- /dev/null
+++ b/awt/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,197 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GlyphJustificationInfo class provides information about the glyph's
+ * justification properties. There are four justification properties: weight,
+ * priority, absorb, and limit.
+ * <p>
+ * There are two sets of metrics: growing and shrinking. Growing metrics are
+ * used when the glyphs are to be spread apart to fit a larger width. Shrinking
+ * metrics are used when the glyphs are to be moved together to fit a smaller
+ * width.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public final class GlyphJustificationInfo {
+
+ /**
+ * The Constant PRIORITY_KASHIDA indicates the highest justification
+ * priority.
+ */
+ public static final int PRIORITY_KASHIDA = 0;
+
+ /**
+ * The Constant PRIORITY_WHITESPACE indicates the second highest
+ * justification priority.
+ */
+ public static final int PRIORITY_WHITESPACE = 1;
+
+ /**
+ * The Constant PRIORITY_INTERCHAR indicates the second lowest justification
+ * priority.
+ */
+ public static final int PRIORITY_INTERCHAR = 2;
+
+ /**
+ * The Constant PRIORITY_NONE indicates the lowest justification priority.
+ */
+ public static final int PRIORITY_NONE = 3;
+
+ /**
+ * The grow absorb flag indicates if this glyph absorbs all extra space at
+ * this and lower priority levels when it grows.
+ */
+ public final boolean growAbsorb;
+
+ /**
+ * The grow left limit value represents the maximum value by which the left
+ * side of this glyph grows.
+ */
+ public final float growLeftLimit;
+
+ /**
+ * The grow right limit value repesents the maximum value by which the right
+ * side of this glyph grows.
+ */
+ public final float growRightLimit;
+
+ /**
+ * The grow priority value represents the priority level of this glyph as it
+ * is growing.
+ */
+ public final int growPriority;
+
+ /**
+ * The shrink absorb fleg indicates this glyph absorbs all remaining
+ * shrinkage at this and lower priority levels as it shrinks.
+ */
+ public final boolean shrinkAbsorb;
+
+ /**
+ * The shrink left limit value represents the maximum value by which the
+ * left side of this glyph shrinks.
+ */
+ public final float shrinkLeftLimit;
+
+ /**
+ * The shrink right limit value represents the maximum value by which the
+ * right side of this glyph shrinks.
+ */
+ public final float shrinkRightLimit;
+
+ /**
+ * The shrink priority represents the glyth's priority level as it is
+ * shrinking.
+ */
+ public final int shrinkPriority;
+
+ /**
+ * The weight of the glyph.
+ */
+ public final float weight;
+
+ /**
+ * Instantiates a new GlyphJustificationInfo object which contains glyph's
+ * justification properties.
+ *
+ * @param weight
+ * the weight of glyph.
+ * @param growAbsorb
+ * indicates if this glyph contais all space at this priority and
+ * lower priority levels when it grows.
+ * @param growPriority
+ * indicates the priority level of this glyph when it grows.
+ * @param growLeftLimit
+ * indicates the maximum value of which the left side of this
+ * glyph can grow.
+ * @param growRightLimit
+ * the maximum value of which the right side of this glyph can
+ * grow.
+ * @param shrinkAbsorb
+ * indicates if this glyph contains all remaining shrinkage at
+ * this and lower priority levels when it shrinks.
+ * @param shrinkPriority
+ * indicates the glyph's priority level when it shrinks.
+ * @param shrinkLeftLimit
+ * indicates the maximum value of which the left side of this
+ * glyph can shrink.
+ * @param shrinkRightLimit
+ * indicates the maximum amount by which the right side of this
+ * glyph can shrink.
+ */
+ public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
+ float growLeftLimit, float growRightLimit, boolean shrinkAbsorb, int shrinkPriority,
+ float shrinkLeftLimit, float shrinkRightLimit) {
+
+ if (weight < 0) {
+ // awt.19C=weight must be a positive number
+ throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
+ }
+ this.weight = weight;
+
+ if (growLeftLimit < 0) {
+ // awt.19D=growLeftLimit must be a positive number
+ throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
+ }
+ this.growLeftLimit = growLeftLimit;
+
+ if (growRightLimit < 0) {
+ // awt.19E=growRightLimit must be a positive number
+ throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
+ }
+ this.growRightLimit = growRightLimit;
+
+ if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
+ // awt.19F=incorrect value for shrinkPriority, more than
+ // PRIORITY_NONE or less than PRIORITY_KASHIDA value
+ throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
+ }
+ this.shrinkPriority = shrinkPriority;
+
+ if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
+ // awt.200=incorrect value for growPriority, more than PRIORITY_NONE
+ // or less than PRIORITY_KASHIDA value
+ throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
+ }
+ this.growPriority = growPriority;
+
+ if (shrinkLeftLimit < 0) {
+ // awt.201=shrinkLeftLimit must be a positive number
+ throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
+ }
+ this.shrinkLeftLimit = shrinkLeftLimit;
+
+ if (shrinkRightLimit < 0) {
+ // awt.202=shrinkRightLimit must be a positive number
+ throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
+ }
+ this.shrinkRightLimit = shrinkRightLimit;
+
+ this.shrinkAbsorb = shrinkAbsorb;
+ this.growAbsorb = growAbsorb;
+ }
+}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..2871722
--- /dev/null
+++ b/awt/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,266 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphMetrics class provides information about the size and shape of a
+ * single glyph. Each glyph has information to specify whether its baseline is
+ * horizontal or vertical as well as information on how it interacts with other
+ * characters in a text, given as one of the following types: STANDARD,
+ * LIGATURE, COMBINING, or COMPONENT.
+ *
+ * @since Android 1.0
+ */
+public final class GlyphMetrics {
+
+ // advance width of the glyph character cell
+ /**
+ * The advance x.
+ */
+ private float advanceX;
+
+ // advance height of the glyph character cell
+ /**
+ * The advance y.
+ */
+ private float advanceY;
+
+ // flag if the glyph horizontal
+ /**
+ * The horizontal.
+ */
+ private boolean horizontal;
+
+ // glyph type code
+ /**
+ * The glyph type.
+ */
+ private byte glyphType;
+
+ // bounding box for outline of the glyph
+ /**
+ * The bounds.
+ */
+ private Rectangle2D.Float bounds;
+
+ /**
+ * The Constant STANDARD indicates a glyph that represents a single
+ * character.
+ */
+ public static final byte STANDARD = 0;
+
+ /**
+ * The Constant LIGATURE indicates a glyph that represents multiple
+ * characters as a ligature.
+ */
+ public static final byte LIGATURE = 1;
+
+ /**
+ * The Constant COMBINING indicates a glyph which has no caret position
+ * between glyphs (for example umlaut).
+ */
+ public static final byte COMBINING = 2;
+
+ /**
+ * The Constant COMPONENT indicates a glyph with no corresponding character
+ * in the backing store.
+ */
+ public static final byte COMPONENT = 3;
+
+ /**
+ * The Constant WHITESPACE indicates a glyph without visual representation.
+ */
+ public static final byte WHITESPACE = 4;
+
+ /**
+ * Instantiates a new GlyphMetrics object with the specified parameters.
+ *
+ * @param horizontal
+ * specifies if metrics are for a horizontal baseline (true
+ * value), or a vertical baseline (false value).
+ * @param advanceX
+ * the X component of the glyph's advance.
+ * @param advanceY
+ * the Y component of the glyph's advance.
+ * @param bounds
+ * the glyph's bounds.
+ * @param glyphType
+ * the glyph's type.
+ */
+ public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, Rectangle2D bounds,
+ byte glyphType) {
+ this.horizontal = horizontal;
+ this.advanceX = advanceX;
+ this.advanceY = advanceY;
+
+ this.bounds = new Rectangle2D.Float();
+ this.bounds.setRect(bounds);
+
+ this.glyphType = glyphType;
+ }
+
+ /**
+ * Instantiates a new horizontal GlyphMetrics with the specified parameters.
+ *
+ * @param advanceX
+ * the X component of the glyph's advance.
+ * @param bounds
+ * the glyph's bounds.
+ * @param glyphType
+ * the glyph's type.
+ */
+ public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
+ this.advanceX = advanceX;
+ this.advanceY = 0;
+
+ this.horizontal = true;
+
+ this.bounds = new Rectangle2D.Float();
+ this.bounds.setRect(bounds);
+
+ this.glyphType = glyphType;
+ }
+
+ /**
+ * Gets the glyph's bounds.
+ *
+ * @return glyph's bounds.
+ */
+ public Rectangle2D getBounds2D() {
+ return (Rectangle2D.Float)this.bounds.clone();
+ }
+
+ /**
+ * Checks if this glyph is whitespace or not.
+ *
+ * @return true, if this glyph is whitespace, false otherwise.
+ */
+ public boolean isWhitespace() {
+ return ((this.glyphType & 4) == WHITESPACE);
+ }
+
+ /**
+ * Checks if this glyph is standard or not.
+ *
+ * @return true, if this glyph is standard, false otherwise.
+ */
+ public boolean isStandard() {
+ return ((this.glyphType & 3) == STANDARD);
+ }
+
+ /**
+ * Checks if this glyph is ligature or not.
+ *
+ * @return true, if this glyph is ligature, false otherwise.
+ */
+ public boolean isLigature() {
+ return ((this.glyphType & 3) == LIGATURE);
+ }
+
+ /**
+ * Checks if this glyph is component or not.
+ *
+ * @return true, if this glyph is component, false otherwise.
+ */
+ public boolean isComponent() {
+ return ((this.glyphType & 3) == COMPONENT);
+ }
+
+ /**
+ * Checks if this glyph is combining or not.
+ *
+ * @return true, if this glyph is combining, false otherwise.
+ */
+ public boolean isCombining() {
+ return ((this.glyphType & 3) == COMBINING);
+ }
+
+ /**
+ * Gets the glyph's type.
+ *
+ * @return the glyph's type.
+ */
+ public int getType() {
+ return this.glyphType;
+ }
+
+ /**
+ * Gets the distance from the right (for horizontal) or bottom (for
+ * vertical) of the glyph bounds to the advance.
+ *
+ * @return the distance from the right (for horizontal) or bottom (for
+ * vertical) of the glyph bounds to the advance.
+ */
+ public float getRSB() {
+ if (this.horizontal) {
+ return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
+ }
+ return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
+ }
+
+ /**
+ * Gets the distance from 0, 0 to the left (for horizontal) or top (for
+ * vertical) of the glyph bounds.
+ *
+ * @return the distance from 0, 0 to the left (for horizontal) or top (for
+ * vertical) of the glyph bounds.
+ */
+ public float getLSB() {
+ if (this.horizontal) {
+ return this.bounds.x;
+ }
+ return this.bounds.y;
+ }
+
+ /**
+ * Gets the Y component of the glyph's advance.
+ *
+ * @return the Y component of the glyph's advance.
+ */
+ public float getAdvanceY() {
+ return this.advanceY;
+ }
+
+ /**
+ * Gets the X component of the glyph's advance.
+ *
+ * @return the X component of the glyph's advance.
+ */
+ public float getAdvanceX() {
+ return this.advanceX;
+ }
+
+ /**
+ * Gets the glyph's advance along the baseline.
+ *
+ * @return the glyph's advance.
+ */
+ public float getAdvance() {
+ if (this.horizontal) {
+ return this.advanceX;
+ }
+ return this.advanceY;
+ }
+
+}
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..a72b774
--- /dev/null
+++ b/awt/java/awt/font/GlyphVector.java
@@ -0,0 +1,403 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphVector class contains a collection of glyphs with geometric
+ * information and each glyph's location. Each GlyphVector can be associated
+ * with only one Font. GlyphVector contains the following properties for each
+ * glyph:
+ * <ul>
+ * <li>the glyph position;</li>
+ * <li>the transform of the glyph;</li>
+ * <li>the metrics of the glyph in the context of the GlyphVector.</li>
+ * </ul>
+ *
+ * @since Android 1.0
+ */
+public abstract class GlyphVector implements Cloneable {
+
+ /**
+ * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector has
+ * per-glyph transforms.
+ */
+ public static final int FLAG_HAS_TRANSFORMS = 1;
+
+ /**
+ * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that the GlyphVector
+ * has per-glyph position adjustments.
+ */
+ public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+
+ /**
+ * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a right to
+ * left run direction.
+ */
+ public static final int FLAG_RUN_RTL = 4;
+
+ /**
+ * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector has a
+ * complex glyph to char mapping.
+ */
+ public static final int FLAG_COMPLEX_GLYPHS = 8;
+
+ /**
+ * The Constant FLAG_MASK indicates a mask for supported flags from
+ * getLayoutFlags.
+ */
+ public static final int FLAG_MASK = 15; // (|) mask of other flags
+
+ /**
+ * Instantiates a new GlyphVector.
+ */
+ public GlyphVector() {
+ }
+
+ /**
+ * Gets the pixel bounds of the GlyphVector when rendered at the specified
+ * location with the specified FontRenderContext.
+ *
+ * @param frc
+ * the FontRenderContext.
+ * @param x
+ * the X coordinate of the GlyphVector's location.
+ * @param y
+ * the Y coordinate of the GlyphVector's location.
+ * @return the pixel bounds
+ */
+ public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+ // default implementation - integer Rectangle, that encloses visual
+ // bounds rectangle
+ Rectangle2D visualRect = getVisualBounds();
+
+ int minX = (int)Math.floor(visualRect.getMinX() + x);
+ int minY = (int)Math.floor(visualRect.getMinY() + y);
+ int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+ int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+ return new Rectangle(minX, minY, width, height);
+ }
+
+ /**
+ * Gets the pixel bounds of the glyph with the specified index in this
+ * GlyphVector which is rendered with the specified FontRenderContext at the
+ * specified location.
+ *
+ * @param index
+ * the glyph index in this GlyphVector.
+ * @param frc
+ * the FontRenderContext.
+ * @param x
+ * the X coordinate of the GlyphVector's location.
+ * @param y
+ * the Y coordinate of the GlyphVector's location.
+ * @return a Rectangle bounds.
+ */
+ public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, float x, float y) {
+ Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
+
+ int minX = (int)Math.floor(visualRect.getMinX() + x);
+ int minY = (int)Math.floor(visualRect.getMinY() + y);
+ int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+ int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+ return new Rectangle(minX, minY, width, height);
+ }
+
+ /**
+ * Gets the visual bounds of the GlyphVector.
+ *
+ * @return the visual bounds of the GlyphVector.
+ */
+ public abstract Rectangle2D getVisualBounds();
+
+ /**
+ * Gets the logical bounds of the GlyphVector.
+ *
+ * @return the logical bounds of the GlyphVector.
+ */
+ public abstract Rectangle2D getLogicalBounds();
+
+ /**
+ * Sets the position of the specified glyph in this GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyph index in this GlyphVector.
+ * @param newPos
+ * the new position of the glyph at the specified glyphIndex.
+ */
+ public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
+
+ /**
+ * Gets the position of the specified glyph in this GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyph index in this GlyphVector.
+ * @return the position of the specified glyph in this GlyphVector.
+ */
+ public abstract Point2D getGlyphPosition(int glyphIndex);
+
+ /**
+ * Sets the affine transform to a glyph with the specified index in this
+ * GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyth index in this GlyphVector.
+ * @param trans
+ * the AffineTransform to be assigned to the specified glyph.
+ */
+ public abstract void setGlyphTransform(int glyphIndex, AffineTransform trans);
+
+ /**
+ * Gets the transform of the specified glyph in this GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyph index in this GlyphVector.
+ * @return the new transform of the glyph.
+ */
+ public abstract AffineTransform getGlyphTransform(int glyphIndex);
+
+ /**
+ * Compares this GlyphVector with the specified GlyphVector objects.
+ *
+ * @param glyphVector
+ * the GlyphVector object to be compared.
+ * @return true, if this GlyphVector is equal to the specified GlyphVector
+ * object, false otherwise.
+ */
+ public abstract boolean equals(GlyphVector glyphVector);
+
+ /**
+ * Gets the metrics of the glyph with the specified index in this
+ * GlyphVector.
+ *
+ * @param glyphIndex
+ * index in this GlyphVector.
+ * @return the metrics of the glyph with the specified index in this
+ * GlyphVector.
+ */
+ public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
+
+ /**
+ * Gets the justification information of the glyph whose index is specified.
+ *
+ * @param glyphIndex
+ * the glyph index.
+ * @return the GlyphJustificationInfo for the specified glyph.
+ */
+ public abstract GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex);
+
+ /**
+ * Gets the FontRenderContext of this GlyphVector.
+ *
+ * @return the FontRenderContext of this GlyphVector.
+ */
+ public abstract FontRenderContext getFontRenderContext();
+
+ /**
+ * Gets a Shape object which defines the visual representation of the
+ * specified glyph in this GlyphVector, translated a distance of x in the X
+ * direction and y in the Y direction.
+ *
+ * @param glyphIndex
+ * the glyth index in this GlyphVector.
+ * @param x
+ * the distance in the X direction to translate the shape object
+ * before returning it.
+ * @param y
+ * the distance in the Y direction to translate the shape object
+ * before returning it.
+ * @return a Shape object which represents the visual representation of the
+ * specified glyph in this GlyphVector - glyph outline.
+ */
+ public Shape getGlyphOutline(int glyphIndex, float x, float y) {
+ Shape initialShape = getGlyphOutline(glyphIndex);
+ AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
+ return trans.createTransformedShape(initialShape);
+ }
+
+ /**
+ * Gets the visual bounds of the specified glyph in the GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyph index in this GlyphVector.
+ * @return the glyph visual bounds of the glyph with the specified index in
+ * the GlyphVector.
+ */
+ public abstract Shape getGlyphVisualBounds(int glyphIndex);
+
+ /**
+ * Gets a Shape object which defines the visual representation of the
+ * specified glyph in this GlyphVector.
+ *
+ * @param glyphIndex
+ * the glyth index in this GlyphVector.
+ * @return a Shape object which represents the visual representation of the
+ * specified glyph in this GlyphVector - glyph outline.
+ */
+ public abstract Shape getGlyphOutline(int glyphIndex);
+
+ /**
+ * Gets the logical bounds of the specified glyph in the GlyphVector.
+ *
+ * @param glyphIndex
+ * the index in this GlyphVector of the glyph from which to
+ * retrieve its logical bounds
+ * @return the logical bounds of the specified glyph in the GlyphVector.
+ */
+ public abstract Shape getGlyphLogicalBounds(int glyphIndex);
+
+ /**
+ * Gets the visual representation of this GlyphVector rendered in x, y
+ * location as a Shape object.
+ *
+ * @param x
+ * the x coordinate of the GlyphVector.
+ * @param y
+ * the y coordinate of the GlyphVector.
+ * @return the visual representation of this GlyphVector as a Shape object.
+ */
+ public abstract Shape getOutline(float x, float y);
+
+ /**
+ * Gets the visual representation of this GlyphVector as a Shape object.
+ *
+ * @return the visual representation of this GlyphVector as a Shape object.
+ */
+ public abstract Shape getOutline();
+
+ /**
+ * Gets the font of this GlyphVector.
+ *
+ * @return the font of this GlyphVector.
+ */
+ public abstract Font getFont();
+
+ /**
+ * Gets an array of the glyph codes of the specified glyphs.
+ *
+ * @param beginGlyphIndex
+ * the index into this GlyphVector at which to start retrieving
+ * glyph codes.
+ * @param numEntries
+ * the number of glyph codes.
+ * @param codeReturn
+ * the array into which the resulting glyphcodes will be written.
+ * @return the array of the glyph codes.
+ */
+ public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, int[] codeReturn);
+
+ /**
+ * Gets an array of the character indices of the specified glyphs.
+ *
+ * @param beginGlyphIndex
+ * the index of the first glyph to return information for.
+ * @param numEntries
+ * the number of glyph indices to return.
+ * @param codeReturn
+ * the array into which the resulting character indices will be
+ * written.
+ * @return an array of character indices for the specifies glyphs.
+ */
+ public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, int[] codeReturn) {
+ if (codeReturn == null) {
+ codeReturn = new int[numEntries];
+ }
+
+ for (int i = 0; i < numEntries; i++) {
+ codeReturn[i] = getGlyphCharIndex(i + beginGlyphIndex);
+ }
+ return codeReturn;
+ }
+
+ /**
+ * Gets an array of the positions of the specified glyphs in this
+ * GlyphVector.
+ *
+ * @param beginGlyphIndex
+ * the index of the first glyph to return information for.
+ * @param numEntries
+ * the number of glyphs to return information for.
+ * @param positionReturn
+ * the array where the result will be stored.
+ * @return an array of glyph positions.
+ */
+ public abstract float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+ float[] positionReturn);
+
+ /**
+ * Gets the glyph code of the specified glyph.
+ *
+ * @param glyphIndex
+ * the index in this GlyphVector which corresponds to the glyph
+ * from which to retrieve the glyphcode.
+ * @return the glyphcode of the specified glyph.
+ */
+ public abstract int getGlyphCode(int glyphIndex);
+
+ /**
+ * Gets the first logical character's index of the specified glyph.
+ *
+ * @param glyphIndex
+ * the glyph index.
+ * @return the the first logical character's index.
+ */
+ public int getGlyphCharIndex(int glyphIndex) {
+ // default implemetation one-to-one
+ return glyphIndex;
+ }
+
+ /**
+ * Sets default layout to this GlyphVector.
+ */
+ public abstract void performDefaultLayout();
+
+ /**
+ * Gets the number of glyphs in the GlyphVector.
+ *
+ * @return the number of glyphs in the GlyphVector.
+ */
+ public abstract int getNumGlyphs();
+
+ /**
+ * Gets flags which describe the global state of the GlyphVector. The
+ * default implementation returns 0.
+ *
+ * @return the layout flags
+ */
+ public int getLayoutFlags() {
+ // default implementation - returned value is 0
+ return 0;
+ }
+
+}
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..8480e0f
--- /dev/null
+++ b/awt/java/awt/font/GraphicAttribute.java
@@ -0,0 +1,179 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicAttribute abstract class provides an opportunity to insert
+ * graphical elements in printed text.
+ *
+ * @since Android 1.0
+ */
+public abstract class GraphicAttribute {
+
+ /**
+ * The Constant TOP_ALIGNMENT indicates using the top line to calculate
+ * placement of graphics.
+ */
+ public static final int TOP_ALIGNMENT = -1;
+
+ /**
+ * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to
+ * calculate placement of graphics.
+ */
+ public static final int BOTTOM_ALIGNMENT = -2;
+
+ /**
+ * The Constant ROMAN_BASELINE indicates the placement of the roman baseline
+ * with respect to the graphics origin.
+ */
+ public static final int ROMAN_BASELINE = 0;
+
+ /**
+ * The Constant CENTER_BASELINE indicates the placement of the center
+ * baseline with respect to the graphics origin.
+ */
+ public static final int CENTER_BASELINE = 1;
+
+ /**
+ * The Constant HANGING_BASELINE indicates the placement of the hanging
+ * baseline with respect to the graphics origin.
+ */
+ public static final int HANGING_BASELINE = 2;
+
+ // the alignment of this GraphicAttribute
+ /**
+ * The alignment.
+ */
+ private int alignment;
+
+ /**
+ * Instantiates a new graphic attribute with the specified alignment.
+ *
+ * @param align
+ * the specified alignment.
+ */
+ protected GraphicAttribute(int align) {
+ if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
+ // awt.198=Illegal alignment argument
+ throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
+ }
+ this.alignment = align;
+ }
+
+ /**
+ * Draws the GraphicAttribute at the specified location.
+ *
+ * @param graphics
+ * the Graphics.
+ * @param x
+ * the X coordinate of GraphicAttribute location.
+ * @param y
+ * the Y coordinate of GraphicAttribute location.
+ */
+ public abstract void draw(Graphics2D graphics, float x, float y);
+
+ /**
+ * Gets the GraphicAttribute's advance. It's the distance from the point at
+ * which the graphic is rendered and the point where the next character or
+ * graphic is rendered.
+ *
+ * @return the GraphicAttribute's advance.
+ */
+ public abstract float getAdvance();
+
+ /**
+ * Gets the alignment of this GraphicAttribute.
+ *
+ * @return the alignment of this GraphicAttribute.
+ */
+ public final int getAlignment() {
+ return this.alignment;
+ }
+
+ /**
+ * Gets the ascent of this GraphicAttribute.
+ *
+ * @return the ascent of this GraphicAttribute.
+ */
+ public abstract float getAscent();
+
+ /**
+ * Gets the bounds of this GraphicAttribute.
+ *
+ * @return the bounds of this GraphicAttribute.
+ */
+ public Rectangle2D getBounds() {
+ float ascent = getAscent();
+ float advance = getAdvance();
+ float descent = getDescent();
+
+ // Default implementation - see API documentation.
+ return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
+ }
+
+ /**
+ * Gets the descent of this GraphicAttribute.
+ *
+ * @return the descent of this GraphicAttribute.
+ */
+ public abstract float getDescent();
+
+ /**
+ * Gets the GlyphJustificationInfo of this GraphicAttribute.
+ *
+ * @return the GlyphJustificationInfo of this GraphicAttribute.
+ */
+ public GlyphJustificationInfo getJustificationInfo() {
+
+ /*
+ * Default implementation. Since documentation doesn't describe default
+ * values, they were calculated based on 1.5 release behavior and can be
+ * obtained using next test sample: // Create GraphicAttribute class
+ * implementation public class MyGraphicAttribute extends
+ * GraphicAttribute { protected MyGraphicAttribute(int align) {
+ * super(align); } public float getDescent() { return 0; } public float
+ * getAdvance() { return 1; } public void draw(Graphics2D g2, float x,
+ * float y) { } public float getAscent() { return 0; } }
+ * MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0); // print
+ * justification parameters
+ * System.out.println(myGA.getJustificationInfo().growAbsorb);
+ * System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
+ * System.out.println(myGA.getJustificationInfo().growLeftLimit);
+ * System.out.println(myGA.getJustificationInfo().growPriority);
+ * System.out.println(myGA.getJustificationInfo().growRightLimit);
+ * System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
+ * System.out.println(myGA.getJustificationInfo().shrinkPriority);
+ * System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
+ * System.out.println(myGA.getJustificationInfo().weight);
+ */
+ float advance = getAdvance();
+ return new GlyphJustificationInfo(advance, false,
+ GlyphJustificationInfo.PRIORITY_INTERCHAR, advance / 3, advance / 3, false,
+ GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, 0);
+ }
+
+}
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..d6d4758
--- /dev/null
+++ b/awt/java/awt/font/ImageGraphicAttribute.java
@@ -0,0 +1,185 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ImageGraphicAttribute class provides an opportunity to insert images to a
+ * text.
+ *
+ * @since Android 1.0
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute {
+
+ // Image object rendered by this ImageGraphicAttribute
+ /**
+ * The image.
+ */
+ private Image fImage;
+
+ // X coordinate of the origin point
+ /**
+ * The origin x.
+ */
+ private float fOriginX;
+
+ // Y coordinate of the origin point
+ /**
+ * The origin y.
+ */
+ private float fOriginY;
+
+ // the width of the image object
+ /**
+ * The img width.
+ */
+ private float fImgWidth;
+
+ // the height of the image object
+ /**
+ * The img height.
+ */
+ private float fImgHeight;
+
+ /**
+ * Instantiates a new ImageGraphicAttribute with the specified image,
+ * alignment and origins.
+ *
+ * @param image
+ * the Image to be rendered by ImageGraphicAttribute.
+ * @param alignment
+ * the alignment of the ImageGraphicAttribute.
+ * @param originX
+ * the origin X coordinate in the image of ImageGraphicAttribute.
+ * @param originY
+ * the origin Y coordinate in the image of ImageGraphicAttribute.
+ */
+ public ImageGraphicAttribute(Image image, int alignment, float originX, float originY) {
+ super(alignment);
+
+ this.fImage = image;
+ this.fOriginX = originX;
+ this.fOriginY = originY;
+
+ this.fImgWidth = fImage.getWidth(null);
+ this.fImgHeight = fImage.getHeight(null);
+
+ }
+
+ /**
+ * Instantiates a new ImageGraphicAttribute with the specified image and
+ * alignment.
+ *
+ * @param image
+ * the Image to be rendered by ImageGraphicAttribute.
+ * @param alignment
+ * the alignment of the ImageGraphicAttribute.
+ */
+ public ImageGraphicAttribute(Image image, int alignment) {
+ this(image, alignment, 0, 0);
+ }
+
+ /**
+ * Returns a hash code of this ImageGraphicAttribute object.
+ *
+ * @return the hash code of this ImageGraphicAttribute object.
+ */
+ @Override
+ public int hashCode() {
+ HashCode hash = new HashCode();
+
+ hash.append(fImage.hashCode());
+ hash.append(getAlignment());
+ return hash.hashCode();
+ }
+
+ /**
+ * Compares the specified ImageGraphicAttribute object with this
+ * ImageGraphicAttribute object.
+ *
+ * @param iga
+ * the ImageGraphicAttribute object to be compared.
+ * @return true, if the specified ImageGraphicAttribute object is equal to
+ * this ImageGraphicAttribute object, false otherwise.
+ */
+ public boolean equals(ImageGraphicAttribute iga) {
+ if (iga == null) {
+ return false;
+ }
+
+ if (iga == this) {
+ return true;
+ }
+
+ return (fOriginX == iga.fOriginX && fOriginY == iga.fOriginY
+ && getAlignment() == iga.getAlignment() && fImage.equals(iga.fImage));
+ }
+
+ /**
+ * Compares the specified Object with this ImageGraphicAttribute object.
+ *
+ * @param obj
+ * the Object to be compared.
+ * @return true, if the specified Object is equal to this
+ * ImageGraphicAttribute object, false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ try {
+ return equals((ImageGraphicAttribute)obj);
+ } catch (ClassCastException e) {
+ return false;
+ }
+
+ }
+
+ @Override
+ public void draw(Graphics2D g2, float x, float y) {
+ g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
+ }
+
+ @Override
+ public float getAdvance() {
+ return Math.max(0, fImgWidth - fOriginX);
+ }
+
+ @Override
+ public float getAscent() {
+ return Math.max(0, fOriginY);
+ }
+
+ @Override
+ public Rectangle2D getBounds() {
+ return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
+ }
+
+ @Override
+ public float getDescent() {
+ return Math.max(0, fImgHeight - fOriginY);
+ }
+
+}
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..4800093
--- /dev/null
+++ b/awt/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,238 @@
+/*
+ * 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 java.awt.font;
+
+import java.text.AttributedCharacterIterator; //???AWT: import java.text.BreakIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class LineBreakMeasurer provides methods to measure the graphical
+ * representation of a text in order to determine where to add line breaks so
+ * the resulting line of text fits its wrapping width. The wrapping width
+ * defines the visual width of the paragraph.
+ *
+ * @since Android 1.0
+ */
+public final class LineBreakMeasurer {
+
+ /**
+ * The tm.
+ */
+ private TextMeasurer tm = null;
+
+ // ???AWT private BreakIterator bi = null;
+ /**
+ * The position.
+ */
+ private int position = 0;
+
+ /**
+ * The maxpos.
+ */
+ int maxpos = 0;
+
+ /**
+ * Instantiates a new LineBreakMeasurer object for the specified text.
+ *
+ * @param text
+ * the AttributedCharacterIterator object which contains text
+ * with at least one character.
+ * @param frc
+ * the FontRenderContext represented information about graphic
+ * device.
+ */
+ public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+ // ???AWT: this(text, BreakIterator.getLineInstance(), frc);
+ }
+
+ /*
+ * ???AWT public LineBreakMeasurer( AttributedCharacterIterator text,
+ * BreakIterator bi, FontRenderContext frc ) { tm = new TextMeasurer(text,
+ * frc); this.bi = bi; this.bi.setText(text); position =
+ * text.getBeginIndex(); maxpos = tm.aci.getEndIndex(); }
+ */
+
+ /**
+ * Deletes a character from the specified position of the text, updates this
+ * LineBreakMeasurer object.
+ *
+ * @param newText
+ * the new text.
+ * @param pos
+ * the position of the character which is deleted.
+ */
+ public void deleteChar(AttributedCharacterIterator newText, int pos) {
+ tm.deleteChar(newText, pos);
+ // ???AWT: bi.setText(newText);
+
+ position = newText.getBeginIndex();
+
+ maxpos--;
+ }
+
+ /**
+ * Gets current position of this LineBreakMeasurer.
+ *
+ * @return the current position of this LineBreakMeasurer
+ */
+ public int getPosition() {
+ return position;
+ }
+
+ /**
+ * Inserts a character at the specified position in the text, updates this
+ * LineBreakMeasurer object.
+ *
+ * @param newText
+ * the new text.
+ * @param pos
+ * the position of the character which is inserted.
+ */
+ public void insertChar(AttributedCharacterIterator newText, int pos) {
+ tm.insertChar(newText, pos);
+ // ???AWT: bi.setText(newText);
+
+ position = newText.getBeginIndex();
+
+ maxpos++;
+ }
+
+ /**
+ * Returns the next line of text, updates current position in this
+ * LineBreakMeasurer.
+ *
+ * @param wrappingWidth
+ * the maximum visible line width.
+ * @param offsetLimit
+ * the limit point within the text indicating that no further
+ * text should be included on the line; the paragraph break.
+ * @param requireNextWord
+ * if true, null is returned (the entire word at the current
+ * position does not fit within the wrapping width); if false, a
+ * valid layout is returned that includes at least the character
+ * at the current position.
+ * @return the next TextLayout which begins at the current position and
+ * represents the next line of text with width wrappingWidth, null
+ * is returned if the entire word at the current position does not
+ * fit within the wrapping width.
+ */
+ public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+ if (position == maxpos) {
+ return null;
+ }
+
+ int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
+
+ if (nextPosition == position) {
+ return null;
+ }
+ TextLayout layout = tm.getLayout(position, nextPosition);
+ position = nextPosition;
+ return layout;
+ }
+
+ /**
+ * Returns the next line of text.
+ *
+ * @param wrappingWidth
+ * the maximum visible line width.
+ * @return the next line of text.
+ */
+ public TextLayout nextLayout(float wrappingWidth) {
+ return nextLayout(wrappingWidth, maxpos, false);
+ }
+
+ /**
+ * Returns the end position of the next line of text.
+ *
+ * @param wrappingWidth
+ * the maximum visible line width.
+ * @return the end position of the next line of text.
+ */
+ public int nextOffset(float wrappingWidth) {
+ return nextOffset(wrappingWidth, maxpos, false);
+ }
+
+ /**
+ * Returns the end position of the next line of text.
+ *
+ * @param wrappingWidth
+ * the maximum visible line width.
+ * @param offsetLimit
+ * the limit point withing the text indicating that no further
+ * text should be included on the line; the paragraph break.
+ * @param requireNextWord
+ * if true, the current position is returned if the entire next
+ * word does not fit within wrappingWidth; if false, the offset
+ * returned is at least one greater than the current position.
+ * @return the end position of the next line of text.
+ * @throws IllegalArgumentException
+ * if the offsetLimit is less than the current position.
+ */
+ public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+ if (offsetLimit <= position) {
+ // awt.203=Offset limit should be greater than current position.
+ throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
+ }
+
+ if (position == maxpos) {
+ return position;
+ }
+
+ int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
+ int correctedPos = breakPos;
+
+ // This check is required because bi.preceding(maxpos) throws an
+ // exception
+ /*
+ * ???AWT if (breakPos == maxpos) { correctedPos = maxpos; } else if
+ * (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
+ * correctedPos = bi.following(breakPos); } else { correctedPos =
+ * bi.preceding(breakPos); }
+ */
+
+ if (position >= correctedPos) {
+ if (requireNextWord) {
+ correctedPos = position;
+ } else {
+ correctedPos = Math.max(position + 1, breakPos);
+ }
+ }
+
+ return Math.min(correctedPos, offsetLimit);
+ }
+
+ /**
+ * Sets the new position of this LineBreakMeasurer.
+ *
+ * @param pos
+ * the new position of this LineBreakMeasurer.
+ */
+ public void setPosition(int pos) {
+ if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
+ // awt.33=index is out of range
+ throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
+ }
+ position = pos;
+ }
+}
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..4b03e5d
--- /dev/null
+++ b/awt/java/awt/font/LineMetrics.java
@@ -0,0 +1,116 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+/**
+ * The LineMetrics class provides information such as concerning how the text is
+ * positioned with respect to the base line, such as ascent, descent, and
+ * leading.
+ *
+ * @since Android 1.0
+ */
+public abstract class LineMetrics {
+
+ /**
+ * Gets the baseline offsets of the text according to the the baseline of
+ * this text.
+ *
+ * @return the baseline offsets of the text according to the the baseline of
+ * this text.
+ */
+ public abstract float[] getBaselineOffsets();
+
+ /**
+ * Gets the number of characters of the text.
+ *
+ * @return the number of characters of the text.
+ */
+ public abstract int getNumChars();
+
+ /**
+ * Gets the baseline index, returns one of the following index:
+ * ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
+ *
+ * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE or
+ * HANGING_BASELINE.
+ */
+ public abstract int getBaselineIndex();
+
+ /**
+ * Gets the thickness of the underline.
+ *
+ * @return the thickness of the underline.
+ */
+ public abstract float getUnderlineThickness();
+
+ /**
+ * Gets the offset of the underline.
+ *
+ * @return the offset of the underline.
+ */
+ public abstract float getUnderlineOffset();
+
+ /**
+ * Gets the thickness of strike through line.
+ *
+ * @return the thickness of strike through line.
+ */
+ public abstract float getStrikethroughThickness();
+
+ /**
+ * Gets the offset of the strike through line.
+ *
+ * @return the offset of the strike through line.
+ */
+ public abstract float getStrikethroughOffset();
+
+ /**
+ * Gets the leading of the text.
+ *
+ * @return the leading of the text.
+ */
+ public abstract float getLeading();
+
+ /**
+ * Gets the height of the text as a sum of the ascent, the descent and the
+ * leading.
+ *
+ * @return the height of the text as a sum of the ascent, the descent and
+ * the leading.
+ */
+ public abstract float getHeight();
+
+ /**
+ * Gets the descent of the text.
+ *
+ * @return the descent of the text.
+ */
+ public abstract float getDescent();
+
+ /**
+ * Gets the ascent of the text.
+ *
+ * @return the ascent of the text.
+ */
+ public abstract float getAscent();
+
+}
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..d264f24
--- /dev/null
+++ b/awt/java/awt/font/MultipleMaster.java
@@ -0,0 +1,91 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * The MultipleMaster interface provides methods to manipulate MultipleMaster
+ * type fonts and retrieve graphical and design data from them.
+ *
+ * @since Android 1.0
+ */
+public interface MultipleMaster {
+
+ /**
+ * Derives a new multiple master font based on the specified parameters.
+ *
+ * @param glyphWidths
+ * float array which represents width of each glyph in font
+ * space.
+ * @param avgStemWidth
+ * the average stem width in font space.
+ * @param typicalCapHeight
+ * the typical upper case char height.
+ * @param typicalXHeight
+ * the typical lower case char height.
+ * @param italicAngle
+ * the slope angle for italics.
+ * @return a MultipleMaster font.
+ */
+ public Font deriveMMFont(float[] glyphWidths, float avgStemWidth, float typicalCapHeight,
+ float typicalXHeight, float italicAngle);
+
+ /**
+ * Derives a new multiple master font based on the design axis values
+ * contained in the specified array.
+ *
+ * @param axes
+ * an float array which contains axis values.
+ * @return a MultipleMaster font.
+ */
+ public Font deriveMMFont(float[] axes);
+
+ /**
+ * Gets default design values for the axes.
+ *
+ * @return the default design values for the axes.
+ */
+ public float[] getDesignAxisDefaults();
+
+ /**
+ * Gets the array of design axis names.
+ *
+ * @return the array of design axis names.
+ */
+ public String[] getDesignAxisNames();
+
+ /**
+ * Gets the array of design axis ranges.
+ *
+ * @return the array of design axis ranges.
+ */
+ public float[] getDesignAxisRanges();
+
+ /**
+ * Gets the number of multiple master design controls.
+ *
+ * @return the number of multiple master design controls.
+ */
+ public int getNumDesignAxes();
+
+}
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
new file mode 100644
index 0000000..db66911
--- /dev/null
+++ b/awt/java/awt/font/OpenType.java
@@ -0,0 +1,418 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+/**
+ * The OpenType interface provides constants and methods for getting instance
+ * data for fonts of type OpenType and TrueType. For more information, see the
+ * <a
+ * href="http://partners.adobe.com/public/developer/opentype/index_spec.html">
+ * OpenType specification</a>.
+ *
+ * @since Android 1.0
+ */
+public interface OpenType {
+
+ /**
+ * The Constant TAG_ACNT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_ACNT = 1633906292;
+
+ /**
+ * The Constant TAG_AVAR indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_AVAR = 1635148146;
+
+ /**
+ * The Constant TAG_BASE indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_BASE = 1111577413;
+
+ /**
+ * The Constant TAG_BDAT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_BDAT = 1650745716;
+
+ /**
+ * The Constant TAG_BLOC indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_BLOC = 1651273571;
+
+ /**
+ * The Constant TAG_BSLN indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_BSLN = 1651731566;
+
+ /**
+ * The Constant TAG_CFF indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_CFF = 1128678944;
+
+ /**
+ * The Constant TAG_CMAP indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_CMAP = 1668112752;
+
+ /**
+ * The Constant TAG_CVAR indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_CVAR = 1668702578;
+
+ /**
+ * The Constant TAG_CVT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_CVT = 1668707360;
+
+ /**
+ * The Constant TAG_DSIG indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_DSIG = 1146308935;
+
+ /**
+ * The Constant TAG_EBDT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_EBDT = 1161970772;
+
+ /**
+ * The Constant TAG_EBLC indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_EBLC = 1161972803;
+
+ /**
+ * The Constant TAG_EBSC indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_EBSC = 1161974595;
+
+ /**
+ * The Constant TAG_FDSC indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_FDSC = 1717859171;
+
+ /**
+ * The Constant TAG_FEAT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_FEAT = 1717920116;
+
+ /**
+ * The Constant TAG_FMTX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_FMTX = 1718449272;
+
+ /**
+ * The Constant TAG_FPGM indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_FPGM = 1718642541;
+
+ /**
+ * The Constant TAG_FVAR indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_FVAR = 1719034226;
+
+ /**
+ * The Constant TAG_GASP indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GASP = 1734439792;
+
+ /**
+ * The Constant TAG_GDEF indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GDEF = 1195656518;
+
+ /**
+ * The Constant TAG_GLYF indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GLYF = 1735162214;
+
+ /**
+ * The Constant TAG_GPOS indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GPOS = 1196445523;
+
+ /**
+ * The Constant TAG_GSUB indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GSUB = 1196643650;
+
+ /**
+ * The Constant TAG_GVAR indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_GVAR = 1735811442;
+
+ /**
+ * The Constant TAG_HDMX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_HDMX = 1751412088;
+
+ /**
+ * The Constant TAG_HEAD indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_HEAD = 1751474532;
+
+ /**
+ * The Constant TAG_HHEA indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_HHEA = 1751672161;
+
+ /**
+ * The Constant TAG_HMTX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_HMTX = 1752003704;
+
+ /**
+ * The Constant TAG_JSTF indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_JSTF = 1246975046;
+
+ /**
+ * The Constant TAG_JUST indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_JUST = 1786082164;
+
+ /**
+ * The Constant TAG_KERN indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_KERN = 1801810542;
+
+ /**
+ * The Constant TAG_LCAR indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_LCAR = 1818452338;
+
+ /**
+ * The Constant TAG_LOCA indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_LOCA = 1819239265;
+
+ /**
+ * The Constant TAG_LTSH indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_LTSH = 1280594760;
+
+ /**
+ * The Constant TAG_MAXP indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_MAXP = 1835104368;
+
+ /**
+ * The Constant TAG_MMFX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_MMFX = 1296909912;
+
+ /**
+ * The Constant TAG_MMSD indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_MMSD = 1296913220;
+
+ /**
+ * The Constant TAG_MORT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_MORT = 1836020340;
+
+ /**
+ * The Constant TAG_NAME indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_NAME = 1851878757;
+
+ /**
+ * The Constant TAG_OPBD indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_OPBD = 1836020340;
+
+ /**
+ * The Constant TAG_OS2 indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_OS2 = 1330851634;
+
+ /**
+ * The Constant TAG_PCLT indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_PCLT = 1346587732;
+
+ /**
+ * The Constant TAG_POST indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_POST = 1886352244;
+
+ /**
+ * The Constant TAG_PREP indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_PREP = 1886545264;
+
+ /**
+ * The Constant TAG_PROP indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_PROP = 1886547824;
+
+ /**
+ * The Constant TAG_TRAK indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_TRAK = 1953653099;
+
+ /**
+ * The Constant TAG_TYP1 indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_TYP1 = 1954115633;
+
+ /**
+ * The Constant TAG_VDMX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_VDMX = 1447316824;
+
+ /**
+ * The Constant TAG_VHEA indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_VHEA = 1986553185;
+
+ /**
+ * The Constant TAG_VMTX indicates corresponding table tag in the Open Type
+ * Specification.
+ */
+ public static final int TAG_VMTX = 1986884728;
+
+ /**
+ * Returns the OpenType font version.
+ *
+ * @return the the OpenType font version.
+ */
+ public int getVersion();
+
+ /**
+ * Gets the table for a specified tag. Sfnt tables include cmap, name and
+ * head items.
+ *
+ * @param sfntTag
+ * the sfnt tag.
+ * @return a byte array contains the font data corresponding to the
+ * specified tag.
+ */
+ public byte[] getFontTable(int sfntTag);
+
+ /**
+ * Gets the table for a specified tag. Sfnt tables include cmap, name and
+ * head items.
+ *
+ * @param sfntTag
+ * the sfnt tag.
+ * @param offset
+ * the offset of the returned table.
+ * @param count
+ * the number of returned table.
+ * @return the table corresponding to sfntTag and containing the bytes
+ * starting at offset byte and including count bytes.
+ */
+ public byte[] getFontTable(int sfntTag, int offset, int count);
+
+ /**
+ * Gets the table for a specified tag. Sfnt tables include cmap, name and
+ * head items.
+ *
+ * @param strSfntTag
+ * the str sfnt tag as a String.
+ * @return a byte array contains the font data corresponding to the
+ * specified tag.
+ */
+ public byte[] getFontTable(String strSfntTag);
+
+ /**
+ * Gets the table for a specified tag. Sfnt tables include cmap, name and
+ * head items.
+ *
+ * @param strSfntTag
+ * the sfnt tag as a String.
+ * @param offset
+ * the offset of the returned table.
+ * @param count
+ * the number of returned table.
+ * @return the table corresponding to sfntTag and containing the bytes
+ * starting at offset byte and including count bytes.
+ */
+ public byte[] getFontTable(String strSfntTag, int offset, int count);
+
+ /**
+ * Gets the table size for a specified tag.
+ *
+ * @param strSfntTag
+ * the sfnt tag as a String.
+ * @return the table size for a specified tag.
+ */
+ public int getFontTableSize(String strSfntTag);
+
+ /**
+ * Gets the table size for a specified tag.
+ *
+ * @param sfntTag
+ * the sfnt tag.
+ * @return the table size for a specified tag.
+ */
+ public int getFontTableSize(int sfntTag);
+
+}
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..182bffd
--- /dev/null
+++ b/awt/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,206 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ShapeGraphicAttribute class provides an opportunity to insert shapes to a
+ * text.
+ *
+ * @since Android 1.0
+ */
+public final class ShapeGraphicAttribute extends GraphicAttribute {
+
+ // shape to render
+ /**
+ * The shape.
+ */
+ private Shape fShape;
+
+ // flag, if the shape should be stroked (true) or filled (false)
+ /**
+ * The stroke.
+ */
+ private boolean fStroke;
+
+ // bounds of the shape
+ /**
+ * The bounds.
+ */
+ private Rectangle2D fBounds;
+
+ // X coordinate of the origin point
+ /**
+ * The origin x.
+ */
+ private float fOriginX;
+
+ // Y coordinate of the origin point
+ /**
+ * The origin y.
+ */
+ private float fOriginY;
+
+ // width of the shape
+ /**
+ * The shape width.
+ */
+ private float fShapeWidth;
+
+ // height of the shape
+ /**
+ * The shape height.
+ */
+ private float fShapeHeight;
+
+ /**
+ * The Constant STROKE indicates whether the Shape is stroked or not.
+ */
+ public static final boolean STROKE = true;
+
+ /**
+ * The Constant FILL indicates whether the Shape is filled or not.
+ */
+ public static final boolean FILL = false;
+
+ /**
+ * Instantiates a new ShapeGraphicAttribute object for the specified Shape.
+ *
+ * @param shape
+ * the shape to be rendered by this ShapeGraphicAttribute.
+ * @param alignment
+ * the alignment of this ShapeGraphicAttribute.
+ * @param stroke
+ * true if the Shape is stroked, false if the Shape is filled.
+ */
+ public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
+ super(alignment);
+
+ this.fShape = shape;
+ this.fStroke = stroke;
+
+ this.fBounds = fShape.getBounds2D();
+
+ this.fOriginX = (float)fBounds.getMinX();
+ this.fOriginY = (float)fBounds.getMinY();
+
+ this.fShapeWidth = (float)fBounds.getWidth();
+ this.fShapeHeight = (float)fBounds.getHeight();
+ }
+
+ /**
+ * Returns a hash code of this ShapeGraphicAttribute object.
+ *
+ * @return a hash code of this ShapeGraphicAttribute object.
+ */
+ @Override
+ public int hashCode() {
+ HashCode hash = new HashCode();
+
+ hash.append(fShape.hashCode());
+ hash.append(getAlignment());
+ return hash.hashCode();
+ }
+
+ /**
+ * Compares this ShapeGraphicAttribute object to the specified
+ * ShapeGraphicAttribute object.
+ *
+ * @param sga
+ * the ShapeGraphicAttribute object to be compared.
+ * @return true, if this ShapeGraphicAttribute object is equal to the
+ * specified ShapeGraphicAttribute object, false otherwise.
+ */
+ public boolean equals(ShapeGraphicAttribute sga) {
+ if (sga == null) {
+ return false;
+ }
+
+ if (sga == this) {
+ return true;
+ }
+
+ return (fStroke == sga.fStroke && getAlignment() == sga.getAlignment() && fShape
+ .equals(sga.fShape));
+
+ }
+
+ /**
+ * Compares this ShapeGraphicAttribute object to the specified Object.
+ *
+ * @param obj
+ * the Object to be compared.
+ * @return true, if this ShapeGraphicAttribute object is equal to the
+ * specified Object, false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ try {
+ return equals((ShapeGraphicAttribute)obj);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public void draw(Graphics2D g2, float x, float y) {
+ AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+ if (fStroke == STROKE) {
+ Stroke oldStroke = g2.getStroke();
+ g2.setStroke(new BasicStroke());
+ g2.draw(at.createTransformedShape(fShape));
+ g2.setStroke(oldStroke);
+ } else {
+ g2.fill(at.createTransformedShape(fShape));
+ }
+
+ }
+
+ @Override
+ public float getAdvance() {
+ return Math.max(0, fShapeWidth + fOriginX);
+ }
+
+ @Override
+ public float getAscent() {
+ return Math.max(0, -fOriginY);
+ }
+
+ @Override
+ public Rectangle2D getBounds() {
+ return (Rectangle2D)fBounds.clone();
+ }
+
+ @Override
+ public float getDescent() {
+ return Math.max(0, fShapeHeight + fOriginY);
+ }
+
+}
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..6460eba
--- /dev/null
+++ b/awt/java/awt/font/TextHitInfo.java
@@ -0,0 +1,215 @@
+/*
+ * 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 java.awt.font;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The TextHitInfo class provides information about a caret position in a text
+ * model for insertion or deletion of a character in a text. The TextHitInfo
+ * defines two biases of the character: leading or trailing. Leading position
+ * means the left edge of the specified character (TextHitInfo.leading(2) method
+ * for "text" returns the left side of "x"). Trailing position means the right
+ * edge of the specified character (TextHitInfo.trailing(2) method for "text"
+ * returns the right side of "x").
+ *
+ * @since Android 1.0
+ */
+public final class TextHitInfo {
+
+ /**
+ * The char idx.
+ */
+ private int charIdx; // Represents character index in the line
+
+ /**
+ * The is trailing.
+ */
+ private boolean isTrailing;
+
+ /**
+ * Instantiates a new text hit info.
+ *
+ * @param idx
+ * the idx.
+ * @param isTrailing
+ * the is trailing.
+ */
+ private TextHitInfo(int idx, boolean isTrailing) {
+ charIdx = idx;
+ this.isTrailing = isTrailing;
+ }
+
+ /**
+ * Returns the textual string representation of this TextHitInfo instance.
+ *
+ * @return the string representation.
+ */
+ @Override
+ public String toString() {
+ return new String("TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
+ (isTrailing ? "Trailing" : "Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ );
+ }
+
+ /**
+ * Compares this TextHitInfo object with the specified object.
+ *
+ * @param obj
+ * the Object to be compared.
+ * @return true, if the specified object is a TextHitInfo object with the
+ * same data values as this TextHitInfo, false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof TextHitInfo) {
+ return equals((TextHitInfo)obj);
+ }
+ return false;
+ }
+
+ /**
+ * Compares this TextHitInfo object with the specified TextHitInfo object.
+ *
+ * @param thi
+ * the TextHitInfo object to be compared.
+ * @return true, if this TextHitInfo object has the same data values as the
+ * specified TextHitInfo object, false otherwise.
+ */
+ public boolean equals(TextHitInfo thi) {
+ return thi != null && thi.charIdx == charIdx && thi.isTrailing == isTrailing;
+ }
+
+ /**
+ * Gets a TextHitInfo object with its character index at the specified
+ * offset from the character index of this TextHitInfo.
+ *
+ * @param offset
+ * the offset.
+ * @return the TextHitInfo.
+ */
+ public TextHitInfo getOffsetHit(int offset) {
+ return new TextHitInfo(charIdx + offset, isTrailing);
+ }
+
+ /**
+ * Gets a TextHitInfo associated with the other side of the insertion point.
+ *
+ * @return the other hit.
+ */
+ public TextHitInfo getOtherHit() {
+ return isTrailing ? new TextHitInfo(charIdx + 1, false)
+ : new TextHitInfo(charIdx - 1, true);
+ }
+
+ /**
+ * Returns true if the leading edge of the character is hit, false if the
+ * trailing edge of the character is hit.
+ *
+ * @return true if the leading edge of the character is hit, false if the
+ * trailing edge of the character is hit.
+ */
+ public boolean isLeadingEdge() {
+ return !isTrailing;
+ }
+
+ /**
+ * Returns the hash code value of this TextHitInfo instance.
+ *
+ * @return the hash code value.
+ */
+ @Override
+ public int hashCode() {
+ return HashCode.combine(charIdx, isTrailing);
+ }
+
+ /**
+ * Gets the insertion index.
+ *
+ * @return the insertion index: character index if the leading edge is hit,
+ * or character index + 1 if the trailing edge is hit.
+ */
+ public int getInsertionIndex() {
+ return isTrailing ? charIdx + 1 : charIdx;
+ }
+
+ /**
+ * Gets the index of the character hit.
+ *
+ * @return the character hit's index.
+ */
+ public int getCharIndex() {
+ return charIdx;
+ }
+
+ /**
+ * Returns a TextHitInfo associated with the trailing edge of the character
+ * at the specified char index.
+ *
+ * @param charIndex
+ * the char index.
+ * @return the TextHitInfo associated with the trailing edge of the
+ * character at the specified char index.
+ */
+ public static TextHitInfo trailing(int charIndex) {
+ return new TextHitInfo(charIndex, true);
+ }
+
+ /**
+ * Returns a TextHitInfo object associated with the leading edge of the
+ * character at the specified char index.
+ *
+ * @param charIndex
+ * the char index.
+ * @return the TextHitInfo object associated with the leading edge of the
+ * character at the specified char index.
+ */
+ public static TextHitInfo leading(int charIndex) {
+ return new TextHitInfo(charIndex, false);
+ }
+
+ /**
+ * Returns a (trailing) TextHitInfo object associated with the character
+ * before the specified offset.
+ *
+ * @param offset
+ * the offset.
+ * @return the TextHitInfo object associated with the character before the
+ * specified offset.
+ */
+ public static TextHitInfo beforeOffset(int offset) {
+ return new TextHitInfo(offset - 1, true);
+ }
+
+ /**
+ * Returns a (leading) TextHitInfo object associated with the character
+ * after the specified offset.
+ *
+ * @param offset
+ * the offset.
+ * @return the TextHitInfo object associated with the character after the
+ * specified offset.
+ */
+ public static TextHitInfo afterOffset(int offset) {
+ return new TextHitInfo(offset, false);
+ }
+}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..cc6f0ba
--- /dev/null
+++ b/awt/java/awt/font/TextLayout.java
@@ -0,0 +1,927 @@
+/*
+ * 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 java.awt.font;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.font.BasicMetrics;
+import org.apache.harmony.awt.gl.font.CaretManager;
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TextLayout class defines the graphical representation of character data.
+ * This class provides method for obtaining information about cursor positioning
+ * and movement, split cursors for text with different directions, logical and
+ * visual highlighting, multiple baselines, hits, justification, ascent,
+ * descent, and advance, and rendering. A TextLayout object can be rendered
+ * using Graphics context.
+ *
+ * @since Android 1.0
+ */
+public final class TextLayout implements Cloneable {
+
+ /**
+ * The CaretPolicy class provides a policy for obtaining the caret location.
+ * The single getStrongCaret method specifies the policy.
+ */
+ public static class CaretPolicy {
+
+ /**
+ * Instantiates a new CaretPolicy.
+ */
+ public CaretPolicy() {
+ // Nothing to do
+ }
+
+ /**
+ * Returns whichever of the two specified TextHitInfo objects has the
+ * stronger caret (higher character level) in the specified TextLayout.
+ *
+ * @param hit1
+ * the first TextHitInfo of the specified TextLayout.
+ * @param hit2
+ * the second TextHitInfo of the specified TextLayout.
+ * @param layout
+ * the TextLayout.
+ * @return the TextHitInfo with the stronger caret.
+ */
+ public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
+ // Stronger hit is the one with greater level.
+ // If the level is same, leading edge is stronger.
+
+ int level1 = layout.getCharacterLevel(hit1.getCharIndex());
+ int level2 = layout.getCharacterLevel(hit2.getCharIndex());
+
+ if (level1 == level2) {
+ return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
+ }
+ return level1 > level2 ? hit1 : hit2;
+ }
+
+ }
+
+ /**
+ * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
+ */
+ public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+
+ /**
+ * The breaker.
+ */
+ private TextRunBreaker breaker;
+
+ /**
+ * The metrics valid.
+ */
+ private boolean metricsValid = false;
+
+ /**
+ * The tmc.
+ */
+ private TextMetricsCalculator tmc;
+
+ /**
+ * The metrics.
+ */
+ private BasicMetrics metrics;
+
+ /**
+ * The caret manager.
+ */
+ private CaretManager caretManager;
+
+ /**
+ * The justification width.
+ */
+ float justificationWidth = -1;
+
+ /**
+ * Instantiates a new TextLayout object from the specified string and Font.
+ *
+ * @param string
+ * the string to be displayed.
+ * @param font
+ * the font of the text.
+ * @param frc
+ * the FontRenderContext object for obtaining information about a
+ * graphics device.
+ */
+ public TextLayout(String string, Font font, FontRenderContext frc) {
+ if (string == null) {
+ // awt.01='{0}' parameter is null
+ throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (font == null) {
+ // awt.01='{0}' parameter is null
+ throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (string.length() == 0) {
+ // awt.02='{0}' parameter has zero length
+ throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ AttributedString as = new AttributedString(string);
+ as.addAttribute(TextAttribute.FONT, font);
+ this.breaker = new TextRunBreaker(as.getIterator(), frc);
+ caretManager = new CaretManager(breaker);
+ }
+
+ /**
+ * Instantiates a new TextLayout from the specified text and a map of
+ * attributes.
+ *
+ * @param string
+ * the string to be displayed.
+ * @param attributes
+ * the attributes to be used for obtaining the text style.
+ * @param frc
+ * the FontRenderContext object for obtaining information about a
+ * graphics device.
+ */
+ public TextLayout(String string,
+ Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
+ FontRenderContext frc) {
+ if (string == null) {
+ // awt.01='{0}' parameter is null
+ throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (attributes == null) {
+ // awt.01='{0}' parameter is null
+ throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (string.length() == 0) {
+ // awt.02='{0}' parameter has zero length
+ throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ AttributedString as = new AttributedString(string);
+ as.addAttributes(attributes, 0, string.length());
+ this.breaker = new TextRunBreaker(as.getIterator(), frc);
+ caretManager = new CaretManager(breaker);
+ }
+
+ /**
+ * Instantiates a new TextLayout from the AttributedCharacterIterator.
+ *
+ * @param text
+ * the AttributedCharacterIterator.
+ * @param frc
+ * the FontRenderContext object for obtaining information about a
+ * graphics device.
+ */
+ public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
+ if (text == null) {
+ // awt.03='{0}' iterator parameter is null
+ throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (text.getBeginIndex() == text.getEndIndex()) {
+ // awt.04='{0}' iterator parameter has zero length
+ throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ this.breaker = new TextRunBreaker(text, frc);
+ caretManager = new CaretManager(breaker);
+ }
+
+ /**
+ * Instantiates a new text layout.
+ *
+ * @param breaker
+ * the breaker.
+ */
+ TextLayout(TextRunBreaker breaker) {
+ this.breaker = breaker;
+ caretManager = new CaretManager(this.breaker);
+ }
+
+ /**
+ * Returns a hash code of this TextLayout object.
+ *
+ * @return a hash code of this TextLayout object.
+ */
+ @Override
+ public int hashCode() {
+ return breaker.hashCode();
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return a copy of this object.
+ */
+ @Override
+ protected Object clone() {
+ TextLayout res = new TextLayout((TextRunBreaker)breaker.clone());
+
+ if (justificationWidth >= 0) {
+ res.handleJustify(justificationWidth);
+ }
+
+ return res;
+ }
+
+ /**
+ * Compares this TextLayout object to the specified TextLayout object.
+ *
+ * @param layout
+ * the TextLayout object to be compared.
+ * @return true, if this TextLayout object is equal to the specified
+ * TextLayout object, false otherwise.
+ */
+ public boolean equals(TextLayout layout) {
+ if (layout == null) {
+ return false;
+ }
+ return this.breaker.equals(layout.breaker);
+ }
+
+ /**
+ * Compares this TextLayout object to the specified Object.
+ *
+ * @param obj
+ * the Object to be compared.
+ * @return true, if this TextLayout object is equal to the specified Object,
+ * false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof TextLayout ? equals((TextLayout)obj) : false;
+ }
+
+ /**
+ * Gets the string representation for this TextLayout.
+ *
+ * @return the string representation for this TextLayout.
+ */
+ @Override
+ public String toString() { // what for?
+ return super.toString();
+ }
+
+ /**
+ * Draws this TextLayout at the specified location with the specified
+ * Graphics2D context.
+ *
+ * @param g2d
+ * the Graphics2D object which renders this TextLayout.
+ * @param x
+ * the X coordinate of the TextLayout origin.
+ * @param y
+ * the Y coordinate of the TextLayout origin.
+ */
+ public void draw(Graphics2D g2d, float x, float y) {
+ updateMetrics();
+ breaker.drawSegments(g2d, x, y);
+ }
+
+ /**
+ * Update metrics.
+ */
+ private void updateMetrics() {
+ if (!metricsValid) {
+ breaker.createAllSegments();
+ tmc = new TextMetricsCalculator(breaker);
+ metrics = tmc.createMetrics();
+ metricsValid = true;
+ }
+ }
+
+ /**
+ * Gets the advance of this TextLayout object.
+ *
+ * @return the advance of this TextLayout object.
+ */
+ public float getAdvance() {
+ updateMetrics();
+ return metrics.getAdvance();
+ }
+
+ /**
+ * Gets the ascent of this TextLayout object.
+ *
+ * @return the ascent of this TextLayout object.
+ */
+ public float getAscent() {
+ updateMetrics();
+ return metrics.getAscent();
+ }
+
+ /**
+ * Gets the baseline of this TextLayout object.
+ *
+ * @return the baseline of this TextLayout object.
+ */
+ public byte getBaseline() {
+ updateMetrics();
+ return (byte)metrics.getBaseLineIndex();
+ }
+
+ /**
+ * Gets the float array of offsets for the baselines which are used in this
+ * TextLayout.
+ *
+ * @return the float array of offsets for the baselines which are used in
+ * this TextLayout.
+ */
+ public float[] getBaselineOffsets() {
+ updateMetrics();
+ return tmc.getBaselineOffsets();
+ }
+
+ /**
+ * Gets the black box bounds of the characters in the specified area. The
+ * black box bounds is an Shape which contains all bounding boxes of all the
+ * glyphs of the characters between firstEndpoint and secondEndpoint
+ * parameters values.
+ *
+ * @param firstEndpoint
+ * the first point of the area.
+ * @param secondEndpoint
+ * the second point of the area.
+ * @return the Shape which contains black box bounds.
+ */
+ public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+ updateMetrics();
+ if (firstEndpoint < secondEndpoint) {
+ return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+ }
+ return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
+ }
+
+ /**
+ * Gets the bounds of this TextLayout.
+ *
+ * @return the bounds of this TextLayout.
+ */
+ public Rectangle2D getBounds() {
+ updateMetrics();
+ return breaker.getVisualBounds();
+ }
+
+ /**
+ * Gets information about the caret of the specified TextHitInfo.
+ *
+ * @param hitInfo
+ * the TextHitInfo.
+ * @return the information about the caret of the specified TextHitInfo.
+ */
+ public float[] getCaretInfo(TextHitInfo hitInfo) {
+ updateMetrics();
+ return caretManager.getCaretInfo(hitInfo);
+ }
+
+ /**
+ * Gets information about the caret of the specified TextHitInfo of a
+ * character in this TextLayout.
+ *
+ * @param hitInfo
+ * the TextHitInfo of a character in this TextLayout.
+ * @param bounds
+ * the bounds to which the caret info is constructed.
+ * @return the caret of the specified TextHitInfo.
+ */
+ public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
+ updateMetrics();
+ return caretManager.getCaretInfo(hitInfo);
+ }
+
+ /**
+ * Gets a Shape which represents the caret of the specified TextHitInfo in
+ * the bounds of this TextLayout.
+ *
+ * @param hitInfo
+ * the TextHitInfo.
+ * @param bounds
+ * the bounds to which the caret info is constructed.
+ * @return the Shape which represents the caret.
+ */
+ public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
+ updateMetrics();
+ return caretManager.getCaretShape(hitInfo, this);
+ }
+
+ /**
+ * Gets a Shape which represents the caret of the specified TextHitInfo in
+ * the bounds of this TextLayout.
+ *
+ * @param hitInfo
+ * the TextHitInfo.
+ * @return the Shape which represents the caret.
+ */
+ public Shape getCaretShape(TextHitInfo hitInfo) {
+ updateMetrics();
+ return caretManager.getCaretShape(hitInfo, this);
+ }
+
+ /**
+ * Gets two Shapes for the strong and weak carets with default caret policy
+ * and null bounds: the first element is the strong caret, the second is the
+ * weak caret or null.
+ *
+ * @param offset
+ * an offset in the TextLayout.
+ * @return an array of two Shapes corresponded to the strong and weak
+ * carets.
+ */
+ public Shape[] getCaretShapes(int offset) {
+ return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
+ }
+
+ /**
+ * Gets two Shapes for the strong and weak carets with the default caret
+ * policy: the first element is the strong caret, the second is the weak
+ * caret or null.
+ *
+ * @param offset
+ * an offset in the TextLayout.
+ * @param bounds
+ * the bounds to which to extend the carets.
+ * @return an array of two Shapes corresponded to the strong and weak
+ * carets.
+ */
+ public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
+ return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
+ }
+
+ /**
+ * Gets two Shapes for the strong and weak carets: the first element is the
+ * strong caret, the second is the weak caret or null.
+ *
+ * @param offset
+ * an offset in the TextLayout.
+ * @param bounds
+ * the bounds to which to extend the carets.
+ * @param policy
+ * the specified CaretPolicy.
+ * @return an array of two Shapes corresponded to the strong and weak
+ * carets.
+ */
+ public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
+ if (offset < 0 || offset > breaker.getCharCount()) {
+ // awt.195=Offset is out of bounds
+ throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+ }
+
+ updateMetrics();
+ return caretManager.getCaretShapes(offset, bounds, policy, this);
+ }
+
+ /**
+ * Gets the number of characters in this TextLayout.
+ *
+ * @return the number of characters in this TextLayout.
+ */
+ public int getCharacterCount() {
+ return breaker.getCharCount();
+ }
+
+ /**
+ * Gets the level of the character with the specified index.
+ *
+ * @param index
+ * the specified index of the character.
+ * @return the level of the character.
+ */
+ public byte getCharacterLevel(int index) {
+ if (index == -1 || index == getCharacterCount()) {
+ return (byte)breaker.getBaseLevel();
+ }
+ return breaker.getLevel(index);
+ }
+
+ /**
+ * Gets the descent of this TextLayout.
+ *
+ * @return the descent of this TextLayout.
+ */
+ public float getDescent() {
+ updateMetrics();
+ return metrics.getDescent();
+ }
+
+ /**
+ * Gets the TextLayout wich is justified with the specified width related to
+ * this TextLayout.
+ *
+ * @param justificationWidth
+ * the width which is used for justification.
+ * @return a TextLayout justified to the specified width.
+ * @throws Error
+ * the error occures if this TextLayout has been already
+ * justified.
+ */
+ public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
+ float justification = breaker.getJustification();
+
+ if (justification < 0) {
+ // awt.196=Justification impossible, layout already justified
+ throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
+ } else if (justification == 0) {
+ return this;
+ }
+
+ TextLayout justifiedLayout = new TextLayout((TextRunBreaker)breaker.clone());
+ justifiedLayout.handleJustify(justificationWidth);
+ return justifiedLayout;
+ }
+
+ /**
+ * Gets the leading of this TextLayout.
+ *
+ * @return the leading of this TextLayout.
+ */
+ public float getLeading() {
+ updateMetrics();
+ return metrics.getLeading();
+ }
+
+ /**
+ * Gets a Shape representing the logical selection betweeen the specified
+ * endpoints and extended to the natural bounds of this TextLayout.
+ *
+ * @param firstEndpoint
+ * the first selected endpoint within the area of characters
+ * @param secondEndpoint
+ * the second selected endpoint within the area of characters
+ * @return a Shape represented the logical selection betweeen the specified
+ * endpoints.
+ */
+ public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
+ updateMetrics();
+ return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
+ }
+
+ /**
+ * Gets a Shape representing the logical selection betweeen the specified
+ * endpoints and extended to the specified bounds of this TextLayout.
+ *
+ * @param firstEndpoint
+ * the first selected endpoint within the area of characters
+ * @param secondEndpoint
+ * the second selected endpoint within the area of characters
+ * @param bounds
+ * the specified bounds of this TextLayout.
+ * @return a Shape represented the logical selection betweeen the specified
+ * endpoints.
+ */
+ public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint, Rectangle2D bounds) {
+ updateMetrics();
+
+ if (firstEndpoint > secondEndpoint) {
+ if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
+ // awt.197=Endpoints are out of range
+ throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+ }
+ return caretManager.getLogicalHighlightShape(secondEndpoint, firstEndpoint, bounds,
+ this);
+ }
+ if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
+ // awt.197=Endpoints are out of range
+ throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+ }
+ return caretManager.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds, this);
+ }
+
+ /**
+ * Gets the logical ranges of text which corresponds to a visual selection.
+ *
+ * @param hit1
+ * the first endpoint of the visual range.
+ * @param hit2
+ * the second endpoint of the visual range.
+ * @return the logical ranges of text which corresponds to a visual
+ * selection.
+ */
+ public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+ return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the left (or up at the end of
+ * the line) of the specified offset.
+ *
+ * @param offset
+ * the offset in this TextLayout.
+ * @return the TextHitInfo for the next caret to the left (or up at the end
+ * of the line) of the specified hit, or null if there is no hit.
+ */
+ public TextHitInfo getNextLeftHit(int offset) {
+ return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the left (or up at the end of
+ * the line) of the specified hit.
+ *
+ * @param hitInfo
+ * the initial hit.
+ * @return the TextHitInfo for the next caret to the left (or up at the end
+ * of the line) of the specified hit, or null if there is no hit.
+ */
+ public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+ breaker.createAllSegments();
+ return caretManager.getNextLeftHit(hitInfo);
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the left (or up at the end of
+ * the line) of the specified offset, given the specified caret policy.
+ *
+ * @param offset
+ * the offset in this TextLayout.
+ * @param policy
+ * the policy to be used for obtaining the strong caret.
+ * @return the TextHitInfo for the next caret to the left of the specified
+ * offset, or null if there is no hit.
+ */
+ public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
+ if (offset < 0 || offset > breaker.getCharCount()) {
+ // awt.195=Offset is out of bounds
+ throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+ }
+
+ TextHitInfo hit = TextHitInfo.afterOffset(offset);
+ TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+ TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
+
+ if (nextLeftHit != null) {
+ return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the right (or down at the end
+ * of the line) of the specified hit.
+ *
+ * @param hitInfo
+ * the initial hit.
+ * @return the TextHitInfo for the next caret to the right (or down at the
+ * end of the line) of the specified hit, or null if there is no
+ * hit.
+ */
+ public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+ breaker.createAllSegments();
+ return caretManager.getNextRightHit(hitInfo);
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the right (or down at the end
+ * of the line) of the specified offset.
+ *
+ * @param offset
+ * the offset in this TextLayout.
+ * @return the TextHitInfo for the next caret to the right of the specified
+ * offset, or null if there is no hit.
+ */
+ public TextHitInfo getNextRightHit(int offset) {
+ return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+ }
+
+ /**
+ * Gets the TextHitInfo for the next caret to the right (or down at the end
+ * of the line) of the specified offset, given the specified caret policy.
+ *
+ * @param offset
+ * the offset in this TextLayout.
+ * @param policy
+ * the policy to be used for obtaining the strong caret.
+ * @return the TextHitInfo for the next caret to the right of the specified
+ * offset, or null if there is no hit.
+ */
+ public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
+ if (offset < 0 || offset > breaker.getCharCount()) {
+ // awt.195=Offset is out of bounds
+ throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+ }
+
+ TextHitInfo hit = TextHitInfo.afterOffset(offset);
+ TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+ TextHitInfo nextRightHit = getNextRightHit(strongHit);
+
+ if (nextRightHit != null) {
+ return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the outline of this TextLayout as a Shape.
+ *
+ * @param xform
+ * the AffineTransform to be used to transform the outline before
+ * returning it, or null if no transformation is desired.
+ * @return the outline of this TextLayout as a Shape.
+ */
+ public Shape getOutline(AffineTransform xform) {
+ breaker.createAllSegments();
+
+ GeneralPath outline = breaker.getOutline();
+
+ if (outline != null && xform != null) {
+ outline.transform(xform);
+ }
+
+ return outline;
+ }
+
+ /**
+ * Gets the visible advance of this TextLayout which is defined as diffence
+ * between leading (advance) and trailing whitespace.
+ *
+ * @return the visible advance of this TextLayout.
+ */
+ public float getVisibleAdvance() {
+ updateMetrics();
+
+ // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
+ // base direction, so it is also trailing
+ // in logical representation. We use this fact.
+ int lastNonWhitespace = breaker.getLastNonWhitespace();
+
+ if (lastNonWhitespace < 0) {
+ return 0;
+ } else if (lastNonWhitespace == getCharacterCount() - 1) {
+ return getAdvance();
+ } else if (justificationWidth >= 0) { // Layout is justified
+ return justificationWidth;
+ } else {
+ breaker.pushSegments(breaker.getACI().getBeginIndex(), lastNonWhitespace
+ + breaker.getACI().getBeginIndex() + 1);
+
+ breaker.createAllSegments();
+
+ float visAdvance = tmc.createMetrics().getAdvance();
+
+ breaker.popSegments();
+ return visAdvance;
+ }
+ }
+
+ /**
+ * Gets a Shape which corresponds to the highlighted (selected) area based
+ * on two hit locations within the text and extends to the bounds.
+ *
+ * @param hit1
+ * the first text hit location.
+ * @param hit2
+ * the second text hit location.
+ * @param bounds
+ * the rectangle that the highlighted area should be extended or
+ * restricted to.
+ * @return a Shape which corresponds to the highlighted (selected) area.
+ */
+ public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
+ return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
+ }
+
+ /**
+ * Gets a Shape which corresponds to the highlighted (selected) area based
+ * on two hit locations within the text.
+ *
+ * @param hit1
+ * the first text hit location.
+ * @param hit2
+ * the second text hit location.
+ * @return a Shape which corresponds to the highlighted (selected) area.
+ */
+ public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
+ breaker.createAllSegments();
+ return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
+ }
+
+ /**
+ * Gets the TextHitInfo for a hit on the opposite side of the specified
+ * hit's caret.
+ *
+ * @param hitInfo
+ * the specified TextHitInfo.
+ * @return the TextHitInfo for a hit on the opposite side of the specified
+ * hit's caret.
+ */
+ public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+ return caretManager.getVisualOtherHit(hitInfo);
+ }
+
+ /**
+ * Justifies the text; this method should be overridden by subclasses.
+ *
+ * @param justificationWidth
+ * the width for justification.
+ */
+ protected void handleJustify(float justificationWidth) {
+ float justification = breaker.getJustification();
+
+ if (justification < 0) {
+ // awt.196=Justification impossible, layout already justified
+ throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
+ } else if (justification == 0) {
+ return;
+ }
+
+ float gap = (justificationWidth - getVisibleAdvance()) * justification;
+ breaker.justify(gap);
+ this.justificationWidth = justificationWidth;
+
+ // Correct metrics
+ tmc = new TextMetricsCalculator(breaker);
+ tmc.correctAdvance(metrics);
+ }
+
+ /**
+ * Returns a TextHitInfo object that gives information on which division
+ * point (between two characters) is corresponds to a hit (such as a mouse
+ * click) at the specified coordinates.
+ *
+ * @param x
+ * the X coordinate in this TextLayout.
+ * @param y
+ * the Y coordinate in this TextLayout. TextHitInfo object
+ * corresponding to the given coordinates within the text.
+ * @return the information about the character at the specified position.
+ */
+ public TextHitInfo hitTestChar(float x, float y) {
+ return hitTestChar(x, y, getBounds());
+ }
+
+ /**
+ * Returns a TextHitInfo object that gives information on which division
+ * point (between two characters) is corresponds to a hit (such as a mouse
+ * click) at the specified coordinates within the specified text rectangle.
+ *
+ * @param x
+ * the X coordinate in this TextLayout.
+ * @param y
+ * the Y coordinate in this TextLayout.
+ * @param bounds
+ * the bounds of the text area. TextHitInfo object corresponding
+ * to the given coordinates within the text.
+ * @return the information about the character at the specified position.
+ */
+ public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
+ if (x > bounds.getMaxX()) {
+ return breaker.isLTR() ? TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo
+ .leading(0);
+ }
+
+ if (x < bounds.getMinX()) {
+ return breaker.isLTR() ? TextHitInfo.leading(0) : TextHitInfo.trailing(breaker
+ .getCharCount() - 1);
+ }
+
+ return breaker.hitTest(x, y);
+ }
+
+ /**
+ * Returns true if this TextLayout has a "left to right" direction.
+ *
+ * @return true if this TextLayout has a "left to right" direction, false if
+ * this TextLayout has a "right to left" direction.
+ */
+ public boolean isLeftToRight() {
+ return breaker.isLTR();
+ }
+
+ /**
+ * Returns true if this TextLayout is vertical, false otherwise.
+ *
+ * @return true if this TextLayout is vertical, false if horizontal.
+ */
+ public boolean isVertical() {
+ return false;
+ }
+}
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..9741f59
--- /dev/null
+++ b/awt/java/awt/font/TextMeasurer.java
@@ -0,0 +1,182 @@
+/*
+ * 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 java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+
+/**
+ * The TextMeasurer class provides utilities for line break operations.
+ *
+ * @since Android 1.0
+ */
+public final class TextMeasurer implements Cloneable {
+
+ /**
+ * The aci.
+ */
+ AttributedCharacterIterator aci;
+
+ /**
+ * The frc.
+ */
+ FontRenderContext frc;
+
+ /**
+ * The breaker.
+ */
+ TextRunBreaker breaker = null;
+
+ /**
+ * The tmc.
+ */
+ TextMetricsCalculator tmc = null;
+
+ /**
+ * Instantiates a new text measurer from the specified text.
+ *
+ * @param text
+ * the source text.
+ * @param frc
+ * the FontRenderContext.
+ */
+ public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+ this.aci = text;
+ this.frc = frc;
+ breaker = new TextRunBreaker(aci, this.frc);
+ tmc = new TextMetricsCalculator(breaker);
+ }
+
+ /**
+ * Replaces the current text with the new text, inserting a break character
+ * at the specified insert position.
+ *
+ * @param newParagraph
+ * the new paragraph text.
+ * @param insertPos
+ * the position in the text where the character is inserted.
+ */
+ public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+ AttributedCharacterIterator oldAci = aci;
+ aci = newParagraph;
+ if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
+ - (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
+ breaker = new TextRunBreaker(aci, this.frc);
+ tmc = new TextMetricsCalculator(breaker);
+ } else {
+ breaker.insertChar(newParagraph, insertPos);
+ }
+ }
+
+ /**
+ * Replaces the current text with the new text and deletes a character at
+ * the specified position.
+ *
+ * @param newParagraph
+ * the paragraph text after deletion.
+ * @param deletePos
+ * the position in the text where the character is removed.
+ */
+ public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+ AttributedCharacterIterator oldAci = aci;
+ aci = newParagraph;
+ if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
+ - (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
+ breaker = new TextRunBreaker(aci, this.frc);
+ tmc = new TextMetricsCalculator(breaker);
+ } else {
+ breaker.deleteChar(newParagraph, deletePos);
+ }
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return a copy of this object.
+ */
+ @Override
+ protected Object clone() {
+ return new TextMeasurer((AttributedCharacterIterator)aci.clone(), frc);
+ }
+
+ /**
+ * Returns a TextLayout of the specified character range.
+ *
+ * @param start
+ * the index of the first character.
+ * @param limit
+ * the index after the last character.
+ * @return a TextLayout for the characters beginning at "start" up to "end".
+ */
+ public TextLayout getLayout(int start, int limit) {
+ breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
+
+ breaker.createAllSegments();
+ TextLayout layout = new TextLayout((TextRunBreaker)breaker.clone());
+
+ breaker.popSegments();
+ return layout;
+ }
+
+ /**
+ * Returns the graphical width of a line beginning at "start" parameter and
+ * including characters up to "end" parameter. "start" and "end" are
+ * absolute indices, not relative to the "start" of the paragraph.
+ *
+ * @param start
+ * the character index at which to start measuring.
+ * @param end
+ * the character index at which to stop measuring.
+ * @return the graphical width of a line beginning at "start" and including
+ * characters up to "end".
+ */
+ public float getAdvanceBetween(int start, int end) {
+ breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
+
+ breaker.createAllSegments();
+ float retval = tmc.createMetrics().getAdvance();
+
+ breaker.popSegments();
+ return retval;
+ }
+
+ /**
+ * Returns the index of the first character which is not fit on a line
+ * beginning at start and possible measuring up to maxAdvance in graphical
+ * width.
+ *
+ * @param start
+ * he character index at which to start measuring.
+ * @param maxAdvance
+ * the graphical width in which the line must fit.
+ * @return the index after the last character that is fit on a line
+ * beginning at start, which is not longer than maxAdvance in
+ * graphical width.
+ */
+ public int getLineBreakIndex(int start, float maxAdvance) {
+ breaker.createAllSegments();
+ return breaker.getLineBreakIndex(start - aci.getBeginIndex(), maxAdvance)
+ + aci.getBeginIndex();
+ }
+}
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..ff2caa2
--- /dev/null
+++ b/awt/java/awt/font/TransformAttribute.java
@@ -0,0 +1,86 @@
+/*
+ * 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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TransformAttribute class is a wrapper for the AffineTransform class in
+ * order to use it as attribute.
+ *
+ * @since Android 1.0
+ */
+public final class TransformAttribute implements Serializable {
+
+ /**
+ * The Constant serialVersionUID.
+ */
+ private static final long serialVersionUID = 3356247357827709530L;
+
+ // affine transform of this TransformAttribute instance
+ /**
+ * The transform.
+ */
+ private AffineTransform fTransform;
+
+ /**
+ * Instantiates a new TransformAttribute from the specified AffineTransform.
+ *
+ * @param transform
+ * the AffineTransform to be wrapped.
+ */
+ public TransformAttribute(AffineTransform transform) {
+ if (transform == null) {
+ // awt.94=transform can not be null
+ throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+ }
+ if (!transform.isIdentity()) {
+ this.fTransform = new AffineTransform(transform);
+ }
+ }
+
+ /**
+ * Gets the initial AffineTransform which is wrapped.
+ *
+ * @return the initial AffineTransform which is wrapped.
+ */
+ public AffineTransform getTransform() {
+ if (fTransform != null) {
+ return new AffineTransform(fTransform);
+ }
+ return new AffineTransform();
+ }
+
+ /**
+ * Checks if this transform is an identity transform.
+ *
+ * @return true, if this transform is an identity transform, false
+ * otherwise.
+ */
+ public boolean isIdentity() {
+ return (fTransform == null);
+ }
+
+}
diff --git a/awt/java/awt/font/package.html b/awt/java/awt/font/package.html
new file mode 100644
index 0000000..788dcc0
--- /dev/null
+++ b/awt/java/awt/font/package.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <p>
+ This package contains classes to support the representation of different types of fonts for example TrueType fonts.
+ </p>
+ @since Android 1.0
+ </body>
+</html>