Beispiel #1
0
        public void Draw(Texture2D texture, RectangleF targetRectangle, RectangleF?sourceRectangle, Color color, Vector2 origin, QuadEffects effects, float layerDepth)
        {
            PrepareGroup();

            if (targetRectangle.Width == 0 || targetRectangle.Height == 0)
            {
                // Empty draw, ignore it
                return;
            }

            var bounds = texture.Bounds;
            var s      = new Vector2I(bounds.Width, bounds.Height);

            var entry = new BatchEntry();

            entry.Texture       = texture;
            entry.Color         = color;
            entry.SourceRect    = sourceRectangle ?? new RectangleF(0, 0, s.X, s.Y);
            entry.Origin        = origin;
            entry.SpriteEffects = effects;
            entry.Transform     =
                Matrix.CreateScale(targetRectangle.Width / entry.SourceRect.Width, targetRectangle.Height / entry.SourceRect.Height, 1.0f) *
                Matrix.CreateTranslation(targetRectangle.X, targetRectangle.Y, 0);

            currentBatch.Entries.Add(entry);
        }
Beispiel #2
0
        public void Draw(DrawArgs args)
        {
            Vector3 c_pos = CameraManager.Current.position;
            float c_dist = (float)(Math.Pow(args.Position.X - c_pos.X, 2) + Math.Pow(args.Position.Y - c_pos.Y, 2) + Math.Pow(args.Position.Y - c_pos.Y, 2));

            BatchEntry r = new BatchEntry(this, c_dist, (DrawArgs)args.Clone());
            BatchManager.Current.Add(r);
        }
Beispiel #3
0
        private static void CreateBatchAction(BatchEntry batch, int durationOverride)
        {
            PageStorage <ManualActionExecutionData> .Instance.StorageData.Name          = batch.Name;
            PageStorage <ManualActionExecutionData> .Instance.StorageData.ExecutionList = new List <ManualActionExecutionData.ManualActionExecution>()
            {
                new ManualActionExecutionData.ManualActionExecution(batch.ChannelId, batch.Duration, batch.ActivateMasterChannel, durationOverride)
            };
            PageStorage <ManualActionExecutionData> .Instance.Save();

            PageStorage <ManualActionExecutionData> .Instance.StorageData.Name          = "";
            PageStorage <ManualActionExecutionData> .Instance.StorageData.ExecutionList = null;
        }
Beispiel #4
0
        public void Draw(FontLayout layout)
        {
            PrepareGroup();

            if (layout.Layout.Count == 0)
            {
                return;
            }

            var     areaSize = layout.Area.Size;
            Vector2 origin   = Vector2.Zero;

            switch (layout.Alignment)
            {
            case AlignmentType.NorthWest: break;

            case AlignmentType.SouthWest: origin.Y = areaSize.Y; break;

            case AlignmentType.West: origin.Y = areaSize.Y / 2; break;

            case AlignmentType.Center: origin = areaSize / 2; break;

            case AlignmentType.North: origin.X = areaSize.X / 2; break;

            case AlignmentType.NorthEast: origin.X = areaSize.X; break;

            case AlignmentType.East: origin.X = areaSize.X; origin.Y = areaSize.Y / 2; break;

            case AlignmentType.SouthEast: origin.X = areaSize.X; origin.Y = areaSize.Y; break;

            case AlignmentType.South: origin.X = areaSize.X / 2; origin.Y = areaSize.Y; break;
            }

            foreach (var c in layout.Layout)
            {
                var entry = new BatchEntry();
                entry.Texture       = c.Texture;
                entry.Color         = c.Color;
                entry.SourceRect    = c.Source;
                entry.Origin        = Vector2.Zero;
                entry.SpriteEffects = QuadEffects.RoundPositions;

                // TODO: Optimize
                entry.Transform =
                    Matrix.CreateTranslation(-origin.X + c.Offset.X, -origin.Y + c.Offset.Y, 0)
                    * Matrix.CreateScale(layout.Scale.X, layout.Scale.Y, 1)
                    * Matrix.CreateTranslation(origin.X + layout.Position.X, origin.Y + layout.Position.Y, 0);

                currentBatch.Entries.Add(entry);
            }
        }
