~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/platform/graphics/chromium/VDMXParser.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are
 
6
 * met:
 
7
 *
 
8
 *     * Redistributions of source code must retain the above copyright
 
9
 * notice, this list of conditions and the following disclaimer.
 
10
 *     * Redistributions in binary form must reproduce the above
 
11
 * copyright notice, this list of conditions and the following disclaimer
 
12
 * in the documentation and/or other materials provided with the
 
13
 * distribution.
 
14
 *     * Neither the name of Google Inc. nor the names of its
 
15
 * contributors may be used to endorse or promote products derived from
 
16
 * this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
19
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
20
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
21
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
22
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
24
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
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.
 
29
 */
 
30
 
 
31
#include <stdint.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
 
 
35
#include <wtf/ByteOrder.h>
 
36
 
 
37
// Buffer helper class
 
38
//
 
39
// This class perform some trival buffer operations while checking for
 
40
// out-of-bounds errors. As a family they return false if anything is amiss,
 
41
// updating the current offset otherwise.
 
42
class Buffer {
 
43
public:
 
44
    Buffer(const uint8_t* buffer, size_t length)
 
45
        : m_buffer(buffer)
 
46
        , m_length(length)
 
47
        , m_offset(0) { }
 
48
 
 
49
    bool skip(size_t numBytes)
 
50
    {
 
51
        if (m_offset + numBytes > m_length)
 
52
            return false;
 
53
        m_offset += numBytes;
 
54
        return true;
 
55
    }
 
56
 
 
57
    bool readU8(uint8_t* value)
 
58
    {
 
59
        if (m_offset + sizeof(uint8_t) > m_length)
 
60
            return false;
 
61
        *value = m_buffer[m_offset];
 
62
        m_offset += sizeof(uint8_t);
 
63
        return true;
 
64
    }
 
65
 
 
66
    bool readU16(uint16_t* value)
 
67
    {
 
68
        if (m_offset + sizeof(uint16_t) > m_length)
 
69
            return false;
 
70
        memcpy(value, m_buffer + m_offset, sizeof(uint16_t));
 
71
        *value = ntohs(*value);
 
72
        m_offset += sizeof(uint16_t);
 
73
        return true;
 
74
    }
 
75
 
 
76
    bool readS16(int16_t* value)
 
77
    {
 
78
        return readU16(reinterpret_cast<uint16_t*>(value));
 
79
    }
 
80
 
 
81
    size_t offset() const
 
82
    {
 
83
        return m_offset;
 
84
    }
 
85
 
 
86
    void setOffset(size_t newoffset)
 
87
    {
 
88
        m_offset = newoffset;
 
89
    }
 
90
 
 
91
private:
 
92
    const uint8_t *const m_buffer;
 
93
    const size_t m_length;
 
94
    size_t m_offset;
 
95
};
 
96
 
 
97
// VDMX parsing code.
 
98
//
 
99
// VDMX tables are found in some TrueType/OpenType fonts and contain
 
100
// ascender/descender overrides for certain (usually small) sizes. This is
 
101
// needed in order to match font metrics on Windows.
 
102
//
 
103
// Freetype does not parse these tables so we do so here.
 
104
 
 
105
namespace WebCore {
 
106
 
 
107
// Parse a TrueType VDMX table.
 
108
//   yMax: (output) the ascender value from the table
 
109
//   yMin: (output) the descender value from the table (negative!)
 
110
//   vdmx: the table bytes
 
111
//   vdmxLength: length of @vdmx, in bytes
 
112
//   targetPixelSize: the pixel size of the font (e.g. 16)
 
113
//
 
114
// Returns true iff a suitable match are found. Otherwise, *yMax and *yMin are
 
115
// untouched. size_t must be 32-bits to avoid overflow.
 
116
//
 
117
// See http://www.microsoft.com/opentype/otspec/vdmx.htm
 
118
bool parseVDMX(int* yMax, int* yMin,
 
119
               const uint8_t* vdmx, size_t vdmxLength,
 
120
               unsigned targetPixelSize)
 
121
{
 
122
    Buffer buf(vdmx, vdmxLength);
 
123
 
 
124
    // We ignore the version. Future tables should be backwards compatible with
 
125
    // this layout.
 
126
    uint16_t numRatios;
 
127
    if (!buf.skip(4) || !buf.readU16(&numRatios))
 
128
        return false;
 
129
 
 
130
    // Now we have two tables. Firstly we have @numRatios Ratio records, then a
 
131
    // matching array of @numRatios offsets. We save the offset of the beginning
 
132
    // of this second table.
 
133
    //
 
134
    // Range 6 <= x <= 262146
 
135
    unsigned long offsetTableOffset =
 
136
        buf.offset() + 4 /* sizeof struct ratio */ * numRatios;
 
137
 
 
138
    unsigned desiredRatio = 0xffffffff;
 
139
    // We read 4 bytes per record, so the offset range is
 
140
    //   6 <= x <= 524286
 
141
    for (unsigned i = 0; i < numRatios; ++i) {
 
142
        uint8_t xRatio, yRatio1, yRatio2;
 
143
 
 
144
        if (!buf.skip(1)
 
145
            || !buf.readU8(&xRatio)
 
146
            || !buf.readU8(&yRatio1)
 
147
            || !buf.readU8(&yRatio2))
 
148
            return false;
 
149
 
 
150
        // This either covers 1:1, or this is the default entry (0, 0, 0)
 
151
        if ((xRatio == 1 && yRatio1 <= 1 && yRatio2 >= 1)
 
152
            || (xRatio == 0 && yRatio1 == 0 && yRatio2 == 0)) {
 
153
            desiredRatio = i;
 
154
            break;
 
155
        }
 
156
    }
 
157
 
 
158
    if (desiredRatio == 0xffffffff) // no ratio found
 
159
        return false;
 
160
 
 
161
    // Range 10 <= x <= 393216
 
162
    buf.setOffset(offsetTableOffset + sizeof(uint16_t) * desiredRatio);
 
163
 
 
164
    // Now we read from the offset table to get the offset of another array
 
165
    uint16_t groupOffset;
 
166
    if (!buf.readU16(&groupOffset))
 
167
        return false;
 
168
    // Range 0 <= x <= 65535
 
169
    buf.setOffset(groupOffset);
 
170
 
 
171
    uint16_t numRecords;
 
172
    if (!buf.readU16(&numRecords) || !buf.skip(sizeof(uint16_t)))
 
173
        return false;
 
174
 
 
175
    // We read 6 bytes per record, so the offset range is
 
176
    //   4 <= x <= 458749
 
177
    for (unsigned i = 0; i < numRecords; ++i) {
 
178
        uint16_t pixelSize;
 
179
        if (!buf.readU16(&pixelSize))
 
180
            return false;
 
181
        // the entries are sorted, so we can abort early if need be
 
182
        if (pixelSize > targetPixelSize)
 
183
            return false;
 
184
 
 
185
        if (pixelSize == targetPixelSize) {
 
186
            int16_t tempYMax, tempYMin;
 
187
            if (!buf.readS16(&tempYMax)
 
188
                || !buf.readS16(&tempYMin))
 
189
                return false;
 
190
            *yMin = tempYMin;
 
191
            *yMax = tempYMax;
 
192
            return true;
 
193
        }
 
194
        if (!buf.skip(2 * sizeof(int16_t)))
 
195
            return false;
 
196
    }
 
197
 
 
198
    return false;
 
199
}
 
200
 
 
201
} // namespace WebCore