Пример #1
0
char
hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
                         const uint16_t *chars, size_t len, ssize_t *iter) {
  if (*iter == (size_t) -1)
    return 0;

  const size_t ending_index = *iter;
  const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter);
  unsigned cps = 1;
  if (init_cp == HB_InvalidCodePoint)
    return 0;
  const HB_Script init_script = code_point_to_script(init_cp);
  HB_Script current_script = init_script;
  output->script = init_script;

  for (;;) {
    if (*iter < 0)
      break;
    const ssize_t prev_iter = *iter;
    const uint32_t cp = utf16_to_code_point_prev(chars, len, iter);
    if (cp == HB_InvalidCodePoint)
      return 0;
    cps++;
    const HB_Script script = code_point_to_script(cp);

    if (script != current_script) {
      if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) {
        // If we started off as inherited, we take whatever we can find.
        output->script = script;
        current_script = script;
        continue;
      } else if (script == HB_Script_Inherited) {
        /* BEGIN android-changed
           We apply the same fix for Chrome to Android.
           Chrome team will talk with upsteam about it.
           Just assume that whatever follows this combining character is within
           the same script.  This is incorrect if you had language1 + combining
           char + language 2, but that is rare and this code is suspicious
           anyway.
           END android-changed */
        continue;
      } else {
        *iter = prev_iter;
        cps--;
        break;
      }
    }
  }

  if (output->script == HB_Script_Inherited)
    output->script = HB_Script_Common;

  output->pos = *iter + 1;
  output->length = ending_index - *iter;
  if (num_code_points)
    *num_code_points = cps;
  return 1;
}
Пример #2
0
char
hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
                         const uint16_t *chars, size_t len, ssize_t *iter) {
  if (*iter == len)
    return 0;

  output->pos = *iter;
  const uint32_t init_cp = utf16_to_code_point(chars, len, iter);
  unsigned cps = 1;
  if (init_cp == HB_InvalidCodePoint)
    return 0;
  const HB_Script init_script = code_point_to_script(init_cp);
  HB_Script current_script = init_script;
  output->script = init_script;

  for (;;) {
    if (*iter == len)
      break;
    const ssize_t prev_iter = *iter;
    const uint32_t cp = utf16_to_code_point(chars, len, iter);
    if (cp == HB_InvalidCodePoint)
      return 0;
    cps++;
    const HB_Script script = code_point_to_script(cp);

    if (script != current_script) {
        /* BEGIN android-changed
           The condition was not correct by doing "a == b == constant"
           END android-changed */
      if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) {
        // If we started off as inherited, we take whatever we can find.
        output->script = script;
        current_script = script;
        continue;
      } else if (script == HB_Script_Inherited) {
        continue;
      } else {
        *iter = prev_iter;
        cps--;
        break;
      }
    }
  }

  if (output->script == HB_Script_Inherited)
    output->script = HB_Script_Common;

  output->length = *iter - output->pos;
  if (num_code_points)
    *num_code_points = cps;
  return 1;
}
char
hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
                         const uint16_t *chars, size_t len, ssize_t *iter) {
  if (*iter == (size_t) -1)
    return 0;

  const size_t ending_index = *iter;
  const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter);
  unsigned cps = 1;
  if (init_cp == HB_InvalidCodePoint)
    return 0;
  const HB_Script init_script = code_point_to_script(init_cp);
  HB_Script current_script = init_script;
  output->script = init_script;

  for (;;) {
    if (*iter < 0)
      break;
    const ssize_t prev_iter = *iter;
    const uint32_t cp = utf16_to_code_point_prev(chars, len, iter);
    if (cp == HB_InvalidCodePoint)
      return 0;
    cps++;
    const HB_Script script = code_point_to_script(cp);

    if (script != current_script) {
      if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) {
        // If we started off as inherited, we take whatever we can find.
        output->script = script;
        current_script = script;
        continue;
      } else if (script == HB_Script_Inherited) {
        current_script = script;
        continue;
      } else {
        *iter = prev_iter;
        cps--;
        break;
      }
    }
  }

  if (output->script == HB_Script_Inherited)
    output->script = HB_Script_Common;

  output->pos = *iter + 1;
  output->length = ending_index - *iter;
  if (num_code_points)
    *num_code_points = cps;
  return 1;
}
Пример #4
0
int PalFont_RenderText( void         *aContext,
                        unsigned int *aBitmap,
                        int           aBitmapWidth,
                        int           aBitmapHeight,
                        const char   *text,
                        int           textIndex,
                        int           textLength,
                        int          *aPen_x,
                        int          *aPen_y,
                        PalFont_BBox_t*aBBox,
                        int           resetBox ) {
   ft_Context_t *ftContext = FT_CONTEXT( aContext );
   HarfBuzz_t    aHarfBuzz;
   int           err       = 0;
   uint16_t      str[ MAX_CHARS ];
   int           i;
   int           nChars;
   int           isArabic  = 0;
   int           savePenX, savePenY;

   /* firstly convert to UTF-16 in str */
   for ( i = 0; i < MAX_CHARS; i++ ) {
      int aCharCode = getNextUnicodeFromUTF8( ( unsigned char ** )&text );
      if ( aCharCode == 0 ) {
         break;
      }
      str[ i ] = aCharCode;
   }

   /* we cant handle more than MAX_CHARS */
   if ( i == MAX_CHARS ) {
      return -1;
   }

   /* add termination, not sure if needed */
   str[ i ] = '\0';
   nChars   = i;

   /* do we have any Arabic? */
   for ( i = 0; i < nChars; i++ ) {
      if ( code_point_to_script( str[ i ] ) == HB_Script_Arabic ) {
         isArabic = 1;
         break;
      }
   }

   /* if we do then reverse any runs of Latin */
   if ( isArabic != 0 ) {
      int j;
      for ( j = 0 ; j < nChars; ) {
        /* set i to the start of latin */
        for ( i = j; i < nChars; i++ ) {
           if ( isLatin( str[ i ] ) != 0 ) {
              break;
           }
        }
        /* set j to the end of latin + 1 */
        for ( j = i; j < nChars; j++ ) {
           if ( isLatin( str[ j ] ) == 0 ) {
               break;
            }
         }
         reverse_text( str, i, j - i );
      }
   }

   err = Utf16_To_Harfbuzz( aContext, str, nChars, &aHarfBuzz );
   if ( err != 0 ) {
      return err;
   }

   if ( aPen_x != NULL ) {
      savePenX = *aPen_x;
   }

   if ( aPen_y != NULL ) {
      savePenY = *aPen_y;
   }

   err = PalFont_RenderHarfBuzz( ftContext,
                                 aBitmap,
                                 aBitmapWidth,
                                 aBitmapHeight,
                                &aHarfBuzz,
                                 textIndex,
                                 textLength,
                                 aPen_x,
                                 aPen_y,
                                 aBBox,
                                 resetBox,
                                 isArabic,
                                 0 );
   if ( err != 0 ) {
      return err;
   }

   if ( ( ftContext->m_Synth & SynthTwoColor ) != 0 ) {
      resetBox = 0;

      if ( aPen_x != NULL ) {
         *aPen_x = savePenX;
      }

      if ( aPen_y != NULL ) {
         *aPen_y = savePenY;
      }

      err = PalFont_RenderHarfBuzz( ftContext,
                                    aBitmap,
                                    aBitmapWidth,
                                    aBitmapHeight,
                                    &aHarfBuzz,
                                    textIndex,
                                    textLength,
                                    aPen_x,
                                    aPen_y,
                                    aBBox,
                                    resetBox,
                                    isArabic,
                                    1 );
      if ( err != 0 ) {
         return err;
      }
   }
   return 0;
}
Пример #5
0
//pointless proxy
HB_Script charScript(uint cp)
{
    return code_point_to_script(cp);
}