]> granicus.if.org Git - icu/commitdiff
ICU-12450 move unused com.ibm.icu.dev.tool.cldr.CheckSystemFonts to Unicode Tools...
authorMarkus Scherer <markus.icu@gmail.com>
Tue, 12 Apr 2016 22:10:50 +0000 (22:10 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Tue, 12 Apr 2016 22:10:50 +0000 (22:10 +0000)
X-SVN-Rev: 38614

icu4j/tools/misc/src/com/ibm/icu/dev/tool/cldr/CheckSystemFonts.java [deleted file]

diff --git a/icu4j/tools/misc/src/com/ibm/icu/dev/tool/cldr/CheckSystemFonts.java b/icu4j/tools/misc/src/com/ibm/icu/dev/tool/cldr/CheckSystemFonts.java
deleted file mode 100644 (file)
index 92de7f6..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- **********************************************************************
- * Copyright (c) 2009-2012, Google, International Business Machines
- * Corporation and others.  All Rights Reserved.
- **********************************************************************
- * Author: Mark Davis
- **********************************************************************
- */
-package com.ibm.icu.dev.tool.cldr;
-import java.awt.Font;
-import java.awt.GraphicsEnvironment;
-import java.awt.Shape;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.ibm.icu.dev.util.BagFormatter;
-import com.ibm.icu.dev.util.Tabber.HTMLTabber;
-import com.ibm.icu.dev.util.TransliteratorUtilities;
-import com.ibm.icu.dev.util.UnicodeMap;
-import com.ibm.icu.dev.util.UnicodeMap.Composer;
-import com.ibm.icu.dev.util.UnicodeMapIterator;
-import com.ibm.icu.dev.util.XEquivalenceClass.SetMaker;
-import com.ibm.icu.impl.Row;
-import com.ibm.icu.impl.Row.R2;
-import com.ibm.icu.impl.Utility;
-import com.ibm.icu.lang.UCharacter;
-import com.ibm.icu.lang.UScript;
-import com.ibm.icu.text.Collator;
-import com.ibm.icu.text.Normalizer;
-import com.ibm.icu.text.UTF16;
-import com.ibm.icu.text.UnicodeSet;
-import com.ibm.icu.text.UnicodeSetIterator;
-
-
-public class CheckSystemFonts {
-    
-    static String outputDirectoryName;
-    static Set<String> SKIP_SHAPES = new HashSet<String>();
-    
-    public static void main(String[] args) throws IOException {
-        System.out.println("Arguments:\t" + Arrays.asList(args));
-        if (args.length < 2) {
-            throw new IllegalArgumentException("Need command-line args:" +
-                    "\n\t\tfont-name-regex" +
-                    "\n\t\toutput-directory"
-                    );
-        }
-        Matcher nameMatcher = Pattern.compile(args[0], Pattern.CASE_INSENSITIVE).matcher("");
-        outputDirectoryName = args[1].trim();
-        File outputDirectory = new File(outputDirectoryName);
-        if (!outputDirectory.isDirectory()) {
-            throw new IllegalArgumentException("2nd arg must be valid directory");
-        }
-        loadSkipShapes();
-
-        Map<UnicodeSet,Set<String>> data = new TreeMap<UnicodeSet, Set<String>>();
-        Map<String, Font> fontMap = new TreeMap<String, Font>();
-        getFontData(nameMatcher, data, fontMap);
-        
-        showInvisibles();
-        showSameGlyphs();
-
-        UnicodeMap<Set<String>> map = showEquivalentCoverage(data);
-
-        showRawCoverage(data);
-
-        Map<Set<String>, String> toShortName = showRawCoverage(map);
-
-        showFullCoverage(map, toShortName);
-    }
-
-    private static void loadSkipShapes() {
-        try {
-            BufferedReader in = BagFormatter.openUTF8Reader(outputDirectoryName, "skip_fonts.txt");
-            while (true) {
-                String line = in.readLine();
-                if (line == null) break;
-                String[] fonts = line.trim().split("\\s+");
-                for (String font : fonts) {
-                    SKIP_SHAPES.add(font);
-                }
-            }
-            in.close();
-        } catch (IOException e) {
-            System.err.println("Couldn't open:\t" + outputDirectoryName + "/" + "skip_fonts.txt");
-        }
-    }
-
-
-    private static final Collator English = Collator.getInstance();
-
-    static {
-        English.setStrength(Collator.SECONDARY);
-    }
-
-    public static final UnicodeSet DONT_CARE = new UnicodeSet("[[:cn:][:co:][:cs:]]").freeze();
-    public static final UnicodeSet COVERAGE = new UnicodeSet(DONT_CARE).complement().freeze();
-
-    private static final Comparator<String> SHORTER_FIRST = new Comparator<String>() {
-        public int compare(String n1, String n2) {
-            int result = n1.length() - n2.length();
-            if (result != 0) return result;
-            return n1.compareTo(n2);
-        }
-    };
-
-    private static final Comparator<UnicodeSet> LONGER_SET_FIRST = new Comparator<UnicodeSet>() {
-        public int compare(UnicodeSet n1, UnicodeSet n2) {
-            int result = n1.size() - n2.size();
-            if (result != 0) return -result;
-            return n1.compareTo(n2);
-        }
-    };
-
-    private static final Comparator<Collection> SHORTER_COLLECTION_FIRST = new Comparator<Collection>() {
-        public int compare(Collection n1, Collection n2) {
-            int result = n1.size() - n2.size();
-            if (result != 0) return result;
-            return UnicodeSet.compare(n1, n2);
-        }
-    };
-
-    private static final HashSet SKIP_TERMS = new HashSet(Arrays.asList("black", "blackitalic", "bold", "boldit", "bolditalic", "bolditalicmt", "boldmt",
-            "boldob", "boldoblique", "boldslanted", "book", "bookitalic", "condensed", "condensedblack", "condensedbold", "condensedextrabold",
-            "condensedlight", "condensedmedium", "extracondensed", "extralight", "heavy", "italic", "italicmt", "light", "lightit", "lightitalic", "medium",
-            "mediumitalic", "oblique", "regular", "roman", "semibold", "semibolditalic", "shadow", "slanted", "ultrabold", "ultralight", "ultralightitalic"
-    ));
-
-    private static Composer<Set<String>> composer = new Composer<Set<String>>() {
-        Map<R2<Set<String>, Set<String>>,Set<String>> cache = new HashMap<R2<Set<String>, Set<String>>,Set<String>>();
-        public Set<String> compose(int codePoint, String string, Set<String> a, Set<String> b) {
-            return a == null ? b
-                    : b == null ? null 
-                            : intern(a,b);
-        }
-        private Set<String> intern(Set<String> a, Set<String> b) {
-            R2<Set<String>, Set<String>> row = Row.of(a, b);
-            Set<String> result = cache.get(row);
-            if (result == null) {
-                result = new TreeSet<String>(English);
-                result.addAll(a);
-                result.addAll(b);
-                cache.put(row, result);
-            }
-            return result;
-        }
-    };
-
-
-    private static void showFullCoverage(UnicodeMap<Set<String>> map, Map<Set<String>, String> toShortName) throws IOException {
-        System.out.println("\n***COVERAGE:\t" + map.keySet().size() + "\n");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "coverage.txt");
-
-        for (UnicodeMapIterator<String> it = new UnicodeMapIterator<String>(map); it.nextRange();) {
-            String codes = "U+" + Utility.hex(it.codepoint);
-            String names = UCharacter.getExtendedName(it.codepoint);
-            if (it.codepointEnd != it.codepoint) {
-                codes += "..U+" + Utility.hex(it.codepointEnd);
-                names += ".." + UCharacter.getExtendedName(it.codepointEnd);
-            }
-            out.println(codes + "\t" + toShortName.get(map.get(it.codepoint)) + "\t" + names);
-        }
-
-        UnicodeSet missing = new UnicodeSet(COVERAGE).removeAll(map.keySet());
-        out.println("\nMISSING:\t" + missing.size() + "\n");
-
-        UnicodeMap<String> missingMap = new UnicodeMap<String>();
-        for (UnicodeSetIterator it = new UnicodeSetIterator(missing); it.next();) {
-            missingMap.put(it.codepoint, UScript.getName(UScript.getScript(it.codepoint)) + "-" + getShortAge(it.codepoint));
-        }
-
-        Set<String> sorted = new TreeSet<String>(English);
-        sorted.addAll(missingMap.values());
-        for (String value : sorted) {
-            UnicodeSet items = missingMap.getSet(value);
-            for (UnicodeSetIterator it = new UnicodeSetIterator(items); it.nextRange();) {
-                String codes = "U+" + Utility.hex(it.codepoint);
-                String names = UCharacter.getExtendedName(it.codepoint);
-                if (it.codepointEnd != it.codepoint) {
-                    codes += "..U+" + Utility.hex(it.codepointEnd);
-                    names += ".." + UCharacter.getExtendedName(it.codepointEnd);
-                }
-                out.println(codes + "\t" + value + "\t" + names);
-            }
-            out.println();
-        }
-        out.close();
-    }
-
-    private static Map<Set<String>, String> showRawCoverage(UnicodeMap<Set<String>> map) throws IOException {
-        System.out.println("\n***COMBO NAMES\n");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "combo_names.txt");
-
-        int count = 0;
-        Map<Set<String>, String> toShortName = new HashMap<Set<String>, String>();
-        TreeSet<Set<String>> sortedValues = new TreeSet<Set<String>>(SHORTER_COLLECTION_FIRST);
-        sortedValues.addAll(map.values());
-        for (Set<String> value : sortedValues) {
-            String shortName = "combo" + count++;
-            Set<String> contained = getLargestContained(value, toShortName.keySet());
-            String valueName;
-            if (contained != null) {
-                Set<String> remainder = new TreeSet<String>();
-                remainder.addAll(value);
-                remainder.removeAll(contained);
-                valueName = toShortName.get(contained) + " + " + remainder;
-            } else {
-                valueName = value.toString();
-            }
-            toShortName.put(value, shortName);
-            out.println(shortName + "\t" + valueName);
-        }
-        out.close();
-        return toShortName;
-    }
-
-    private static void showRawCoverage(Map<UnicodeSet, Set<String>> data) throws IOException {
-        System.out.println("\n***RAW COVERAGE (bridging unassigned)\n");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "raw_coverage.txt");
-
-        for (Entry<UnicodeSet, Set<String>> entry : data.entrySet()) {
-            UnicodeSet s = entry.getKey();
-            Set<String> nameSet = entry.getValue();
-            String name = nameSet.iterator().next();
-            UnicodeSet bridged = new UnicodeSet(s).addBridges(DONT_CARE);
-            out.println(name + "\t" + s.size() + "\t" + bridged);
-        }
-        out.close();
-    }
-
-    private static UnicodeMap<Set<String>> showEquivalentCoverage(Map<UnicodeSet, Set<String>> data) throws IOException {
-        System.out.println("\n***EQUIVALENT COVERAGE\n");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "equiv_coverage.txt");
-
-        UnicodeMap<Set<String>> map = new UnicodeMap<Set<String>>();
-
-        Map<String,Set<String>> nameToSingleton = new HashMap<String,Set<String>>();
-
-        for (Entry<UnicodeSet, Set<String>> entry : data.entrySet()) {
-            UnicodeSet s = entry.getKey();
-            Set<String> nameSet = entry.getValue();
-            String name = nameSet.iterator().next();
-            //System.out.println(s);
-            Set<String> temp2 = nameToSingleton.get(name);
-            if (temp2 == null) {
-                temp2 = new TreeSet<String>(English);
-                temp2.add(name);
-            }
-            map.composeWith(s, temp2, composer);
-            if (nameSet.size() > 1) {
-                TreeSet<String> temp = new TreeSet<String>(English);
-                temp.addAll(nameSet);
-                temp.remove(name);
-                out.println(name + "\t" + temp);
-            }
-        }
-        out.close();
-        return map;
-    }
-
-    private static void showSameGlyphs() throws IOException {
-        System.out.println("\n***Visual Equivalences");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "same_glyphs.txt");
-        PrintWriter out2 = BagFormatter.openUTF8Writer(outputDirectoryName, "same_glyphs.html");
-        out2.println("<html><head>");
-        out2.println("<meta content=\"text/html; charset=utf-8\" http-equiv=Content-Type></HEAD>");
-        out2.println("<link rel='stylesheet' href='index.css' type='text/css'>");
-        out2.println("</head><body><table>");
-        HTMLTabber tabber = new HTMLTabber();
-
-        out2.println(tabber.process("Code1\tCode2\tNFC1\tNFC1\tCh1\tCh1\tCh1/F\tCh2/F\tName1\tName2\tFonts"));
-        tabber.setParameters(0, "class='c'");
-        tabber.setParameters(1, "class='c'");
-        tabber.setParameters(2, "class='nf'");
-        tabber.setParameters(3, "class='nf'");
-        tabber.setParameters(4, "class='p'");
-        tabber.setParameters(5, "class='p'");
-        //tabber.setParameters(6, "class='q'");
-        //tabber.setParameters(7, "class='q'");
-        tabber.setParameters(8, "class='n'");
-        tabber.setParameters(9, "class='n'");
-        tabber.setParameters(10, "class='f'");
-
-        for (R2<Integer,Integer> sample : equivalences.keySet()) {
-            final Set<String> reasonSet = equivalences.get(sample);
-            String reasons = reasonSet.toString();
-            if (reasons.length() > 100) reasons = reasons.substring(0,100) + "...";
-            final Integer codepoint1 = sample.get0();
-            final Integer codepoint2 = sample.get1();
-            
-            out.println("U+" + Utility.hex(codepoint1) + "\t" + "U+" + Utility.hex(codepoint2)
-                    + "\t" + showNfc(codepoint1) + "\t" + showNfc(codepoint2)
-                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, false)
-                    + "\t" + UCharacter.getExtendedName(codepoint1) + "\t" + UCharacter.getExtendedName(codepoint2)
-                    + "\t" + reasons);
-            String line = "U+" + Utility.hex(codepoint1) + "\t" + "U+" + Utility.hex(codepoint2)
-                    + "\t" + showNfc(codepoint1) + "\t" + showNfc(codepoint2)
-                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, true)
-                    + "\t" + showChar(codepoint1, false) + "\t" + showChar(codepoint2, true)
-                    + "\t" + UCharacter.getExtendedName(codepoint1) + "\t" + UCharacter.getExtendedName(codepoint2)
-                    + "\t" + reasons;
-            
-            String fonts = "class='q' style='font-family:";
-            int maxCount = 5;
-            for (String font : reasonSet) {
-                if (maxCount != 5) {
-                    fonts += ",";
-                }
-                fonts += font;
-                --maxCount;
-                if (maxCount <= 0) break;
-            }
-            fonts += "'";
-            tabber.setParameters(6, fonts);
-            tabber.setParameters(7, fonts);
-            out2.println(tabber.process(line));
-        }
-        out2.println("</table></body>");
-        out2.close();
-        out.close();
-    }
-
-    private static void showInvisibles() throws IOException {
-        System.out.println("\n***Invisibles Equivalences");
-        PrintWriter out = BagFormatter.openUTF8Writer(outputDirectoryName, "invisibles.txt");
-        for (String sample : invisibles) {
-            String reasons = invisibles.get(sample).toString();
-            if (reasons.length() > 100) reasons = reasons.substring(0,100) + "...";
-            int codepoint = sample.codePointAt(0);
-            out.println("U+" + Utility.hex(sample)
-                    + "\t" + showChar(codepoint, false)
-                    + "\t" + showNfc(codepoint)
-                    + "\t" + UCharacter.getExtendedName(codepoint)
-                    + "\t" + reasons);
-
-        }
-        out.close();
-    }
-
-    private static void getFontData(Matcher nameMatcher, Map<UnicodeSet, Set<String>> data, Map<String, Font> fontMap) {
-        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        Font[] fonts = env.getAllFonts();
-        for (Font font : fonts) {
-            if (!font.isPlain()) {
-                continue;
-            }
-            String name = font.getName();
-            int lastDash = name.lastIndexOf('-');
-            String term = lastDash < 0 ? "" : name.substring(lastDash+1).toLowerCase();
-            if (SKIP_TERMS.contains(term)) {
-                continue;
-            }
-            if (nameMatcher != null && !nameMatcher.reset(name).find()) {
-                continue;
-            }
-            fontMap.put(name,font);
-        }
-        for (Entry<String, Font> entry : fontMap.entrySet()) {
-            String name = entry.getKey();
-            Font font = entry.getValue();
-            System.out.println(name);
-            UnicodeSet coverage = getCoverage(font);
-            Set<String> sameFonts = data.get(coverage);
-            if (sameFonts == null) {
-                data.put(coverage, sameFonts = new TreeSet<String>(SHORTER_FIRST));
-            } else {
-                System.out.println("\tNote: same coverage as " + sameFonts.iterator().next());
-            }
-            sameFonts.add(name);
-        }
-    }
-    
-    static Comparator<Integer> NFCLower = new Comparator<Integer>() {
-        public int compare(Integer o1, Integer o2) {
-            boolean n1 = Normalizer.isNormalized(o1, Normalizer.NFC, 0);
-            boolean n2 = Normalizer.isNormalized(o2, Normalizer.NFC, 0);
-            if (n1 != n2) return n1 ? -1 : 1;
-            n1 = Normalizer.isNormalized(o1, Normalizer.NFKC, 0);
-            n2 = Normalizer.isNormalized(o2, Normalizer.NFKC, 0);
-            if (n1 != n2) return n1 ? -1 : 1;
-            return o1.compareTo(o2);
-        } 
-    };
-    
-    static Comparator<R2<Integer,Integer>> NFCLowerR2 = new Comparator<R2<Integer,Integer>>() {
-        public int compare(R2<Integer, Integer> o1, R2<Integer, Integer> o2) {
-            int diff = NFCLower.compare(o1.get0(), o2.get0());
-            if (diff != 0) return diff;
-            return NFCLower.compare(o1.get1(), o2.get1());
-        }
-    };
-
-    private static String showNfc(int codepoint) {
-        return Normalizer.isNormalized(codepoint, Normalizer.NFC, 0) ? "" 
-                : Normalizer.isNormalized(codepoint, Normalizer.NFKC, 0) ? "!C" : "!K";
-    }
-
-    private static String showChar(Integer item, boolean html) {
-        return rtlProtect(UTF16.valueOf(item), html);
-    }
-    static UnicodeSet RTL = new UnicodeSet("[[:bc=R:][:bc=AL:][:bc=AN:]]").freeze();
-    static UnicodeSet CONTROLS = new UnicodeSet("[[:cc:][:Zl:][:Zp:]]").freeze();
-    static UnicodeSet INVISIBLES = new UnicodeSet("[:di:]").freeze();
-    static final char LRM = '\u200E';
-
-    private static String rtlProtect(String source, boolean html) {
-        if (CONTROLS.containsSome(source)) {
-            source = "";
-        } else if (INVISIBLES.containsSome(source)) {
-            source = "";
-        } else if (RTL.containsSome(source) || source.startsWith("\"")) {
-            source = LRM + source + LRM;
-        }
-        return html ? TransliteratorUtilities.toHTML.transform(source) : source;
-    }
-
-
-    private static Set<String> getLargestContained(Set<String> value, Collection<Set<String>> collection) {
-        Set<String> best = null;
-        for (Set<String> set : collection) {
-            if (best != null && best.size() > set.size()) {
-                continue;
-            }
-            if (value.containsAll(set)) {
-                best = set;
-            }
-        }
-        return best;
-    }
-
-    private static String getShortAge(int i) {
-        String age = UCharacter.getAge(i).toString();
-        return age.substring(0,age.indexOf('.',age.indexOf('.') + 1));
-    }
-
-    static SetMaker setMaker = new SetMaker() {
-        public Set make() {
-            return new TreeSet();
-        } 
-    };
-
-    static UnicodeMap<Set<String>> invisibles = new UnicodeMap();
-    static Map<R2<Integer,Integer>, Set<String>> equivalences = new TreeMap<R2<Integer,Integer>, Set<String>>(NFCLowerR2);
-//    static Set<String> SKIP_SHAPES = new HashSet<String>(Arrays.asList(
-//            "MT-Extra",
-//            "JCsmPC",
-//            "DFKaiShu-SB-Estd-BF",
-//            "LiGothicMed",
-//            "LiHeiPro",
-//            "LiSongPro",
-//            "LiSungLight",
-//            "PMingLiU",
-//            "SIL-Hei-Med-Jian",
-//            "SIL-Kai-Reg-Jian",
-//            "CharcoalCY",
-//            "GenevaCY",
-//            "HelveticaCYBoldOblique",
-//            "HelveticaCYOblique",
-//            "HelveticaCYPlain",
-//            "HoeflerText-Ornaments",
-//            "Apple-Chancery",
-//            "MSReferenceSpecialty",
-//            "Stencil",
-//            "Hooge0555",
-//            "Hooge0556",
-//            "Desdemona",
-//            "EccentricStd",
-//            "EngraversMT",
-//            "MesquiteStd",
-//            "RosewoodStd-Fill",
-//            "Stencil",
-//            "StencilStd",
-//            "Osaka",
-//            "Osaka-Mono",
-//            "Kroeger0455",
-//            "Kroeger0456",
-//            "Uni0563",
-//            "Uni0564",
-//            "Code2001",
-//            "AppleSymbols",
-//            "AppleGothic", 
-//            "AppleMyungjo",
-//            "JCkg",
-//            "MalithiWeb",
-//            "JCfg"
-//    ));
-
-    // bug on Mac: http://forums.sun.com/thread.jspa?threadID=5209611
-    private static UnicodeSet getCoverage(Font font) {
-        String name = font.getFontName();
-        boolean skipShapes = SKIP_SHAPES.contains(name);
-        UnicodeSet result = new UnicodeSet();
-        final FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
-        char[] array = new char[1];
-        char[] array2 = new char[2];
-        Map<Rectangle2D,Map<Shape,UnicodeSet>> boundsToData = new TreeMap<Rectangle2D,Map<Shape,UnicodeSet>>(ShapeComparator);
-        for (UnicodeSetIterator it = new UnicodeSetIterator(COVERAGE); it.next();) {
-            if (font.canDisplay(it.codepoint)) {
-                char[] temp;
-                if (it.codepoint <= 0xFFFF) {
-                    array[0] = (char) it.codepoint;
-                    temp = array;
-                } else {
-                    Character.toChars(it.codepoint, array2, 0);
-                    temp = array2;
-                }
-
-                GlyphVector glyphVector = font.createGlyphVector(fontRenderContext, temp);
-                int glyphCode = glyphVector.getGlyphCode(0);
-                boolean validchar = (glyphCode > 0);
-                if (!validchar) continue;
-
-                result.add(it.codepoint);
-
-                if (skipShapes) continue;
-                Shape shape = glyphVector.getOutline();
-                if (isInvisible(shape)) {
-                    Set<String> set = invisibles.get(it.codepoint);
-                    if (set == null) {
-                        invisibles.put(it.codepoint, set = new TreeSet<String>());
-                    }
-                    set.add(name);
-                } else {
-                    Rectangle2D bounds = glyphVector.getVisualBounds();
-                    Map<Shape, UnicodeSet> map = boundsToData.get(bounds);
-                    if (map == null) {
-                        boundsToData.put(bounds, map = new TreeMap<Shape,UnicodeSet>(ShapeComparator));
-                    }
-                    UnicodeSet set = map.get(shape);
-                    if (set == null) {
-                        map.put(shape, set = new UnicodeSet());
-                    }
-                    if (false && set.size() != 0) {
-                        System.out.println("Adding " + Utility.hex(it.codepoint) + "\t" + UTF16.valueOf(it.codepoint) +  "\tto " + set.toPattern(false));
-                    }
-                    set.add(it.codepoint);
-                }
-            }
-        }
-        //System.out.println(result.size() + "\t" + result);
-        for (Rectangle2D bounds : boundsToData.keySet()) {
-            Map<Shape, UnicodeSet> map = boundsToData.get(bounds);
-            for (UnicodeSet set : map.values()) {
-                set.removeAll(CONTROLS);
-                if (set.size() != 1) {
-                    //System.out.println(set.toPattern(false));
-                    for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) {
-                        for (UnicodeSetIterator it2 = new UnicodeSetIterator(set); it2.next();) {
-                            int cp = it.codepoint;
-                            int cp2 = it2.codepoint;
-                            if (cp >= cp2) continue;
-                            R2<Integer, Integer> r = Row.of(cp, cp2);
-                            Set<String> reasons = equivalences.get(r);
-                            if (reasons == null) {
-                                equivalences.put(r, reasons = new TreeSet());
-                            }
-                            reasons.add(name);
-                        }
-                    }
-                }
-            }
-        }
-        return result.freeze();
-    }
-
-    static Comparator<Rectangle2D> RectComparator = new Comparator<Rectangle2D>() {
-
-        public int compare(Rectangle2D r1, Rectangle2D r2) {
-            int diff;
-            if (0 != (diff = compareDiff(r1.getX(),r2.getX()))) return diff;
-            if (0 != (diff = compareDiff(r1.getY(),r2.getY()))) return diff;
-            if (0 != (diff = compareDiff(r1.getWidth(),r2.getWidth()))) return diff;
-            if (0 != (diff = compareDiff(r1.getHeight(),r2.getHeight()))) return diff;
-            return 0;
-        }
-
-    };
-
-    static final AffineTransform IDENTITY = new AffineTransform();
-
-    static boolean isInvisible(Shape shape) {
-        return shape.getPathIterator(IDENTITY).isDone();
-    }
-
-    static Comparator<Shape> ShapeComparator = new Comparator<Shape>() {
-        float[] coords1 = new float[6];
-        float[] coords2 = new float[6];
-
-        public int compare(Shape s1, Shape s2) {
-            int diff;
-            PathIterator p1 = s1.getPathIterator(IDENTITY);
-            PathIterator p2 = s2.getPathIterator(IDENTITY);
-            while (true) {
-                if (p1.isDone()) {
-                    return p2.isDone() ? 0 : -1;
-                } else if (p2.isDone()) {
-                    return 1;
-                }
-                int t1 = p1.currentSegment(coords1);
-                int t2 = p2.currentSegment(coords2);
-                diff = t1 - t2;
-                if (diff != 0) return diff;
-                /*
-                 * SEG_MOVETO and SEG_LINETO types returns one point,
-                 * SEG_QUADTO returns two points,
-                 * SEG_CUBICTO returns 3 points
-                 * and SEG_CLOSE does not return any points.
-                 */
-                switch (t1) {
-                case PathIterator.SEG_CUBICTO: 
-                    if (0 != (diff = compareDiff(coords1[5],coords2[5]))) return diff;
-                    if (0 != (diff = compareDiff(coords1[4],coords2[4]))) return diff;
-                case PathIterator.SEG_QUADTO: 
-                    if (0 != (diff = compareDiff(coords1[3],coords2[3]))) return diff;
-                    if (0 != (diff = compareDiff(coords1[2],coords2[2]))) return diff;
-                case PathIterator.SEG_MOVETO:
-                case PathIterator.SEG_LINETO: 
-                    if (0 != (diff = compareDiff(coords1[1],coords2[1]))) return diff;
-                    if (0 != (diff = compareDiff(coords1[0],coords2[0]))) return diff;
-                case PathIterator.SEG_CLOSE: break;
-                default: throw new IllegalArgumentException();
-                }
-                p1.next();
-                p2.next();
-            }
-        }
-    };
-
-    private static int compareDiff(float f, float g) {
-        return f < g ? -1 : f > g ? 1 : 0;
-    }
-    private static int compareDiff(double f, double g) {
-        return f < g ? -1 : f > g ? 1 : 0;
-    }
-}