예제 #1
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;
}
static HB_Bool
hb_freetype_can_render(HB_Font font, const HB_UChar16 *chars, hb_uint32 len) {
  FT_Face face = (FT_Face)font->userData;

  size_t i = 0;
  while (i < len) {
    const uint32_t cp = utf16_to_code_point(chars, len, &i);
    if (FT_Get_Char_Index(face, cp) == 0)
      return 0;
  }

  return 1;
}
static HB_Bool
hb_freetype_string_to_glyphs(HB_Font font,
                             const HB_UChar16 *chars, hb_uint32 len,
                             HB_Glyph *glyphs, hb_uint32 *numGlyphs,
                             HB_Bool is_rtl) {
  FT_Face face = (FT_Face) font->userData;
  if (len > *numGlyphs)
    return 0;

  size_t i = 0, j = 0;
  while (i < len) {
    const uint32_t cp = utf16_to_code_point(chars, len, &i);
    glyphs[j++] = FT_Get_Char_Index(face, cp);
  }

  *numGlyphs = j;

  return 1;
}
예제 #4
0
파일: FontLinux.cpp 프로젝트: dzip/webkit
// Return the code point index for the given |x| offset into the text run.
int Font::offsetForPositionForComplexText(const TextRun& run, int x,
                                          bool includePartialGlyphs) const
{
    // (Mac code ignores includePartialGlyphs, and they don't know what it's
    // supposed to do, so we just ignore it as well.)
    TextRunWalker walker(run, 0, this);

    // If this is RTL text, the first glyph from the left is actually the last
    // code point. So we need to know how many code points there are total in
    // order to subtract. This is different from the length of the TextRun
    // because UTF-16 surrogate pairs are a single code point, but 32-bits long.
    // In LTR we leave this as 0 so that we get the correct value for
    // |basePosition|, below.
    unsigned totalCodePoints = 0;
    if (walker.rtl()) {
        ssize_t offset = 0;
        while (offset < run.length()) {
            utf16_to_code_point(run.characters(), run.length(), &offset);
            totalCodePoints++;
        }
    }

    unsigned basePosition = totalCodePoints;

    // For RTL:
    //   code-point order:  abcd efg hijkl
    //   on screen:         lkjih gfe dcba
    //                                ^   ^
    //                                |   |
    //                  basePosition--|   |
    //                 totalCodePoints----|
    // Since basePosition is currently the total number of code-points, the
    // first thing we do is decrement it so that it's pointing to the start of
    // the current script-run.
    //
    // For LTR, basePosition is zero so it already points to the start of the
    // first script run.
    while (walker.nextScriptRun()) {
        if (walker.rtl())
            basePosition -= walker.numCodePoints();

        if (x < walker.width()) {
            // The x value in question is within this script run. We consider
            // each glyph in presentation order and stop when we find the one
            // covering this position.
            const int glyphIndex = glyphIndexForXPositionInScriptRun(walker, x);

            // Now that we have a glyph index, we have to turn that into a
            // code-point index. Because of ligatures, several code-points may
            // have gone into a single glyph. We iterate over the clusters log
            // and find the first code-point which contributed to the glyph.

            // Some shapers (i.e. Khmer) will produce cluster logs which report
            // that /no/ code points contributed to certain glyphs. Because of
            // this, we take any code point which contributed to the glyph in
            // question, or any subsequent glyph. If we run off the end, then
            // we take the last code point.
            const unsigned short* log = walker.logClusters();
            for (unsigned j = 0; j < walker.numCodePoints(); ++j) {
                if (log[j] >= glyphIndex)
                    return basePosition + j;
            }

            return basePosition + walker.numCodePoints() - 1;
        }

        x -= walker.width();

        if (!walker.rtl())
            basePosition += walker.numCodePoints();
    }

    return basePosition;
}