Beispiel #5
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="text"></param>
            /// <param name="position"></param>
            /// <param name="cameraZoom"></param>
            /// <param name="font"></param>
            /// <param name="textColor"></param>
            /// <param name="outlineColor"></param>
            /// <param name="outlineWidth"></param>
            /// <param name="clipRect">Rect to clip against.  Note this will be inflated to compensate for outline width.</param>
            /// <param name="scaling"></param>
            /// <returns></returns>
            public static BatchEntry CreateEntry(string text, Vector2 position, float cameraZoom, SystemFont font, Color textColor, Color outlineColor = default(Color), float outlineWidth = 0, RectangleF clipRect = default(RectangleF), Vector2 scaling = default(Vector2))
            {
                BatchEntry entry = null;

                if (freeEntries.Count > 0)
                {
                    entry = freeEntries[freeEntries.Count - 1];
                    freeEntries.RemoveAt(freeEntries.Count - 1);
                }
                else
                {
                    entry = new BatchEntry();
                }

                if (scaling == default(Vector2))
                {
                    scaling = Vector2.One;
                }

                entry.cameraZoom = cameraZoom;
                entry.scaling    = scaling;
                entry.text       = text;

                // Adjust position for cameraZoom and outline thickness.
                entry.position = cameraZoom * position;

                entry.font      = font;
                entry.textColor = textColor;

                Vector2 textSize = font.MeasureString(text);

                entry.size = new SizeF(textSize.X + 2.0f * cameraZoom * outlineWidth, textSize.Y);
                if (clipRect == default(RectangleF))
                {
                    // No clipRect was given so make one to fit the text.
                    entry.clipRect = new System.Drawing.RectangleF(position.X * cameraZoom, position.Y * cameraZoom, entry.size.Width, entry.size.Height);
                }
                else
                {
                    entry.clipRect = new System.Drawing.RectangleF(clipRect.X * cameraZoom, clipRect.Y * cameraZoom, clipRect.Width * cameraZoom, clipRect.Height * cameraZoom);
                }
                // Inflate clipRect to account for outline width.
                entry.clipRect.Inflate(cameraZoom * outlineWidth, cameraZoom * outlineWidth);

                entry.outlineColor = outlineColor;
                entry.outlineWidth = outlineWidth;

                return(entry);
            } // end of CreateEntry()
Beispiel #6
0
        public void Draw(Texture2D texture, Matrix transform, Color color, Vector2 origin, float layerDepth)
        {
            PrepareGroup();

            var bounds = texture.Bounds;
            var s      = new Vector2I(bounds.Width, bounds.Height);

            var entry = new BatchEntry();

            entry.Texture    = texture;
            entry.Color      = color;
            entry.SourceRect = new RectangleF(0, 0, s.X, s.Y);
            entry.Transform  = transform;
            entry.Origin     = origin;

            currentBatch.Entries.Add(entry);
        }
Beispiel #7
0
        }   // end of StartBatch()

        /// <summary>
        ///
        /// </summary>
        /// <param name="text"></param>
        /// <param name="position">Position for rendering.</param>
        /// <param name="clipRect">Rect to clip text to.</param>
        /// <param name="font"></param>
        /// <param name="textColor"></param>
        /// <param name="scaling">Only applied to text, not rect.</param>
        /// <param name="outlineColor"></param>
        /// <param name="outlineWidth"></param>
        /// <returns></returns>
        public static Vector2 DrawString(string text, Vector2 position, RectangleF clipRect, SystemFont font, Color textColor, Vector2 scaling = default(Vector2), Color outlineColor = default(Color), float outlineWidth = 0)
        {
            Debug.Assert(inBatch, "You must call StartBatch() before this and EndBatch() when done.");

            if (scaling == default(Vector2))
            {
                scaling = Vector2.One;
            }

            float zoom = camera != null ? camera.Zoom : 1.0f;

            if (zoom != 1.0f)
            {
                // Create a new version of the font matching the zoom.
                font = GetSystemFont(font.Font.Name, font.Font.Size * zoom, font.Font.Style);
            }

            BatchEntry entry = BatchEntry.CreateEntry(text, position, zoom, font, textColor, outlineColor, outlineWidth, clipRect, scaling);

            entries.Add(entry);

            return(new Vector2(entry.size.Width, entry.size.Height));
        }   // end of DrawString()
