Line data Source code
1 : /*
2 : * Copyright 2011 Google Inc. All Rights Reserved.
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #include "sfntly/data/writable_font_data.h"
18 :
19 : #include <algorithm>
20 : #include <limits>
21 :
22 : #include "sfntly/data/memory_byte_array.h"
23 : #include "sfntly/data/growable_memory_byte_array.h"
24 :
25 : namespace sfntly {
26 :
27 0 : WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
28 0 : }
29 :
30 0 : WritableFontData::~WritableFontData() {}
31 :
32 : // static
33 : CALLER_ATTACH
34 0 : WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
35 0 : ByteArrayPtr ba;
36 0 : if (length > 0) {
37 0 : ba = new MemoryByteArray(length);
38 0 : ba->SetFilledLength(length);
39 : } else {
40 0 : ba = new GrowableMemoryByteArray();
41 : }
42 0 : WritableFontDataPtr wfd = new WritableFontData(ba);
43 0 : return wfd.Detach();
44 : }
45 :
46 : // TODO(arthurhsu): re-investigate the memory model of this function. It's
47 : // not too useful without copying, but it's not performance
48 : // savvy to do copying.
49 : CALLER_ATTACH
50 0 : WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
51 0 : ByteArrayPtr ba = new GrowableMemoryByteArray();
52 0 : ba->Put(0, b);
53 0 : WritableFontDataPtr wfd = new WritableFontData(ba);
54 0 : return wfd.Detach();
55 : }
56 :
57 0 : int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
58 0 : array_->Put(BoundOffset(index), b);
59 0 : return 1;
60 : }
61 :
62 0 : int32_t WritableFontData::WriteBytes(int32_t index,
63 : byte_t* b,
64 : int32_t offset,
65 : int32_t length) {
66 0 : return array_->Put(BoundOffset(index),
67 : b,
68 : offset,
69 0 : BoundLength(index, length));
70 : }
71 :
72 0 : int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
73 0 : assert(b);
74 0 : return WriteBytes(index, &((*b)[0]), 0, b->size());
75 : }
76 :
77 0 : int32_t WritableFontData::WriteBytesPad(int32_t index,
78 : ByteVector* b,
79 : int32_t offset,
80 : int32_t length,
81 : byte_t pad) {
82 : int32_t written =
83 0 : array_->Put(BoundOffset(index),
84 0 : &((*b)[0]),
85 : offset,
86 : BoundLength(index,
87 0 : std::min<int32_t>(length, b->size() - offset)));
88 0 : written += WritePadding(written + index, length - written, pad);
89 0 : return written;
90 : }
91 :
92 0 : int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
93 0 : return WritePadding(index, count, (byte_t)0);
94 : }
95 :
96 0 : int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
97 : byte_t pad) {
98 0 : for (int32_t i = 0; i < count; ++i) {
99 0 : array_->Put(index + i, pad);
100 : }
101 0 : return count;
102 : }
103 :
104 0 : int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
105 0 : return WriteByte(index, c);
106 : }
107 :
108 0 : int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
109 0 : WriteByte(index, (byte_t)((us >> 8) & 0xff));
110 0 : WriteByte(index + 1, (byte_t)(us & 0xff));
111 0 : return 2;
112 : }
113 :
114 0 : int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
115 0 : WriteByte(index, (byte_t)(us & 0xff));
116 0 : WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
117 0 : return 2;
118 : }
119 :
120 0 : int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
121 0 : return WriteUShort(index, s);
122 : }
123 :
124 0 : int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
125 0 : WriteByte(index, (byte_t)((ui >> 16) & 0xff));
126 0 : WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
127 0 : WriteByte(index + 2, (byte_t)(ui & 0xff));
128 0 : return 3;
129 : }
130 :
131 0 : int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
132 0 : WriteByte(index, (byte_t)((ul >> 24) & 0xff));
133 0 : WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
134 0 : WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
135 0 : WriteByte(index + 3, (byte_t)(ul & 0xff));
136 0 : return 4;
137 : }
138 :
139 0 : int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
140 0 : WriteByte(index, (byte_t)(ul & 0xff));
141 0 : WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
142 0 : WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
143 0 : WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
144 0 : return 4;
145 : }
146 :
147 0 : int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
148 0 : return WriteULong(index, l);
149 : }
150 :
151 0 : int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
152 0 : return WriteLong(index, f);
153 : }
154 :
155 0 : int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
156 0 : WriteULong(index, (date >> 32) & 0xffffffff);
157 0 : WriteULong(index + 4, date & 0xffffffff);
158 0 : return 8;
159 : }
160 :
161 0 : void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
162 0 : array_->CopyFrom(is, length);
163 0 : }
164 :
165 0 : void WritableFontData::CopyFrom(InputStream* is) {
166 0 : array_->CopyFrom(is);
167 0 : }
168 :
169 0 : CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
170 : int32_t length) {
171 0 : if (offset < 0 || length < 0 ||
172 0 : offset > std::numeric_limits<int32_t>::max() - length ||
173 0 : offset + length > Size()) {
174 : #if !defined (SFNTLY_NO_EXCEPTION)
175 : throw IndexOutOfBoundsException(
176 : "Attempt to bind data outside of its limits");
177 : #endif
178 0 : return NULL;
179 : }
180 0 : FontDataPtr slice = new WritableFontData(this, offset, length);
181 0 : return slice.Detach();
182 : }
183 :
184 0 : CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
185 0 : if (offset < 0 || offset > Size()) {
186 : #if !defined (SFNTLY_NO_EXCEPTION)
187 : throw IndexOutOfBoundsException(
188 : "Attempt to bind data outside of its limits");
189 : #endif
190 0 : return NULL;
191 : }
192 0 : FontDataPtr slice = new WritableFontData(this, offset);
193 0 : return slice.Detach();
194 : }
195 :
196 0 : WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
197 0 : : ReadableFontData(data, offset) {
198 0 : }
199 :
200 0 : WritableFontData::WritableFontData(WritableFontData* data,
201 : int32_t offset,
202 0 : int32_t length)
203 0 : : ReadableFontData(data, offset, length) {
204 0 : }
205 :
206 : } // namespace sfntly
|