/*
 * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 *
 * (C) Copyright IBM Corp. 2005 - All Rights Reserved
 *
 * The original version of this source code and documentation is
 * copyrighted and owned by IBM. These materials are provided
 * under terms of a License Agreement between IBM and Sun.
 * This technology is protected by multiple US and International
 * patents. This notice and attribution to IBM may not be removed.
 */

package sun.font;

import static sun.font.EAttribute.*;
import static java.lang.Math.*;

import java.awt.Font;
import java.awt.Paint;
import java.awt.Toolkit;
import java.awt.font.GraphicAttribute;
import java.awt.font.NumericShaper;
import java.awt.font.TextAttribute;
import java.awt.font.TransformAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.im.InputMethodHighlight;
import java.io.Serializable;
import java.text.Annotation;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.Map;
import java.util.HashMap;
import java.util.Hashtable;

public final class AttributeValues implements Cloneable {
    private int defined;
    private int nondefault;

    private String family = "Default";
    private float weight = 1f;
    private float width = 1f;
    private float posture; // 0f
    private float size = 12f;
    private float tracking; // 0f
    private NumericShaper numericShaping; // null
    private AffineTransform transform; // null == identity
    private GraphicAttribute charReplacement; // null
    private Paint foreground; // null
    private Paint background; // null
    private float justification = 1f;
    private Object imHighlight; // null
    // (can be either Attribute wrapping IMH, or IMH itself
    private Font font; // here for completeness, don't actually use
    private byte imUnderline = -1; // same default as underline
    private byte superscript; // 0
    private byte underline = -1; // arrgh, value for ON is 0
    private byte runDirection = -2; // BIDI.DIRECTION_DEFAULT_LEFT_TO_RIGHT
    private byte bidiEmbedding; // 0
    private byte kerning; // 0
    private byte ligatures; // 0
    private boolean strikethrough; // false
    private boolean swapColors; // false

    private AffineTransform baselineTransform; // derived from transform
    private AffineTransform charTransform; // derived from transform

    private static final AttributeValues DEFAULT = new AttributeValues();

    // type-specific API
    public String getFamily() { return family; }
    public void setFamily(String f) { this.family = f; update(EFAMILY); }

    public float getWeight() { return weight; }
    public void setWeight(float f) { this.weight = f; update(EWEIGHT); }

    public float getWidth() { return width; }
    public void setWidth(float f) { this.width = f; update(EWIDTH); }

    public float getPosture() { return posture; }
    public void setPosture(float f) { this.posture = f; update(EPOSTURE); }

    public float getSize() { return size; }
    public void setSize(float f) { this.size = f; update(ESIZE); }

    public AffineTransform getTransform() { return transform; }
    public void setTransform(AffineTransform f) {
        this.transform = (f == null || f.isIdentity())
            ? DEFAULT.transform
            : new AffineTransform(f);
        updateDerivedTransforms();
        update(ETRANSFORM);
    }
    public void setTransform(TransformAttribute f) {
        this.transform = (f == null || f.isIdentity())
            ? DEFAULT.transform
            : f.getTransform();
        updateDerivedTransforms();
        update(ETRANSFORM);
    }

    public int getSuperscript() { return superscript; }
    public void setSuperscript(int f) {
      this.superscript = (byte)f; update(ESUPERSCRIPT); }

    public Font getFont() { return font; }
    public void setFont(Font f) { this.font = f; update(EFONT); }

    public GraphicAttribute getCharReplacement() { return charReplacement; }
    public void setCharReplacement(GraphicAttribute f) {
      this.charReplacement = f; update(ECHAR_REPLACEMENT); }

    public Paint getForeground() { return foreground; }
    public void setForeground(Paint f) {
      this.foreground = f; update(EFOREGROUND); }

    public Paint getBackground() { return background; }
    public void setBackground(Paint f) {
      this.background = f; update(EBACKGROUND); }

    public int getUnderline() { return underline; }
    public void setUnderline(int f) {
      this.underline = (byte)f; update(EUNDERLINE); }