Beispiel #8
0
        public BatchPage(BatchEntry batch, ManualPage parent) : base("div")
        {
            const int labelSize = 100;

            _batch = batch;
            SetBorder(BorderKind.Rounded, StylingColor.Secondary);

            #region Initialize Grid

            Grid grid = new Grid(this);
            grid.AddStyling(StylingOption.MarginRight, 2);
            grid.AddStyling(StylingOption.MarginLeft, 2);
            grid.AddStyling(StylingOption.MarginTop, 4);
            grid.AddStyling(StylingOption.MarginBottom, 2);

            #endregion Initialize Grid

            #region JobName

            MultiInputGroup batchNameMultiInputGroup = new MultiInputGroup();
            batchNameMultiInputGroup.AppendLabel("BatchName", labelSize);
            StylableTextInput batchNameTextInput = batchNameMultiInputGroup.AppendTextInput("Name?", startText: batch.Name);
            batchNameMultiInputGroup.AppendValidation("", "Ein Batch-Auftrag mit diesem Namen existiert bereits", false);
            batchNameMultiInputGroup.AppendCustomElement(new Button(StylingColor.Success, asOutline: true, text: "Namen übernehmen", fontAwesomeIcon: "save"), false).Click += (sender, args) =>
            {
                if (batchNameTextInput.Value == "")
                {
                    batchNameTextInput.SetValidation(false, true);
                    return;
                }
                if (PageStorage <ManualData> .Instance.StorageData.BatchEntries.Any(entry => entry.Name == batchNameTextInput.Value))
                {
                    if (batch.Name == batchNameTextInput.Value)
                    {
                        return;
                    }
                    else
                    {
                        batchNameTextInput.SetValidation(false, true);
                    }
                }
                else
                {
                    batchNameTextInput.SetValidation(true, false);
                    foreach (BatchEntry entry in PageStorage <ManualData> .Instance.StorageData.JobEntries.SelectMany(
                                 entry => entry.BatchEntries.Where(batchEntry =>
                                                                   batchEntry.Name == batch.Name && batchEntry != batch)))
                    {
                        entry.Name = batchNameTextInput.Value;
                    }
                    batch.Name = batchNameTextInput.Value;
                    parent.UpdateBatch();
                }
            };

            Button deleteJobButton = batchNameMultiInputGroup.AppendCustomElement(new Button(StylingColor.Danger, asOutline: true, text: "Batch-Auftrag Löschen", fontAwesomeIcon: "trash"), false);
            deleteJobButton.Click += (sender, args) =>
            {
                const string confirmMessage = "Wirklich Löschen";
                if (deleteJobButton.Text != confirmMessage)
                {
                    deleteJobButton.Text = confirmMessage;
                    return;
                }
                else
                {
                    PageStorage <ManualData> .Instance.StorageData.BatchEntries.Remove(batch);

                    List <JobEntry> removeList = new List <JobEntry>();

                    foreach (JobEntry entry in PageStorage <ManualData> .Instance.StorageData.JobEntries.Where(entry =>
                                                                                                               entry.BatchEntries.Any(batchEntry => batchEntry.Name == batch.Name)))
                    {
                        entry.BatchEntries.RemoveAll(batchEntry => batchEntry.Name == batch.Name);
                        if (entry.BatchEntries.Count == 0)
                        {
                            removeList.Add(entry);
                        }
                    }

                    foreach (JobEntry jobEntry in removeList)
                    {
                        PageStorage <ManualData> .Instance.StorageData.JobEntries.Remove(jobEntry);
                    }

                    parent.UpdateBatch();
                    parent.UpdateJobs();
                }
            };

            batchNameMultiInputGroup.AddStyling(StylingOption.MarginBottom, 2);
            grid.AddRow().AppendCollum(batchNameMultiInputGroup, autoSize: true);

            MultiInputGroup batchActionMultiInputGroup = new MultiInputGroup();
            batchActionMultiInputGroup.AppendLabel("Aktion", labelSize);
            batchActionMultiInputGroup.AppendLabel(batch.ToString());
            batchActionMultiInputGroup.AddStyling(StylingOption.MarginBottom, 1);
            grid.AddRow().AppendCollum(batchActionMultiInputGroup, autoSize: true);

            #endregion JobName

            #region ExecuteAction

            #region Init Container

            Container firstContainer = new Container();
            firstContainer.SetBorder(BorderKind.Rounded, StylingColor.Info);
            firstContainer.AddStyling(StylingOption.MarginTop, 3);
            firstContainer.AddStyling(StylingOption.MarginBottom, 1);
            firstContainer.AddStyling(StylingOption.PaddingTop, 3);
            firstContainer.AddStyling(StylingOption.PaddingBottom, 2);
            grid.AddRow().AppendCollum(firstContainer, autoSize: true);

            #endregion Init Container

            #region create Heading

            Heading firstHeading = new Heading(5, "Batch Ausführen ...");
            firstContainer.AppendChild(firstHeading);

            #endregion create Heading

            #region Override

            OverrideInputGroup overrideInputGroup = new OverrideInputGroup(100);
            firstContainer.AppendChild(overrideInputGroup);

            #endregion Override

            #region StartButton

            Button startButton = new Button(StylingColor.Success, true, text: "Einreihen!", fontAwesomeIcon: "plus-circle", asBlock: true);
            firstContainer.AppendChild(startButton);
            startButton.Click += (o, args) =>
            {
                startButton.IsDisabled = true;
                try
                {
                    CreateBatchAction(batch, overrideInputGroup.Value);

                    startButton.Text = "Wurde Eingereiht";
                    Task.Run(() =>
                    {
                        System.Threading.Thread.Sleep(5000);
                        startButton.Text = "Einreihen!";
                        startButton.SetFontAwesomeIcon("plus-circle");
                        return(startButton.IsDisabled = false);
                    });
                }
                catch (Exception)
                {
                    startButton.Text = "Einreihen fehlgeschlagen";
                    throw;
                }
            };
            firstContainer.AppendChild(startButton);
            startButton.AddStyling(StylingOption.MarginBottom, 2);

            #endregion StartButton

            #endregion ExecuteAction

            #region AddToJob

            #region Init Container

            Container secondContainer = new Container();
            secondContainer.SetBorder(BorderKind.Rounded, StylingColor.Info);
            secondContainer.AddStyling(StylingOption.MarginTop, 3);
            secondContainer.AddStyling(StylingOption.MarginBottom, 1);
            secondContainer.AddStyling(StylingOption.PaddingTop, 3);
            secondContainer.AddStyling(StylingOption.PaddingBottom, 2);
            grid.AddRow().AppendCollum(secondContainer, autoSize: true);

            #endregion Init Container

            #region create Heading

            Heading heading = new Heading(5, "... zu Job-Auftrag hinzufügen");
            secondContainer.AppendChild(heading);

            #endregion create Heading

            #region JobName Input

            _jobNameMultiInputGroup = new MultiInputGroup();
            _jobNameMultiInputGroup.AddStyling(StylingOption.MarginTop, 4);
            _jobNameMultiInputGroup.AppendLabel("Name für den Job-Auftrag:");
            StylableTextInput jobNameTextInput = _jobNameMultiInputGroup.AppendTextInput("Name?");
            _jobNameMultiInputGroup.AppendValidation("", "Es gibt bereits einen Job mit diesem Namen", false);
            _jobNameMultiInputGroup.IsHidden = true;
            secondContainer.AppendChild(_jobNameMultiInputGroup);

            #endregion JobName Input

            #region jobSelect

            MultiInputGroup jobSelectMultiInputGroup = new MultiInputGroup();
            jobSelectMultiInputGroup.AddStyling(StylingOption.MarginTop, 4);
            jobSelectMultiInputGroup.AppendLabel("Ziel Job:");
            _jobSelectDropdown = jobSelectMultiInputGroup.AppendCustomElement(new Dropdown(new Button(StylingColor.Secondary, true, text: "Bitte Wählen!"), DropdownDirection.DropDown), false);
            FillJobDropDown();
            jobSelectMultiInputGroup.AppendValidation("", "Dieser Batch-Auftrag ist bereits Bestandteil des Jobs", true);
            secondContainer.AppendChild(jobSelectMultiInputGroup);

            #endregion jobSelect

            #region Appent To Job or Create New

            _appendToJobButton = new Button(StylingColor.Success, true, text: "Zu Job-Auftrag hinzufügen", fontAwesomeIcon: "save", asBlock: true);
            _appendToJobButton.AddStyling(StylingOption.MarginTop, 2);
            _appendToJobButton.Click += (sender, args) =>
            {
                if (batchNameTextInput.Value == "")
                {
                    jobNameTextInput.SetValidation(false, true);
                    return;
                }
                if (_jobSelectDropdown.Button.Text == NewJobString)
                {
                    if (PageStorage <ManualData> .Instance.StorageData.JobEntries.Any(entry => entry.Name == jobNameTextInput.Value) || jobNameTextInput.Value == "")
                    {
                        // Invalid entered Name
                        jobNameTextInput.SetValidation(false, true);
                    }
                    else
                    {
                        // Create Job
                        jobNameTextInput.SetValidation(true, false);
                        PageStorage <ManualData> .Instance.StorageData.JobEntries.Add(new JobEntry(jobNameTextInput.Value, batch));

                        parent.UpdateJobs();
                        _jobNameMultiInputGroup.IsHidden = true;
                        _jobSelectDropdown.Button.Text   = jobNameTextInput.Value;

                        _appendToJobButton.IsHidden   = true;
                        _removeFromJobButton.IsHidden = false;
                    }
                }
                else
                {
                    jobNameTextInput.SetValidation(false, false);

                    // Add To Job
                    PageStorage <ManualData> .Instance.StorageData.JobEntries.First(entry => entry.Name == _jobSelectDropdown.Button.Text).BatchEntries.Add(batch);

                    parent.UpdateJobs();

                    _appendToJobButton.IsHidden   = true;
                    _removeFromJobButton.IsHidden = false;
                }
            };
            secondContainer.AppendChild(_appendToJobButton);

            #endregion Appent To Job or Create New

            #region Remove From Job

            _removeFromJobButton = new Button(StylingColor.Danger, true, text: "Aus Job löschen", fontAwesomeIcon: "trash", asBlock: true);
            _removeFromJobButton.AddStyling(StylingOption.MarginTop, 2);
            _removeFromJobButton.IsHidden = true;
            _removeFromJobButton.Click   += (sender, args) =>
            {
                if (PageStorage <ManualData> .Instance.StorageData.JobEntries.Any(entry => entry.Name == _jobSelectDropdown.Button.Text))
                {
                    JobEntry jobEntry = PageStorage <ManualData> .Instance.StorageData.JobEntries.First(entry => entry.Name == _jobSelectDropdown.Button.Text);

                    jobEntry.BatchEntries.RemoveAll(entry => entry.Name == _batch.Name);
                    if (jobEntry.BatchEntries.Count == 0)
                    {
                        PageStorage <ManualData> .Instance.StorageData.JobEntries.Remove(jobEntry);
                    }
                }
                _removeFromJobButton.IsHidden = true;
                _appendToJobButton.IsHidden   = false;
                FillJobDropDown();
                parent.UpdateJobs();
            };
            secondContainer.AppendChild(_removeFromJobButton);

            #endregion Remove From Job

            #endregion AddToJob
        }
