/* * Copyright 2006, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus */ #include "FlatIconImporter.h" #include #include #include #include #include #include "AffineTransformer.h" #include "AutoDeleter.h" #include "ContourTransformer.h" #include "FlatIconFormat.h" #include "GradientTransformable.h" #include "Icon.h" #include "LittleEndianBuffer.h" #include "PathCommandQueue.h" #include "PathContainer.h" #include "PathSourceShape.h" #include "PerspectiveTransformer.h" #include "Shape.h" #include "StrokeTransformer.h" #include "Style.h" #include "StyleContainer.h" #include "VectorPath.h" using std::nothrow; // constructor FlatIconImporter::FlatIconImporter() #ifdef ICON_O_MATIC : Importer() #endif { } // destructor FlatIconImporter::~FlatIconImporter() { } // Import status_t FlatIconImporter::Import(Icon* icon, BPositionIO* stream) { #ifdef ICON_O_MATIC status_t ret = Init(icon); if (ret < B_OK) return ret; #else status_t ret; #endif // seek around in the stream to figure out the size off_t size = stream->Seek(0, SEEK_END); if (stream->Seek(0, SEEK_SET) != 0) return B_ERROR; // we chicken out on anything larger than 256k if (size <= 0 || size > 256 * 1024) return B_BAD_VALUE; // read the entire stream into a buffer LittleEndianBuffer buffer(size); if (!buffer.Buffer()) return B_NO_MEMORY; if (stream->Read(buffer.Buffer(), size) != size) return B_ERROR; ret = _ParseSections(buffer, icon); return ret; } // Import status_t FlatIconImporter::Import(Icon* icon, uint8* _buffer, size_t size) { #ifdef ICON_O_MATIC status_t ret = Init(icon); if (ret < B_OK) return ret; #endif if (!_buffer) return B_BAD_VALUE; // attach LittleEndianBuffer to buffer LittleEndianBuffer buffer(_buffer, size); return _ParseSections(buffer, icon); } // #pragma mark - // _ParseSections status_t FlatIconImporter::_ParseSections(LittleEndianBuffer& buffer, Icon* icon) { // test if this is an icon at all uint32 magic; if (!buffer.Read(magic) || magic != FLAT_ICON_MAGIC) return B_BAD_TYPE; // styles StyleContainer* styles = icon->Styles(); status_t ret = _ParseStyles(buffer, styles); if (ret < B_OK) { printf("FlatIconImporter::_ParseSections() - " "error parsing styles: %s\n", strerror(ret)); return ret; } // paths PathContainer* paths = icon->Paths(); ret = _ParsePaths(buffer, paths); if (ret < B_OK) { printf("FlatIconImporter::_ParseSections() - " "error parsing paths: %s\n", strerror(ret)); return ret; } // shapes ret = _ParseShapes(buffer, styles, paths, icon->Shapes()); if (ret < B_OK) { printf("FlatIconImporter::_ParseSections() - " "error parsing shapes: %s\n", strerror(ret)); return ret; } return B_OK; } // _ReadTransformable static bool _ReadTransformable(LittleEndianBuffer& buffer, Transformable* transformable) { int32 matrixSize = Transformable::matrix_size; double matrix[matrixSize]; for (int32 i = 0; i < matrixSize; i++) { float value; if (!read_float_24(buffer, value)) return false; matrix[i] = value; } transformable->LoadFrom(matrix); return true; } // _ReadTranslation static bool _ReadTranslation(LittleEndianBuffer& buffer, Transformable* transformable) { BPoint t; if (read_coord(buffer, t.x) && read_coord(buffer, t.y)) { transformable->TranslateBy(t); return true; } return false; } // _ReadColorStyle static Style* _ReadColorStyle(LittleEndianBuffer& buffer, bool alpha, bool gray) { rgb_color color; if (alpha) { if (gray) { if (!buffer.Read(color.red) || !buffer.Read(color.alpha)) return NULL; color.green = color.blue = color.red; } else { if (!buffer.Read((uint32&)color)) return NULL; } } else { color.alpha = 255; if (gray) { if (!buffer.Read(color.red)) return NULL; color.green = color.blue = color.red; } else { if (!buffer.Read(color.red) || !buffer.Read(color.green) || !buffer.Read(color.blue)) return NULL; } } return new (nothrow) Style(color); } // _ReadGradientStyle static Style* _ReadGradientStyle(LittleEndianBuffer& buffer) { Style* style = new (nothrow) Style(); if (!style) return NULL; ObjectDeleter