summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc48
1 files changed, 44 insertions, 4 deletions
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
index 2c11652ffcf..e1710f6bb2a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
@@ -8,12 +8,48 @@
// having to rely on the platform being able to instantiate this font format.
#include <hb.h>
+#include "base/sys_byteorder.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace blink {
+namespace {
+
+FontFormatCheck::COLRVersion determineCOLRVersion(
+ const FontFormatCheck::TableTagsVector& table_tags,
+ const hb_face_t* face) {
+ const hb_tag_t kCOLRTag = HB_TAG('C', 'O', 'L', 'R');
+
+ // Only try to read version if header size is sufficient.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/colr#header
+ const unsigned int kMinCOLRHeaderSize = 14;
+ if (table_tags.size() && table_tags.Contains(kCOLRTag) &&
+ table_tags.Contains(HB_TAG('C', 'P', 'A', 'L'))) {
+ HbScoped<hb_blob_t> table_blob(hb_face_reference_table(face, kCOLRTag));
+ if (hb_blob_get_length(table_blob.get()) < kMinCOLRHeaderSize)
+ return FontFormatCheck::COLRVersion::kNoCOLR;
+
+ unsigned required_bytes_count = 2u;
+ const char* colr_data =
+ hb_blob_get_data(table_blob.get(), &required_bytes_count);
+ if (required_bytes_count < 2u)
+ return FontFormatCheck::COLRVersion::kNoCOLR;
+
+ uint16_t colr_version =
+ base::NetToHost16(*reinterpret_cast<const uint16_t*>(colr_data));
+
+ if (colr_version == 0)
+ return FontFormatCheck::COLRVersion::kCOLRV0;
+ else if (colr_version == 1)
+ return FontFormatCheck::COLRVersion::kCOLRV1;
+ }
+ return FontFormatCheck::COLRVersion::kNoCOLR;
+}
+
+} // namespace
+
FontFormatCheck::FontFormatCheck(sk_sp<SkData> sk_data) {
HbScoped<hb_blob_t> font_blob(hb_blob_create(
reinterpret_cast<const char*>(sk_data->bytes()), sk_data->size(),
@@ -25,6 +61,8 @@ FontFormatCheck::FontFormatCheck(sk_sp<SkData> sk_data) {
table_tags_.resize(table_count);
if (!hb_face_get_table_tags(face.get(), 0, &table_count, table_tags_.data()))
table_tags_.resize(0);
+
+ colr_version_ = determineCOLRVersion(table_tags_, face.get());
}
bool FontFormatCheck::IsVariableFont() {
@@ -37,10 +75,12 @@ bool FontFormatCheck::IsCbdtCblcColorFont() {
table_tags_.Contains(HB_TAG('C', 'B', 'L', 'C'));
}
-bool FontFormatCheck::IsColrCpalColorFont() {
- return table_tags_.size() &&
- table_tags_.Contains(HB_TAG('C', 'O', 'L', 'R')) &&
- table_tags_.Contains(HB_TAG('C', 'P', 'A', 'L'));
+bool FontFormatCheck::IsColrCpalColorFontV0() {
+ return colr_version_ == COLRVersion::kCOLRV0;
+}
+
+bool FontFormatCheck::IsColrCpalColorFontV1() {
+ return colr_version_ == COLRVersion::kCOLRV1;
}
bool FontFormatCheck::IsSbixColorFont() {