Beispiel #9
0
        private void Render(RenderQueue.Batch renderBatch)
        {
            var batch   = (Batch)renderBatch;
            var entries = batch.Entries;

            if (entries.Count > 0)
            {
                RenderHelpers.SetBlendMode(blendMode);

                GL.Disable(EnableCap.CullFace);
                GL.Disable(EnableCap.DepthTest);
                //GL.Viewport(graphicsDevice.Viewport.X, graphicsDevice.BackBufferSize.Y - graphicsDevice.Viewport.Y - graphicsDevice.Viewport.Height, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height);

                currentEffect.Projection = Projection ?? CurrentContext.ActiveScreen.DefaultProjection;
                currentEffect.View       = transform;

                currentEffect.Enable();

                for (int i = 0; i < entries.Count;)
                {
                    int        quadIndex  = 0;
                    BatchEntry firstEntry = entries[i];
                    Texture2D  texture    = firstEntry.Texture;

                    if (AddEntry(ref firstEntry, quadIndex++) == 0)
                    {
                        Debug.WriteLine("Warning: out of QuadBatch capacity!");
                        break;
                    }

                    // Push in new quads until we reach a new texture
                    int entryCount = 1;
                    for (int j = i + 1; j < entries.Count; ++j)
                    {
                        BatchEntry futureEntry = entries[j];
                        if (futureEntry.Texture != texture)
                        {
                            break;
                        }

                        int added = AddEntry(ref futureEntry, quadIndex++);
                        if (added == 0)
                        {
                            Debug.WriteLine("Warning: out of QuadBatch capacity!");
                        }
                        entryCount += added;                         // If we're out of entry slots, do not increase entryCount
                    }

                    // Set texture
                    GL.BindTexture(TextureTarget.Texture2D, texture.textureId);
                    RenderHelpers.SetSamplers(textureSampling);

                    GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjects[0]);
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(entryCount * 6 * Vertex2Tex2Color.GetSize()), quads, BufferUsageHint.DynamicDraw);
                    //GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, (IntPtr)(entryCount * 6 * Vertex2Tex2Color.GetSize()), quads);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, vertexBufferObjects[1]);

                    if (currentEffect.ColorAttribute.HasValue)
                    {
                        GL.VertexAttribPointer(currentEffect.ColorAttribute.Value, 4, VertexAttribPointerType.UnsignedByte, true, Vertex2Tex2Color.GetSize(), sizeof(float) * 2);
                    }

                    GL.VertexAttribPointer(currentEffect.VertexAttribute, 2, VertexAttribPointerType.Float, false, Vertex2Tex2Color.GetSize(), 0);
                    GL.VertexAttribPointer(currentEffect.TextureCoordinatesAttribute, 2, VertexAttribPointerType.Float, false, Vertex2Tex2Color.GetSize(), sizeof(float) * 2 + sizeof(byte) * 4);
                    GL.DrawElements(BeginMode.Triangles, entryCount * 6, DrawElementsType.UnsignedShort, 0);

                    i += entryCount;
                }

                entries.Clear();

                currentEffect.Disable();
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
            }

            // This group is done, recycle it to the pool
            batchPool.Delete(batch);
        }
