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 24namespace sfntly { 25 26WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) { 27} 28 29WritableFontData::~WritableFontData() {} 30 31// static 32CALLER_ATTACH 33WritableFontData* 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. 48CALLER_ATTACH 49WritableFontData* 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 56int32_t WritableFontData::WriteByte(int32_t index, byte_t b) { 57 array_->Put(BoundOffset(index), b); 58 return 1; 59} 60 61int32_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 71int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) { 72 assert(b); 73 return WriteBytes(index, &((*b)[0]), 0, b->size()); 74} 75 76int32_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 91int32_t WritableFontData::WritePadding(int32_t index, int32_t count) { 92 return WritePadding(index, count, (byte_t)0); 93} 94 95int32_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 103int32_t WritableFontData::WriteChar(int32_t index, byte_t c) { 104 return WriteByte(index, c); 105} 106 107int32_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 113int32_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 119int32_t WritableFontData::WriteShort(int32_t index, int32_t s) { 120 return WriteUShort(index, s); 121} 122 123int32_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 130int32_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 138int32_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 146int32_t WritableFontData::WriteLong(int32_t index, int64_t l) { 147 return WriteULong(index, l); 148} 149 150int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) { 151 return WriteLong(index, f); 152} 153 154int32_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 160void WritableFontData::CopyFrom(InputStream* is, int32_t length) { 161 array_->CopyFrom(is, length); 162} 163 164void WritableFontData::CopyFrom(InputStream* is) { 165 array_->CopyFrom(is); 166} 167 168CALLER_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 181CALLER_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 193WritableFontData::WritableFontData(WritableFontData* data, int32_t offset) 194 : ReadableFontData(data, offset) { 195} 196 197WritableFontData::WritableFontData(WritableFontData* data, 198 int32_t offset, 199 int32_t length) 200 : ReadableFontData(data, offset, length) { 201} 202 203} // namespace sfntly 204