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 .