15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Koji Ishii <kojiishi@gmail.com> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(OPENTYPE_VERTICAL) 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/opentype/OpenTypeVerticalData.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/SharedBuffer.h" 30a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/SimpleFontData.h" 3119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "platform/fonts/GlyphPage.h" 3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/fonts/opentype/OpenTypeTypes.h" 331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatRect.h" 347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/RefPtr.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace OpenType { 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t GSUBTag = OT_MAKE_TAG('G', 'S', 'U', 'B'); 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t HheaTag = OT_MAKE_TAG('h', 'h', 'e', 'a'); 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t HmtxTag = OT_MAKE_TAG('h', 'm', 't', 'x'); 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t VheaTag = OT_MAKE_TAG('v', 'h', 'e', 'a'); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t VmtxTag = OT_MAKE_TAG('v', 'm', 't', 'x'); 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t VORGTag = OT_MAKE_TAG('V', 'O', 'R', 'G'); 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t DefaultScriptTag = OT_MAKE_TAG('D', 'F', 'L', 'T'); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t VertFeatureTag = OT_MAKE_TAG('v', 'e', 'r', 't'); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#pragma pack(1) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct HheaTable { 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Fixed version; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 ascender; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 descender; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 lineGap; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 advanceWidthMax; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 minLeftSideBearing; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 minRightSideBearing; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 xMaxExtent; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretSlopeRise; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretSlopeRun; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretOffset; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 reserved[4]; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 metricDataFormat; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 numberOfHMetrics; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct VheaTable { 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Fixed version; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 ascent; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 descent; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 lineGap; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 advanceHeightMax; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 minTopSideBearing; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 minBottomSideBearing; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 yMaxExtent; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretSlopeRise; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretSlopeRun; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 caretOffset; 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 reserved[4]; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 metricDataFormat; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 numOfLongVerMetrics; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct HmtxTable { 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct Entry { 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 advanceWidth; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 lsb; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } entries[1]; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct VmtxTable { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct Entry { 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 advanceHeight; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 topSideBearing; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } entries[1]; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct VORGTable { 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 majorVersion; 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 minorVersion; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 defaultVertOriginY; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 numVertOriginYMetrics; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct VertOriginYMetrics { 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 glyphIndex; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Int16 vertOriginY; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } vertOriginYMetrics[1]; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t requiredSize() const { return sizeof(*this) + sizeof(VertOriginYMetrics) * (numVertOriginYMetrics - 1); } 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct CoverageTable : TableBase { 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 coverageFormat; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct Coverage1Table : CoverageTable { 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 glyphCount; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::GlyphID glyphArray[1]; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct Coverage2Table : CoverageTable { 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 rangeCount; 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct RangeRecord { 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::GlyphID start; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::GlyphID end; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 startCoverageIndex; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } ranges[1]; 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct SubstitutionSubTable : TableBase { 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 substFormat; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset coverageOffset; 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CoverageTable* coverage(const SharedBuffer& buffer) const { return validateOffset<CoverageTable>(buffer, coverageOffset); } 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct SingleSubstitution2SubTable : SubstitutionSubTable { 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 glyphCount; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::GlyphID substitute[1]; 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct LookupTable : TableBase { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 lookupType; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 lookupFlag; 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 subTableCount; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset subTableOffsets[1]; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // OpenType::UInt16 markFilteringSet; this field comes after variable length, so offset is determined dynamically. 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool getSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countSubTable = subTableCount; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &subTableOffsets[countSubTable])) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lookupType != 1) // "Single Substitution Subtable" is all what we support 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < countSubTable; ++i) { 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SubstitutionSubTable* substitution = validateOffset<SubstitutionSubTable>(buffer, subTableOffsets[i]); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!substitution) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CoverageTable* coverage = substitution->coverage(buffer); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!coverage) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (substitution->substFormat != 2) // "Single Substitution Format 2" is all what we support 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SingleSubstitution2SubTable* singleSubstitution2 = validatePtr<SingleSubstitution2SubTable>(buffer, substitution); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!singleSubstitution2) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countTo = singleSubstitution2->glyphCount; 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &singleSubstitution2->substitute[countTo])) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (coverage->coverageFormat) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 1: { // Coverage Format 1 (e.g., MS Gothic) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Coverage1Table* coverage1 = validatePtr<Coverage1Table>(buffer, coverage); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!coverage1) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countFrom = coverage1->glyphCount; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &coverage1->glyphArray[countFrom]) || countTo != countFrom) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < countTo; ++i) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) map->set(coverage1->glyphArray[i], singleSubstitution2->substitute[i]); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 2: { // Coverage Format 2 (e.g., Adobe Kozuka Gothic) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Coverage2Table* coverage2 = validatePtr<Coverage2Table>(buffer, coverage); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!coverage2) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countRange = coverage2->rangeCount; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &coverage2->ranges[countRange])) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0, indexTo = 0; i < countRange; ++i) { 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t from = coverage2->ranges[i].start; 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t fromEnd = coverage2->ranges[i].end + 1; // OpenType "end" is inclusive 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (indexTo + (fromEnd - from) > countTo) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (; from != fromEnd; ++from, ++indexTo) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) map->set(from, singleSubstitution2->substitute[indexTo]); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct LookupList : TableBase { 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 lookupCount; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset lookupOffsets[1]; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LookupTable* lookup(uint16_t index, const SharedBuffer& buffer) const 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = lookupCount; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index >= count || !isValidEnd(buffer, &lookupOffsets[count])) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<LookupTable>(buffer, lookupOffsets[index]); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct FeatureTable : TableBase { 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset featureParams; 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 lookupCount; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 lookupListIndex[1]; 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool getGlyphSubstitutions(const LookupList* lookups, HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = lookupCount; 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &lookupListIndex[count])) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < count; ++i) { 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LookupTable* lookup = lookups->lookup(lookupListIndex[i], buffer); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lookup || !lookup->getSubstitutions(map, buffer)) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct FeatureList : TableBase { 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 featureCount; 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct FeatureRecord { 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Tag featureTag; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset featureOffset; 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } features[1]; 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* feature(uint16_t index, OpenType::Tag tag, const SharedBuffer& buffer) const 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = featureCount; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index >= count || !isValidEnd(buffer, &features[count])) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (features[index].featureTag == tag) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<FeatureTable>(buffer, features[index].featureOffset); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* findFeature(OpenType::Tag tag, const SharedBuffer& buffer) const 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < featureCount; ++i) { 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isValidEnd(buffer, &features[i]) && features[i].featureTag == tag) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<FeatureTable>(buffer, features[i].featureOffset); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct LangSysTable : TableBase { 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset lookupOrder; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 reqFeatureIndex; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 featureCount; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 featureIndex[1]; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* feature(OpenType::Tag featureTag, const FeatureList* features, const SharedBuffer& buffer) const 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = featureCount; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &featureIndex[count])) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < count; ++i) { 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* featureTable = features->feature(featureIndex[i], featureTag, buffer); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (featureTable) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return featureTable; 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct ScriptTable : TableBase { 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset defaultLangSysOffset; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 langSysCount; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct LangSysRecord { 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Tag langSysTag; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset langSysOffset; 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } langSysRecords[1]; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = langSysCount; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &langSysRecords[count])) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t offset = defaultLangSysOffset; 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (offset) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<LangSysTable>(buffer, offset); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (count) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<LangSysTable>(buffer, langSysRecords[0].langSysOffset); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct ScriptList : TableBase { 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::UInt16 scriptCount; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct ScriptRecord { 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Tag scriptTag; 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset scriptOffset; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } scripts[1]; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptTable* script(OpenType::Tag tag, const SharedBuffer& buffer) const 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = scriptCount; 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isValidEnd(buffer, &scripts[count])) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < count; ++i) { 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (scripts[i].scriptTag == tag) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<ScriptTable>(buffer, scripts[i].scriptOffset); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptTable* defaultScript(const SharedBuffer& buffer) const 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t count = scriptCount; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!count || !isValidEnd(buffer, &scripts[count])) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptTable* scriptOfDefaultTag = script(OpenType::DefaultScriptTag, buffer); 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (scriptOfDefaultTag) 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return scriptOfDefaultTag; 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return validateOffset<ScriptTable>(buffer, scripts[0].scriptOffset); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptTable* scriptTable = defaultScript(buffer); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!scriptTable) 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return scriptTable->defaultLangSys(buffer); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct GSUBTable : TableBase { 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Fixed version; 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset scriptListOffset; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset featureListOffset; 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpenType::Offset lookupListOffset; 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptList* scriptList(const SharedBuffer& buffer) const { return validateOffset<ScriptList>(buffer, scriptListOffset); } 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureList* featureList(const SharedBuffer& buffer) const { return validateOffset<FeatureList>(buffer, featureListOffset); } 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LookupList* lookupList(const SharedBuffer& buffer) const { return validateOffset<LookupList>(buffer, lookupListOffset); } 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ScriptList* scripts = scriptList(buffer); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!scripts) 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return scripts->defaultLangSys(buffer); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* feature(OpenType::Tag featureTag, const SharedBuffer& buffer) const 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LangSysTable* langSys = defaultLangSys(buffer); 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureList* features = featureList(buffer); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!features) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* feature = 0; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (langSys) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) feature = langSys->feature(featureTag, features, buffer); 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!feature) { 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the font has no langSys table, or has no default script and the first script doesn't 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // have the requested feature, then use the first matching feature directly. 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) feature = features->findFeature(featureTag, buffer); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return feature; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool getVerticalGlyphSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FeatureTable* verticalFeatureTable = feature(OpenType::VertFeatureTag, buffer); 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!verticalFeatureTable) 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LookupList* lookups = lookupList(buffer); 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return lookups && verticalFeatureTable->getGlyphSubstitutions(lookups, map, buffer); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#pragma pack() 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace OpenType 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_defaultVertOriginY(0) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadMetrics(platformData); 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadVerticalGlyphSubstitutions(platformData); 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void OpenTypeVerticalData::loadMetrics(const FontPlatformData& platformData) 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load hhea and hmtx to get x-component of vertical origins. 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If these tables are missing, it's not an OpenType font. 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::HheaTag); 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::HheaTable* hhea = OpenType::validateTable<OpenType::HheaTable>(buffer); 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hhea) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countHmtxEntries = hhea->numberOfHMetrics; 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!countHmtxEntries) { 415a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Invalid numberOfHMetrics"); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer = platformData.openTypeTable(OpenType::HmtxTag); 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::HmtxTable* hmtx = OpenType::validateTable<OpenType::HmtxTable>(buffer, countHmtxEntries); 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hmtx) { 422a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("hhea exists but hmtx does not (or broken)"); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_advanceWidths.resize(countHmtxEntries); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < countHmtxEntries; ++i) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_advanceWidths[i] = hmtx->entries[i].advanceWidth; 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load vhea first. This table is required for fonts that support vertical flow. 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer = platformData.openTypeTable(OpenType::VheaTag); 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::VheaTable* vhea = OpenType::validateTable<OpenType::VheaTable>(buffer); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!vhea) 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countVmtxEntries = vhea->numOfLongVerMetrics; 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!countVmtxEntries) { 436a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Invalid numOfLongVerMetrics"); 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load VORG. This table is optional. 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer = platformData.openTypeTable(OpenType::VORGTag); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::VORGTable* vorg = OpenType::validateTable<OpenType::VORGTable>(buffer); 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (vorg && buffer->size() >= vorg->requiredSize()) { 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_defaultVertOriginY = vorg->defaultVertOriginY; 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t countVertOriginYMetrics = vorg->numVertOriginYMetrics; 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!countVertOriginYMetrics) { 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add one entry so that hasVORG() becomes true 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_vertOriginY.set(0, m_defaultVertOriginY); 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < countVertOriginYMetrics; ++i) { 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::VORGTable::VertOriginYMetrics& metrics = vorg->vertOriginYMetrics[i]; 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_vertOriginY.set(metrics.glyphIndex, metrics.vertOriginY); 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load vmtx then. This table is required for fonts that support vertical flow. 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer = platformData.openTypeTable(OpenType::VmtxTag); 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::VmtxTable* vmtx = OpenType::validateTable<OpenType::VmtxTable>(buffer, countVmtxEntries); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!vmtx) { 461a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("vhea exists but vmtx does not (or broken)"); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_advanceHeights.resize(countVmtxEntries); 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint16_t i = 0; i < countVmtxEntries; ++i) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_advanceHeights[i] = vmtx->entries[i].advanceHeight; 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // VORG is preferred way to calculate vertical origin than vmtx, 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // so load topSideBearing from vmtx only if VORG is missing. 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasVORG()) 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t sizeExtra = buffer->size() - sizeof(OpenType::VmtxTable::Entry) * countVmtxEntries; 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sizeExtra % sizeof(OpenType::Int16)) { 475a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("vmtx has incorrect tsb count"); 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t countTopSideBearings = countVmtxEntries + sizeExtra / sizeof(OpenType::Int16); 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_topSideBearings.resize(countTopSideBearings); 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t i; 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i < countVmtxEntries; ++i) 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_topSideBearings[i] = vmtx->entries[i].topSideBearing; 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i < countTopSideBearings) { 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::Int16* pTopSideBearingsExtra = reinterpret_cast<const OpenType::Int16*>(&vmtx->entries[countVmtxEntries]); 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (; i < countTopSideBearings; ++i, ++pTopSideBearingsExtra) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_topSideBearings[i] = *pTopSideBearingsExtra; 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void OpenTypeVerticalData::loadVerticalGlyphSubstitutions(const FontPlatformData& platformData) 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::GSUBTag); 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const OpenType::GSUBTable* gsub = OpenType::validateTable<OpenType::GSUBTable>(buffer); 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (gsub) 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gsub->getVerticalGlyphSubstitutions(&m_verticalGlyphMap, *buffer.get()); 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float OpenTypeVerticalData::advanceHeight(const SimpleFontData* font, Glyph glyph) const 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t countHeights = m_advanceHeights.size(); 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (countHeights) { 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t advanceFUnit = m_advanceHeights[glyph < countHeights ? glyph : countHeights - 1]; 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float advance = advanceFUnit * font->sizePerUnit(); 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return advance; 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // No vertical info in the font file; use height as advance. 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return font->fontMetrics().height(); 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void OpenTypeVerticalData::getVerticalTranslationsForGlyphs(const SimpleFontData* font, const Glyph* glyphs, size_t count, float* outXYArray) const 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t countWidths = m_advanceWidths.size(); 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(countWidths > 0); 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FontMetrics& metrics = font->fontMetrics(); 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float sizePerUnit = font->sizePerUnit(); 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float ascent = metrics.ascent(); 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool useVORG = hasVORG(); 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t countTopSideBearings = m_topSideBearings.size(); 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float defaultVertOriginY = std::numeric_limits<float>::quiet_NaN(); 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (float* end = &(outXYArray[count * 2]); outXYArray != end; ++glyphs, outXYArray += 2) { 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Glyph glyph = *glyphs; 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t widthFUnit = m_advanceWidths[glyph < countWidths ? glyph : countWidths - 1]; 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float width = widthFUnit * sizePerUnit; 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) outXYArray[0] = -width / 2; 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For Y, try VORG first. 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (useVORG) { 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int16_t vertOriginYFUnit = m_vertOriginY.get(glyph); 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (vertOriginYFUnit) { 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) outXYArray[1] = -vertOriginYFUnit * sizePerUnit; 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 534926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (std::isnan(defaultVertOriginY)) 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) defaultVertOriginY = -m_defaultVertOriginY * sizePerUnit; 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) outXYArray[1] = defaultVertOriginY; 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If no VORG, try vmtx next. 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (countTopSideBearings) { 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int16_t topSideBearingFUnit = m_topSideBearings[glyph < countTopSideBearings ? glyph : countTopSideBearings - 1]; 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float topSideBearing = topSideBearingFUnit * sizePerUnit; 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect bounds = font->boundsForGlyph(glyph); 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) outXYArray[1] = bounds.y() - topSideBearing; 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // No vertical info in the font file; use ascent as vertical origin. 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) outXYArray[1] = -ascent; 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void OpenTypeVerticalData::substituteWithVerticalGlyphs(const SimpleFontData* font, GlyphPage* glyphPage, unsigned offset, unsigned length) const 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const HashMap<Glyph, Glyph>& map = m_verticalGlyphMap; 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (map.isEmpty()) 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned index = offset, end = offset + length; index < end; ++index) { 56110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch GlyphData glyphData = glyphPage->glyphDataForIndex(index); 56210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (glyphData.glyph && glyphData.fontData == font) { 56310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch Glyph to = map.get(glyphData.glyph); 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (to) 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyphPage->setGlyphDataForIndex(index, to, font); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 570c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(OPENTYPE_VERTICAL) 572