Home | History | Annotate | Download | only in layout
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html#License
      3 /*
      4  *******************************************************************************
      5  * Copyright (C) 1998-2004, International Business Machines Corporation and    *
      6  * others. All Rights Reserved.                                                *
      7  *******************************************************************************
      8  *
      9  * Created on Dec 3, 2003
     10  *
     11  *******************************************************************************
     12  */
     13 package com.ibm.icu.dev.tool.layout;
     14 
     15 import com.ibm.icu.lang.UCharacter;
     16 import com.ibm.icu.lang.UProperty;
     17 
     18 public class ArabicShaping {
     19 
     20     // arabic   shaping type code
     21 
     22     // shaping bit masks
     23     static final int MASK_SHAPE_RIGHT   = 1; // if this bit set, shapes to right
     24     static final int MASK_SHAPE_LEFT = 2;   // if this bit set, shapes to left
     25     static final int MASK_TRANSPARENT   = 4; // if this bit set, is transparent (ignore other bits)
     26     static final int MASK_NOSHAPE   = 8; // if this bit set, don't shape this char, i.e. tatweel
     27 
     28     // shaping values
     29     public static final int VALUE_NONE = 0;
     30     public static final int VALUE_RIGHT = MASK_SHAPE_RIGHT;
     31     public static final int VALUE_LEFT = MASK_SHAPE_LEFT;
     32     public static final int VALUE_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT;
     33     public static final int VALUE_TRANSPARENT = MASK_TRANSPARENT;
     34     public static final int VALUE_NOSHAPE_DUAL = MASK_NOSHAPE | VALUE_DUAL;
     35     public static final int VALUE_NOSHAPE_NONE = MASK_NOSHAPE;
     36 
     37     public static int getShapeType(char ch)
     38     {
     39         int tt = UCharacter.getIntPropertyValue(ch, UProperty.JOINING_TYPE);
     40 
     41         switch(tt) {
     42             case UCharacter.JoiningType.JOIN_CAUSING:
     43                 return VALUE_NOSHAPE_DUAL;
     44 
     45             case UCharacter.JoiningType.LEFT_JOINING:
     46                 return VALUE_LEFT;
     47 
     48             case UCharacter.JoiningType.RIGHT_JOINING:
     49                 return VALUE_RIGHT;
     50 
     51             case UCharacter.JoiningType.DUAL_JOINING:
     52                 return VALUE_DUAL;
     53 
     54             case UCharacter.JoiningType.TRANSPARENT:
     55                 return VALUE_TRANSPARENT;
     56 
     57             case UCharacter.JoiningType.NON_JOINING:
     58             default:
     59                 return VALUE_NOSHAPE_NONE;
     60         }
     61     }
     62 
     63     /*
     64      * Chars in logical order.
     65      * leftType is shaping code of char to logical left of range
     66      * rightType is shaping code of char to logical right of range
     67      */
     68 
     69     public static void shape(char[] chars, int leftType, int rightType, ClassTable isolClassTable) {
     70         // iterate in logical order from left to right
     71         //
     72         // the effective right char is the most recently encountered
     73         // non-transparent char
     74         //
     75         // four boolean states:
     76         //   the effective right char shapes
     77         //   the effective right char causes right shaping
     78         //   the current char shapes
     79         //   the current char causes left shaping
     80         //
     81         // if both cause shaping, then
     82         //   right += 2 (isolate to initial, or final to medial)
     83         //   cur += 1 (isolate to final)
     84 
     85         // ern is effective right logical index
     86         int ern = -1;
     87 
     88         boolean rightShapes = false;
     89         boolean rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
     90 
     91         for (int n = 0; n < chars.length; n++) {
     92             char c = chars[n];
     93             int t = getShapeType(c);
     94 
     95             if ((t & MASK_TRANSPARENT) != 0) {
     96                 continue;
     97             }
     98 
     99             boolean curShapes = (t & MASK_NOSHAPE) == 0;
    100             boolean curCauses = (t & MASK_SHAPE_RIGHT) != 0;
    101 
    102             if (rightCauses && curCauses) {
    103                 if (rightShapes) {
    104                     chars[ern] += 2;
    105                 }
    106 
    107                 if (curShapes) {
    108                     chars[n] = (char) (isolClassTable.getGlyphClassID(c) + 1);
    109                 }
    110             } else {
    111                 if (curShapes) {
    112                     chars[n] = (char) isolClassTable.getGlyphClassID(c);
    113                 }
    114             }
    115 
    116             rightShapes = curShapes;
    117             rightCauses = (t & MASK_SHAPE_LEFT) != 0;
    118             ern = n;
    119         }
    120 
    121         if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
    122             chars[ern] += 2;
    123         }
    124     }
    125 }
    126