bool SFNTNameTable::ReadU16Name(const NameRecordMatchers &aMatchers,
                                mozilla::u16string &aU16Name) {
  MOZ_ASSERT(!aMatchers.empty());

  for (size_t i = 0; i < aMatchers.length(); ++i) {
    const NameRecord *record = mFirstRecord;
    while (record != mEndOfRecords) {
      switch (aMatchers[i](record)) {
        case eNameDecoderUTF16:
          return ReadU16NameFromU16Record(record, aU16Name);
#if defined(XP_MACOSX)
        case eNameDecoderMacRoman:
          return ReadU16NameFromMacRomanRecord(record, aU16Name);
#endif
        case eNameDecoderNone:
          break;
        default:
          MOZ_CRASH("Invalid matcher encoding type");
          break;
      }
      ++record;
    }
  }

  return false;
}
bool
SFNTNameTable::ReadU16Name(const NameRecordMatchers& aMatchers,
                           mozilla::u16string& aU16Name)
{
  MOZ_ASSERT(!aMatchers.empty());

  for (size_t i = 0; i < aMatchers.length(); ++i) {
    const NameRecord* record = mFirstRecord;
    while (record != mEndOfRecords) {
      if (aMatchers[i](record)) {
        return ReadU16NameFromRecord(record, aU16Name);
      }
      ++record;
    }
  }

  return false;
}
static NameRecordMatchers*
CreateCanonicalU16Matchers(const BigEndianUint16& aNameID)
{
  NameRecordMatchers *matchers = new NameRecordMatchers();

  // First, look for the English name (this will normally succeed).
  matchers->append(
    [=](const NameRecord *aNameRecord) {
        return aNameRecord->nameID == aNameID &&
               aNameRecord->languageID == CANONICAL_LANG_ID &&
               aNameRecord->platformID == PLATFORM_ID &&
               IsUTF16Encoding(aNameRecord);
    });

  // Second, look for all languages.
  matchers->append(
    [=](const NameRecord *aNameRecord) {
        return aNameRecord->nameID == aNameID &&
               aNameRecord->platformID == PLATFORM_ID &&
               IsUTF16Encoding(aNameRecord);
    });

#if defined(XP_MACOSX)
  // On Mac may be dealing with font that only has Microsoft name entries.
  matchers->append(
    [=](const NameRecord *aNameRecord) {
        return aNameRecord->nameID == aNameID &&
               aNameRecord->languageID == LANG_ID_MICROSOFT_EN_US &&
               aNameRecord->platformID == PLATFORM_ID_MICROSOFT &&
               IsUTF16Encoding(aNameRecord);
    });
  matchers->append(
    [=](const NameRecord *aNameRecord) {
        return aNameRecord->nameID == aNameID &&
               aNameRecord->platformID == PLATFORM_ID_MICROSOFT &&
               IsUTF16Encoding(aNameRecord);
    });
#endif

  return matchers;
}
static NameRecordMatchers *CreateCanonicalMatchers(
    const BigEndianUint16 &aNameID) {
  // For Windows, we return only Microsoft platform name record
  // matchers. On Mac, we return matchers for both Microsoft platform
  // records and Mac platform records.
  NameRecordMatchers *matchers = new NameRecordMatchers();

#if defined(XP_MACOSX)
  // First, look for the English name.
  if (!matchers->append([=](const NameRecord *aNameRecord) {
        if (aNameRecord->nameID == aNameID &&
            aNameRecord->languageID == LANG_ID_MAC_ENGLISH &&
            aNameRecord->platformID == PLATFORM_ID_MAC &&
            IsMacRomanEncoding(aNameRecord)) {
          return eNameDecoderMacRoman;
        } else {
          return eNameDecoderNone;
        }
      })) {
    MOZ_CRASH();
  }

  // Second, look for all languages.
  if (!matchers->append([=](const NameRecord *aNameRecord) {
        if (aNameRecord->nameID == aNameID &&
            aNameRecord->platformID == PLATFORM_ID_MAC &&
            IsMacRomanEncoding(aNameRecord)) {
          return eNameDecoderMacRoman;
        } else {
          return eNameDecoderNone;
        }
      })) {
    MOZ_CRASH();
  }
#endif /* defined(XP_MACOSX) */

  // First, look for the English name (this will normally succeed).
  if (!matchers->append([=](const NameRecord *aNameRecord) {
        if (aNameRecord->nameID == aNameID &&
            aNameRecord->languageID == LANG_ID_MICROSOFT_EN_US &&
            aNameRecord->platformID == PLATFORM_ID_MICROSOFT &&
            IsUTF16Encoding(aNameRecord)) {
          return eNameDecoderUTF16;
        } else {
          return eNameDecoderNone;
        }
      })) {
    MOZ_CRASH();
  }

  // Second, look for all languages.
  if (!matchers->append([=](const NameRecord *aNameRecord) {
        if (aNameRecord->nameID == aNameID &&
            aNameRecord->platformID == PLATFORM_ID_MICROSOFT &&
            IsUTF16Encoding(aNameRecord)) {
          return eNameDecoderUTF16;
        } else {
          return eNameDecoderNone;
        }
      })) {
    MOZ_CRASH();
  }

  return matchers;
}