1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/* 2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved. 3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License"); 5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License. 6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at 7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * http://www.apache.org/licenses/LICENSE-2.0 9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software 11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS, 12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and 14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License. 15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */ 16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 17464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/data/writable_font_data.h" 18464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 198f090032dd4f8f8908f338cc73bb840b788377f2stuartg@google.com#include <algorithm> 208f090032dd4f8f8908f338cc73bb840b788377f2stuartg@google.com 2133e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com#include "sfntly/data/memory_byte_array.h" 2233e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com#include "sfntly/data/growable_memory_byte_array.h" 2333e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com 24464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comnamespace sfntly { 25464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 26464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comWritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) { 27464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 28464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 29246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comWritableFontData::~WritableFontData() {} 30464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 3133e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com// static 3233e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.comCALLER_ATTACH 3333e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.comWritableFontData* WritableFontData::CreateWritableFontData(int32_t length) { 3433e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ByteArrayPtr ba; 3533e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com if (length > 0) { 3633e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ba = new MemoryByteArray(length); 3733e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ba->SetFilledLength(length); 3833e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com } else { 3933e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ba = new GrowableMemoryByteArray(); 4033e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com } 4133e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com WritableFontDataPtr wfd = new WritableFontData(ba); 4233e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com return wfd.Detach(); 4333e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com} 4433e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com 4532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com// TODO(arthurhsu): re-investigate the memory model of this function. It's 4632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com// not too useful without copying, but it's not performance 4732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com// savvy to do copying. 4833e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.comCALLER_ATTACH 4933e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.comWritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) { 5033e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ByteArrayPtr ba = new GrowableMemoryByteArray(); 5133e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com ba->Put(0, b); 5233e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com WritableFontDataPtr wfd = new WritableFontData(ba); 5333e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com return wfd.Detach(); 5433e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com} 5533e4b13b001b82d8b26a2066ba77fe04bbd6f9a8dfilimon@google.com 56246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteByte(int32_t index, byte_t b) { 57246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com array_->Put(BoundOffset(index), b); 58464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 1; 59464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 60464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 6132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.comint32_t WritableFontData::WriteBytes(int32_t index, 6232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com byte_t* b, 6332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com int32_t offset, 64246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t length) { 6532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com return array_->Put(BoundOffset(index), 66246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com b, 6732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com offset, 6832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com BoundLength(index, length)); 69464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 70464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 71246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) { 7232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com assert(b); 7332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com return WriteBytes(index, &((*b)[0]), 0, b->size()); 74464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 75464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 766b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.comint32_t WritableFontData::WriteBytesPad(int32_t index, 776b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com ByteVector* b, 786b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com int32_t offset, 796b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com int32_t length, 806b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com byte_t pad) { 816b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com int32_t written = 826b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com array_->Put(BoundOffset(index), 836b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com &((*b)[0]), 846b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com offset, 856b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com BoundLength(index, 866b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com std::min<int32_t>(length, b->size() - offset))); 87333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com written += WritePadding(written + index, length - written, pad); 886b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com return written; 896b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com} 906b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com 91333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t WritableFontData::WritePadding(int32_t index, int32_t count) { 92333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com return WritePadding(index, count, (byte_t)0); 93333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com} 94333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com 95333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t WritableFontData::WritePadding(int32_t index, int32_t count, 96333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com byte_t pad) { 97333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com for (int32_t i = 0; i < count; ++i) { 98333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com array_->Put(index + i, pad); 99333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com } 100333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com return count; 101333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com} 102333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com 103246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteChar(int32_t index, byte_t c) { 104246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return WriteByte(index, c); 105464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 106464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 107246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteUShort(int32_t index, int32_t us) { 108246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index, (byte_t)((us >> 8) & 0xff)); 109246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 1, (byte_t)(us & 0xff)); 110464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 2; 111464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 112464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 113246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) { 114246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index, (byte_t)(us & 0xff)); 115246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 1, (byte_t)((us >> 8) & 0xff)); 116464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 2; 117464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 118464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 119246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteShort(int32_t index, int32_t s) { 120246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return WriteUShort(index, s); 121464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 122464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 123246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) { 124246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index, (byte_t)((ui >> 16) & 0xff)); 125246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff)); 126246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 2, (byte_t)(ui & 0xff)); 127464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 3; 128464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 129464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 130246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteULong(int32_t index, int64_t ul) { 131246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index, (byte_t)((ul >> 24) & 0xff)); 132246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff)); 133246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff)); 134246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 3, (byte_t)(ul & 0xff)); 135464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 4; 136464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 137464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 138246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) { 139246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index, (byte_t)(ul & 0xff)); 140246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff)); 141246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff)); 142246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff)); 143464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 4; 144464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 145464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 146246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteLong(int32_t index, int64_t l) { 147246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return WriteULong(index, l); 148464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 149464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 15032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.comint32_t WritableFontData::WriteFixed(int32_t index, int32_t f) { 15132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com return WriteLong(index, f); 152464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 153464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 154246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) { 155246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteULong(index, (date >> 32) & 0xffffffff); 156246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com WriteULong(index + 4, date & 0xffffffff); 157464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 8; 158464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 159464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 160c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.comvoid WritableFontData::CopyFrom(InputStream* is, int32_t length) { 161c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com array_->CopyFrom(is, length); 162c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com} 163c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com 164c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.comvoid WritableFontData::CopyFrom(InputStream* is) { 165c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com array_->CopyFrom(is); 166c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com} 167c10c3d53cd1401f158e89697b7fe019b6828fa00arthurhsu@google.com 168246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset, 169464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com int32_t length) { 170246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com if (offset < 0 || offset + length > Size()) { 171144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com#if !defined (SFNTLY_NO_EXCEPTION) 172144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com throw IndexOutOfBoundsException( 173144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com "Attempt to bind data outside of its limits"); 174144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com#endif 175464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return NULL; 176464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 177464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com FontDataPtr slice = new WritableFontData(this, offset, length); 178246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return slice.Detach(); 179464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 180464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 181246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) { 182246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com if (offset > Size()) { 183144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com#if !defined (SFNTLY_NO_EXCEPTION) 184144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com throw IndexOutOfBoundsException( 185144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com "Attempt to bind data outside of its limits"); 186144e5cb2b372c30d8a4b90267b52646368dd89fcarthurhsu@google.com#endif 187464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return NULL; 188464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 189464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com FontDataPtr slice = new WritableFontData(this, offset); 190246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return slice.Detach(); 191246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 192246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 193246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comWritableFontData::WritableFontData(WritableFontData* data, int32_t offset) 194246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com : ReadableFontData(data, offset) { 195246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 196246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 197246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comWritableFontData::WritableFontData(WritableFontData* data, 198246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t offset, 199246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t length) 200246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com : ReadableFontData(data, offset, length) { 201464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 202464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 203464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} // namespace sfntly 204