< prev index next >

src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java

Print this page

        

@@ -131,10 +131,34 @@
             }
         }
         return missingGlyph;
     }
 
+    private int convertToGlyph(int unicode, int variationSelector) {
+        if (variationSelector == 0) {
+            return convertToGlyph(unicode);
+        }
+        for (int slot = 0; slot < font.numSlots; slot++) {
+            if (!hasExcludes || !font.isExcludedChar(slot, unicode)) {
+                CharToGlyphMapper mapper = getSlotMapper(slot);
+                int glyphCode = missingGlyph;
+                if (mapper.hasVariationSelectorGlyph(unicode, 
+                                                     variationSelector)) {
+                    int glyphCodes[] = { 0, 0};
+                    int codes[] = {unicode, variationSelector};
+                    mapper.charsToGlyphs(2, codes, glyphCodes);
+                    glyphCode = glyphCodes[0];
+                    if (glyphCode != mapper.getMissingGlyphCode()) {
+                        glyphCode = compositeGlyphCode(slot, glyphCode);
+                        return glyphCode;
+                    }
+                }
+            }
+        }
+        return convertToGlyph(unicode); //retry without Variation Selector
+    }
+
     public int getNumGlyphs() {
         int numGlyphs = 0;
         /* The number of glyphs in a composite is affected by
          * exclusion ranges and duplicates (ie the same code point is
          * mapped by two different fonts) and also whether or not to

@@ -191,27 +215,52 @@
      */
     public boolean charsToGlyphsNS(int count, char[] unicodes, int[] glyphs) {
 
         for (int i=0; i<count; i++) {
             int code = unicodes[i]; // char is unsigned.
+            int step = 1;
+            int variationSelector = 0;
 
             if (code >= HI_SURROGATE_START &&
                 code <= HI_SURROGATE_END && i < count - 1) {
                 char low = unicodes[i + 1];
 
                 if (low >= LO_SURROGATE_START &&
                     low <= LO_SURROGATE_END) {
                     code = (code - HI_SURROGATE_START) *
                         0x400 + low - LO_SURROGATE_START + 0x10000;
                     glyphs[i + 1] = INVISIBLE_GLYPH_ID;
+                    step = 2;
                 }
             }
 
+            if (i < count - step &&
+                isVariationSelector(unicodes[i+step]) &&
+                isBaseChar(code)) {
+                variationSelector = unicodes[i+step];
+                glyphs[i] = convertToGlyph(code, variationSelector);
+                glyphs[i+step] = INVISIBLE_GLYPH_ID;
+                i += 1;
+            } else if (i < count - step -1 &&
+                       isVariationSelector(unicodes[i+step],
+                                           unicodes[i+step+1]) &&
+                       isBaseChar(code)) {
+                variationSelector = (unicodes[i+step] 
+                                     - HI_SURROGATE_START) * 0x400 
+                                    + unicodes[i+step+1] - LO_SURROGATE_START
+                                    + 0x10000;
+                glyphs[i] = convertToGlyph(code, variationSelector);
+                glyphs[i+step] = INVISIBLE_GLYPH_ID;
+                glyphs[i+step+1] = INVISIBLE_GLYPH_ID;
+                i += 2;
+            }
+            if (variationSelector == 0) {
             int gc = glyphs[i] = getCachedGlyphCode(code);
             if (gc == UNINITIALIZED_GLYPH) {
                 glyphs[i] = convertToGlyph(code);
             }
+            }
 
             if (code < FontUtilities.MIN_LAYOUT_CHARCODE) {
                 continue;
             }
             else if (FontUtilities.isComplexCharCode(code)) {

@@ -230,44 +279,74 @@
      * one char at a time. However the cache should fill very rapidly.
      */
     public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
         for (int i=0; i<count; i++) {
             int code = unicodes[i]; // char is unsigned.
+            int variationSelector = 0;
+            int step = 1;
 
             if (code >= HI_SURROGATE_START &&
                 code <= HI_SURROGATE_END && i < count - 1) {
                 char low = unicodes[i + 1];
 
                 if (low >= LO_SURROGATE_START &&
                     low <= LO_SURROGATE_END) {
                     code = (code - HI_SURROGATE_START) *
                         0x400 + low - LO_SURROGATE_START + 0x10000;
 
-                    int gc = glyphs[i] = getCachedGlyphCode(code);
-                    if (gc == UNINITIALIZED_GLYPH) {
-                        glyphs[i] = convertToGlyph(code);
-                    }
-                    i += 1; // Empty glyph slot after surrogate
-                    glyphs[i] = INVISIBLE_GLYPH_ID;
-                    continue;
+                    glyphs[i+1] = INVISIBLE_GLYPH_ID;
+                    step = 2;
                 }
             }
 
+            if (i < count - step &&
+                isVariationSelector(unicodes[i+step]) &&
+                isBaseChar(code)) {
+                    variationSelector = unicodes[i+step];
+                    glyphs[i] = convertToGlyph(code, variationSelector);
+                    glyphs[i+step] = INVISIBLE_GLYPH_ID;
+                    i += 1;
+            } else if (i < count - step -1 &&
+                       isVariationSelector(unicodes[i+step], 
+                                           unicodes[i+step+1]) &&
+                       isBaseChar(code)) {
+                variationSelector = (unicodes[i+step] 
+                                     - HI_SURROGATE_START) * 0x400 
+                                    + unicodes[i+step+1] - LO_SURROGATE_START
+                                    + 0x10000;
+                glyphs[i] = convertToGlyph(code, variationSelector);
+                glyphs[i+step] = INVISIBLE_GLYPH_ID;
+                glyphs[i+step+1] = INVISIBLE_GLYPH_ID;
+                i += 2;
+            }
+            if (variationSelector == 0) {
             int gc = glyphs[i] = getCachedGlyphCode(code);
             if (gc == UNINITIALIZED_GLYPH) {
                 glyphs[i] = convertToGlyph(code);
             }
         }
+            if (code >= 0x10000) {
+                i++;
+            }
+        }
     }
 
     public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
         for (int i=0; i<count; i++) {
             int code = unicodes[i];
 
+            if (i < count-1
+                && isVariationSelector(unicodes[i+1])
+                && isBaseChar(code) ) {
+                glyphs[i] = convertToGlyph(code, unicodes[i+1]);
+                glyphs[i+1] = INVISIBLE_GLYPH_ID;
+                i++;
+            } else {
             glyphs[i] = getCachedGlyphCode(code);
             if (glyphs[i] == UNINITIALIZED_GLYPH) {
                 glyphs[i] = convertToGlyph(code);
             }
         }
     }
+    }
 
 }
< prev index next >