Exemplo n.º 1
0
static int AnalyzeParagraph( paragraph_t *p_paragraph )
{
    fribidi_get_bidi_types(  p_paragraph->p_code_points,
                             p_paragraph->i_size,
                             p_paragraph->p_types );
    fribidi_get_par_embedding_levels( p_paragraph->p_types,
                                      p_paragraph->i_size,
                                      &p_paragraph->paragraph_type,
                                      p_paragraph->p_levels );

#ifdef HAVE_HARFBUZZ
    hb_unicode_funcs_t *p_funcs = hb_unicode_funcs_get_default();
    for( int i = 0; i < p_paragraph->i_size; ++i )
        p_paragraph->p_scripts[ i ] =
            hb_unicode_script( p_funcs, p_paragraph->p_code_points[ i ] );

    hb_script_t i_last_script;
    int i_last_script_index = -1;
    int i_last_set_index = -1;

    /*
     * For shaping to work, characters that are assigned HB_SCRIPT_COMMON or
     * HB_SCRIPT_INHERITED should be resolved to the last encountered valid
     * script value, if any, and to the first one following them otherwise
     */
    for( int i = 0; i < p_paragraph->i_size; ++i )
    {
        if( p_paragraph->p_scripts[ i ] == HB_SCRIPT_COMMON
            || p_paragraph->p_scripts[ i ] == HB_SCRIPT_INHERITED)
        {
            if( i_last_script_index != -1)
            {
                p_paragraph->p_scripts[ i ] = i_last_script;
                i_last_set_index = i;
            }
        }
        else
        {
            for( int j = i_last_set_index + 1; j < i; ++j )
                p_paragraph->p_scripts[ j ] = p_paragraph->p_scripts[ i ];

            i_last_script = p_paragraph->p_scripts[ i ];
            i_last_script_index = i;
            i_last_set_index = i;
        }
    }
#endif //HAVE_HARFBUZZ

    return VLC_SUCCESS;
}
Exemplo n.º 2
0
bool GlyphString::analyze(bool resolveScripts, bool breakOnLevelChange)
{
    if (mState != Initialized)
        return false;

    fribidi_get_bidi_types(mCodePoints, mSize, mTypes);
    fribidi_get_par_embedding_levels(mTypes, mSize, &mParType, mLevels);

    hb_unicode_funcs_t *ufuncs = hb_unicode_funcs_get_default();
    for (int i = 0; i < mSize; ++i)
        mScripts[i] = hb_unicode_script(ufuncs, mCodePoints[i]);

    if (resolveScripts) {
        hb_script_t lastScriptValue;
        int lastScriptIndex = -1;
        int lastSetIndex = -1;

        for (int i = 0; i < mSize; ++i) {
            if (mScripts[i] == HB_SCRIPT_COMMON || mScripts[i] == HB_SCRIPT_INHERITED) {
                if (lastScriptIndex != -1) {
                    mScripts[i] = lastScriptValue;
                    lastSetIndex = i;
                }
            } else {
                for (int j = lastSetIndex + 1; j < i; ++j)
                    mScripts[j] = mScripts[i];
                lastScriptValue = mScripts[i];
                lastScriptIndex = i;
                lastSetIndex = i;
            }
        }
    }

    int runID = 0;
    hb_script_t lastScript = mScripts[0];
    int lastLevel = mLevels[0];
    int lastRunStart = 0;
    for (int i = 0; i <= mSize; ++i) {
        if (i == mSize || mScripts[i] != lastScript ||
                (breakOnLevelChange && mLevels[i] != lastLevel))
        {
            ++runID;
            RunInfo run;
            run.startOffset = lastRunStart;
            run.endOffset = i;
            run.script = lastScript;
            run.direction = lastLevel & 1 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
            mRunInfos.push_back(run);
            if (i < mSize) {
                lastScript = mScripts[i];
                lastLevel = mLevels[i];
                lastRunStart = i;
            } else {
                break;
            }
        }
        mRuns[i] = runID;
    }

    mState = Analyzed;
    return true;
}
Exemplo n.º 3
0
/* Resolve the script for each character in the input string, if the character
 * script is common or inherited it takes the script of the character before it
 * except paired characters which we try to make them use the same script. We
 * then split the BiDi runs, if necessary, on script boundaries.
 */
static bool
_raqm_resolve_scripts (raqm_t *rq)
{
  int last_script_index = -1;
  int last_set_index = -1;
  hb_script_t last_script_value = HB_SCRIPT_INVALID;
  raqm_stack_t *stack = NULL;

  if (rq->scripts)
    return true;

  rq->scripts = malloc (sizeof (hb_script_t) * rq->text_len);
  if (!rq->scripts)
    return false;

  for (size_t i = 0; i < rq->text_len; ++i)
    rq->scripts[i] = hb_unicode_script (hb_unicode_funcs_get_default (),
                                        rq->text[i]);

#ifdef RAQM_TESTING
  RAQM_TEST ("Before script detection:\n");
  for (size_t i = 0; i < rq->text_len; ++i)
  {
    SCRIPT_TO_STRING (rq->scripts[i]);
    RAQM_TEST ("script for ch[%zu]\t%s\n", i, buff);
  }
  RAQM_TEST ("\n");
#endif

  stack = _raqm_stack_new (rq->text_len);
  if (!stack)
    return false;

  for (int i = 0; i < (int) rq->text_len; i++)
  {
    if (rq->scripts[i] == HB_SCRIPT_COMMON && last_script_index != -1)
    {
      int pair_index = get_pair_index (rq->text[i]);
      if (pair_index >= 0)
      {
        if (IS_OPEN (pair_index))
        {
          /* is a paired character */
          rq->scripts[i] = last_script_value;
          last_set_index = i;
          _raqm_stack_push (stack, rq->scripts[i], pair_index);
        }
        else
        {
          /* is a close paired character */
          /* find matching opening (by getting the last even index for current
           * odd index) */
          int pi = pair_index & ~1;
          while (STACK_IS_NOT_EMPTY (stack) &&
                 stack->pair_index[stack->size] != pi)
          {
            _raqm_stack_pop (stack);
          }
          if (STACK_IS_NOT_EMPTY (stack))
          {
            rq->scripts[i] = _raqm_stack_top (stack);
            last_script_value = rq->scripts[i];
            last_set_index = i;
          }
          else
          {
            rq->scripts[i] = last_script_value;
            last_set_index = i;
          }
        }
      }
      else
      {
        rq->scripts[i] = last_script_value;
        last_set_index = i;
      }
    }
    else if (rq->scripts[i] == HB_SCRIPT_INHERITED && last_script_index != -1)
    {
      rq->scripts[i] = last_script_value;
      last_set_index = i;
    }
    else
    {
      for (int j = last_set_index + 1; j < i; ++j)
        rq->scripts[j] = rq->scripts[i];
      last_script_value = rq->scripts[i];
      last_script_index = i;
      last_set_index = i;
    }
  }

#ifdef RAQM_TESTING
  RAQM_TEST ("After script detection:\n");
  for (size_t i = 0; i < rq->text_len; ++i)
  {
    SCRIPT_TO_STRING (rq->scripts[i]);
    RAQM_TEST ("script for ch[%zu]\t%s\n", i, buff);
  }
  RAQM_TEST ("\n");
#endif

  _raqm_stack_free (stack);

  return true;
}