    public boolean getStrikethrough() { return strikethrough; }
    public void setStrikethrough(boolean f) {
      this.strikethrough = f; update(ESTRIKETHROUGH); }

    public int getRunDirection() { return runDirection; }
    public void setRunDirection(int f) {
      this.runDirection = (byte)f; update(ERUN_DIRECTION); }

    public int getBidiEmbedding() { return bidiEmbedding; }
    public void setBidiEmbedding(int f) {
      this.bidiEmbedding = (byte)f; update(EBIDI_EMBEDDING); }

    public float getJustification() { return justification; }
    public void setJustification(float f) {
      this.justification = f; update(EJUSTIFICATION); }

    public Object getInputMethodHighlight() { return imHighlight; }
    public void setInputMethodHighlight(Annotation f) {
      this.imHighlight = f; update(EINPUT_METHOD_HIGHLIGHT); }
    public void setInputMethodHighlight(InputMethodHighlight f) {
      this.imHighlight = f; update(EINPUT_METHOD_HIGHLIGHT); }

    public int getInputMethodUnderline() { return imUnderline; }
    public void setInputMethodUnderline(int f) {
      this.imUnderline = (byte)f; update(EINPUT_METHOD_UNDERLINE); }

    public boolean getSwapColors() { return swapColors; }
    public void setSwapColors(boolean f) {
      this.swapColors = f; update(ESWAP_COLORS); }

    public NumericShaper getNumericShaping() { return numericShaping; }
    public void setNumericShaping(NumericShaper f) {
      this.numericShaping = f; update(ENUMERIC_SHAPING); }

    public int getKerning() { return kerning; }
    public void setKerning(int f) {
      this.kerning = (byte)f; update(EKERNING); }

    public float getTracking() { return tracking; }
    public void setTracking(float f) {
      this.tracking = (byte)f; update(ETRACKING); }

    public int getLigatures() { return ligatures; }
    public void setLigatures(int f) {
      this.ligatures = (byte)f; update(ELIGATURES); }


    public AffineTransform getBaselineTransform() { return baselineTransform; }
    public AffineTransform getCharTransform() { return charTransform; }

    // mask api

    public static int getMask(EAttribute att) {
        return att.mask;
    }

    public static int getMask(EAttribute ... atts) {
        int mask = 0;
        for (EAttribute a: atts) {
            mask |= a.mask;
        }
        return mask;
    }

    public static final int MASK_ALL =
        getMask(EAttribute.values());

    public void unsetDefault() {
        defined &= nondefault;
    }

    public void defineAll(int mask) {
        defined |= mask;
        if ((defined & EBASELINE_TRANSFORM.mask) != 0) {
            throw new InternalError("can't define derived attribute");
        }
    }

    public boolean allDefined(int mask) {
        return (defined & mask) == mask;
    }

    public boolean anyDefined(int mask) {
        return (defined & mask) != 0;
    }

    public boolean anyNonDefault(int mask) {
        return (nondefault & mask) != 0;
    }

    // generic EAttribute API

    public boolean isDefined(EAttribute a) {
        return (defined & a.mask) != 0;
    }

    public boolean isNonDefault(EAttribute a) {
        return (nondefault & a.mask) != 0;
    }

    public void setDefault(EAttribute a) {
        if (a.att == null) {
            throw new InternalError("can't set default derived attribute: " + a);
        }
        i_set(a, DEFAULT);
        defined |= a.mask;
        nondefault &= ~a.mask;
    }

    public void unset(EAttribute a) {
        if (a.att == null) {
            throw new InternalError("can't unset derived attribute: " + a);
        }
        i_set(a, DEFAULT);
        defined &= ~a.mask;
        nondefault &= ~a.mask;
    }

    public void set(EAttribute a, AttributeValues src) {
        if (a.att == null) {
            throw new InternalError("can't set derived attribute: " + a);
        }
        if (src == null || src == DEFAULT) {
            setDefault(a);
        } else {
            if ((src.defined & a.mask) != 0) {
                i_set(a, src);
                update(a);
            }
        }
    }

