Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
SkOTTableName::Iterator Class Reference

#include <SkOTTable_name.h>

Classes

struct  Record
 

Public Member Functions

 Iterator (const uint8_t *nameTable, size_t size)
 
 Iterator (const uint8_t *nameTable, size_t size, SK_OT_USHORT type)
 
void reset (SK_OT_USHORT type)
 
bool next (Record &)
 

Detailed Description

Definition at line 544 of file SkOTTable_name.h.

Constructor & Destructor Documentation

◆ Iterator() [1/2]

SkOTTableName::Iterator::Iterator ( const uint8_t *  nameTable,
size_t  size 
)
inline

Definition at line 546 of file SkOTTable_name.h.

547 : fNameTable(nameTable), fNameTableSize(size), fIndex(0), fType(-1) { }

◆ Iterator() [2/2]

SkOTTableName::Iterator::Iterator ( const uint8_t *  nameTable,
size_t  size,
SK_OT_USHORT  type 
)
inline

Definition at line 548 of file SkOTTable_name.h.

549 : fNameTable(nameTable), fNameTableSize(size), fIndex(0), fType(type)
550 { }

Member Function Documentation

◆ next()

bool SkOTTableName::Iterator::next ( Record record)

Definition at line 457 of file SkOTTable_name.cpp.

