diff options
| -rw-r--r-- | dmagick/Image.d | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/dmagick/Image.d b/dmagick/Image.d index 510cfb0..b9e727e 100644 --- a/dmagick/Image.d +++ b/dmagick/Image.d @@ -6,10 +6,13 @@ module dmagick.Image; +import std.algorithm : min; +import std.array; import std.conv; import std.math; import std.string; import std.typecons : Tuple; +import std.uni; import core.memory; import core.runtime; import core.time; @@ -420,25 +423,40 @@ class Image *-------------------- * Params: * text = The text. - * boundingArea = - * The location/bounding area for the text, - * if the height and width are 0 the height and - * with of the image are used to calculate - * the bounding area. + * xOffset = The x coordinate. + * yOffset = The y coordinate. * gravity = Placement gravity. * degrees = The angle of the Text. */ void annotate( string text, + size_t xOffset, + size_t yOffset, + GravityType gravity = GravityType.NorthWestGravity, + double degrees = 0.0) + { + annotate(text, Geometry(size_t.max, size_t.max, xOffset, yOffset), gravity, degrees); + } + + /** + * Ditto, but word wraps the text so it stays withing the + * boundingArea. if the height and width are 0 the height and + * with of the image are used to calculate the bounding area. + */ + void annotate( + string text, Geometry boundingArea = Geometry.init, GravityType gravity = GravityType.NorthWestGravity, double degrees = 0.0) { - if ( boundingArea == Geometry.init ) - { + if ( boundingArea.width == 0 ) boundingArea.width = columns; + + if ( boundingArea.height == 0 ) boundingArea.height = rows; - } + + if ( boundingArea.width > 0 ) + text = wordWrap(text, boundingArea); DrawInfo* drawInfo = options.drawInfo; AffineMatrix oldAffine = options.affine; @@ -4270,6 +4288,53 @@ class Image magick.opacity = color.opacityQuantum; } + private string wordWrap(string text, Geometry boundingBox) + { + size_t pos; + string[] lines; + + while ( !text.empty ) + { + for ( size_t i; i < text.length; i++ ) + { + if ( isWhite(text[i]) || i == text.length-1 ) + { + TypeMetric metric = getTypeMetrics(text[0..i]); + + if ( metric.width > boundingBox.width ) + { + if ( pos == 0 ) + pos = i; + + break; + } + + pos = i; + + if ( text[i] == '\n' ) + break; + + if ( i == text.length-1 ) + pos++; + } + } + + lines ~= text[0 .. pos].strip(); + text = text[min(pos+1, text.length) .. $]; + pos = 0; + } + + return join(lines, "\n"); + } + + unittest + { + Image img = new Image(Geometry(200, 200), new Color()); + string wraped = img.wordWrap("Lorem ipsum dolor sit amet.", Geometry(100, 200)); + + assert(wraped == "Lorem ipsum\ndolor sit amet."); + } + private template getStorageType(T) { static if ( is( T == byte) ) |
