diff options
Diffstat (limited to 'sfntly/data/writable_font_data.cc')
-rw-r--r-- | sfntly/data/writable_font_data.cc | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/sfntly/data/writable_font_data.cc b/sfntly/data/writable_font_data.cc new file mode 100644 index 0000000..4b3b440 --- /dev/null +++ b/sfntly/data/writable_font_data.cc @@ -0,0 +1,203 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sfntly/data/writable_font_data.h" + +#include <algorithm> + +#include "sfntly/data/memory_byte_array.h" +#include "sfntly/data/growable_memory_byte_array.h" + +namespace sfntly { + +WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) { +} + +WritableFontData::~WritableFontData() {} + +// static +CALLER_ATTACH +WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) { + ByteArrayPtr ba; + if (length > 0) { + ba = new MemoryByteArray(length); + ba->SetFilledLength(length); + } else { + ba = new GrowableMemoryByteArray(); + } + WritableFontDataPtr wfd = new WritableFontData(ba); + return wfd.Detach(); +} + +// TODO(arthurhsu): re-investigate the memory model of this function. It's +// not too useful without copying, but it's not performance +// savvy to do copying. +CALLER_ATTACH +WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) { + ByteArrayPtr ba = new GrowableMemoryByteArray(); + ba->Put(0, b); + WritableFontDataPtr wfd = new WritableFontData(ba); + return wfd.Detach(); +} + +int32_t WritableFontData::WriteByte(int32_t index, byte_t b) { + array_->Put(BoundOffset(index), b); + return 1; +} + +int32_t WritableFontData::WriteBytes(int32_t index, + byte_t* b, + int32_t offset, + int32_t length) { + return array_->Put(BoundOffset(index), + b, + offset, + BoundLength(index, length)); +} + +int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) { + assert(b); + return WriteBytes(index, &((*b)[0]), 0, b->size()); +} + +int32_t WritableFontData::WriteBytesPad(int32_t index, + ByteVector* b, + int32_t offset, + int32_t length, + byte_t pad) { + int32_t written = + array_->Put(BoundOffset(index), + &((*b)[0]), + offset, + BoundLength(index, + std::min<int32_t>(length, b->size() - offset))); + written += WritePadding(written + index, length - written, pad); + return written; +} + +int32_t WritableFontData::WritePadding(int32_t index, int32_t count) { + return WritePadding(index, count, (byte_t)0); +} + +int32_t WritableFontData::WritePadding(int32_t index, int32_t count, + byte_t pad) { + for (int32_t i = 0; i < count; ++i) { + array_->Put(index + i, pad); + } + return count; +} + +int32_t WritableFontData::WriteChar(int32_t index, byte_t c) { + return WriteByte(index, c); +} + +int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) { + WriteByte(index, (byte_t)((us >> 8) & 0xff)); + WriteByte(index + 1, (byte_t)(us & 0xff)); + return 2; +} + +int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) { + WriteByte(index, (byte_t)(us & 0xff)); + WriteByte(index + 1, (byte_t)((us >> 8) & 0xff)); + return 2; +} + +int32_t WritableFontData::WriteShort(int32_t index, int32_t s) { + return WriteUShort(index, s); +} + +int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) { + WriteByte(index, (byte_t)((ui >> 16) & 0xff)); + WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff)); + WriteByte(index + 2, (byte_t)(ui & 0xff)); + return 3; +} + +int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) { + WriteByte(index, (byte_t)((ul >> 24) & 0xff)); + WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff)); + WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff)); + WriteByte(index + 3, (byte_t)(ul & 0xff)); + return 4; +} + +int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) { + WriteByte(index, (byte_t)(ul & 0xff)); + WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff)); + WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff)); + WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff)); + return 4; +} + +int32_t WritableFontData::WriteLong(int32_t index, int64_t l) { + return WriteULong(index, l); +} + +int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) { + return WriteLong(index, f); +} + +int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) { + WriteULong(index, (date >> 32) & 0xffffffff); + WriteULong(index + 4, date & 0xffffffff); + return 8; +} + +void WritableFontData::CopyFrom(InputStream* is, int32_t length) { + array_->CopyFrom(is, length); +} + +void WritableFontData::CopyFrom(InputStream* is) { + array_->CopyFrom(is); +} + +CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset, + int32_t length) { + if (offset < 0 || offset + length > Size()) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException( + "Attempt to bind data outside of its limits"); +#endif + return NULL; + } + FontDataPtr slice = new WritableFontData(this, offset, length); + return slice.Detach(); +} + +CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) { + if (offset > Size()) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException( + "Attempt to bind data outside of its limits"); +#endif + return NULL; + } + FontDataPtr slice = new WritableFontData(this, offset); + return slice.Detach(); +} + +WritableFontData::WritableFontData(WritableFontData* data, int32_t offset) + : ReadableFontData(data, offset) { +} + +WritableFontData::WritableFontData(WritableFontData* data, + int32_t offset, + int32_t length) + : ReadableFontData(data, offset, length) { +} + +} // namespace sfntly |