summaryrefslogtreecommitdiff
path: root/sfntly/data/writable_font_data.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sfntly/data/writable_font_data.cc')
-rw-r--r--sfntly/data/writable_font_data.cc203
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