예제 #1
0
        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,
            });
        }