1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8015556
  27  * @summary Surrogate pairs do not render properly on MacOS X.
  28  */
  29 
  30 import java.util.Locale;
  31 import java.awt.*;
  32 import java.awt.font.*;
  33 import javax.swing.*;
  34 
  35 public class SuppCharTest {
  36 
  37    static String str = "ABC\uD840\uDC01\uD840\uDC00AB";
  38    static String EXTB_FONT = "MingLiU-ExtB";
  39 
  40    public static void main(String args[]) throws Exception {
  41 
  42       final Font font = new Font(EXTB_FONT, Font.PLAIN, 36);
  43       if (!EXTB_FONT.equalsIgnoreCase(font.getFamily(Locale.ENGLISH))) {
  44          return;
  45       }
  46 
  47       SwingUtilities.invokeLater(new Runnable(){
  48         @Override
  49         public void run(){
  50             JFrame f = new JFrame("Test Supplementary Char Support");
  51             Component c = new SuppCharComp(font, str);
  52             f.add("Center", c);
  53             JButton b = new JButton(str);
  54             b.setFont(font);
  55             f.add("South", b);
  56             f.pack();
  57             f.setVisible(true);
  58         }
  59       });
  60 
  61       /* If a supplementary character was found, 'invisible glyphs'
  62        * with value 65535 will be inserted in the place of the 2nd (low)
  63        * char index. So we are looking here to make sure such substitutions
  64        * took place.
  65        */
  66       FontRenderContext frc = new FontRenderContext(null, false, false);
  67       GlyphVector gv = font.createGlyphVector(frc, str);
  68       int numGlyphs = gv.getNumGlyphs();
  69       int[] codes = gv.getGlyphCodes(0, numGlyphs, null);
  70       boolean foundInvisibleGlyph = false;
  71       for (int i=0; i<numGlyphs;i++) {
  72            if (codes[i] == 65535) {
  73                foundInvisibleGlyph = true;
  74                break;
  75            }
  76       }
  77 
  78       if (!foundInvisibleGlyph) {
  79            throw new RuntimeException("No invisible glyphs");
  80       }
  81 
  82       if (font.canDisplayUpTo(str) != -1) {
  83           throw new RuntimeException("Font can't display all chars");
  84       }
  85 
  86    }
  87 }
  88 
  89 class SuppCharComp extends Component {
  90 
  91   static final int w=400, h=250;
  92   public Dimension preferredSize() {
  93      return new Dimension(w,h);
  94   }
  95 
  96   String str = null;
  97   Font font = null;
  98   public SuppCharComp(Font font, String str) {
  99     this.font = font;
 100     this.str = str;
 101   }
 102   public void paint(Graphics g) {
 103      Graphics2D g2d = (Graphics2D)g.create();
 104      g2d.setColor(Color.white);
 105      g2d.fillRect(0,0,w,h);
 106      g2d.setColor(Color.black);
 107      int y = 0;
 108      g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
 109                           RenderingHints.VALUE_FRACTIONALMETRICS_ON);
 110      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
 111                           RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
 112 
 113      g2d.setFont(font);
 114      g2d.drawString(str, 10, 50);
 115 
 116      FontRenderContext frc = g2d.getFontRenderContext();
 117      GlyphVector gv = font.createGlyphVector(frc, str);
 118      g2d.drawGlyphVector(gv, 10, 100);
 119      TextLayout tl = new TextLayout(str, font, frc);
 120      tl.draw(g2d, 10, 150);
 121      char[] ca = str.toCharArray();
 122      g2d.drawChars(ca, 0, ca.length, 10, 200);
 123 
 124   }
 125 
 126 }
 127