Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: third_party/WebKit/Source/platform/fonts/WebFontDecoder.cpp

Issue 2032943002: Avoid one temporary copy on web fonts decoding (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 10 matching lines...) Expand all
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "platform/fonts/opentype/OpenTypeSanitizer.h" 31 #include "platform/fonts/WebFontDecoder.h"
32 32
33 #include "hb.h"
34 #include "ots-memory-stream.h"
35 #include "platform/Histogram.h" 33 #include "platform/Histogram.h"
36 #include "platform/SharedBuffer.h" 34 #include "platform/SharedBuffer.h"
37 #include "platform/TraceEvent.h" 35 #include "platform/TraceEvent.h"
36 #include "platform/fonts/FontCache.h"
38 #include "public/platform/Platform.h" 37 #include "public/platform/Platform.h"
38 #include "third_party/harfbuzz-ng/src/hb.h"
39 #include "third_party/ots/include/ots-memory-stream.h"
40 #include "third_party/skia/include/core/SkStream.h"
39 #include "wtf/CurrentTime.h" 41 #include "wtf/CurrentTime.h"
40 42
41 #include <stdarg.h> 43 #include <stdarg.h>
42 44
43 namespace blink { 45 namespace blink {
44 46
45 static void recordDecodeSpeedHistogram(SharedBuffer* buffer, double decodeTime, size_t decodedSize) 47 namespace {
46 {
47 if (decodeTime <= 0)
48 return;
49 48
50 double kbPerSecond = decodedSize / (1000 * decodeTime); 49 class BlinkOTSContext final : public ots::OTSContext {
51 if (buffer->size() >= 4) { 50 DISALLOW_NEW();
52 const char* data = buffer->data(); 51 public:
53 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F' ) {
54 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, woffHistogram, new CustomCountHistogram("WebFont.DecodeSpeed.WOFF", 1000, 300000, 50));
55 woffHistogram.count(kbPerSecond);
56 return;
57 }
58 52
59 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2' ) { 53 void Message(int level, const char *format, ...) override;
60 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, woff2Histogram , new CustomCountHistogram("WebFont.DecodeSpeed.WOFF2", 1000, 300000, 50)); 54 ots::TableAction GetTableAction(uint32_t tag) override;
61 woff2Histogram.count(kbPerSecond); 55 const String& getErrorString() { return m_errorString; }
62 return;
63 }
64 }
65 56
66 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, sfntHistogram, new Cus tomCountHistogram("WebFont.DecodeSpeed.SFNT", 1000, 300000, 50)); 57 private:
67 sfntHistogram.count(kbPerSecond); 58 String m_errorString;
68 } 59 };
69
70 PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize()
71 {
72 if (!m_buffer) {
73 setErrorString("Empty Buffer");
74 return nullptr;
75 }
76
77 // This is the largest web font size which we'll try to transcode.
78 static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB
79 if (m_buffer->size() > maxWebFontSize) {
80 setErrorString("Web font size more than 30MB");
81 return nullptr;
82 }
83
84 // A transcoded font is usually smaller than an original font.
85 // However, it can be slightly bigger than the original one due to
86 // name table replacement and/or padding for glyf table.
87 //
88 // With WOFF fonts, however, we'll be decompressing, so the result can be
89 // much larger than the original.
90
91 ots::ExpandingMemoryStream output(m_buffer->size(), maxWebFontSize);
92 double start = currentTime();
93 BlinkOTSContext otsContext;
94
95 TRACE_EVENT_BEGIN0("blink", "DecodeFont");
96 bool ok = otsContext.Process(&output, reinterpret_cast<const uint8_t*>(m_buf fer->data()), m_buffer->size());
97 TRACE_EVENT_END0("blink", "DecodeFont");
98
99 if (!ok) {
100 setErrorString(otsContext.getErrorString());
101 return nullptr;
102 }
103
104 const size_t transcodeLen = output.Tell();
105 recordDecodeSpeedHistogram(m_buffer, currentTime() - start, transcodeLen);
106 return SharedBuffer::create(static_cast<unsigned char*>(output.get()), trans codeLen);
107 }
108
109 bool OpenTypeSanitizer::supportsFormat(const String& format)
110 {
111 return equalIgnoringCase(format, "woff") || equalIgnoringCase(format, "woff2 ");
112 }
113 60
114 void BlinkOTSContext::Message(int level, const char *format, ...) 61 void BlinkOTSContext::Message(int level, const char *format, ...)
115 { 62 {
116 va_list args; 63 va_list args;
117 va_start(args, format); 64 va_start(args, format);
118 65
119 #if COMPILER(MSVC) 66 #if COMPILER(MSVC)
120 int result = _vscprintf(format, args); 67 int result = _vscprintf(format, args);
121 #else 68 #else
122 char ch; 69 char ch;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 case gdefTag: 113 case gdefTag:
167 case gposTag: 114 case gposTag:
168 case gsubTag: 115 case gsubTag:
169 #endif 116 #endif
170 return ots::TABLE_ACTION_PASSTHRU; 117 return ots::TABLE_ACTION_PASSTHRU;
171 default: 118 default:
172 return ots::TABLE_ACTION_DEFAULT; 119 return ots::TABLE_ACTION_DEFAULT;
173 } 120 }
174 } 121 }
175 122
123 void recordDecodeSpeedHistogram(const char* data, size_t length, double decodeTi me, size_t decodedSize)
124 {
125 if (decodeTime <= 0)
126 return;
127
128 double kbPerSecond = decodedSize / (1000 * decodeTime);
129 if (length >= 4) {
130 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F' ) {
131 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, woffHistogram, new CustomCountHistogram("WebFont.DecodeSpeed.WOFF", 1000, 300000, 50));
132 woffHistogram.count(kbPerSecond);
133 return;
134 }
135
136 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2' ) {
137 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, woff2Histogram , new CustomCountHistogram("WebFont.DecodeSpeed.WOFF2", 1000, 300000, 50));
138 woff2Histogram.count(kbPerSecond);
139 return;
140 }
141 }
142
143 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, sfntHistogram, new Cus tomCountHistogram("WebFont.DecodeSpeed.SFNT", 1000, 300000, 50));
144 sfntHistogram.count(kbPerSecond);
145 }
146
147 } // namespace
148
149 // static
150 bool WebFontDecoder::supportsFormat(const String& format)
151 {
152 return equalIgnoringCase(format, "woff") || equalIgnoringCase(format, "woff2 ");
153 }
154
155 PassRefPtr<SkTypeface> WebFontDecoder::decode(SharedBuffer* buffer)
156 {
157 if (!buffer) {
158 setErrorString("Empty Buffer");
159 return nullptr;
160 }
161
162 // This is the largest web font size which we'll try to transcode.
163 // TODO(bashi): 30MB seems low. Update the limit if necessary.
164 static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB
165 if (buffer->size() > maxWebFontSize) {
166 setErrorString("Web font size more than 30MB");
167 return nullptr;
168 }
169
170 // Most web fonts are compressed, so the result can be much larger than
171 // the original.
172 ots::ExpandingMemoryStream output(buffer->size(), maxWebFontSize);
173 double start = currentTime();
174 BlinkOTSContext otsContext;
175 const char* data = buffer->data();
176
177 TRACE_EVENT_BEGIN0("blink", "DecodeFont");
178 bool ok = otsContext.Process(&output, reinterpret_cast<const uint8_t*>(data) , buffer->size());
179 TRACE_EVENT_END0("blink", "DecodeFont");
180
181 if (!ok) {
182 setErrorString(otsContext.getErrorString());
183 return nullptr;
184 }
185
186 const size_t decodedLength = output.Tell();
187 recordDecodeSpeedHistogram(data, buffer->size(), currentTime() - start, deco dedLength);
188
189 sk_sp<SkData> skData = SkData::MakeWithCopy(output.get(), decodedLength);
190 SkMemoryStream* stream = new SkMemoryStream(skData);
191 #if OS(WIN)
192 RefPtr<SkTypeface> typeface = adoptRef(FontCache::fontCache()->fontManager() ->createFromStream(stream));
193 #else
194 RefPtr<SkTypeface> typeface = adoptRef(SkTypeface::CreateFromStream(stream)) ;
195 #endif
196 if (!typeface) {
197 setErrorString("Not a valid font data");
198 return nullptr;
199 }
200
201 return typeface.release();
202 }
203
176 } // namespace blink 204 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698