• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 #include "sfntly/data/memory_byte_array.h"
22 #include "sfntly/data/growable_memory_byte_array.h"
23 
24 namespace sfntly {
25 
WritableFontData(ByteArray * ba)26 WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
27 }
28 
~WritableFontData()29 WritableFontData::~WritableFontData() {}
30 
31 // static
32 CALLER_ATTACH
CreateWritableFontData(int32_t length)33 WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
34   ByteArrayPtr ba;
35   if (length > 0) {
36     ba = new MemoryByteArray(length);
37     ba->SetFilledLength(length);
38   } else {
39     ba = new GrowableMemoryByteArray();
40   }
41   WritableFontDataPtr wfd = new WritableFontData(ba);
42   return wfd.Detach();
43 }
44 
45 // TODO(arthurhsu): re-investigate the memory model of this function.  It's
46 //                  not too useful without copying, but it's not performance
47 //                  savvy to do copying.
48 CALLER_ATTACH
CreateWritableFontData(ByteVector * b)49 WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
50   ByteArrayPtr ba = new GrowableMemoryByteArray();
51   ba->Put(0, b);
52   WritableFontDataPtr wfd = new WritableFontData(ba);
53   return wfd.Detach();
54 }
55 
WriteByte(int32_t index,byte_t b)56 int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
57   array_->Put(BoundOffset(index), b);
58   return 1;
59 }
60 
WriteBytes(int32_t index,byte_t * b,int32_t offset,int32_t length)61 int32_t WritableFontData::WriteBytes(int32_t index,
62                                      byte_t* b,
63                                      int32_t offset,
64                                      int32_t length) {
65   return array_->Put(BoundOffset(index),
66                      b,
67                      offset,
68                      BoundLength(index, length));
69 }
70 
WriteBytes(int32_t index,ByteVector * b)71 int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
72   assert(b);
73   return WriteBytes(index, &((*b)[0]), 0, b->size());
74 }
75 
WriteBytesPad(int32_t index,ByteVector * b,int32_t offset,int32_t length,byte_t pad)76 int32_t WritableFontData::WriteBytesPad(int32_t index,
77                                         ByteVector* b,
78                                         int32_t offset,
79                                         int32_t length,
80                                         byte_t pad) {
81   int32_t written =
82       array_->Put(BoundOffset(index),
83                   &((*b)[0]),
84                   offset,
85                   BoundLength(index,
86                               std::min<int32_t>(length, b->size() - offset)));
87   written += WritePadding(written + index, length - written, pad);
88   return written;
89 }
90 
WritePadding(int32_t index,int32_t count)91 int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
92   return WritePadding(index, count, (byte_t)0);
93 }
94 
WritePadding(int32_t index,int32_t count,byte_t pad)95 int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
96                                        byte_t pad) {
97   for (int32_t i = 0; i < count; ++i) {
98     array_->Put(index + i, pad);
99   }
100   return count;
101 }
102 
WriteChar(int32_t index,byte_t c)103 int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
104   return WriteByte(index, c);
105 }
106 
WriteUShort(int32_t index,int32_t us)107 int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
108   WriteByte(index, (byte_t)((us >> 8) & 0xff));
109   WriteByte(index + 1, (byte_t)(us & 0xff));
110   return 2;
111 }
112 
WriteUShortLE(int32_t index,int32_t us)113 int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
114   WriteByte(index, (byte_t)(us & 0xff));
115   WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
116   return 2;
117 }
118 
WriteShort(int32_t index,int32_t s)119 int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
120   return WriteUShort(index, s);
121 }
122 
WriteUInt24(int32_t index,int32_t ui)123 int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
124   WriteByte(index, (byte_t)((ui >> 16) & 0xff));
125   WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
126   WriteByte(index + 2, (byte_t)(ui & 0xff));
127   return 3;
128 }
129 
WriteULong(int32_t index,int64_t ul)130 int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
131   WriteByte(index, (byte_t)((ul >> 24) & 0xff));
132   WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
133   WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
134   WriteByte(index + 3, (byte_t)(ul & 0xff));
135   return 4;
136 }
137 
WriteULongLE(int32_t index,int64_t ul)138 int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
139   WriteByte(index, (byte_t)(ul & 0xff));
140   WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
141   WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
142   WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
143   return 4;
144 }
145 
WriteLong(int32_t index,int64_t l)146 int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
147   return WriteULong(index, l);
148 }
149 
WriteFixed(int32_t index,int32_t f)150 int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
151   return WriteLong(index, f);
152 }
153 
WriteDateTime(int32_t index,int64_t date)154 int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
155   WriteULong(index, (date >> 32) & 0xffffffff);
156   WriteULong(index + 4, date & 0xffffffff);
157   return 8;
158 }
159 
CopyFrom(InputStream * is,int32_t length)160 void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
161   array_->CopyFrom(is, length);
162 }
163 
CopyFrom(InputStream * is)164 void WritableFontData::CopyFrom(InputStream* is) {
165   array_->CopyFrom(is);
166 }
167 
Slice(int32_t offset,int32_t length)168 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
169                                                 int32_t length) {
170   if (offset < 0 || offset + length > Size()) {
171 #if !defined (SFNTLY_NO_EXCEPTION)
172     throw IndexOutOfBoundsException(
173         "Attempt to bind data outside of its limits");
174 #endif
175     return NULL;
176   }
177   FontDataPtr slice = new WritableFontData(this, offset, length);
178   return slice.Detach();
179 }
180 
Slice(int32_t offset)181 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
182   if (offset > Size()) {
183 #if !defined (SFNTLY_NO_EXCEPTION)
184     throw IndexOutOfBoundsException(
185         "Attempt to bind data outside of its limits");
186 #endif
187     return NULL;
188   }
189   FontDataPtr slice = new WritableFontData(this, offset);
190   return slice.Detach();
191 }
192 
WritableFontData(WritableFontData * data,int32_t offset)193 WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
194     : ReadableFontData(data, offset) {
195 }
196 
WritableFontData(WritableFontData * data,int32_t offset,int32_t length)197 WritableFontData::WritableFontData(WritableFontData* data,
198                                    int32_t offset,
199                                    int32_t length)
200     : ReadableFontData(data, offset, length) {
201 }
202 
203 }  // namespace sfntly
204