diff --git a/inc/ManagedString.h b/inc/ManagedString.h index 7ff9060..653e96c 100644 --- a/inc/ManagedString.h +++ b/inc/ManagedString.h @@ -32,7 +32,7 @@ class ManagedString /** * Constructor. - * Create a managed string from a specially prepared string literal. + * Create a managed string from a specially prepared string literal. It will ptr->incr(). * * @param ptr The literal - first two bytes should be 0xff, then the length in little endian, then the literal. The literal has to be 4-byte aligned. * @@ -42,7 +42,13 @@ class ManagedString * ManagedString s((StringData*)(void*)hello); * @endcode */ - ManagedString(StringData *p) : ptr(p) {} + ManagedString(StringData *ptr); + + /** + * Get current ptr, do not decr() it, and set the current instance to empty string. + * This is to be used by specialized runtimes which pass StringData around. + */ + StringData *leakData(); /** * Constructor. diff --git a/inc/MicroBit.h b/inc/MicroBit.h index e3ea4a2..e8f18af 100644 --- a/inc/MicroBit.h +++ b/inc/MicroBit.h @@ -5,6 +5,7 @@ #pragma GCC diagnostic ignored "-Wconversion-null" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wparentheses" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #include "mbed.h" diff --git a/inc/MicroBitImage.h b/inc/MicroBitImage.h index bb0e028..71c3310 100644 --- a/inc/MicroBitImage.h +++ b/inc/MicroBitImage.h @@ -39,6 +39,12 @@ class MicroBitImage public: static MicroBitImage EmptyImage; // Shared representation of a null image. + /** + * Get current ptr, do not decr() it, and set the current instance to empty image. + * This is to be used by specialized runtimes which pass ImageData around. + */ + ImageData *leakData(); + /** * Return a 2D array representing the bitmap image. */ @@ -49,17 +55,17 @@ class MicroBitImage /** * Constructor. - * Create an image from a specially prepared constant array, with no copying. + * Create an image from a specially prepared constant array, with no copying. Will call ptr->incr(). * - * @param p The literal - first two bytes should be 0xff, then width, height, and the bitmap. The literal has to be 4-byte aligned. + * @param ptr The literal - first two bytes should be 0xff, then width, height, and the bitmap. The literal has to be 4-byte aligned. * * Example: * @code * static const uint8_t heart[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 10, 5, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart - * ManagedString s((ImageData*)(void*)heart); + * MicroBitImage i((ImageData*)(void*)heart); * @endcode */ - MicroBitImage(ImageData *p) : ptr(p) {} + MicroBitImage(ImageData *ptr); /** * Default Constructor. @@ -392,7 +398,7 @@ class MicroBitImage * @endcode */ ManagedString toString(); - + /** * Crops the image to the given dimensions * @@ -412,6 +418,17 @@ class MicroBitImage */ MicroBitImage crop(int startx, int starty, int finx, int finy); + /** + * Check if image is read-only (i.e., residing in flash). + */ + bool isReadOnly(); + + /** + * Create a copy of the image bitmap. Used particularly, when isReadOnly() is true. + * + * @return an instance of MicroBitImage which can be modified independently of the current instance + */ + MicroBitImage clone(); }; #endif diff --git a/source/ManagedString.cpp b/source/ManagedString.cpp index c730967..66af6fe 100644 --- a/source/ManagedString.cpp +++ b/source/ManagedString.cpp @@ -31,6 +31,34 @@ void ManagedString::initString(const char *str) memcpy(ptr->data, str, len+1); } +/** + * Constructor. + * Create a managed string from a specially prepared string literal. It will ptr->incr(). + * + * @param ptr The literal - first two bytes should be 0xff, then the length in little endian, then the literal. The literal has to be 4-byte aligned. + * + * Example: + * @code + * static const char hello[] __attribute__ ((aligned (4))) = "\xff\xff\x05\x00" "Hello"; + * ManagedString s((StringData*)(void*)hello); + * @endcode + */ +ManagedString::ManagedString(StringData *p) +{ + ptr = p; + ptr->incr(); +} + +/** + * Get current ptr, do not decr() it, and set the current instance to empty string. + * This is to be used by specialized runtimes which pass StringData around. + */ +StringData* ManagedString::leakData() +{ + StringData *res = ptr; + initEmpty(); + return res; +} /** * Constructor. diff --git a/source/MicroBitImage.cpp b/source/MicroBitImage.cpp index a5c7781..059ee7b 100644 --- a/source/MicroBitImage.cpp +++ b/source/MicroBitImage.cpp @@ -7,10 +7,12 @@ #include "MicroBit.h" +static const uint8_t empty[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 1, 1, 0, 0 }; + /* * The null image. We actally create a small one byte buffer here, just to keep NULL pointers out of the equation. */ -MicroBitImage MicroBitImage::EmptyImage(1,1); +MicroBitImage MicroBitImage::EmptyImage((ImageData*)(void*)empty); /** * Default Constructor. @@ -163,6 +165,36 @@ MicroBitImage::MicroBitImage(const char *s) } } +/** + * Constructor. + * Create an image from a specially prepared constant array, with no copying. Will call ptr->incr(). + * + * @param ptr The literal - first two bytes should be 0xff, then width, height, and the bitmap. The literal has to be 4-byte aligned. + * + * Example: + * @code + * static const uint8_t heart[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 10, 5, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart + * MicroBitImage i((ImageData*)(void*)heart); + * @endcode + */ +MicroBitImage::MicroBitImage(ImageData *p) +{ + ptr = p; + ptr->incr(); +} + +/** + * Get current ptr, do not decr() it, and set the current instance to empty image. + * This is to be used by specialized runtimes which pass ImageData around. + */ +ImageData *MicroBitImage::leakData() +{ + ImageData* res = ptr; + init_empty(); + return res; +} + + /** * Constructor. * Create a bitmap representation of a given size, based on a given buffer. @@ -762,3 +794,21 @@ MicroBitImage MicroBitImage::crop(int startx, int starty, int cropWidth, int cro return MicroBitImage(newWidth, newHeight, cropped); } + +/** + * Check if image is read-only (i.e., residing in flash). + */ +bool MicroBitImage::isReadOnly() +{ + return ptr->isReadOnly(); +} + +/** + * Create a copy of the image bitmap. Used particularly, when isReadOnly() is true. + * + * @return an instance of MicroBitImage which can be modified independently of the current instance + */ +MicroBitImage MicroBitImage::clone() +{ + return MicroBitImage(getWidth(), getHeight(), getBitmap()); +}