public static PhpArray imagettftext(Context ctx, PhpResource im, double size, double angle, int x, int y, long color, string font_file, string text) { var img = PhpGdImageResource.ValidImage(im); if (img == null) { return(null); } if (string.IsNullOrEmpty(font_file)) { PhpException.Throw(PhpError.Warning, Resources.filename_cannot_be_empty); return(null); } var font_stream = PhpStream.Open(ctx, font_file, "rb"); if (font_stream == null) { PhpException.Throw(PhpError.Warning, Resources.invalid_font_filename, font_file); return(null); } // Font preparation FontFamily family; try { family = new FontCollection().Install(font_stream.RawStream); // TODO: perf: global font collection cache if (ReferenceEquals(family, null)) { throw new InvalidOperationException(); } } catch { PhpException.Throw(PhpError.Warning, Resources.invalid_font_filename, font_file); return(null); } finally { font_stream.Dispose(); } FontStyle style; if (family.IsStyleAvailible(FontStyle.Regular)) { style = FontStyle.Regular; } else if (family.IsStyleAvailible(FontStyle.Bold)) { style = FontStyle.Bold; } else if (family.IsStyleAvailible(FontStyle.Italic)) { style = FontStyle.Italic; } else if (family.IsStyleAvailible(FontStyle.BoldItalic)) { style = FontStyle.BoldItalic; } else { return(null); } var font = new Font(family, (float)size, style); var textsize = TextMeasurer.Measure(text, new RendererOptions(font)); // text transformation: var matrix = (angle == 0.0) ? Matrix3x2.Identity : Matrix3x2.CreateRotation((float)(angle * -2.0 * Math.PI / 360.0f)); matrix.Translation = new Vector2(x, y); var path = new SixLabors.Shapes.PathBuilder(matrix).AddLine(0, 0, textsize.Width, 0).Build(); // draw the text: // TODO: col < 0 => turn off antialiasing img.Image.DrawText(text, font, FromRGBA(Math.Abs(color)), path); // calculate drawen text boundaries: var pts = new Vector2[] { new Vector2(0, textsize.Height), // lower left new Vector2(textsize.Width, textsize.Height), // lower right new Vector2(textsize.Width, 0), // upper right new Vector2(0, 0), // upper left }; for (int i = 0; i < pts.Length; i++) { pts[i] = Vector2.Transform(pts[i], matrix); } return(new PhpArray(8) { pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, pts[2].X, pts[2].Y, pts[3].X, pts[3].Y, }); }