/*
 * Copyright (c) 2018, 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.
 *
 * 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.
 */


/* @test
   @bug 7017058 8191130 8195836
   @summary Test handling of ZWJ by layout.
 */

/*
 * A forced mapping of ZWJ (u+200D) to a special invisible glyph ID
 * was breaking many uses of ZWJ to form ligatures in fonts supporting
 * Indic scripts (Malayalam, Bengali, Sinhala at least) and also Emoji.
 * Without knowing the exact properties of a font under test, and also
 * how a layout engine maps chars to glyphs, it is difficult to write
 * a complete robust automated test.
 * So whilst it tries to show rendering for any fonts that claims to
 * support the target alphabet, it will fail only when specific known
 * fonts fail.
 * The test automatically passes or fails only if these fonts do
 * not ligature away the ZWJ.
 * Besides this the test renders the specific text from these fonts
 * and any others that claim to fully support the text, so it can be
 * manually examined if so desired.
 */

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Locale;

public class ZWJLigatureTest {

   // These are fonts and scripts on Windows that should support
   // the behaviours enough to make reliable tests";

   static final String malayalamName = "Malayalam";
   static final String malayalamFont = "Kartika";
   static final String malayalamText = "\u0D2C\u0D3E\u0D32\u0D28\u0D4D\u200D";

   static final String bengaliName = "Bengali";
   static final String bengaliFont = "Vrinda";
   static final String bengaliText =
       "\u09CE \u09A4\u09CD\u200D " +
       "\u09A4\u09BE\u09CE \u09A4\u09BE\u09A4\u09CD\u200D";

   static final String sinhalaName = "Sinhala";
   static final String sinhalaFont = "Iskoola Pota";
   static final String sinhalaText =
       "\u0DC1\u0DCA\u200D\u0DBB\u0DD3" +
       "\u0D9A\u0DCA\u200D\u0DBB\u0DD2" +
       "\u0D9A\u0DCA\u200D\u0DBB\u0DD3" +
       "\u0DA7\u0DCA\u200D\u0DBB\u0DDA" +
       "\u0DB6\u0DCA\u200D\u0DBB\u0DD0" +
       "\u0D9B\u0DCA\u200D\u0DBA\u0DCF";


   static String[] scripts = { malayalamName, bengaliName, sinhalaName };
   static String[] fontNames = { malayalamFont, bengaliFont, sinhalaFont };
   static String[] text = { malayalamText, bengaliText, sinhalaText };


   static void doTest() {
       boolean testFailed = false;

       BufferedImage bi = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
       Graphics2D g2d = (Graphics2D)bi.getGraphics();
       FontRenderContext frc = g2d.getFontRenderContext();
       for (int f=0; f < fontNames.length; f++) {
           Font font = new Font(fontNames[f], Font.PLAIN, 30);
           String family = font.getFamily(Locale.ENGLISH).toLowerCase();
           if (!fontNames[f].toLowerCase().equals(family)) {
               System.out.println(fontNames[f] + " not found, skipping.");
               continue;
           } else {
               System.out.println("Testing " + fontNames[f] +
                                  " for " + scripts[f]);
           }
           char[] chs = text[f].toCharArray();
           GlyphVector gv = font.layoutGlyphVector(frc, chs, 0, chs.length, 0);
           for (int g=0; g<gv.getNumGlyphs(); g++) {
               int glyph = gv.getGlyphCode(g);
               int charIdx = gv.getGlyphCharIndex(g);
               int codePoint = text[f].codePointAt(charIdx);
               Point2D pos = gv.getGlyphPosition(g);

               if (codePoint == 0x200D) {
                  testFailed = true;
                  System.out.println("FAIL: GOT ZWJ\n");
               }
               System.out.println("["+g+"]: gid="+Integer.toHexString(glyph)
                   +", charIdx="+Integer.toHexString(charIdx)
                   +", codePoint="+Integer.toHexString(codePoint)
                   +", pos=["+pos.getX()+","+pos.getY()+"]");
               }
           }
           if (testFailed) {
               throw new RuntimeException("TEST FAILED");
           }
    }

    public static void main(String[] args) {
        doTest();
    }
}