Beispiel #10
0
        private int AddEntry(ref BatchEntry entry, int quadIndex)
        {
            if (quadIndex >= capacity)
            {
                return(0);
            }

            float contentScale = 1.0f;
            float w            = entry.SourceRect.Width;
            float h            = entry.SourceRect.Height;

            var      bounds      = entry.Texture.Bounds;
            Vector2I realSize    = new Vector2I(bounds.Width, bounds.Height);
            float    atlasWidth  = realSize.X;
            float    atlasHeight = realSize.Y;
            Quad     q           = new Quad();

            Vector2 topLeft     = new Vector2(-entry.Origin.X, -entry.Origin.Y);
            Vector2 topRight    = new Vector2(topLeft.X + w, topLeft.Y);
            Vector2 bottomLeft  = new Vector2(topLeft.X, topLeft.Y + h);
            Vector2 bottomRight = new Vector2(topLeft.X + w, topLeft.Y + h);

            topLeft     = Vector2.Transform(topLeft, entry.Transform);
            topRight    = Vector2.Transform(topRight, entry.Transform);
            bottomLeft  = Vector2.Transform(bottomLeft, entry.Transform);
            bottomRight = Vector2.Transform(bottomRight, entry.Transform);

            q.TopLeft.Position     = topLeft;
            q.TopRight.Position    = topRight;
            q.BottomLeft.Position  = bottomLeft;
            q.BottomRight.Position = bottomRight;

            if ((entry.SpriteEffects & QuadEffects.RoundPositions) != 0)
            {
                q.TopLeft.Position.X     = (int)q.TopLeft.Position.X;
                q.TopLeft.Position.Y     = (int)q.TopLeft.Position.Y;
                q.TopRight.Position.X    = (int)q.TopRight.Position.X;
                q.TopRight.Position.Y    = (int)q.TopRight.Position.Y;
                q.BottomLeft.Position.X  = (int)q.BottomLeft.Position.X;
                q.BottomLeft.Position.Y  = (int)q.BottomLeft.Position.Y;
                q.BottomRight.Position.X = (int)q.BottomRight.Position.X;
                q.BottomRight.Position.Y = (int)q.BottomRight.Position.Y;
            }

            q.TopLeft.Color     = entry.Color;
            q.TopRight.Color    = entry.Color;
            q.BottomLeft.Color  = entry.Color;
            q.BottomRight.Color = entry.Color;

            float left, right, top, bottom;

            {
                left   = entry.SourceRect.X * contentScale / atlasWidth;
                right  = left + entry.SourceRect.Width * contentScale / atlasWidth;
                top    = entry.SourceRect.Y * contentScale / atlasHeight;
                bottom = top + entry.SourceRect.Height * contentScale / atlasHeight;

                if ((entry.SpriteEffects & QuadEffects.FlipHorizontally) != 0)
                {
                    var temp = left;
                    left  = right;
                    right = temp;
                }

                if ((entry.SpriteEffects & QuadEffects.FlipVertically) != 0)
                {
                    var temp = top;
                    top    = bottom;
                    bottom = temp;
                }

                q.BottomLeft.TextureCoordinate.X  = left;
                q.BottomLeft.TextureCoordinate.Y  = bottom;
                q.BottomRight.TextureCoordinate.X = right;
                q.BottomRight.TextureCoordinate.Y = bottom;
                q.TopLeft.TextureCoordinate.X     = left;
                q.TopLeft.TextureCoordinate.Y     = top;
                q.TopRight.TextureCoordinate.X    = right;
                q.TopRight.TextureCoordinate.Y    = top;
            }

            quads[quadIndex] = q;
            return(1);
        }