    public void set(EAttribute a, Object o) {
        if (a.att == null) {
            throw new InternalError("can't set derived attribute: " + a);
        }
        if (o != null) {
            try {
                i_set(a, o);
                update(a);
                return;
            } catch (Exception e) {
            }
        }
        setDefault(a);
    }

    public Object get(EAttribute a) {
        if (a.att == null) {
            throw new InternalError("can't get derived attribute: " + a);
        }
        if ((nondefault & a.mask) != 0) {
            return i_get(a);
        }
        return null;
    }

    // merging

    public AttributeValues merge(Map<? extends Attribute, ?>map) {
        return merge(map, MASK_ALL);
    }

    public AttributeValues merge(Map<? extends Attribute, ?>map,
                                 int mask) {
        if (map instanceof AttributeMap &&
            ((AttributeMap) map).getValues() != null) {
            merge(((AttributeMap)map).getValues(), mask);
        } else if (map != null && !map.isEmpty()) {
            for (Map.Entry<? extends Attribute, ?> e: map.entrySet()) {
                try {
                    EAttribute ea = EAttribute.forAttribute(e.getKey());
                    if (ea!= null && (mask & ea.mask) != 0) {
                        set(ea, e.getValue());
                    }
                } catch (ClassCastException cce) {
                    // IGNORED
                }
            }
        }
        return this;
    }

    public AttributeValues merge(AttributeValues src) {
        return merge(src, MASK_ALL);
    }

    public AttributeValues merge(AttributeValues src, int mask) {
        int m = mask & src.defined;
        for (EAttribute ea: EAttribute.atts) {
            if (m == 0) {
                break;
            }
            if ((m & ea.mask) != 0) {
                m &= ~ea.mask;
                i_set(ea, src);
                update(ea);
            }
        }
        return this;
    }

    // creation API

    public static AttributeValues fromMap(Map<? extends Attribute, ?> map) {
        return fromMap(map, MASK_ALL);
    }

    public static AttributeValues fromMap(Map<? extends Attribute, ?> map,
                                          int mask) {
        return new AttributeValues().merge(map, mask);
    }

    public Map<TextAttribute, Object> toMap(Map<TextAttribute, Object> fill) {
        if (fill == null) {
            fill = new HashMap<TextAttribute, Object>();
        }

        for (int m = defined, i = 0; m != 0; ++i) {
            EAttribute ea = EAttribute.atts[i];
            if ((m & ea.mask) != 0) {
                m &= ~ea.mask;
                fill.put(ea.att, get(ea));
            }
        }

        return fill;
    }

    // key must be serializable, so use String, not Object
    private static final String DEFINED_KEY =
        "sun.font.attributevalues.defined_key";

    public static boolean is16Hashtable(Hashtable<Object, Object> ht) {
        return ht.containsKey(DEFINED_KEY);
    }

    public static AttributeValues
    fromSerializableHashtable(Hashtable<Object, Object> ht)
    {
        AttributeValues result = new AttributeValues();
        if (ht != null && !ht.isEmpty()) {
            for (Map.Entry<Object, Object> e: ht.entrySet()) {
                Object key = e.getKey();
                Object val = e.getValue();
                if (key.equals(DEFINED_KEY)) {
                    result.defineAll(((Integer)val).intValue());
                } else {
                    try {
                        EAttribute ea =
                            EAttribute.forAttribute((Attribute)key);
                        if (ea != null) {
                            result.set(ea, val);
                        }
                    }
                    catch (ClassCastException ex) {
                    }
                }
            }
        }
        return result;
    }