457 {
458 SkOTTableName nameTable;
459 if (fNameTableSize < sizeof(nameTable)) {
460 return false;
461 }
462 memcpy(&nameTable, fNameTable, sizeof(nameTable));
463
464 const uint8_t* nameRecords = fNameTable + sizeof(nameTable);
465 const size_t nameRecordsSize = fNameTableSize - sizeof(nameTable);
466
467 const size_t stringTableOffset = SkEndian_SwapBE16(nameTable.stringOffset);
468 if (fNameTableSize < stringTableOffset) {
469 return false;
470 }
471 const uint8_t* stringTable = fNameTable + stringTableOffset;
472 const size_t stringTableSize = fNameTableSize - stringTableOffset;
473
474 // Find the next record which matches the requested type.
475 SkOTTableName::Record nameRecord;
476 const size_t nameRecordsCount = SkEndian_SwapBE16(nameTable.count);
477 const size_t nameRecordsMax = std::min(nameRecordsCount, nameRecordsSize / sizeof(nameRecord));
478 do {
479 if (fIndex >= nameRecordsMax) {
480 return false;
481 }
482
483 memcpy(&nameRecord, nameRecords + sizeof(nameRecord)*fIndex, sizeof(nameRecord));
484 ++fIndex;
485 } while (fType != -1 && nameRecord.nameID.fontSpecific != fType);
486
487 record.type = nameRecord.nameID.fontSpecific;
488
489 // Decode the name into UTF-8.
490 const size_t nameOffset = SkEndian_SwapBE16(nameRecord.offset);
491 const size_t nameLength = SkEndian_SwapBE16(nameRecord.length);
492 if (stringTableSize < nameOffset + nameLength) {
493 return false; // continue?
494 }
495 const uint8_t* nameString = stringTable + nameOffset;
496 switch (nameRecord.platformID.value) {
499 != nameRecord.encodingID.windows.value
501 != nameRecord.encodingID.windows.value
503 != nameRecord.encodingID.windows.value)
504 {
505 record.name.reset();
506 break; // continue?
507 }
508 [[fallthrough]];
511 SkString_from_UTF16BE(nameString, nameLength, record.name);
512 break;
513
515 // TODO: need better decoding, especially on Mac.
517 != nameRecord.encodingID.macintosh.value)
518 {
519 record.name.reset();
520 break; // continue?
521 }
522 SkStringFromMacRoman(nameString, nameLength, record.name);
523 break;
524
526 // These should never appear in a 'name' table.
527 default:
528 SkASSERT(false);
529 record.name.reset();
530 break; // continue?
531 }
532
533 // Determine the language.
534 const uint16_t languageID = SkEndian_SwapBE16(nameRecord.languageID.languageTagID);
535
536 // Handle format 1 languages.
537 if (SkOTTableName::format_1 == nameTable.format && languageID >= 0x8000) {
538 const uint16_t languageTagRecordIndex = languageID - 0x8000;
539
540 if (nameRecordsSize < sizeof(nameRecord)*nameRecordsCount) {
541 return false; //"und" or break?
542 }
543 const uint8_t* format1extData = nameRecords + sizeof(nameRecord)*nameRecordsCount;
544 size_t format1extSize = nameRecordsSize - sizeof(nameRecord)*nameRecordsCount;
545 SkOTTableName::Format1Ext format1ext;
546 if (format1extSize < sizeof(format1ext)) {
547 return false; // "und" or break?
548 }
549 memcpy(&format1ext, format1extData, sizeof(format1ext));
550
551 const uint8_t* languageTagRecords = format1extData + sizeof(format1ext);
552 size_t languageTagRecordsSize = format1extSize - sizeof(format1ext);
553 if (languageTagRecordIndex < SkEndian_SwapBE16(format1ext.langTagCount)) {
555 if (languageTagRecordsSize < sizeof(languageTagRecord)*(languageTagRecordIndex+1)) {
556 return false; // "und"?
557 }
558 const uint8_t* languageTagData = languageTagRecords
559 + sizeof(languageTagRecord)*languageTagRecordIndex;
560 memcpy(&languageTagRecord, languageTagData, sizeof(languageTagRecord));
561
562 uint16_t languageOffset = SkEndian_SwapBE16(languageTagRecord.offset);
563 uint16_t languageLength = SkEndian_SwapBE16(languageTagRecord.length);
564
565 if (fNameTableSize < stringTableOffset + languageOffset + languageLength) {
566 return false; // "und"?
567 }
568 const uint8_t* languageString = stringTable + languageOffset;
569 SkString_from_UTF16BE(languageString, languageLength, record.language);
570 return true;
571 }
572 }
573
574 // Handle format 0 languages, translating them into BCP 47.
575 const BCP47FromLanguageId target = { languageID, "" };
576 int languageIndex = SkTSearch<BCP47FromLanguageId, BCP47FromLanguageIdLess>(
578 if (languageIndex >= 0) {
579 record.language = BCP47FromLanguageID[languageIndex].bcp47;
580 return true;
581 }
582
583 // Unknown language, return the BCP 47 code 'und' for 'undetermined'.
584 record.language = "und";
585 return true;
586}
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkEndian_SwapBE16(n)
Definition SkEndian.h:135
static const struct BCP47FromLanguageId BCP47FromLanguageID[]
static void SkStringFromMacRoman(const uint8_t *macRoman, size_t length, SkString &utf8)
static void SkString_from_UTF16BE(const uint8_t *utf16be, size_t length, SkString &utf8)
uint32_t * target
enum SkOTTableName::Record::EncodingID::Macintosh::Value value
enum SkOTTableName::Record::EncodingID::Windows::Value value
enum SkOTTableName::Record::PlatformID::Value value
struct SkOTTableName::Record::PlatformID platformID
union SkOTTableName::Record::NameID nameID
union SkOTTableName::Record::LanguageID languageID
union SkOTTableName::Record::EncodingID encodingID
SK_OT_USHORT stringOffset
SK_OT_USHORT format
static const SK_OT_USHORT format_1
SK_OT_USHORT count
struct SkOTTableName::Record::EncodingID::Windows windows
struct SkOTTableName::Record::EncodingID::Macintosh macintosh

◆ reset()

void SkOTTableName::Iterator::reset ( SK_OT_USHORT  type)
inline

Definition at line 552 of file SkOTTable_name.h.

552 {
553 fIndex = 0;
554 fType = type;
555 }

The documentation for this class was generated from the following files: