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

Side by Side Diff: Source/platform/fonts/opentype/OpenTypeVerticalData.cpp

Issue 617103003: Replace ENABLE_OPENTYPE_VERTICAL implementation with HarfBuzz (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@removeOpenTypeVertical
Patch Set: Additional TestExpectations tweaking for Mac Created 6 years 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) 2012 Koji Ishii <kojiishi@gmail.com> 2 * Copyright (C) 2012 Koji Ishii <kojiishi@gmail.com>
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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24 24
25 #include "config.h" 25 #include "config.h"
26 #if ENABLE(OPENTYPE_VERTICAL)
27 #include "platform/fonts/opentype/OpenTypeVerticalData.h" 26 #include "platform/fonts/opentype/OpenTypeVerticalData.h"
28 27
29 #include "platform/SharedBuffer.h" 28 #include "platform/SharedBuffer.h"
30 #include "platform/fonts/SimpleFontData.h" 29 #include "platform/fonts/SimpleFontData.h"
31 #include "platform/fonts/GlyphPage.h" 30 #include "platform/fonts/GlyphPage.h"
32 #include "platform/fonts/opentype/OpenTypeTypes.h" 31 #include "platform/fonts/opentype/OpenTypeTypes.h"
33 #include "platform/geometry/FloatRect.h" 32 #include "platform/geometry/FloatRect.h"
34 #include "wtf/RefPtr.h" 33 #include "wtf/RefPtr.h"
35 34
36 namespace blink { 35 namespace blink {
37 namespace OpenType { 36 namespace OpenType {
38 37
39 const uint32_t GSUBTag = OT_MAKE_TAG('G', 'S', 'U', 'B');
40 const uint32_t HheaTag = OT_MAKE_TAG('h', 'h', 'e', 'a'); 38 const uint32_t HheaTag = OT_MAKE_TAG('h', 'h', 'e', 'a');
41 const uint32_t HmtxTag = OT_MAKE_TAG('h', 'm', 't', 'x'); 39 const uint32_t HmtxTag = OT_MAKE_TAG('h', 'm', 't', 'x');
42 const uint32_t VheaTag = OT_MAKE_TAG('v', 'h', 'e', 'a'); 40 const uint32_t VheaTag = OT_MAKE_TAG('v', 'h', 'e', 'a');
43 const uint32_t VmtxTag = OT_MAKE_TAG('v', 'm', 't', 'x'); 41 const uint32_t VmtxTag = OT_MAKE_TAG('v', 'm', 't', 'x');
44 const uint32_t VORGTag = OT_MAKE_TAG('V', 'O', 'R', 'G'); 42 const uint32_t VORGTag = OT_MAKE_TAG('V', 'O', 'R', 'G');
45 43
46 const uint32_t DefaultScriptTag = OT_MAKE_TAG('D', 'F', 'L', 'T');
47
48 const uint32_t VertFeatureTag = OT_MAKE_TAG('v', 'e', 'r', 't');
49
50 #pragma pack(1) 44 #pragma pack(1)
51 45
52 struct HheaTable { 46 struct HheaTable {
53 OpenType::Fixed version; 47 OpenType::Fixed version;
54 OpenType::Int16 ascender; 48 OpenType::Int16 ascender;
55 OpenType::Int16 descender; 49 OpenType::Int16 descender;
56 OpenType::Int16 lineGap; 50 OpenType::Int16 lineGap;
57 OpenType::Int16 advanceWidthMax; 51 OpenType::Int16 advanceWidthMax;
58 OpenType::Int16 minLeftSideBearing; 52 OpenType::Int16 minLeftSideBearing;
59 OpenType::Int16 minRightSideBearing; 53 OpenType::Int16 minRightSideBearing;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 OpenType::Int16 defaultVertOriginY; 97 OpenType::Int16 defaultVertOriginY;
104 OpenType::UInt16 numVertOriginYMetrics; 98 OpenType::UInt16 numVertOriginYMetrics;
105 struct VertOriginYMetrics { 99 struct VertOriginYMetrics {
106 OpenType::UInt16 glyphIndex; 100 OpenType::UInt16 glyphIndex;
107 OpenType::Int16 vertOriginY; 101 OpenType::Int16 vertOriginY;
108 } vertOriginYMetrics[1]; 102 } vertOriginYMetrics[1];
109 103
110 size_t requiredSize() const { return sizeof(*this) + sizeof(VertOriginYMetri cs) * (numVertOriginYMetrics - 1); } 104 size_t requiredSize() const { return sizeof(*this) + sizeof(VertOriginYMetri cs) * (numVertOriginYMetrics - 1); }
111 }; 105 };
112 106
113 struct CoverageTable : TableBase {
114 OpenType::UInt16 coverageFormat;
115 };
116
117 struct Coverage1Table : CoverageTable {
118 OpenType::UInt16 glyphCount;
119 OpenType::GlyphID glyphArray[1];
120 };
121
122 struct Coverage2Table : CoverageTable {
123 OpenType::UInt16 rangeCount;
124 struct RangeRecord {
125 OpenType::GlyphID start;
126 OpenType::GlyphID end;
127 OpenType::UInt16 startCoverageIndex;
128 } ranges[1];
129 };
130
131 struct SubstitutionSubTable : TableBase {
132 OpenType::UInt16 substFormat;
133 OpenType::Offset coverageOffset;
134
135 const CoverageTable* coverage(const SharedBuffer& buffer) const { return val idateOffset<CoverageTable>(buffer, coverageOffset); }
136 };
137
138 struct SingleSubstitution2SubTable : SubstitutionSubTable {
139 OpenType::UInt16 glyphCount;
140 OpenType::GlyphID substitute[1];
141 };
142
143 struct LookupTable : TableBase {
144 OpenType::UInt16 lookupType;
145 OpenType::UInt16 lookupFlag;
146 OpenType::UInt16 subTableCount;
147 OpenType::Offset subTableOffsets[1];
148 // OpenType::UInt16 markFilteringSet; this field comes after variable length , so offset is determined dynamically.
149
150 bool getSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer ) const
151 {
152 uint16_t countSubTable = subTableCount;
153 if (!isValidEnd(buffer, &subTableOffsets[countSubTable]))
154 return false;
155 if (lookupType != 1) // "Single Substitution Subtable" is all what we su pport
156 return false;
157 for (uint16_t i = 0; i < countSubTable; ++i) {
158 const SubstitutionSubTable* substitution = validateOffset<Substituti onSubTable>(buffer, subTableOffsets[i]);
159 if (!substitution)
160 return false;
161 const CoverageTable* coverage = substitution->coverage(buffer);
162 if (!coverage)
163 return false;
164 if (substitution->substFormat != 2) // "Single Substitution Format 2 " is all what we support
165 return false;
166 const SingleSubstitution2SubTable* singleSubstitution2 = validatePtr <SingleSubstitution2SubTable>(buffer, substitution);
167 if (!singleSubstitution2)
168 return false;
169 uint16_t countTo = singleSubstitution2->glyphCount;
170 if (!isValidEnd(buffer, &singleSubstitution2->substitute[countTo]))
171 return false;
172 switch (coverage->coverageFormat) {
173 case 1: { // Coverage Format 1 (e.g., MS Gothic)
174 const Coverage1Table* coverage1 = validatePtr<Coverage1Table>(bu ffer, coverage);
175 if (!coverage1)
176 return false;
177 uint16_t countFrom = coverage1->glyphCount;
178 if (!isValidEnd(buffer, &coverage1->glyphArray[countFrom]) || co untTo != countFrom)
179 return false;
180 for (uint16_t i = 0; i < countTo; ++i)
181 map->set(coverage1->glyphArray[i], singleSubstitution2->subs titute[i]);
182 break;
183 }
184 case 2: { // Coverage Format 2 (e.g., Adobe Kozuka Gothic)
185 const Coverage2Table* coverage2 = validatePtr<Coverage2Table>(bu ffer, coverage);
186 if (!coverage2)
187 return false;
188 uint16_t countRange = coverage2->rangeCount;
189 if (!isValidEnd(buffer, &coverage2->ranges[countRange]))
190 return false;
191 for (uint16_t i = 0, indexTo = 0; i < countRange; ++i) {
192 uint16_t from = coverage2->ranges[i].start;
193 uint16_t fromEnd = coverage2->ranges[i].end + 1; // OpenType "end" is inclusive
194 if (indexTo + (fromEnd - from) > countTo)
195 return false;
196 for (; from != fromEnd; ++from, ++indexTo)
197 map->set(from, singleSubstitution2->substitute[indexTo]) ;
198 }
199 break;
200 }
201 default:
202 return false;
203 }
204 }
205 return true;
206 }
207 };
208
209 struct LookupList : TableBase {
210 OpenType::UInt16 lookupCount;
211 OpenType::Offset lookupOffsets[1];
212
213 const LookupTable* lookup(uint16_t index, const SharedBuffer& buffer) const
214 {
215 uint16_t count = lookupCount;
216 if (index >= count || !isValidEnd(buffer, &lookupOffsets[count]))
217 return 0;
218 return validateOffset<LookupTable>(buffer, lookupOffsets[index]);
219 }
220 };
221
222 struct FeatureTable : TableBase {
223 OpenType::Offset featureParams;
224 OpenType::UInt16 lookupCount;
225 OpenType::UInt16 lookupListIndex[1];
226
227 bool getGlyphSubstitutions(const LookupList* lookups, HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const
228 {
229 uint16_t count = lookupCount;
230 if (!isValidEnd(buffer, &lookupListIndex[count]))
231 return false;
232 for (uint16_t i = 0; i < count; ++i) {
233 const LookupTable* lookup = lookups->lookup(lookupListIndex[i], buff er);
234 if (!lookup || !lookup->getSubstitutions(map, buffer))
235 return false;
236 }
237 return true;
238 }
239 };
240
241 struct FeatureList : TableBase {
242 OpenType::UInt16 featureCount;
243 struct FeatureRecord {
244 OpenType::Tag featureTag;
245 OpenType::Offset featureOffset;
246 } features[1];
247
248 const FeatureTable* feature(uint16_t index, OpenType::Tag tag, const SharedB uffer& buffer) const
249 {
250 uint16_t count = featureCount;
251 if (index >= count || !isValidEnd(buffer, &features[count]))
252 return 0;
253 if (features[index].featureTag == tag)
254 return validateOffset<FeatureTable>(buffer, features[index].featureO ffset);
255 return 0;
256 }
257
258 const FeatureTable* findFeature(OpenType::Tag tag, const SharedBuffer& buffe r) const
259 {
260 for (uint16_t i = 0; i < featureCount; ++i) {
261 if (isValidEnd(buffer, &features[i]) && features[i].featureTag == ta g)
262 return validateOffset<FeatureTable>(buffer, features[i].featureO ffset);
263 }
264 return 0;
265 }
266 };
267
268 struct LangSysTable : TableBase {
269 OpenType::Offset lookupOrder;
270 OpenType::UInt16 reqFeatureIndex;
271 OpenType::UInt16 featureCount;
272 OpenType::UInt16 featureIndex[1];
273
274 const FeatureTable* feature(OpenType::Tag featureTag, const FeatureList* fea tures, const SharedBuffer& buffer) const
275 {
276 uint16_t count = featureCount;
277 if (!isValidEnd(buffer, &featureIndex[count]))
278 return 0;
279 for (uint16_t i = 0; i < count; ++i) {
280 const FeatureTable* featureTable = features->feature(featureIndex[i] , featureTag, buffer);
281 if (featureTable)
282 return featureTable;
283 }
284 return 0;
285 }
286 };
287
288 struct ScriptTable : TableBase {
289 OpenType::Offset defaultLangSysOffset;
290 OpenType::UInt16 langSysCount;
291 struct LangSysRecord {
292 OpenType::Tag langSysTag;
293 OpenType::Offset langSysOffset;
294 } langSysRecords[1];
295
296 const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const
297 {
298 uint16_t count = langSysCount;
299 if (!isValidEnd(buffer, &langSysRecords[count]))
300 return 0;
301 uint16_t offset = defaultLangSysOffset;
302 if (offset)
303 return validateOffset<LangSysTable>(buffer, offset);
304 if (count)
305 return validateOffset<LangSysTable>(buffer, langSysRecords[0].langSy sOffset);
306 return 0;
307 }
308 };
309
310 struct ScriptList : TableBase {
311 OpenType::UInt16 scriptCount;
312 struct ScriptRecord {
313 OpenType::Tag scriptTag;
314 OpenType::Offset scriptOffset;
315 } scripts[1];
316
317 const ScriptTable* script(OpenType::Tag tag, const SharedBuffer& buffer) con st
318 {
319 uint16_t count = scriptCount;
320 if (!isValidEnd(buffer, &scripts[count]))
321 return 0;
322 for (uint16_t i = 0; i < count; ++i) {
323 if (scripts[i].scriptTag == tag)
324 return validateOffset<ScriptTable>(buffer, scripts[i].scriptOffs et);
325 }
326 return 0;
327 }
328
329 const ScriptTable* defaultScript(const SharedBuffer& buffer) const
330 {
331 uint16_t count = scriptCount;
332 if (!count || !isValidEnd(buffer, &scripts[count]))
333 return 0;
334 const ScriptTable* scriptOfDefaultTag = script(OpenType::DefaultScriptTa g, buffer);
335 if (scriptOfDefaultTag)
336 return scriptOfDefaultTag;
337 return validateOffset<ScriptTable>(buffer, scripts[0].scriptOffset);
338 }
339
340 const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const
341 {
342 const ScriptTable* scriptTable = defaultScript(buffer);
343 if (!scriptTable)
344 return 0;
345 return scriptTable->defaultLangSys(buffer);
346 }
347 };
348
349 struct GSUBTable : TableBase {
350 OpenType::Fixed version;
351 OpenType::Offset scriptListOffset;
352 OpenType::Offset featureListOffset;
353 OpenType::Offset lookupListOffset;
354
355 const ScriptList* scriptList(const SharedBuffer& buffer) const { return vali dateOffset<ScriptList>(buffer, scriptListOffset); }
356 const FeatureList* featureList(const SharedBuffer& buffer) const { return va lidateOffset<FeatureList>(buffer, featureListOffset); }
357 const LookupList* lookupList(const SharedBuffer& buffer) const { return vali dateOffset<LookupList>(buffer, lookupListOffset); }
358
359 const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const
360 {
361 const ScriptList* scripts = scriptList(buffer);
362 if (!scripts)
363 return 0;
364 return scripts->defaultLangSys(buffer);
365 }
366
367 const FeatureTable* feature(OpenType::Tag featureTag, const SharedBuffer& bu ffer) const
368 {
369 const LangSysTable* langSys = defaultLangSys(buffer);
370 const FeatureList* features = featureList(buffer);
371 if (!features)
372 return 0;
373 const FeatureTable* feature = 0;
374 if (langSys)
375 feature = langSys->feature(featureTag, features, buffer);
376 if (!feature) {
377 // If the font has no langSys table, or has no default script and th e first script doesn't
378 // have the requested feature, then use the first matching feature d irectly.
379 feature = features->findFeature(featureTag, buffer);
380 }
381 return feature;
382 }
383
384 bool getVerticalGlyphSubstitutions(HashMap<Glyph, Glyph>* map, const SharedB uffer& buffer) const
385 {
386 const FeatureTable* verticalFeatureTable = feature(OpenType::VertFeature Tag, buffer);
387 if (!verticalFeatureTable)
388 return false;
389 const LookupList* lookups = lookupList(buffer);
390 return lookups && verticalFeatureTable->getGlyphSubstitutions(lookups, m ap, buffer);
391 }
392 };
393
394 #pragma pack() 107 #pragma pack()
395 108
396 } // namespace OpenType 109 } // namespace OpenType
397 110
398 OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) 111 OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData)
399 : m_defaultVertOriginY(0) 112 : m_defaultVertOriginY(0)
400 { 113 {
401 loadMetrics(platformData); 114 loadMetrics(platformData);
402 loadVerticalGlyphSubstitutions(platformData);
403 } 115 }
404 116
405 void OpenTypeVerticalData::loadMetrics(const FontPlatformData& platformData) 117 void OpenTypeVerticalData::loadMetrics(const FontPlatformData& platformData)
406 { 118 {
407 // Load hhea and hmtx to get x-component of vertical origins. 119 // Load hhea and hmtx to get x-component of vertical origins.
408 // If these tables are missing, it's not an OpenType font. 120 // If these tables are missing, it's not an OpenType font.
409 RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::HheaTag); 121 RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::HheaTag);
410 const OpenType::HheaTable* hhea = OpenType::validateTable<OpenType::HheaTabl e>(buffer); 122 const OpenType::HheaTable* hhea = OpenType::validateTable<OpenType::HheaTabl e>(buffer);
411 if (!hhea) 123 if (!hhea)
412 return; 124 return;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 size_t i; 192 size_t i;
481 for (i = 0; i < countVmtxEntries; ++i) 193 for (i = 0; i < countVmtxEntries; ++i)
482 m_topSideBearings[i] = vmtx->entries[i].topSideBearing; 194 m_topSideBearings[i] = vmtx->entries[i].topSideBearing;
483 if (i < countTopSideBearings) { 195 if (i < countTopSideBearings) {
484 const OpenType::Int16* pTopSideBearingsExtra = reinterpret_cast<const Op enType::Int16*>(&vmtx->entries[countVmtxEntries]); 196 const OpenType::Int16* pTopSideBearingsExtra = reinterpret_cast<const Op enType::Int16*>(&vmtx->entries[countVmtxEntries]);
485 for (; i < countTopSideBearings; ++i, ++pTopSideBearingsExtra) 197 for (; i < countTopSideBearings; ++i, ++pTopSideBearingsExtra)
486 m_topSideBearings[i] = *pTopSideBearingsExtra; 198 m_topSideBearings[i] = *pTopSideBearingsExtra;
487 } 199 }
488 } 200 }
489 201
490 void OpenTypeVerticalData::loadVerticalGlyphSubstitutions(const FontPlatformData & platformData)
491 {
492 RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::GSUBTag);
493 const OpenType::GSUBTable* gsub = OpenType::validateTable<OpenType::GSUBTabl e>(buffer);
494 if (gsub)
495 gsub->getVerticalGlyphSubstitutions(&m_verticalGlyphMap, *buffer.get());
496 }
497
498 float OpenTypeVerticalData::advanceHeight(const SimpleFontData* font, Glyph glyp h) const 202 float OpenTypeVerticalData::advanceHeight(const SimpleFontData* font, Glyph glyp h) const
499 { 203 {
500 size_t countHeights = m_advanceHeights.size(); 204 size_t countHeights = m_advanceHeights.size();
501 if (countHeights) { 205 if (countHeights) {
502 uint16_t advanceFUnit = m_advanceHeights[glyph < countHeights ? glyph : countHeights - 1]; 206 uint16_t advanceFUnit = m_advanceHeights[glyph < countHeights ? glyph : countHeights - 1];
503 float advance = advanceFUnit * font->sizePerUnit(); 207 float advance = advanceFUnit * font->sizePerUnit();
504 return advance; 208 return advance;
505 } 209 }
506 210
507 // No vertical info in the font file; use height as advance. 211 // No vertical info in the font file; use height as advance.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 FloatRect bounds = font->boundsForGlyph(glyph); 248 FloatRect bounds = font->boundsForGlyph(glyph);
545 outXYArray[1] = bounds.y() - topSideBearing; 249 outXYArray[1] = bounds.y() - topSideBearing;
546 continue; 250 continue;
547 } 251 }
548 252
549 // No vertical info in the font file; use ascent as vertical origin. 253 // No vertical info in the font file; use ascent as vertical origin.
550 outXYArray[1] = -ascent; 254 outXYArray[1] = -ascent;
551 } 255 }
552 } 256 }
553 257
554 void OpenTypeVerticalData::substituteWithVerticalGlyphs(const SimpleFontData* fo nt, GlyphPage* glyphPage, unsigned offset, unsigned length) const
555 {
556 const HashMap<Glyph, Glyph>& map = m_verticalGlyphMap;
557 if (map.isEmpty())
558 return;
559
560 for (unsigned index = offset, end = offset + length; index < end; ++index) {
561 GlyphData glyphData = glyphPage->glyphDataForIndex(index);
562 if (glyphData.glyph && glyphData.fontData == font) {
563 Glyph to = map.get(glyphData.glyph);
564 if (to)
565 glyphPage->setGlyphDataForIndex(index, to, font);
566 }
567 }
568 }
569
570 } // namespace blink 258 } // namespace blink
571 #endif // ENABLE(OPENTYPE_VERTICAL)
OLDNEW
« no previous file with comments | « Source/platform/fonts/opentype/OpenTypeVerticalData.h ('k') | Source/platform/fonts/shaping/HarfBuzzFace.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698