Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / thebes / gfxOTSUtils.h
blobe73fe264bb358e621774a57e647c796e1f956e3a
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef GFX_OTS_UTILS_H
7 #define GFX_OTS_UTILS_H
9 #include "gfxFontUtils.h"
11 #include "opentype-sanitiser.h"
13 struct gfxOTSMozAlloc {
14 void* Grow(void* aPtr, size_t aLength) { return moz_xrealloc(aPtr, aLength); }
15 void* ShrinkToFit(void* aPtr, size_t aLength) {
16 return moz_xrealloc(aPtr, aLength);
18 void Free(void* aPtr) { free(aPtr); }
21 // Based on ots::ExpandingMemoryStream from ots-memory-stream.h,
22 // adapted to use Mozilla allocators and to allow the final
23 // memory buffer to be adopted by the client.
24 template <typename AllocT = gfxOTSMozAlloc>
25 class gfxOTSExpandingMemoryStream : public ots::OTSStream {
26 public:
27 // limit output/expansion to 256MB by default
28 enum { DEFAULT_LIMIT = 256 * 1024 * 1024 };
30 explicit gfxOTSExpandingMemoryStream(size_t initial,
31 size_t limit = DEFAULT_LIMIT)
32 : mLength(initial), mLimit(limit), mOff(0) {
33 mPtr = mAlloc.Grow(nullptr, mLength);
36 ~gfxOTSExpandingMemoryStream() { mAlloc.Free(mPtr); }
38 size_t size() override { return mLimit; }
40 // Return the buffer, resized to fit its contents (as it may have been
41 // over-allocated during growth), and give up ownership of it so the
42 // caller becomes responsible to call free() when finished with it.
43 auto forget() {
44 auto p = mAlloc.ShrinkToFit(mPtr, mOff);
45 mPtr = nullptr;
46 return p;
49 bool WriteRaw(const void* data, size_t length) override {
50 if ((mOff + length > mLength) ||
51 (mLength > std::numeric_limits<size_t>::max() - mOff)) {
52 if (mLength == mLimit) {
53 return false;
55 size_t newLength = (mLength + 1) * 2;
56 if (newLength < mLength) {
57 return false;
59 if (newLength > mLimit) {
60 newLength = mLimit;
62 mPtr = mAlloc.Grow(mPtr, newLength);
63 mLength = newLength;
64 return WriteRaw(data, length);
66 std::memcpy(static_cast<char*>(mPtr) + mOff, data, length);
67 mOff += length;
68 return true;
71 bool Seek(off_t position) override {
72 if (position < 0) {
73 return false;
75 if (static_cast<size_t>(position) > mLength) {
76 return false;
78 mOff = position;
79 return true;
82 off_t Tell() const override { return mOff; }
84 private:
85 AllocT mAlloc;
86 void* mPtr;
87 size_t mLength;
88 const size_t mLimit;
89 off_t mOff;
92 class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
93 public:
94 gfxOTSContext() {
95 using namespace mozilla;
97 // Whether to apply OTS validation to OpenType Layout tables
98 mCheckOTLTables = StaticPrefs::gfx_downloadable_fonts_otl_validation();
99 // Whether to preserve Variation tables in downloaded fonts
100 mCheckVariationTables =
101 StaticPrefs::gfx_downloadable_fonts_validate_variation_tables();
102 // Whether to preserve color bitmap glyphs
103 mKeepColorBitmaps =
104 StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps();
105 // Whether to preserve SVG glyphs (which can be expensive in Core Text,
106 // so better to drop them if we're not going to render them anyhow).
107 mKeepSVG = StaticPrefs::gfx_font_rendering_opentype_svg_enabled();
110 virtual ots::TableAction GetTableAction(uint32_t aTag) override {
111 // Pass through or validate OTL and Variation tables, depending on prefs.
112 if ((!mCheckOTLTables && (aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
113 aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
114 aTag == TRUETYPE_TAG('G', 'S', 'U', 'B')))) {
115 return ots::TABLE_ACTION_PASSTHRU;
117 auto isVariationTable = [](uint32_t aTag) -> bool {
118 return aTag == TRUETYPE_TAG('a', 'v', 'a', 'r') ||
119 aTag == TRUETYPE_TAG('c', 'v', 'a', 'r') ||
120 aTag == TRUETYPE_TAG('f', 'v', 'a', 'r') ||
121 aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
122 aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
123 aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
124 aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
125 aTag == TRUETYPE_TAG('V', 'V', 'A', 'R');
127 if (!mCheckVariationTables && isVariationTable(aTag)) {
128 return ots::TABLE_ACTION_PASSTHRU;
130 if (!gfxPlatform::HasVariationFontSupport() && isVariationTable(aTag)) {
131 return ots::TABLE_ACTION_DROP;
133 // Preserve SVG table if OpenType-SVG rendering is enabled.
134 if (aTag == TRUETYPE_TAG('S', 'V', 'G', ' ')) {
135 return mKeepSVG ? ots::TABLE_ACTION_PASSTHRU : ots::TABLE_ACTION_DROP;
137 // Preserve BASE table; harfbuzz will sanitize it before using.
138 if (aTag == TRUETYPE_TAG('B', 'A', 'S', 'E')) {
139 return ots::TABLE_ACTION_PASSTHRU;
141 if (mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
142 aTag == TRUETYPE_TAG('C', 'B', 'L', 'C'))) {
143 return ots::TABLE_ACTION_PASSTHRU;
145 return ots::TABLE_ACTION_DEFAULT;
148 static size_t GuessSanitizedFontSize(size_t aLength,
149 gfxUserFontType aFontType,
150 bool aStrict = true) {
151 switch (aFontType) {
152 case GFX_USERFONT_UNKNOWN:
153 // If being permissive of unknown types, make a reasonable guess
154 // at how much room the sanitized font may take, if it passes. Just
155 // enough extra space to accomodate some growth without excessive
156 // bloat in case of large fonts. 1.5x is a reasonable compromise
157 // for growable vectors in general.
158 return aStrict || !aLength ? 0 : (aLength * 3) / 2;
159 case GFX_USERFONT_WOFF:
160 return aLength * 2;
161 case GFX_USERFONT_WOFF2:
162 return aLength * 3;
163 default:
164 return aLength;
168 static size_t GuessSanitizedFontSize(const uint8_t* aData, size_t aLength,
169 bool aStrict = true) {
170 gfxUserFontType fontType =
171 gfxFontUtils::DetermineFontDataType(aData, aLength);
172 return GuessSanitizedFontSize(aLength, fontType, aStrict);
175 private:
176 bool mCheckOTLTables;
177 bool mCheckVariationTables;
178 bool mKeepColorBitmaps;
179 bool mKeepSVG;
182 #endif /* GFX_OTS_UTILS_H */