    public Hashtable<Object, Object> toSerializableHashtable() {
        Hashtable<Object, Object> ht = new Hashtable<>();
        int hashkey = defined;
        for (int m = defined, i = 0; m != 0; ++i) {
            EAttribute ea = EAttribute.atts[i];
            if ((m & ea.mask) != 0) {
                m &= ~ea.mask;
                Object o = get(ea);
                if (o == null) {
                    // hashkey will handle it
                } else if (o instanceof Serializable) { // check all...
                    ht.put(ea.att, o);
                } else {
                    hashkey &= ~ea.mask;
                }
            }
        }
        ht.put(DEFINED_KEY, Integer.valueOf(hashkey));

        return ht;
    }

    // boilerplate
    public int hashCode() {
        return defined << 8 ^ nondefault;
    }

    public boolean equals(Object rhs) {
        try {
            return equals((AttributeValues)rhs);
        }
        catch (ClassCastException e) {
        }
        return false;
    }

    public boolean equals(AttributeValues rhs) {
        // test in order of most likely to differ and easiest to compare
        // also assumes we're generally calling this only if family,
        // size, weight, posture are the same

        if (rhs == null) return false;
        if (rhs == this) return true;

        return defined == rhs.defined
            && nondefault == rhs.nondefault
            && underline == rhs.underline
            && strikethrough == rhs.strikethrough
            && superscript == rhs.superscript
            && width == rhs.width
            && kerning == rhs.kerning
            && tracking == rhs.tracking
            && ligatures == rhs.ligatures
            && runDirection == rhs.runDirection
            && bidiEmbedding == rhs.bidiEmbedding
            && swapColors == rhs.swapColors
            && equals(transform, rhs.transform)
            && equals(foreground, rhs.foreground)
            && equals(background, rhs.background)
            && equals(numericShaping, rhs.numericShaping)
            && equals(justification, rhs.justification)
            && equals(charReplacement, rhs.charReplacement)
            && size == rhs.size
            && weight == rhs.weight
            && posture == rhs.posture
            && equals(family, rhs.family)
            && equals(font, rhs.font)
            && imUnderline == rhs.imUnderline
            && equals(imHighlight, rhs.imHighlight);
    }

