diff --git a/src/Peachpie.Library.Graphics/Exif.cs b/src/Peachpie.Library.Graphics/Exif.cs index 600654ed01..962563034e 100644 --- a/src/Peachpie.Library.Graphics/Exif.cs +++ b/src/Peachpie.Library.Graphics/Exif.cs @@ -97,7 +97,7 @@ public static PhpArray exif_read_data(Context ctx, string filename, string secti //array.Add("FileDateTime", (int)File.GetCreationTime(filename).ToOADate()); array.Add("FileSize", (int)bytes.Length); - IImageInfo image; + ImageInfo image; using (var ms = new MemoryStream(bytes)) { @@ -130,9 +130,8 @@ static PhpValue ExifValueToPhpValue(object value) { if (value != null) { - if (value is Array) + if (value is Array arr) { - var arr = (Array)value; var phparr = new PhpArray(arr.Length); for (int i = 0; i < arr.Length; i++) @@ -171,15 +170,15 @@ static bool TryAsDouble(object value, out double dval) { dval = 0.0; - if (value is float) + if (value is float f) { - dval = (float)value; + dval = f; return true; } - if (value is double) + if (value is double d) { - dval = (double)value; + dval = d; return true; } @@ -190,45 +189,45 @@ static bool TryAsLong(object value, out long ival) { ival = 0; - if (value is int) + if (value is int i) { - ival = (int)value; + ival = i; return true; } - if (value is long) + if (value is long l) { - ival = (long)value; + ival = l; return true; } - if (value is uint) + if (value is uint u) { - ival = (uint)value; + ival = u; return true; } - if (value is byte) + if (value is byte b) { - ival = (byte)value; + ival = b; return true; } - if (value is sbyte) + if (value is sbyte sb) { - ival = (sbyte)value; + ival = sb; return true; } - if (value is short) + if (value is short s) { - ival = (short)value; + ival = s; return true; } - if (value is ushort) + if (value is ushort us) { - ival = (ushort)value; + ival = us; return true; } @@ -260,14 +259,7 @@ public static string exif_tagname(int index) //} //return null; - if (GetExifTagMap().TryGetValue((ushort)index, out var name)) - { - return name; - } - else - { - return null; - } + return GetExifTagMap().GetValueOrDefault((ushort)index); } /// @@ -284,7 +276,7 @@ Dictionary BuildMap() var props = typeof(ExifTag).GetProperties(); foreach (var p in props) { - if (p.GetMethod.IsStatic && p.GetValue(null) is ExifTag exiftag) + if (p.GetMethod?.IsStatic == true && p.GetValue(null) is ExifTag exiftag) { map[(ushort)exiftag] = exiftag.ToString(); } @@ -374,22 +366,20 @@ public static PhpString exif_thumbnail(Context ctx, string filename, PhpAlias wi return default(PhpString); // get thumbnail from 's content: - using (var ms = new MemoryStream(bytes)) + try { - try + //using (var image = Image.Load(bytes.AsSpan())) { // TODO: Image.Identify needs a new overload that returns the format. - using (var image = Image.Load(ms, out format)) - { - // return byte[] ~ image.MetaData.ExifProfile{ this.data, this.thumbnailOffset, this.thumbnailLength } - thumbnail = image.Metadata.ExifProfile.CreateThumbnail(); - } - } - catch - { - return default(PhpString); + var imageInfo = Image.Identify(bytes.AsSpan()); + // return byte[] ~ image.MetaData.ExifProfile{ this.data, this.thumbnailOffset, this.thumbnailLength } + imageInfo.Metadata.ExifProfile.TryCreateThumbnail(out thumbnail); } } + catch + { + return default(PhpString); + } if (thumbnail == null) { diff --git a/src/Peachpie.Library.Graphics/FloodFillProcessor{TPixel}.cs b/src/Peachpie.Library.Graphics/FloodFillProcessor{TPixel}.cs index cee714af72..ad7e6e6ffd 100644 --- a/src/Peachpie.Library.Graphics/FloodFillProcessor{TPixel}.cs +++ b/src/Peachpie.Library.Graphics/FloodFillProcessor{TPixel}.cs @@ -35,69 +35,73 @@ protected override void OnFrameApply(ImageFrame source) //var pixelSpan = source.GetPixelSpan(); //int rowLength = source.Width; - var segmentQueue = new Queue<(Point point, int rightEdge)>(); - segmentQueue.Enqueue((_startPoint, _startPoint.X)); - - while (segmentQueue.Count > 0) + source.ProcessPixelRows(accessor => { - var (currentPoint, rightEdge) = segmentQueue.Dequeue(); - var currentY = currentPoint.Y; - var currentX = currentPoint.X; - - var rowSpan = source.GetPixelRowSpan(currentY); - int leftEdge; - leftEdge = currentX; + var segmentQueue = new Queue<(Point point, int rightEdge)>(); + segmentQueue.Enqueue((_startPoint, _startPoint.X)); - // Filling until reaching a border of specified color - if (_toBorder) + while (segmentQueue.Count > 0) { - // Get the row segment to be colored - while (rightEdge + 1 < source.Width) - { - var edgeColor = GetPixel(rowSpan, rightEdge + 1); - if (edgeColor.Equals(_borderColor) || edgeColor.Equals(_fillColor)) - break; + var (currentPoint, rightEdge) = segmentQueue.Dequeue(); + var currentY = currentPoint.Y; + var currentX = currentPoint.X; + + var rowSpan = accessor.GetRowSpan(currentY); + int leftEdge; + leftEdge = currentX; - rightEdge++; + // Filling until reaching a border of specified color + if (_toBorder) + { + // Get the row segment to be colored + while (rightEdge + 1 < source.Width) + { + var edgeColor = GetPixel(rowSpan, rightEdge + 1); + if (edgeColor.Equals(_borderColor) || edgeColor.Equals(_fillColor)) + break; + + rightEdge++; + } + while (leftEdge - 1 < source.Width) + { + var edgeColor = GetPixel(rowSpan, leftEdge - 1); + if (edgeColor.Equals(_borderColor) || edgeColor.Equals(_fillColor)) + break; + + leftEdge--; + } + + // Actually color the row + SetPixelRow(rowSpan, leftEdge, rightEdge, _fillColor); + + // Add the segments to be filled above and below to the queue + if (currentY > 0) + AddFillingSegmentsToQueueWithBorder(floodFrom, accessor.GetRowSpan(currentY - 1), segmentQueue, leftEdge, rightEdge, currentY - 1); + if (currentY + 1 < source.Height) + AddFillingSegmentsToQueueWithBorder(floodFrom, accessor.GetRowSpan(currentY + 1), segmentQueue, leftEdge, rightEdge, currentY + 1); } - while (leftEdge - 1 < source.Width) + else + // Filling whole region of same color { - var edgeColor = GetPixel(rowSpan, leftEdge - 1); - if (edgeColor.Equals(_borderColor) || edgeColor.Equals(_fillColor)) - break; - - leftEdge--; + // Get the row segment to be colored + while (rightEdge + 1 < source.Width && GetPixel(rowSpan, rightEdge + 1).Equals(floodFrom)) + rightEdge++; + while (leftEdge > 0 && GetPixel(rowSpan, leftEdge - 1).Equals(floodFrom)) + leftEdge--; + + // Actually color the row + SetPixelRow(rowSpan, leftEdge, rightEdge, _fillColor); + + // Add the segments to be filled above and below to the queue + if (currentY > 0) + AddFillingSegmentsToQueue(floodFrom, accessor.GetRowSpan(currentY - 1), segmentQueue, leftEdge, rightEdge, currentY - 1); + if (currentY + 1 < source.Height) + AddFillingSegmentsToQueue(floodFrom, accessor.GetRowSpan(currentY + 1), segmentQueue, leftEdge, rightEdge, currentY + 1); } - - // Actually color the row - SetPixelRow(rowSpan, leftEdge, rightEdge, _fillColor); - - // Add the segments to be filled above and below to the queue - if (currentY > 0) - AddFillingSegmentsToQueueWithBorder(floodFrom, source.GetPixelRowSpan(currentY - 1), segmentQueue, leftEdge, rightEdge, currentY - 1); - if (currentY + 1 < source.Height) - AddFillingSegmentsToQueueWithBorder(floodFrom, source.GetPixelRowSpan(currentY + 1), segmentQueue, leftEdge, rightEdge, currentY + 1); - } - else - // Filling whole region of same color - { - // Get the row segment to be colored - while (rightEdge + 1 < source.Width && GetPixel(rowSpan, rightEdge + 1).Equals(floodFrom)) - rightEdge++; - while (leftEdge > 0 && GetPixel(rowSpan, leftEdge - 1).Equals(floodFrom)) - leftEdge--; - - // Actually color the row - SetPixelRow(rowSpan, leftEdge, rightEdge, _fillColor); - - // Add the segments to be filled above and below to the queue - if (currentY > 0) - AddFillingSegmentsToQueue(floodFrom, source.GetPixelRowSpan(currentY - 1), segmentQueue, leftEdge, rightEdge, currentY - 1); - if (currentY + 1 < source.Height) - AddFillingSegmentsToQueue(floodFrom, source.GetPixelRowSpan(currentY + 1), segmentQueue, leftEdge, rightEdge, currentY + 1); } - } + + }); } private static void AddFillingSegmentsToQueue(TPixel floodFrom, Span rowSpan, Queue<(Point, int)> segmentQueue, int xStart, int xEnd, int y) diff --git a/src/Peachpie.Library.Graphics/Peachpie.Library.Graphics.csproj b/src/Peachpie.Library.Graphics/Peachpie.Library.Graphics.csproj index c082970d6e..76a724acc3 100644 --- a/src/Peachpie.Library.Graphics/Peachpie.Library.Graphics.csproj +++ b/src/Peachpie.Library.Graphics/Peachpie.Library.Graphics.csproj @@ -9,9 +9,9 @@ Peachpie PHP language library functions for image processing. - - - + + + diff --git a/src/Peachpie.Library.Graphics/PhpGd2.cs b/src/Peachpie.Library.Graphics/PhpGd2.cs index 64d8d7aaa6..fe4a519e7b 100644 --- a/src/Peachpie.Library.Graphics/PhpGd2.cs +++ b/src/Peachpie.Library.Graphics/PhpGd2.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Numerics; @@ -7,7 +6,6 @@ using Pchp.Library.Streams; using SixLabors.Fonts; using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Drawing; using SixLabors.ImageSharp.Drawing.Processing; using SixLabors.ImageSharp.Formats; @@ -52,7 +50,7 @@ public static class PhpGd2 public const string GD_EXTRA_VERSION = ""; //"beta"; /// - /// When the bundled version of GD is used this is 1 otherwise its set to 0. + /// When the bundled version of GD is used, this is 1 otherwise it's set to 0. /// public const int GD_BUNDLED = 1; @@ -185,12 +183,12 @@ public enum FilledArcStyles public enum ColorValues { /// - /// Special color option which can be used in stead of color allocated with or . + /// Special color option which can be used instead of color allocated with or . /// STYLED = -2, /// - /// Special color option which can be used in stead of color allocated with or . + /// Special color option which can be used instead of color allocated with or . /// BRUSHED = -3, @@ -226,51 +224,51 @@ public enum ColorValues public enum FilterTypes { /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// NEGATE, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// GRAYSCALE, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// BRIGHTNESS, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// CONTRAST, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// COLORIZE, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// EDGEDETECT, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// EMBOSS, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// GAUSSIAN_BLUR, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// SELECTIVE_BLUR, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// MEAN_REMOVAL, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// SMOOTH, /// - /// Special GD filter used by the function. + /// Special GD filter used by the function. /// PIXELATE, } @@ -446,7 +444,7 @@ public static PhpResource imagecreatetruecolor(int x_size, int y_size) return img; } - static PhpGdImageResource imagecreatecommon(int x_size, int y_size, IConfigurationModule configuration, IImageFormat format) + static PhpGdImageResource imagecreatecommon(int x_size, int y_size, IImageFormatConfigurationModule configuration, IImageFormat format) { if (x_size <= 0 || y_size <= 0) { @@ -471,7 +469,9 @@ public static PhpResource imagecreatefromstring(byte[] image) try { - return new PhpGdImageResource(Image.Load(image, out var format), format); + return new PhpGdImageResource( + Image.Load(image.AsSpan()) + ); } catch { @@ -561,7 +561,7 @@ public static PhpResource imagecreatefromxpm(Context ctx, string filename) return imagercreatefromfile(ctx, filename); } - static PhpGdImageResource imagercreatefromfile(Context ctx, string filename, IConfigurationModule formatOpt = null) + static PhpGdImageResource imagercreatefromfile(Context ctx, string filename, IImageFormatConfigurationModule formatOpt = null) { if (string.IsNullOrEmpty(filename)) { @@ -569,27 +569,27 @@ static PhpGdImageResource imagercreatefromfile(Context ctx, string filename, ICo return null; } - var configuration = (formatOpt == null) - ? Configuration.Default - : new Configuration(formatOpt); + var decoderOptions = (formatOpt == null) + ? new DecoderOptions() + : new DecoderOptions() { Configuration = new Configuration(formatOpt) } + ; Image img = null; - IImageFormat format = null; - + using (var stream = Utils.OpenStream(ctx, filename)) { if (stream != null) { try { - img = Image.Load(configuration, stream, out format); + img = Image.Load(decoderOptions, stream); } catch { } } } return (img != null) - ? new PhpGdImageResource(img, format) + ? new PhpGdImageResource(img) : null; } @@ -767,7 +767,7 @@ static Font CreateFontById(int fontInd) // TODO: cache statically // Get the first available of specified sans serif system fonts - var result = SystemFonts.TryFind("Consolas", out var fontFamily) || SystemFonts.TryFind("Lucida Console", out fontFamily) || SystemFonts.TryFind("Arial", out fontFamily) || SystemFonts.TryFind("Verdana", out fontFamily) || SystemFonts.TryFind("Tahoma", out fontFamily); + var result = SystemFonts.TryGet("Consolas", out var fontFamily) || SystemFonts.TryGet("Lucida Console", out fontFamily) || SystemFonts.TryGet("Arial", out fontFamily) || SystemFonts.TryGet("Verdana", out fontFamily) || SystemFonts.TryGet("Tahoma", out fontFamily); // Couldn't find the system font. if (!result) @@ -777,7 +777,7 @@ static Font CreateFontById(int fontInd) var fontStyle = FontStyle.Regular; if (fontInd == 3 || fontInd >= 5) { - if (fontFamily.IsStyleAvailable(FontStyle.Bold)) + if (fontFamily.TryGetMetrics(FontStyle.Bold, out _)) { fontStyle = FontStyle.Bold; } @@ -811,12 +811,7 @@ static Font CreateFontByFontFile(Context ctx, string font_file, double size) try { - family = new FontCollection().Install(font_stream.RawStream); // TODO: perf: global font collection cache - - if (family == null) - { - throw new InvalidDataException(); - } + family = new FontCollection().Add(font_stream.RawStream); // TODO: perf: global font collection cache } catch { @@ -830,19 +825,19 @@ static Font CreateFontByFontFile(Context ctx, string font_file, double size) FontStyle style; - if (family.IsStyleAvailable(FontStyle.Regular)) + if (family.TryGetMetrics(FontStyle.Regular, out _)) { style = FontStyle.Regular; } - else if (family.IsStyleAvailable(FontStyle.Bold)) + else if (family.TryGetMetrics(FontStyle.Bold, out _)) { style = FontStyle.Bold; } - else if (family.IsStyleAvailable(FontStyle.Italic)) + else if (family.TryGetMetrics(FontStyle.Italic, out _)) { style = FontStyle.Italic; } - else if (family.IsStyleAvailable(FontStyle.BoldItalic)) + else if (family.TryGetMetrics(FontStyle.BoldItalic, out _)) { style = FontStyle.BoldItalic; } @@ -1034,8 +1029,13 @@ public static bool imagerectangle(PhpResource im, int x1, int y1, int x2, int y2 var rect = new RectangleF(x1, y1, x2 - x1, y2 - y1); - var opt = new ShapeGraphicsOptions(); - opt.GraphicsOptions.Antialias = img.AntiAlias; + var opt = new DrawingOptions + { + GraphicsOptions = + { + Antialias = img.AntiAlias + } + }; img.Image.Mutate(o => o.Draw(opt, FromRGBA(col), 1.0f, rect)); @@ -1109,8 +1109,8 @@ public static bool imagesettile(PhpResource image, PhpResource tile) return null; } - var rendererOptions = new RendererOptions(font); - var textsize = TextMeasurer.Measure(text, rendererOptions); + var rendererOptions = new TextOptions(font); + var textsize = TextMeasurer.MeasureSize(text, rendererOptions); // text transformation: var matrix = (angle == 0.0) ? Matrix3x2.Identity : Matrix3x2.CreateRotation((float)(angle * -2.0 * Math.PI / 360.0f)); @@ -1213,9 +1213,11 @@ public static bool imageline(PhpResource im, int x1, int y1, int x2, int y2, int var img = PhpGdImageResource.ValidImage(im); if (img != null) { - var opt = new ShapeGraphicsOptions(); + var opt = new DrawingOptions(); opt.GraphicsOptions.Antialias = img.AntiAlias; - img.Image.Mutate(o => o.DrawLines(opt, GetAlphaColor(img, color), 1.0f, new PointF[] { new PointF(x1, y1), new PointF(x2, y2) })); + img.Image.Mutate( + o => o.DrawLine(opt, GetAlphaColor(img, color), 1.0f, new PointF[] { new PointF(x1, y1), new PointF(x2, y2) }) + ); return true; } @@ -1266,7 +1268,13 @@ static bool imagecopy(PhpResource dst_im, PhpResource src_im, int dst_x, int dst .Crop(new Rectangle(src_x, src_y, src_w, src_h)) .Resize(new Size(src_w, src_h)))) { - dst.Image.Mutate(o => o.DrawImage(cropped, opacity: opacity, location: new Point(dst_x, dst_y))); + dst.Image.Mutate( + o => o.DrawImage( + cropped, + opacity: opacity, + backgroundLocation: new Point(dst_x, dst_y) + ) + ); } } catch (Exception ex) @@ -1322,7 +1330,7 @@ public static bool imagegd(PhpResource im) return imagesave(ctx, im, to, (img, stream) => { // use the source's encoder: - var encoder = img.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance) as GifEncoder; + var encoder = img.Configuration.ImageFormatsManager.GetEncoder(GifFormat.Instance) as GifEncoder; // or use default encoding options encoder ??= new GifEncoder(); // TODO: ColorTableMode from allocated colors count? @@ -1350,8 +1358,8 @@ public static bool imagegd(PhpResource im) /// /// Runtime context. /// Image resource. - /// Optional. Filename or stream. If not specified the function saves the image to output stream. - /// Callback that actually save the image to given stream. Called when all checks pass. + /// Optional. Filename or stream. If not specified, the function saves the image to output stream. + /// Callback that actually saves the image to given stream. Called when all checks pass. /// True if save succeeded. static bool imagesave(Context ctx, PhpResource im, PhpValue to/* = null*/, Action, Stream> saveaction) { @@ -1518,7 +1526,7 @@ public static bool imageellipse(PhpResource im, int cx, int cy, int w, int h, lo var ellipse = new EllipsePolygon(cx, cy, w, h); - var opt = new ShapeGraphicsOptions(); + var opt = new DrawingOptions(); opt.GraphicsOptions.Antialias = img.AntiAlias; img.Image.Mutate(o => o.Draw(opt, GetAlphaColor(img, col), 1.0f, ellipse)); @@ -1536,7 +1544,7 @@ public static bool imagefilledellipse(PhpResource im, int cx, int cy, int w, int return false; var ellipse = new EllipsePolygon(cx, cy, w, h); - var opt = new ShapeGraphicsOptions(); + var opt = new DrawingOptions(); opt.GraphicsOptions.Antialias = img.AntiAlias; if (img.tiled != null) @@ -1674,9 +1682,11 @@ public static int imagecolorresolvealpha(PhpResource im, int red, int green, int static bool DrawText(PhpResource im, int fontInd, int x, int y, string text, long col, bool up = false) { - PhpGdImageResource img = PhpGdImageResource.ValidImage(im); + var img = PhpGdImageResource.ValidImage(im); if (img == null) + { return false; + } if (x < 0 || y < 0) return true; if (x > img.Image.Width || y > img.Image.Height) return true; @@ -1684,7 +1694,7 @@ static bool DrawText(PhpResource im, int fontInd, int x, int y, string text, lon var font = CreateFontById(fontInd); var color = FromRGBA(col); - var opt = new TextGraphicsOptions(); + var opt = new DrawingOptions(); opt.GraphicsOptions.Antialias = img.AntiAlias; if (up) @@ -1732,7 +1742,7 @@ static FontRectangle imagefontsize(int fontInd) var font = CreateFontById(fontInd); if (font != null) { - var size = TextMeasurer.Measure("X", new RendererOptions(font)); + var size = TextMeasurer.MeasureSize("X", new TextOptions(font)); if (arr == null || arr.Length <= fontInd) { @@ -1823,9 +1833,10 @@ public static bool imagefilledarc(PhpResource im, long cx, long cy, long w, long AdjustAnglesAndSize(ref w, ref h, ref s, ref e, ref range); // Path Builder object to be used in all the branches - PathBuilder pathBuilder = new PathBuilder(); + var pathBuilder = new PathBuilder(); var color = FromRGBA(col); - var pen = new Pen(color, 1); + + var pen = new SolidPen(color, 1); // edge points, used for both pie and chord PointF startingPoint = new PointF(cx + (int)(Math.Cos(s * Math.PI / 180) * (w / 2.0)), cy + (int)(Math.Sin(s * Math.PI / 180) * (h / 2.0))); @@ -2073,7 +2084,7 @@ public static bool imageopenpolygon(PhpResource image, PhpArray points, int num_ var pointsF = GetPointFsFromArray(points, num_points); - img.Image.Mutate(o => o.DrawLines(new Pen(FromRGBA(color), 1.0f), pointsF)); + img.Image.Mutate(o => o.DrawLine(new SolidPen(FromRGBA(color), 1.0f), pointsF)); return true; } @@ -2107,29 +2118,19 @@ static bool Polygon(PhpResource im, PhpArray point, int num_points, long col, bo if (filled) { - IBrush brush; - - switch (col) + var brush = col switch { - case (long)ColorValues.TILED: - brush = img.tiled; - break; - case (long)ColorValues.STYLED: - brush = img.styled; - break; - case (long)ColorValues.BRUSHED: - brush = img.brushed; - break; - default: - brush = new SolidBrush(FromRGBA(col)); - break; - } + (long)ColorValues.TILED => img.tiled, + (long)ColorValues.STYLED => img.styled, + (long)ColorValues.BRUSHED => img.brushed, + _ => new SolidBrush(FromRGBA(col)) + }; img.Image.Mutate(o => o.FillPolygon(brush, points)); } else { - img.Image.Mutate(o => o.DrawPolygon(new Pen(FromRGBA(col), 1.0f), points)); + img.Image.Mutate(o => o.DrawPolygon(new SolidPen(FromRGBA(col), 1.0f), points)); } return true; diff --git a/src/Peachpie.Library.Graphics/PhpGdImageResource.cs b/src/Peachpie.Library.Graphics/PhpGdImageResource.cs index 93524ebf35..e1e627f00c 100644 --- a/src/Peachpie.Library.Graphics/PhpGdImageResource.cs +++ b/src/Peachpie.Library.Graphics/PhpGdImageResource.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; using Pchp.Core; @@ -58,10 +56,10 @@ internal set internal Rgba32 transparentColor; internal bool IsTransparentColSet = false; - - internal IBrush styled = null; - internal IBrush brushed = null; - internal IBrush tiled = null; + + internal Brush styled = null; + internal Brush brushed = null; + internal Brush tiled = null; internal int LineThickness = 1; @@ -72,7 +70,7 @@ private PhpGdImageResource() { } - internal PhpGdImageResource(int x, int y, IConfigurationModule configuration, IImageFormat format) + internal PhpGdImageResource(int x, int y, IImageFormatConfigurationModule configuration, IImageFormat format) : this(new TImage(new Configuration(configuration), x, y), format) { } @@ -80,7 +78,7 @@ internal PhpGdImageResource(int x, int y, IConfigurationModule configuration, II /// /// Creates PhpGdImageResource without creating internal image. /// - internal PhpGdImageResource(TImage/*!*/image, IImageFormat format) + internal PhpGdImageResource(TImage/*!*/image, IImageFormat format = null) : this() { Debug.Assert(image != null); @@ -90,7 +88,7 @@ internal PhpGdImageResource(TImage/*!*/image, IImageFormat format) // _image = image; - _format = format; + _format = format ?? image.Metadata.DecodedImageFormat; } static void RemoveFramesRange(TImage/*!*/image, int from, int count) diff --git a/src/Peachpie.Runtime/Variables.cs b/src/Peachpie.Runtime/Variables.cs index 5bbb2c1d17..7bbf073c16 100644 --- a/src/Peachpie.Runtime/Variables.cs +++ b/src/Peachpie.Runtime/Variables.cs @@ -522,14 +522,14 @@ public static bool IsDouble(this PhpValue value) /// /// Alias to . /// - public static string AsString(this PhpValue value) => ToStringOrNull(value); + public static string? AsString(this PhpValue value) => ToStringOrNull(value); /// /// In case given value contains a string ( or ), /// its string representation is returned. /// Otherwise null. /// - public static string ToStringOrNull(this PhpValue value) + public static string? ToStringOrNull(this PhpValue value) { IsString(value, out var @string); return @string; @@ -607,7 +607,7 @@ public static byte[] ToBytes(this PhpValue value, Context ctx) /// Checks the value is of type string or &string and gets its value. /// Single-byte strings are decoded using UTF-8. /// - public static bool IsString(this PhpValue value, out string @string) => value.IsStringImpl(out @string); + public static bool IsString(this PhpValue value, [MaybeNullWhen(false)]out string @string) => value.IsStringImpl(out @string); /// /// Checks the value is constructed as mutable .