Beispiel #1
0
FRIBIDI_ENTRY void
fribidi_shape_arabic (
  /* input */
  FriBidiFlags flags,
  const FriBidiLevel *embedding_levels,
  const FriBidiStrIndex len,
  /* input and output */
  FriBidiArabicProp *ar_props,
  FriBidiChar *str
)
{
  DBG ("in fribidi_shape_arabic");

  if UNLIKELY
    (len == 0 || !str) return;

  DBG ("in fribidi_shape");

  fribidi_assert (ar_props);

  if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_ARAB_PRES))
    {
      DO_SHAPING (FRIBIDI_GET_ARABIC_SHAPE_PRES, len, ar_props, str);
    }

  if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_ARAB_LIGA))
    {
      DO_LIGATURING (mandatory_liga_table, embedding_levels, len, ar_props, str);
    }

  if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_ARAB_CONSOLE))
    {
      DO_LIGATURING (console_liga_table, embedding_levels, len, ar_props, str);
      DO_SHAPING (FRIBIDI_GET_ARABIC_SHAPE_NSM, len, ar_props, str);
    }
}
FRIBIDI_ENTRY void
fribidi_shape (
  /* input */
  FriBidiFlags flags,
  const FriBidiLevel *embedding_levels,
  const FriBidiStrIndex len,
  /* input and output */
  FriBidiArabicProp *ar_props,
  FriBidiChar *str
)
{
  if UNLIKELY
    (len == 0 || !str) return;

  DBG ("in fribidi_shape");

  fribidi_assert (embedding_levels);

  if (ar_props)
    fribidi_shape_arabic (flags, embedding_levels, len, ar_props, str);

  if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_MIRRORING))
    fribidi_shape_mirroring (embedding_levels, len, str);
}
FRIBIDI_ENTRY void
fribidi_join_arabic (
  /* input */
  const FriBidiCharType *bidi_types,
  const FriBidiStrIndex len,
  const FriBidiLevel *embedding_levels,
  /* input and output */
  FriBidiArabicProp *ar_props
)
{
  if UNLIKELY
    (len == 0) return;

  DBG ("in fribidi_join_arabic");

  fribidi_assert (bidi_types);
  fribidi_assert (embedding_levels);
  fribidi_assert (ar_props);

# if DEBUG
  if UNLIKELY
    (fribidi_debug_status ())
    {
      print_joining_types (embedding_levels, len, ar_props);
    }
# endif	/* DEBUG */

  /* The joining algorithm turned out very very dirty :(.  That's what happens
   * when you follow the standard which has never been implemented closely
   * before.
   */

  /* 8.2 Arabic - Cursive Joining */
  DBG ("Arabic cursive joining");
  {
    /* The following do not need to be initialized as long as joins is
     * initialized to false.  We just do to turn off compiler warnings. */
    register FriBidiStrIndex saved = 0;
    register FriBidiLevel saved_level = FRIBIDI_SENTINEL;
    register fribidi_boolean saved_shapes = false;
    register FriBidiArabicProp saved_joins_following_mask = 0;

    register fribidi_boolean joins = false;
    register FriBidiStrIndex i;

    for (i = 0; i < len; i++)
      if (!FRIBIDI_IS_JOINING_TYPE_G (ar_props[i]))
	{
	  register fribidi_boolean disjoin = false;
	  register fribidi_boolean shapes = FRIBIDI_ARAB_SHAPES (ar_props[i]);
	  register FriBidiLevel level = FRIBIDI_CONSISTENT_LEVEL (i);

	  if (joins && !FRIBIDI_LEVELS_MATCH (saved_level, level))
	    {
	      disjoin = true;
	      joins = false;
	    }

	  if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
	    {
	      register const FriBidiArabicProp joins_preceding_mask =
		FRIBIDI_JOINS_PRECEDING_MASK (level);

	      if (!joins)
		{
		  if (shapes)
		    FRIBIDI_UNSET_BITS (ar_props[i], joins_preceding_mask);
		}
	      else if (!FRIBIDI_TEST_BITS (ar_props[i], joins_preceding_mask))
	        {
		  disjoin = true;
		}
	      else
	        {
		  register FriBidiStrIndex j;
		  /* This is a FriBidi extension:  we set joining properties
		   * for skipped characters in between, so we can put NSMs on tatweel
		   * later if we want.  Useful on console for example.
		   */
		  for (j = saved + 1; j < i; j++)
		    FRIBIDI_SET_BITS (ar_props[j], joins_preceding_mask | saved_joins_following_mask);
		}
	    }

	  if (disjoin && saved_shapes)
	    FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);

	  if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
	    {
	      saved = i;
	      saved_level = level;
	      saved_shapes = shapes;
	      saved_joins_following_mask =
		FRIBIDI_JOINS_FOLLOWING_MASK (level);
	      joins =
		FRIBIDI_TEST_BITS (ar_props[i], saved_joins_following_mask);
	    }
	}
    if ((joins) && saved_shapes)
      FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);

  }

# if DEBUG
  if UNLIKELY
    (fribidi_debug_status ())
    {
      print_joining_types (embedding_levels, len, ar_props);
    }
# endif	/* DEBUG */

  DBG ("leaving fribidi_join_arabic");
}