Logo Search packages:      
Sourcecode: yudit version File versions

bool SFontTTF::findGlyphs ( SS_UCS4  in,
SV_GlyphIndex out 
) [protected]

This routine tries to find the glyph indeces of a unicode input stream

Parameters:
in is the input stream
len is the length if in
out is the output
Returns:
the nuber of characters processed in 'in'

When using external maps we are using the same map for all tables.

Definition at line 1180 of file SFontTTF.cpp.

References SBinVector< Type >::append(), SScriptProcessor::apply(), SBinVector< Type >::array(), SBVector::clear(), doContextSubstitutions(), SUniMap::encode(), findGlyph(), findJamoGlyphs(), findSouthIndicGlyphs(), SHashtable< BType >::get(), SScriptProcessor::getGlyphs(), getOTFLigature(), getOTFLigatures(), SScriptProcessor::getPositions(), SScriptProcessor::getWidth(), hasOTFLigatures(), SBinVector< Type >::insert(), SUniMap::isOK(), SScriptProcessor::isSupported(), SUniMap::isUMap(), SUniMap::lift(), SScriptProcessor::put(), SHashtable< BType >::put(), SBinVector< Type >::size(), storeMarkPositions(), and substituteOTFGlyph().

Referenced by draw(), and width().

{
  if (!isOK()) return false;
  SString key ((char*)&in, sizeof (SS_UCS4));
  const SString* cached = char2Glyphs.get (key);
  if (cached)
  {
    if (cached->size()<sizeof (SS_GlyphIndex)) return false;
    unsigned int usize = cached->size();
    for (unsigned int i=0; i<usize; i+= sizeof (SS_GlyphIndex))
    {
       out->append (*((SS_GlyphIndex*)&cached->array()[i]));
    }
    return true;
  }
  

  TTF_CMAP* cmap_table = (TTF_CMAP*) tables[SS_TB_CMAP];
  int num_tables = ntohs(cmap_table->numberOfEncodingTables);
  if (num_tables ==0)
  {
    SString chc; char2Glyphs.put (key, chc);
    return false;
  }

  /* Try to get the ligature index from OTF */
  SS_UCS4 lig = in;
  unsigned int liglen = 0;
  unsigned int scriptcode = getLigatureScriptCode (lig);
  /* no support yet for this monster */

  if (scriptcode == SD_COMBINING_LIGATURE)
  {
    /* never comes here */
    SString chc;
    char2Glyphs.put (key, chc);
    return false;
  }
  else if (scriptcode == SD_AS_SHAPES && fontencoding.size() == 0
     && hasOTFLigatures())
  {
    /* No encoder support for OTF single substitution */
    if (hardWire == SS_MSLVT)
    {
      SString chc;
      char2Glyphs.put (key, chc);
      return false;
    }
    bool success = false;

    unsigned int fcode = (lig & 0xf000) >> 12;
    SS_UCS4 gcode = lig & 0x0fff;

    SS_GlyphIndex gi[2];
    unsigned int len = 1;
    bool shouldBe1 = true;
    switch (gcode)
    {
    case 1: /* A000X001 */
      gi[0] = findGlyph (0x072A); 
      gi[1] = findGlyph (0x0308); 
      len = 2;
      shouldBe1 = false;
      break;
    case 2: /* A000X002 */
      gi[0] = findGlyph (0x06A9); 
      gi[1] = findGlyph (0x0627); 
      len = 2;
      break;
    case 3: /* A000X003 */
      gi[0] = findGlyph (0x06A9); 
      gi[1] = findGlyph (0x0644); 
      len = 2;
      break;
    default:
      gi[0] = findGlyph (gcode); 
      break;
    }
    /* Check if we got all glyphs */
    for (unsigned int i=0; i<len;  i++)
    {
      if ( gi[i] == 0)
      {
        SString chc;
        char2Glyphs.put (key, chc);
        return false;
      }
    }
    /* isolated=1 initial=2 medial=3 final=4 */ 
    // Miikka:
    //  For some strange reason, Syriac alaph-fj is known as
    //  "fina" in OTF, and alaph-r as "med2", so we'll swap
    //  these two
    if (gcode == 0x0710) {
       if (fcode == 4) fcode=5;
       else if (fcode == 5) fcode=4;
    }

    if (len==2)
    {
      SS_GlyphIndex out = 0;
      if (getOTFLigature ("syrc", "ccmp", gi, 2, &out, 4))
      {
        gi[0] = out; len = 1;
        success = true;
      }
      /* is it urdu or just urd<space>? */
      else if (getOTFLigature ("urd ", "ccmp", gi, 2, &out, 4))
      {
        gi[0] = out; len = 1;
        success = true;
      }
      else if (getOTFLigature ("urdu", "ccmp", gi, 2, &out, 4))
      {
        gi[0] = out; len = 1;
        success = true;
      }
    }
    const char* fname = getShapeCode (fcode-1);
    SS_GlyphIndex go = substituteOTFGlyph (fname, gi[0]);

    /* use it if found - fallback otherwise */
    if (go)
    {
      gi[0] = go;
      success = true;
    }
    else if (len!=2)/* fallback where placement is important  */
    {
      SString chc;
      char2Glyphs.put (key, chc);
      return false;
    }

    /* Try to get a ligature substitution */
    if (len==2)
    {
      SS_GlyphIndex out = 0;
      /* FIXME: How about URDU? 
       * should we do this before shaping?
       */
      if (getOTFLigature ("syrc", "rlig", gi, 2, &out, 4))
      {
        gi[0] = out; len = 1;
        success = true;
      }
    }
    if (shouldBe1 && len != 1) success = false;
    if (success)
    {
      out->append (gi[0]);
      if (len==2) out->append (gi[1]);

      SString chc ((char*)out->array(), 
        out->size() * sizeof (SS_GlyphIndex));
      char2Glyphs.put (key, chc);
      return true;
    }
    else
    {
      SString chc;
      char2Glyphs.put (key, chc);
      return false;
    }
  }

  /* INDIC */
  else if (isLigature (lig) && hasOTFLigatures() 
      && scriptcode != SD_AS_SHAPES && scriptcode != SD_AS_LITERAL
       && (liglen=getLigatureUnicode(lig, 0)) > 0)
  {
     if ((hardWire == SS_MSLVT || hardWire == SS_NOJAMO)
          && scriptcode!=SD_HANGUL_PREC && scriptcode!=SD_HANGUL_JAMO)
     {
       SString chc;
       char2Glyphs.put (key, chc);
       return false;
     }

     bool fixedcluster = true;

     SS_UCS4* chars =  new SS_UCS4[liglen];
     CHECK_NEW (chars);
     getLigatureUnicode (lig, chars);

     /*
      * Complex script rendering, with uniscribe-like algorithm.
      * This can be enabled with command line:
      *       -us 
      * option.
      * SS_MSLVT and SS_NOJAMO hardwired fonts will not be processed.
      */
     SScriptProcessor engine (this);

     // Should be able to start with ZWJ 
     SS_UCS4 sample = ((chars[0] == 0x200D || chars[0] == 0x25cc) && liglen > 1) ? chars[1] : chars[0];
     // Precompiled Hangul should not go through this.
     if (scriptcode!=SD_HANGUL_PREC 
         && hardWire!=SS_MSLVT 
         && hardWire!=SS_NOJAMO 
         && engine.isSupported(sample))
     {
       bool isbegin = (scriptcode == SD_BENGALI_BEGIN);
       unsigned int plen = engine.put (chars, liglen, isbegin);
       /*
        * We already have a full cluster, so we can fail
        * only if the engine can not find some glyphs.
        */
       if (plen != liglen)
       {
         SString chc;
         char2Glyphs.put (key, chc);
         delete chars;
         return false;
       }
       engine.apply ();
       *out =engine.getGlyphs ();
       if (out->size()==0)
       {
         SString chc;
         char2Glyphs.put (key, chc);
         delete chars;
         return false;
       } 

       /* Maintain our glyph-cache. */
       SString chc ((char*)out->array(), out->size() * sizeof (SS_GlyphIndex));
       char2Glyphs.put (key, chc);

       /* Maintain our position-cache. */
       SV_INT positions = engine.getPositions();
       positions.append (engine.getWidth());
       mark2BaseList.put (key, positions);
       delete chars;
       return true;
     }

     /*
      * Hangul, Thai and Lao is processed right here in the switch
      */
     switch (scriptcode)
     {
     case SD_THAI:
     case SD_LAO:
       {
         bool ret = false;
         /* don't support non-unicode encoded fonts for now */
         const char * script = getLigatureScript (lig);
         if (fontencoding.size()!=0 || !isOK()  || script==0)
         {
           ret = false;
         }
         else
         {
           ret = findSouthIndicGlyphs (key, scriptcode, 
               script, chars, liglen, out);
         }
         if (ret)
         {
           SString chc ((char*)out->array(), 
              out->size() * sizeof (SS_GlyphIndex));
           char2Glyphs.put (key, chc);
         }
         else
         {
           SString chc;
           char2Glyphs.put (key, chc);
         }
         delete chars;
         return ret;
       }
     case SD_HANGUL_PREC:
     case SD_HANGUL_JAMO:
       {
         bool ret = findJamoGlyphs (chars, liglen, out);
         /* cache */
         if (ret)
         {
           SString chc ((char*)out->array(), 
              out->size() * sizeof (SS_GlyphIndex));
           char2Glyphs.put (key, chc);
         }
         else
         {
           SString chc;
           char2Glyphs.put (key, chc);
         }
         delete chars;
         return ret;
       }
     case SD_TAMIL:
       fixedcluster = true;
       break;
     default: 
       fixedcluster = false;
       break;
     }

     SUniMap umap = charEncoder;
     if (!umap.isOK())
     {
        delete chars;
        SString chc;
        char2Glyphs.put (key, chc);
        return false;
     }

     /* we allocate one more to allow for LEFT_RIGHT vowel expansion */
     SS_GlyphIndex* gchars = new SS_GlyphIndex[liglen+1];
     CHECK_NEW (gchars);
     const char * script = getLigatureScript (lig);
     if (script == 0) script = "default";

     /* get the encoder for this table. */
     bool decoded = true; 
     /* we need this hocus-pocus because getLigature works on
        glyph indeces */
     /* for indic modifiers */
     unsigned int mstart = 0;
     unsigned int mend = 0;
     for (unsigned int i=0; i<liglen; i++)
     {
       SS_UCS2 ucs2 = umap.encode (chars[i]);
       if (ucs2==0)
       {
         if (chars[i] > 0xffff)
         {
            decoded = false;
            break;
         }
         /* BE AWARE HACK! Try straight unicode  */
         ucs2 = chars[i];
       }
       gchars[i] =  findGlyph(ucs2);
       if (gchars[i]==0)
       {
         decoded = false;
         break;
       }
       int endtype = getCharType (chars[i]);
       if (i>0 && endtype == SD_INDIC_MODIFIER && mstart == 0)
       {
          mstart = i; mend = liglen;
       }
     }
     /* adjust liglen to where modifiers start */
     if (mstart != 0)
     {
        liglen = mstart;
     }

     /* this is unicode encoded... */
     SS_GlyphIndex halant = findGlyph (getHalant (scriptcode));
     SS_GlyphIndex reorder = 0;
     SS_GlyphIndex addVirama = 0;
     unsigned int inlen = liglen;
     bool *gbase = NULL;

     // post-consonant Malayalam ra has to be reordered to syllable start
     if (scriptcode == SD_MALAYALAM)
        reorder = findGlyph (0x0d30);

     // special rules for clusters ending in virama
     if (decoded && liglen == 2 && chars[1] == getHalant(scriptcode))
     {
       decoded = false;
       unsigned int olen = getOTFLigatures (gchars, inlen, 
            script, "haln", halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS haln=", gchars, olen);
          decoded = true;
          inlen--;
       }
     }
     else if (decoded && chars[liglen-1] == getHalant(scriptcode))
     {
        // todo - RA+H RA+H
        addVirama = gchars[liglen-1];
        inlen--;
     }
     /*
      * Scripts like Tamil do not need complex processing. 
      * The combinations are finite, a fixed cluster suffices.
      */
     if (fixedcluster && decoded)
     {
       SS_GlyphIndex gi;
       unsigned int nind =  getOTFLigature (script, 0, gchars, liglen, &gi);
       if (nind == liglen)
       {
         out->append (gi);
       }
       else
       {
         decoded = false;
       }
     }
     /*
      * Complex script rendering, with our own algorithm.
      */
     else if (decoded)
     {
       /* ----> DEBUG Information */
       debugChars ("GCHARS=", gchars, liglen);
#ifdef DEBUG_LIGATURE
       fprintf (stderr, "Halant=%04X reorder=%04X gbase=%04X\n", 
         halant, reorder, (gbase==0)?0: *gbase);
#endif
       /* ----< DEBUG Information */
       unsigned int olen = getOTFLigatures (gchars, inlen, 
            script, "akhn", halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS akhn=", gchars, olen);
          inlen = olen;
       }
       /* can be at beginning only */
       SS_GlyphIndex rphfGlyph = 0;
       SS_GlyphIndex rphfNone = 0;
       if (inlen>2 && gchars[2] != findGlyph(SD_CD_ZWJ))
       {
         debugChars ("BEFORE RPH =", gchars, inlen);
         SS_GlyphIndex g[2]; g[0] = gchars[0]; g[1] = gchars[1];
         olen = getOTFLigatures (g, 2 , script, "rphf",
              halant, reorder, gbase);
         if (olen == 2)
           olen = getOTFLigatures (g, 2, script, "abvs",
                halant, reorder, gbase);
         if (olen == 1 && liglen > 2)
         {
           int ct = getCharType (chars[2]);
           // if chars[2] == SD_CD_ZWJ will be handled automagically here 
           if (ct == SD_INDIC_CONSONANT_BASE 
             || ct == SD_INDIC_CONSONANT_POST_BASE 
             || ct == SD_INDIC_CONSONANT_BELOW_BASE)
           {
             debugChars ("GCHARS rphf=", g, olen);
             rphfGlyph = g[0];
           }
           else
           {
             //fprintf (stderr, "GCHARS rphfNone\n");
             rphfNone = gchars[0];
           }
           /* remove */
           for (unsigned int i=2; i<inlen; i++) gchars[i-2] = gchars[i];
           inlen -= 2;
         }
         debugChars ("AFTER RPH =", gchars, inlen);
       }

       // Vowel placement in Malayalam is somewhat peculiar, as compared
       // to other Indic scripts; also Telugu and Kannada need special treatment
       if ((scriptcode == SD_MALAYALAM &&
           (getCharType (chars[liglen-1]) == SD_INDIC_LEFT_VOWEL ||
            getCharType (chars[liglen-1]) == SD_INDIC_LEFT_RIGHT_VOWEL)) ||
           ((scriptcode == SD_TELUGU || scriptcode == SD_KANNADA) &&
           liglen > 2))
       {
          gbase = new bool [inlen-1];
          for (unsigned int i=0; i<inlen-1; i++)
          {
             if (gchars[i] == halant)
                gbase[i] = false;
             else gbase[i] = true;
          }
       }

       olen = getOTFLigatures (gchars, inlen,
            script, "blwf", halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS blwf=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen,
            script, "vatu", halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS vatu=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen,
            script, "pstf", halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS pstf=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen, script, "blws",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS blws=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen, script, "psts",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS psts=", gchars, olen);
          inlen = olen;
       }
       /* if we still have U+0931 at this point, let's try U+0930 "half" */
       if (gchars[0] == findGlyph(0x0931) && inlen > 2)
       {
          gchars[0] = findGlyph(0x0930);
          olen = getOTFLigatures (gchars, inlen, script, "half",
               halant, reorder, gbase);
          if (olen != inlen)
          {
             debugChars ("GCHARS eyelash=", gchars, olen);
             inlen = olen;
          }
          else // otherwise we change it back to U+0931
          {
             gchars[0] = findGlyph(0x0931);
          }
       }
       /* Half-forms */
       olen = getOTFLigatures (gchars, inlen, script, "half",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS half=", gchars, olen);
          inlen = olen;
       }

       olen = getOTFLigatures (gchars, inlen, script,
           "!pstf,blwf,vatu,blws,rphf,psts,haln", halant, reorder, gbase);
       while (olen != inlen)
       {
          debugChars ("GCHARS any=", gchars, olen);
          inlen = olen;
          olen = getOTFLigatures (gchars, inlen, script,
            "!pstf,blwf,vatu,blws,rphf,psts,haln", halant, reorder, gbase);
       }

       /* in fact, this alone should do all the junk job (above) */
       /*
        * From: http://www.microsoft.com/typography/otspec/indicot/reg.htm
        *
        * In scripts like Malayalam, the halant form of certain consonants
        * is represented by 'chillaksharams'. These can appear at any
        *  non-initial or final consonant location in a syllable. 
        *
        * - unfortunatelly it is very vague: 'scripts like Malayalam'
        *    gaspar
        */
       if (inlen > 1)
       {
         /* does it start with consonant + halant + ZWJ ? */
         bool firstHalanOK = scriptcode!=SD_MALAYALAM  /* bit vague */
           || (inlen > 2 && gchars[1] == halant && gchars[2] == SD_G_INDIC_ZWJ);

         if (firstHalanOK) /* a bit vague */
         {
            olen = getOTFLigatures (gchars, inlen, script,
              "haln", halant, reorder, gbase);
         }
         else
         {
            olen = getOTFLigatures (&gchars[1], inlen-1, script,
              "haln", halant, reorder, gbase?&gbase[1]:0);
            olen++;
         }
         inlen = olen;
       }

       /* insert back virama and search for feature "haln" */
       if (addVirama)
       {
         gchars[olen] = addVirama;
         inlen++;
         olen = getOTFLigatures (gchars, inlen, script, "haln",
              halant, reorder, gbase);
       }
       /* This is "haln" not applied in while loop because of a specific 
          check condition for SD_G_INDIC_ZWNJ in getOTFLigatures */
       else if (inlen > 1 && gchars[inlen-1] == SD_G_INDIC_ZWNJ)
       {
         if (scriptcode != SD_MALAYALAM) /* a bit vague */
         {
           olen = getOTFLigatures (gchars, inlen-1, script, "haln",
                halant, reorder, gbase);
           if (olen != inlen-1)
           {
              gchars[olen] = gchars[inlen-1];
              olen++;
           }
         }
       }
       /* insert back non repha after getOTFLigatures */
       if (rphfNone)
       {
         for (unsigned int i=olen-1; i>1; i--)
         {
            gchars[i] = gchars[i-2];
         }
         gchars[0] = rphfNone;
         gchars[1] = halant;
         olen += 2;
       }
          
       int endtype = getCharType (chars[liglen-1]);
       switch (endtype)
       {
       case SD_INDIC_LEFT_VOWEL:
         if (olen > 1)
         {
            SS_GlyphIndex g = gchars[olen-1];
            if (gbase)
            {
               unsigned int i;
               for (i=olen-2; i && !gbase[i]; i--);
               for (unsigned int j=olen-1; j > i; j--)
                  gchars[j]=gchars[j-1];
               gchars[i] = g;
            }
            else
            {
               for (unsigned int i=olen-1; i; i--)
                  gchars[i]=gchars[i-1];
               gchars[0] = g;
            }
         }
         break;
       case SD_INDIC_RIGHT_VOWEL:
       case SD_INDIC_TOP_VOWEL:
       case SD_INDIC_BOTTOM_VOWEL:
         if (olen > 0)
         {
            SS_GlyphIndex g = gchars[olen-1];
            if (gbase)
            {
               unsigned int i;
               for (i=olen-2; i && !gbase[i]; i--);
               for (unsigned int j=olen-1; j > i+1; j--)
                  gchars[j]=gchars[j-1];
               gchars[i+1] = g;
            }
         }
         break;
       case SD_INDIC_LEFT_RIGHT_VOWEL:
         if (olen > 0)
         {
           SS_GlyphIndex g1 = findGlyph (getLRVowelLeft(chars[liglen-1]));
           SS_GlyphIndex g2 = findGlyph (getLRVowelRight(chars[liglen-1]));
           if (g1 && g2)
           {
             if (gbase)
             {
               unsigned int i;
               for (i=olen-2; i && !gbase[i]; i--);
               for (unsigned int j=olen-1; j > i; j--)
                  gchars[j]=gchars[j-1];
               gchars[i] = g1;
             }
             else
             {
               for (unsigned int i=olen; i; i--)
                  gchars[i]=gchars[i-1];
               gchars[0] = g1;
             }
             gchars[olen] = g2;
             olen++;
           liglen++; // We increase this, so that the program could notice
             // that the original character sequence has changed
           }
         }
       }
       if (rphfGlyph)
       {
          gchars[olen] = rphfGlyph;
          olen++;
       }
       /* add modifiers back */
       for (unsigned int i=mstart; i<mend; i++)
       {
          gchars[olen] = gchars[i];
          olen++;
          liglen++;
       }
       inlen = olen;
       olen = getOTFLigatures (gchars, inlen, script, "blws",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS blws=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen, script, "abvs",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS abvs=", gchars, olen);
          inlen = olen;
       }
       olen = getOTFLigatures (gchars, inlen, script, "psts",
            halant, reorder, gbase);
       if (olen != inlen)
       {
          debugChars ("GCHARS psts=", gchars, olen);
          inlen = olen;
       }

       /* Finally, do a chaining context substitution */
       bool chained = doContextSubstitutions (gchars, inlen, &olen, script, 0);
       if (chained)
       {
          debugChars ("GCHARS ChainContext=", gchars, olen);
          inlen = olen;
       }
       /* Just consider this decoded, even if no substitution is made. */
       if (olen > 0)
       {
          for (unsigned int i=0; i<olen; i++)
          {
            out->append (gchars[i]);
          }
          decoded = true;
       }
       else
       {
          decoded = false;
       }
     }

     /*
      * At this point both fixed and variable cluster 
      * glyph substitutions have been finished for
      * all scripts.
      */
     if (decoded)
     {
       SString chc ((char*)out->array(), out->size() * sizeof (SS_GlyphIndex));
       char2Glyphs.put (key, chc);
       /* some scripts, like TIBETAN require more fine grained positioning */
       if (!storeMarkPositions (key, out->array(), out->size()))
       {

#ifdef DEBUG_LIGATURE
         fprintf (stderr, "Can not find mark to base for %X\n", in);
#endif
       }
       else
       {
#ifdef DEBUG_LIGATURE
         fprintf (stderr, "Found mark to base for %X\n", in);
#endif
       }

#ifdef DEBUG_LIGATURE
       fprintf (stderr, "SFontTTF.cpp: Found OTF ligature:%s[%04X] %u -> %u: ", 
          script, (lig & 0xffff), liglen, out->size());
       debugChars ("GCHARS glyphs=",out->array(), out->size());
       for (unsigned int i=0; i<liglen; i++)
       {
         fprintf (stderr, " %X", chars[i]);
       }
       fprintf (stderr, "\n");
#endif
       delete chars;
       delete gchars;
       if (gbase) delete gbase;
       return true;
     }
     /* try to fall-back to font encoder, or hardwire if any */
     out->clear();
     delete chars;
     delete gchars;
     if (gbase) delete gbase;
  } /* End of Indic/Hangul/OTF */

  /* Let precomposed Hangul through. */
  
  bool okToProcess = true;

  /* Set okToProcess accoriding to artifical encodings */
  switch (hardWire)
  {
  case SS_MSLVT:
    /* precomposed or jamo */
    okToProcess = ((in>=0xac00 && in<0xd7a4) || getJamoClass (in) != SD_JAMO_X);
    break;
  case SS_NOJAMO:
    /* non jamo */
    okToProcess = (getJamoClass (in) == SD_JAMO_X);
    break;
  case SS_NONE:
  default:
    okToProcess = true;
    break;
  }

  if (!okToProcess)
  {
     SString chc;
     char2Glyphs.put (key, chc);
     return false;
  }

  /**
   * When using external maps we are using the same map for all
   * tables.
   */
  if (fontencoding.size()!=0 &&  charEncoder.isOK() && !charEncoder.isUMap())
  {
     /* max 3 */
     SV_UCS4 ucs4; ucs4.append (in); SV_UCS4 decd;
     SUniMap umap = charEncoder;
     unsigned int lifted = umap.lift (ucs4, 0, false, &decd);
     if (lifted == 0)
     {
        /* try straight - font has to have ascii mapping */
        SS_GlyphIndex gi = (in>=0x80) ? 0 :  findGlyph (in);
        if (gi)
        {
          out->append (gi);
          SString chc ((char*) &gi,  sizeof (SS_GlyphIndex));
          char2Glyphs.put (key, chc);
          return true;
        }
        SString chc; char2Glyphs.put (key, chc);
        return false;
     }
     for (unsigned int i=0; i<decd.size(); i++)
     {
        SS_GlyphIndex gi = findGlyph (decd[i]);
        if (gi == 0)
        {
          out->clear ();
          SString chc; char2Glyphs.put (key, chc);
          return false;
        }
        out->append (gi);
     }
     SString chc ((char*) out->array(), out->size() * sizeof (SS_GlyphIndex));
     char2Glyphs.put (key, chc);
     return true;
  }

  /* as I see there is no way to define multiple tables
   * for now so we just hardcode first one in reality we should
   * go through  0..num_tables
   */
  SUniMap umap = charEncoder;
  if (!umap.isOK())
  {
    SString chc; char2Glyphs.put (key, chc);
    return false;
  }
  /* get the encoder for this table. */
  // FIXME:
  // if in is non-BMP we will just use the value - hack - I know 
  SS_UCS4 ucs4 = (in>0xffff) ? in : (SS_UCS4) umap.encode (in);
  if (ucs4==0)
  {
    SString chc; char2Glyphs.put (key, chc);
    return false;
  }
  SS_GlyphIndex o = findGlyph (ucs4);
  if (o==0)
  {
    /* Try the decomposed one instead */
    if (hardWire==SS_MSLVT && 
       /* chekc for Precomposed Korean or JAMO */
      ((in>=0xac00 && in<0xd7a4) || getJamoClass (in) != SD_JAMO_X))
    {
      SS_UCS4 chars[3]; /* lvt */
      unsigned int liglen = 1;
      /* decompose if precomposed */
      if (in>=0xac00 && in<0xd7a4)
      {
        SS_UCS4 hangul = ucs4 - 0xac00;
        chars[0] = hangul / (21*28) + 0x1100;
        chars[1] = (hangul % (21*28))/28 + 0x1161;
        chars[2] = (hangul % 28) + 0x11a7;
        liglen = (chars[2] == 0x11a7) ? 2 : 3;
      }
      else
      {
        liglen = 1;
        chars[0] = in;
      }
      bool ret = findJamoGlyphs (chars, liglen, out);
      /* cache */
      if (ret)
      {
        if (liglen==1 && getJamoClass (in) != SD_JAMO_L)
        {
          /* standalone jamos fill emptyness */
          SS_GlyphIndex placeHolder = findGlyph (0x4e00);
          if (placeHolder) out->insert (0, placeHolder);
        }
        SString chc ((char*)out->array(), 
           out->size() * sizeof (SS_GlyphIndex));
        char2Glyphs.put (key, chc);
        return ret;
      }
      /* not found */
    }
    /* cache the nothing. */
    SString chc; char2Glyphs.put (key, chc);
    return false;
  }
  out->append (o);
  SString chc ((char*)&o, sizeof (SS_GlyphIndex));
  char2Glyphs.put (key, chc);
  return true;
}


Generated by  Doxygen 1.6.0   Back to index