BUG in GUIControl.OnPreRender
by Scott Goodwin · in Torque X 2D · 02/18/2008 (9:43 am) · 1 replies
In GUIControl.OnPreRender, the cases for wide/non-wide screen are reversed which affects letterboxing.
#region BUG(SDG)
// these cases are reversed
#if !SDG_APPLY_BUGFIXES
// widescreen
if (GFX.GFXDevice.IsWideScreen((int)_bounds.Width, (int)_bounds.Height))
{
// calculate as fixed width, adjusting the height based on how wide the
// display is, creating a horizontal letterbox on fullscreen displays
newBounds.Width = width;
newBounds.Height = width * ratio;
if (newBounds.Height > height)
newBounds.Height = height;
}
// non-widescreen
else
{
// calculate as fixed height, adjusting the width based on how tall the
// display is, creating a vertical letterbox on widescreen displays
newBounds.Height = height;
newBounds.Width = height * (1.0f / ratio);
if (newBounds.Width > width)
newBounds.Width = width;
}
#endif
#endregion
#region BUGFIX(SDG)
#if SDG_APPLY_BUGFIXES
// non-widescreen
if (!GFX.GFXDevice.IsWideScreen((int)_bounds.Width, (int)_bounds.Height))
{
// calculate as fixed width, adjusting the height based on how wide the
// display is, creating a horizontal letterbox on fullscreen displays
newBounds.Width = width;
newBounds.Height = width * ratio;
if (newBounds.Height > height)
newBounds.Height = height;
}
// widescreen
else
{
// calculate as fixed height, adjusting the width based on how tall the
// display is, creating a vertical letterbox on widescreen displays
newBounds.Height = height;
newBounds.Width = height * (1.0f / ratio);
if (newBounds.Width > width)
newBounds.Width = width;
}
#endif
#endregionAbout the author
Torque Owner Scott Goodwin
in the code below.
/// <summary> /// Called before GUIControl.OnRender. Allows for any special processing that is /// needed before rendering the control. /// </summary> public virtual void OnPreRender() { // all bottom level controls should be the same dimensions as the canvas // unless they wish to preserve aspect ratio #region BUG(SDG) // Even with the previous bug fix, this still doesn't work properly in some cases, // (all examples have PreserveAspectRatio=true) // e.g., canvas 1365x768 with ctrl 1024x768. needsResize is false. ctrl doesn't get centered. // e.g., canvas 1365x767 with ctrl 1024x768. needsResize is true. ctrl gets stretched! // e.g., canvas 1024x600 with ctrl 1024x768. needsResize is true. ctrl gets stretched! // etc. should also check case where isWidescreen=true, _bounds.Width != width, // will probably have cases where ctrl doesn't get centered---didn't verify this // Instead...let's just start fresh. #if !SDG_APPLY_BUGFIXES if (_style.PreserveAspectRatio) { float width = GUICanvas.Instance.Bounds.Width; float height = GUICanvas.Instance.Bounds.Height; bool isWidescreen = GFX.GFXDevice.IsWideScreen((int)_bounds.Width, (int)_bounds.Height); bool needsResize = isWidescreen ? (_bounds.Width != width) : (_bounds.Height != height); if (needsResize) { RectangleF newBounds = _bounds; // calculate preserved aspect dimensions float ratio = _bounds.Height / _bounds.Width; #region BUG(SDG) // these cases are reversed #if !SDG_APPLY_BUGFIXES // widescreen if (GFX.GFXDevice.IsWideScreen((int)_bounds.Width, (int)_bounds.Height)) { // calculate as fixed width, adjusting the height based on how wide the // display is, creating a horizontal letterbox on fullscreen displays newBounds.Width = width; newBounds.Height = width * ratio; if (newBounds.Height > height) newBounds.Height = height; } // non-widescreen else { // calculate as fixed height, adjusting the width based on how tall the // display is, creating a vertical letterbox on widescreen displays newBounds.Height = height; newBounds.Width = height * (1.0f / ratio); if (newBounds.Width > width) newBounds.Width = width; } #endif #endregion #region BUGFIX(SDG) #if SDG_APPLY_BUGFIXES // non-widescreen if (!GFXDevice.IsWideScreen((int)_bounds.Width, (int)_bounds.Height)) { // calculate as fixed width, adjusting the height based on how wide the // display is, creating a horizontal letterbox on fullscreen displays newBounds.Width = width; newBounds.Height = width * ratio; if (newBounds.Height > height) newBounds.Height = height; } // widescreen else { // calculate as fixed height, adjusting the width based on how tall the // display is, creating a vertical letterbox on widescreen displays newBounds.Height = height; newBounds.Width = height * (1.0f / ratio); if (newBounds.Width > width) newBounds.Width = width; } #endif #endregion // calculate center position newBounds.X = (width - newBounds.Width) / 2.0f; newBounds.Y = (height - newBounds.Height) / 2.0f; SetBounds(newBounds); } } else { if (_bounds != GUICanvas.Instance.Bounds) SetBounds(GUICanvas.Instance.Bounds); } #endif #endregion #region BUGFIX(SDG) // This is my proposed replacement for the above. #if SDG_APPLY_BUGFIXES if (_style.PreserveAspectRatio) { float canvasWidth = GUICanvas.Instance.Bounds.Width; float canvasHeight = GUICanvas.Instance.Bounds.Height; float canvasRatio = canvasHeight / canvasWidth; float ctrlWidth = _bounds.Width; float ctrlHeight = _bounds.Height; float ctrlRatio = ctrlHeight / ctrlWidth; RectangleF newCtrlBounds = _bounds; if (canvasRatio == ctrlRatio) { if (_bounds != GUICanvas.Instance.Bounds) // stretch/shrink SetBounds(GUICanvas.Instance.Bounds); } else if (canvasRatio > ctrlRatio) { newCtrlBounds.Width = canvasWidth; newCtrlBounds.Height = canvasWidth * ctrlRatio; if (newCtrlBounds.Height > canvasHeight) newCtrlBounds.Height = canvasHeight; // calculate center position newCtrlBounds.X = canvasWidth > newCtrlBounds.Width ? (canvasWidth - newCtrlBounds.Width) / 2.0f : 0; newCtrlBounds.Y = canvasHeight > newCtrlBounds.Height ? (canvasHeight - newCtrlBounds.Height) / 2.0f : 0; SetBounds(newCtrlBounds); } else // if (canvasRatio < ctrlRatio) { newCtrlBounds.Height = canvasHeight; newCtrlBounds.Width = canvasHeight * (1.0f / ctrlRatio); if (newCtrlBounds.Width > canvasWidth) newCtrlBounds.Width = canvasWidth; // calculate center position newCtrlBounds.X = canvasWidth > newCtrlBounds.Width ? (canvasWidth - newCtrlBounds.Width) / 2.0f : 0; newCtrlBounds.Y = canvasHeight > newCtrlBounds.Height ? (canvasHeight - newCtrlBounds.Height) / 2.0f : 0; SetBounds(newCtrlBounds); } } else // if (!_style.PreserveAspectRatio) { if (_bounds != GUICanvas.Instance.Bounds) SetBounds(GUICanvas.Instance.Bounds); } #endif #endregion }