    public AttributeValues clone() {
        try {
            AttributeValues result = (AttributeValues)super.clone();
            if (transform != null) { // AffineTransform is mutable
                result.transform = new AffineTransform(transform);
                result.updateDerivedTransforms();
            }
            // if transform is null, derived transforms are null
            // so there's nothing to do
            return result;
        }
        catch (CloneNotSupportedException e) {
            // never happens
            return null;
        }
    }

    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append('{');
        for (int m = defined, i = 0; m != 0; ++i) {
            EAttribute ea = EAttribute.atts[i];
            if ((m & ea.mask) != 0) {
                m &= ~ea.mask;
                if (b.length() > 1) {
                    b.append(", ");
                }
                b.append(ea);
                b.append('=');
                switch (ea) {
                case EFAMILY: b.append('"');
                  b.append(family);
                  b.append('"'); break;
                case EWEIGHT: b.append(weight); break;
                case EWIDTH: b.append(width); break;
                case EPOSTURE: b.append(posture); break;
                case ESIZE: b.append(size); break;
                case ETRANSFORM: b.append(transform); break;
                case ESUPERSCRIPT: b.append(superscript); break;
                case EFONT: b.append(font); break;
                case ECHAR_REPLACEMENT: b.append(charReplacement); break;
                case EFOREGROUND: b.append(foreground); break;
                case EBACKGROUND: b.append(background); break;
                case EUNDERLINE: b.append(underline); break;
                case ESTRIKETHROUGH: b.append(strikethrough); break;
                case ERUN_DIRECTION: b.append(runDirection); break;
                case EBIDI_EMBEDDING: b.append(bidiEmbedding); break;
                case EJUSTIFICATION: b.append(justification); break;
                case EINPUT_METHOD_HIGHLIGHT: b.append(imHighlight); break;
                case EINPUT_METHOD_UNDERLINE: b.append(imUnderline); break;
                case ESWAP_COLORS: b.append(swapColors); break;
                case ENUMERIC_SHAPING: b.append(numericShaping); break;
                case EKERNING: b.append(kerning); break;
                case ELIGATURES: b.append(ligatures); break;
                case ETRACKING: b.append(tracking); break;
                default: throw new InternalError();
                }
                if ((nondefault & ea.mask) == 0) {
                    b.append('*');
                }
            }
        }
        b.append("[btx=" + baselineTransform + ", ctx=" + charTransform + "]");
        b.append('}');
        return b.toString();
    }

    // internal utilities

    private static boolean equals(Object lhs, Object rhs) {
        return lhs == null ? rhs == null : lhs.equals(rhs);
    }

    private void update(EAttribute a) {
        defined |= a.mask;
        if (i_validate(a)) {
            if (i_equals(a, DEFAULT)) {
                nondefault &= ~a.mask;
            } else {
                nondefault |= a.mask;
            }
        } else {
            setDefault(a);
        }
    }

    // dispatch

    private void i_set(EAttribute a, AttributeValues src) {
        switch (a) {
        case EFAMILY: family = src.family; break;
        case EWEIGHT: weight = src.weight; break;
        case EWIDTH: width = src.width; break;
        case EPOSTURE: posture = src.posture; break;
        case ESIZE: size = src.size; break;
        case ETRANSFORM: transform = src.transform; updateDerivedTransforms(); break;
        case ESUPERSCRIPT: superscript = src.superscript; break;
        case EFONT: font = src.font; break;
        case ECHAR_REPLACEMENT: charReplacement = src.charReplacement; break;
        case EFOREGROUND: foreground = src.foreground; break;
        case EBACKGROUND: background = src.background; break;
        case EUNDERLINE: underline = src.underline; break;
        case ESTRIKETHROUGH: strikethrough = src.strikethrough; break;
        case ERUN_DIRECTION: runDirection = src.runDirection; break;
        case EBIDI_EMBEDDING: bidiEmbedding = src.bidiEmbedding; break;
        case EJUSTIFICATION: justification = src.justification; break;
        case EINPUT_METHOD_HIGHLIGHT: imHighlight = src.imHighlight; break;
        case EINPUT_METHOD_UNDERLINE: imUnderline = src.imUnderline; break;
        case ESWAP_COLORS: swapColors = src.swapColors; break;
        case ENUMERIC_SHAPING: numericShaping = src.numericShaping; break;
        case EKERNING: kerning = src.kerning; break;
        case ELIGATURES: ligatures = src.ligatures; break;
        case ETRACKING: tracking = src.tracking; break;
        default: throw new InternalError();
        }
    }

    private boolean i_equals(EAttribute a, AttributeValues src) {
        switch (a) {
        case EFAMILY: return equals(family, src.family);
        case EWEIGHT: return weight == src.weight;
        case EWIDTH: return width == src.width;
        case EPOSTURE: return posture == src.posture;
        case ESIZE: return size == src.size;
        case ETRANSFORM: return equals(transform, src.transform);
        case ESUPERSCRIPT: return superscript == src.superscript;
        case EFONT: return equals(font, src.font);
        case ECHAR_REPLACEMENT: return equals(charReplacement, src.charReplacement);
        case EFOREGROUND: return equals(foreground, src.foreground);
        case EBACKGROUND: return equals(background, src.background);
        case EUNDERLINE: return underline == src.underline;
        case ESTRIKETHROUGH: return strikethrough == src.strikethrough;
        case ERUN_DIRECTION: return runDirection == src.runDirection;
        case EBIDI_EMBEDDING: return bidiEmbedding == src.bidiEmbedding;
        case EJUSTIFICATION: return justification == src.justification;
        case EINPUT_METHOD_HIGHLIGHT: return equals(imHighlight, src.imHighlight);
        case EINPUT_METHOD_UNDERLINE: return imUnderline == src.imUnderline;
        case ESWAP_COLORS: return swapColors == src.swapColors;
        case ENUMERIC_SHAPING: return equals(numericShaping, src.numericShaping);
        case EKERNING: return kerning == src.kerning;
        case ELIGATURES: return ligatures == src.ligatures;
        case ETRACKING: return tracking == src.tracking;
        default: throw new InternalError();
        }
    }

    private void i_set(EAttribute a, Object o) {
        switch (a) {
        case EFAMILY: family = ((String)o).trim(); break;
        case EWEIGHT: weight = ((Number)o).floatValue(); break;
        case EWIDTH: width = ((Number)o).floatValue(); break;
        case EPOSTURE: posture = ((Number)o).floatValue(); break;
        case ESIZE: size = ((Number)o).floatValue(); break;
        case ETRANSFORM: {
            if (o instanceof TransformAttribute) {
                TransformAttribute ta = (TransformAttribute)o;
                if (ta.isIdentity()) {
                    transform = null;
                } else {
                    transform = ta.getTransform();
                }
            } else {
                transform = new AffineTransform((AffineTransform)o);
            }
            updateDerivedTransforms();
        } break;
        case ESUPERSCRIPT: superscript = (byte)((Integer)o).intValue(); break;
        case EFONT: font = (Font)o; break;
        case ECHAR_REPLACEMENT: charReplacement = (GraphicAttribute)o; break;
        case EFOREGROUND: foreground = (Paint)o; break;
        case EBACKGROUND: background = (Paint)o; break;
        case EUNDERLINE: underline = (byte)((Integer)o).intValue(); break;
        case ESTRIKETHROUGH: strikethrough = ((Boolean)o).booleanValue(); break;
        case ERUN_DIRECTION: {
            if (o instanceof Boolean) {
                runDirection = (byte)(TextAttribute.RUN_DIRECTION_LTR.equals(o) ? 0 : 1);
            } else {
                runDirection = (byte)((Integer)o).intValue();
            }
        } break;
        case EBIDI_EMBEDDING: bidiEmbedding = (byte)((Integer)o).intValue(); break;
        case EJUSTIFICATION: justification = ((Number)o).floatValue(); break;
        case EINPUT_METHOD_HIGHLIGHT: {
            if (o instanceof Annotation) {
                Annotation at = (Annotation)o;
                imHighlight = (InputMethodHighlight)at.getValue();
            } else {
                imHighlight = (InputMethodHighlight)o;
            }
        } break;
        case EINPUT_METHOD_UNDERLINE: imUnderline = (byte)((Integer)o).intValue();
          break;
        case ESWAP_COLORS: swapColors = ((Boolean)o).booleanValue(); break;
        case ENUMERIC_SHAPING: numericShaping = (NumericShaper)o; break;
        case EKERNING: kerning = (byte)((Integer)o).intValue(); break;
        case ELIGATURES: ligatures = (byte)((Integer)o).intValue(); break;
        case ETRACKING: tracking = ((Number)o).floatValue(); break;
        default: throw new InternalError();
        }
    }

    private Object i_get(EAttribute a) {
        switch (a) {
        case EFAMILY: return family;
        case EWEIGHT: return Float.valueOf(weight);
        case EWIDTH: return Float.valueOf(width);
        case EPOSTURE: return Float.valueOf(posture);
        case ESIZE: return Float.valueOf(size);
        case ETRANSFORM:
            return transform == null
                ? TransformAttribute.IDENTITY
                : new TransformAttribute(transform);
        case ESUPERSCRIPT: return Integer.valueOf(superscript);
        case EFONT: return font;
        case ECHAR_REPLACEMENT: return charReplacement;
        case EFOREGROUND: return foreground;
        case EBACKGROUND: return background;
        case EUNDERLINE: return Integer.valueOf(underline);
        case ESTRIKETHROUGH: return Boolean.valueOf(strikethrough);
        case ERUN_DIRECTION: {
            switch (runDirection) {
                // todo: figure out a way to indicate this value
                // case -1: return Integer.valueOf(runDirection);
            case 0: return TextAttribute.RUN_DIRECTION_LTR;
            case 1: return TextAttribute.RUN_DIRECTION_RTL;
            default: return null;
            }
        } // not reachable
        case EBIDI_EMBEDDING: return Integer.valueOf(bidiEmbedding);
        case EJUSTIFICATION: return Float.valueOf(justification);
        case EINPUT_METHOD_HIGHLIGHT: return imHighlight;
        case EINPUT_METHOD_UNDERLINE: return Integer.valueOf(imUnderline);
        case ESWAP_COLORS: return Boolean.valueOf(swapColors);
        case ENUMERIC_SHAPING: return numericShaping;
        case EKERNING: return Integer.valueOf(kerning);
        case ELIGATURES: return Integer.valueOf(ligatures);
        case ETRACKING: return Float.valueOf(tracking);
        default: throw new InternalError();
        }
    }

    private boolean i_validate(EAttribute a) {
        switch (a) {
        case EFAMILY: if (family == null || family.length() == 0)
          family = DEFAULT.family; return true;
        case EWEIGHT: return weight > 0 && weight < 10;
        case EWIDTH: return width >= .5f && width < 10;
        case EPOSTURE: return posture >= -1 && posture <= 1;
        case ESIZE: return size >= 0;
        case ETRANSFORM: if (transform != null && transform.isIdentity())
            transform = DEFAULT.transform; return true;
        case ESUPERSCRIPT: return superscript >= -7 && superscript <= 7;
        case EFONT: return true;
        case ECHAR_REPLACEMENT: return true;
        case EFOREGROUND: return true;
        case EBACKGROUND: return true;
        case EUNDERLINE: return underline >= -1 && underline < 6;
        case ESTRIKETHROUGH: return true;
        case ERUN_DIRECTION: return runDirection >= -2 && runDirection <= 1;
        case EBIDI_EMBEDDING: return bidiEmbedding >= -61 && bidiEmbedding < 62;
        case EJUSTIFICATION: justification = max(0, min (justification, 1));
            return true;
        case EINPUT_METHOD_HIGHLIGHT: return true;
        case EINPUT_METHOD_UNDERLINE: return imUnderline >= -1 && imUnderline < 6;
        case ESWAP_COLORS: return true;
        case ENUMERIC_SHAPING: return true;
        case EKERNING: return kerning >= 0 && kerning <= 1;
        case ELIGATURES: return ligatures >= 0 && ligatures <= 1;
        case ETRACKING: return tracking >= -1 && tracking <= 10;
        default: throw new InternalError("unknown attribute: " + a);
        }
    }

    // Until textlayout is fixed to use AttributeValues, we'll end up
    // creating a map from the values for it.  This is a compromise between
    // creating the whole map and just checking a particular value.
    // Plan to remove these.
    public static float getJustification(Map<?, ?> map) {
        if (map != null) {
            if (map instanceof AttributeMap &&
                ((AttributeMap) map).getValues() != null) {
                return ((AttributeMap)map).getValues().justification;
            }
            Object obj = map.get(TextAttribute.JUSTIFICATION);
            if (obj instanceof Number number) {
                return max(0, min(1, number.floatValue()));
            }
        }
        return DEFAULT.justification;
    }

    public static NumericShaper getNumericShaping(Map<?, ?> map) {
        if (map != null) {
            if (map instanceof AttributeMap &&
                ((AttributeMap) map).getValues() != null) {
                return ((AttributeMap)map).getValues().numericShaping;
            }
            Object obj = map.get(TextAttribute.NUMERIC_SHAPING);
            if (obj instanceof NumericShaper shaper) {
                return shaper;
            }
        }
        return DEFAULT.numericShaping;
    }

    /**
     * If this has an imHighlight, create copy of this with those attributes
     * applied to it.  Otherwise return this unchanged.
     */
    public AttributeValues applyIMHighlight() {
        if (imHighlight != null) {
            InputMethodHighlight hl = null;
            if (imHighlight instanceof InputMethodHighlight) {
                hl = (InputMethodHighlight)imHighlight;
            } else {
                hl = (InputMethodHighlight)((Annotation)imHighlight).getValue();
            }

            Map<TextAttribute, ?> imStyles = hl.getStyle();
            if (imStyles == null) {
                Toolkit tk = Toolkit.getDefaultToolkit();
                imStyles = tk.mapInputMethodHighlight(hl);
            }

            if (imStyles != null) {
                return clone().merge(imStyles);
            }
        }

        return this;
    }

    @SuppressWarnings("unchecked")
    public static AffineTransform getBaselineTransform(Map<?, ?> map) {
        if (map != null) {
            AttributeValues av = null;
            if (map instanceof AttributeMap &&
                ((AttributeMap) map).getValues() != null) {
                av = ((AttributeMap)map).getValues();
            } else if (map.get(TextAttribute.TRANSFORM) != null) {
                av = AttributeValues.fromMap((Map<Attribute, ?>)map); // yuck
            }
            if (av != null) {
                return av.baselineTransform;
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static AffineTransform getCharTransform(Map<?, ?> map) {
        if (map != null) {
            AttributeValues av = null;
            if (map instanceof AttributeMap &&
                ((AttributeMap) map).getValues() != null) {
                av = ((AttributeMap)map).getValues();
            } else if (map.get(TextAttribute.TRANSFORM) != null) {
                av = AttributeValues.fromMap((Map<Attribute, ?>)map); // yuck
            }
            if (av != null) {
                return av.charTransform;
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static float getTracking(Map<?, ?> map) {
        if (map != null) {
            AttributeValues av = null;
            if (map instanceof AttributeMap &&
                    ((AttributeMap) map).getValues() != null) {
                av = ((AttributeMap)map).getValues();
            } else if (map.get(TextAttribute.TRACKING) != null) {
                av = AttributeValues.fromMap((Map<Attribute, ?>)map);
            }
            if (av != null) {
                return av.tracking;
            }
        }
        return 0;
    }

    public void updateDerivedTransforms() {
        // this also updates the mask for the baseline transform
        if (transform == null) {
            baselineTransform = null;
            charTransform = null;
        } else {
            charTransform = new AffineTransform(transform);
            baselineTransform = extractXRotation(charTransform, true);

            if (charTransform.isIdentity()) {
              charTransform = null;
            }

            if (baselineTransform.isIdentity()) {
              baselineTransform = null;
            }
        }

        if (baselineTransform == null) {
            nondefault &= ~EBASELINE_TRANSFORM.mask;
        } else {
            nondefault |= EBASELINE_TRANSFORM.mask;
        }
    }

    public static AffineTransform extractXRotation(AffineTransform tx,
                                                   boolean andTranslation) {
        return extractRotation(new Point2D.Double(1, 0), tx, andTranslation);
    }

    public static AffineTransform extractYRotation(AffineTransform tx,
                                                   boolean andTranslation) {
        return extractRotation(new Point2D.Double(0, 1), tx, andTranslation);
    }

    private static AffineTransform extractRotation(Point2D.Double pt,
        AffineTransform tx, boolean andTranslation) {

        tx.deltaTransform(pt, pt);
        AffineTransform rtx = AffineTransform.getRotateInstance(pt.x, pt.y);

        try {
            AffineTransform rtxi = rtx.createInverse();
            double dx = tx.getTranslateX();
            double dy = tx.getTranslateY();
            tx.preConcatenate(rtxi);
            if (andTranslation) {
                if (dx != 0 || dy != 0) {
                    tx.setTransform(tx.getScaleX(), tx.getShearY(),
                                    tx.getShearX(), tx.getScaleY(), 0, 0);
                    rtx.setTransform(rtx.getScaleX(), rtx.getShearY(),
                                     rtx.getShearX(), rtx.getScaleY(), dx, dy);
                }
            }
        }
        catch (NoninvertibleTransformException e) {
            return null;
        }
        return rtx;
    }
}
