diff --git a/Watermark.Net/src/WatermarkNet.Common/ImageRenderer.cs b/Watermark.Net/src/WatermarkNet.Common/ImageRenderer.cs index c1befdf..d6da9e2 100644 --- a/Watermark.Net/src/WatermarkNet.Common/ImageRenderer.cs +++ b/Watermark.Net/src/WatermarkNet.Common/ImageRenderer.cs @@ -39,43 +39,68 @@ namespace Watermark.Net.src.WatermarkNet.Core } /// - /// Calculates origin point for text watermark based on position and size. + /// Calculates precise origin point for text watermark based on position and metrics. /// - private PointF CalcWatermarkOrigin(int width, int height, float watermarkSize, ImagePosition position) + private PointF CalcWatermarkOrigin(int width, int height, float watermarkSize, ImagePosition position, FontRectangle textSize) { var origin = new PointF(0, 0); - //Static value 1 pt is 72 px per inch - var pixelsPerInch = 72; - var wmHeight = watermarkSize / pixelsPerInch; + var textPading = height / 10; // Minimum padding from edges switch (position) { case ImagePosition.TopLeft: - origin = new PointF(watermarkSize / 2, wmHeight / 2); + origin = new PointF( + Math.Max(0, -textSize.Left) + textPading, + Math.Max(0, -textSize.Top) + textPading + ); break; case ImagePosition.TopCenter: - origin = new PointF(width / 2, wmHeight / 2); + origin = new PointF( + Math.Max(0, width / 2 - textSize.Width / 2 - textSize.Left), + Math.Max(0, -textSize.Top) + textPading + ); break; case ImagePosition.TopRight: - origin = new PointF(width - watermarkSize * 2, wmHeight / 2); + origin = new PointF( + Math.Max(0, width - textSize.Width - textSize.Left) - textPading, + Math.Max(0, -textSize.Top) + textPading + ); break; case ImagePosition.CenterLeft: - origin = new PointF(watermarkSize / 2, height / 2.5f); + origin = new PointF( + Math.Max(0, -textSize.Left) + textPading, + Math.Max(0, height / 2 - textSize.Height / 2 - textSize.Top) + ); break; case ImagePosition.Center: - origin = new PointF(width / 2, height / 2.5f); + origin = new PointF( + Math.Max(0, width / 2 - textSize.Width / 2 - textSize.Left), + Math.Max(0, height / 2 - textSize.Height / 2 - textSize.Top) + ); break; case ImagePosition.CenterRight: - origin = new PointF(width - watermarkSize * 2, height / 2.5f); + origin = new PointF( + Math.Max(0, width - textSize.Width - textSize.Left) - textPading, + Math.Max(0, height / 2 - textSize.Height / 2 - textSize.Top) + ); break; case ImagePosition.BottomLeft: - origin = new PointF(watermarkSize / 2, height - watermarkSize * 2); + origin = new PointF( + Math.Max(0, - textSize.Left) + textPading, + Math.Max(0, height - textSize.Height - textSize.Top) - textPading + ); break; case ImagePosition.BottomCenter: - origin = new PointF(width / 2, height - watermarkSize * 2); + origin = new PointF( + Math.Max(0, width / 2 - textSize.Width / 2 - textSize.Left), + Math.Max(0, height - textSize.Height - textSize.Top) - textPading + ); break; case ImagePosition.BottomRight: - origin = new PointF(width - watermarkSize * 2, height - watermarkSize * 2); + origin = new PointF( + Math.Max(0, width - textSize.Width - textSize.Left) - textPading, + Math.Max(0, height - textSize.Height - textSize.Top) - textPading + ); break; default: break; @@ -167,7 +192,7 @@ namespace Watermark.Net.src.WatermarkNet.Core var textOptions = new RichTextOptions(scaledFont) { ColorFontSupport = ColorFontSupport.MicrosoftColrFormat, - Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, watermark.Layout.Position), + Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, watermark.Layout.Position, size), HorizontalAlignment = HorizontalAlignmentFromPosition(watermark.Layout.Position), VerticalAlignment = VerticalAlignment.Top, }; @@ -176,7 +201,7 @@ namespace Watermark.Net.src.WatermarkNet.Core { foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition))) { - textOptions.Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, position); + textOptions.Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, position, size); textOptions.HorizontalAlignment = HorizontalAlignmentFromPosition(position); processingContext.DrawText(textOptions, watermark.Text, watermark.Style.Color); }