Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #3626 from jmarshallnz/subs_ui_scaling

Fix subtitle scaling for text based subs during windowed video playback
  • Loading branch information...
commit 7f212b97039f986287c20f9852d8c99991b31d76 2 parents 8e2f2de + 7a554ca
@jmarshallnz jmarshallnz authored
View
25 xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp
@@ -151,16 +151,28 @@ void COverlayText::Render(OVERLAY::SRenderState &state)
if(m_layout == NULL)
return;
- /* until we can get gfx scaling correct in windowed mode, we must disable this */
- if(!g_graphicsContext.IsFullScreenVideo())
- return;
-
CRect rs, rd;
g_renderManager.GetVideoRect(rs, rd);
RESOLUTION_INFO res = g_graphicsContext.GetResInfo();
+ /* our coordinates are in screen coordinates constrained to rd, but the font is sized suitably for fullscreen,
+ so we must scale up the positioning to screen coordinates, and then scale down to our final size and position
+ on render */
+
+ /* transform matrix is scale and translate */
+ float scale = rd.Width() / (res.Overscan.right - res.Overscan.left);
+ TransformMatrix mat;
+ mat.m[0][0] = mat.m[1][1] = scale;
+ mat.m[3][0] = rd.x1;
+ mat.m[3][1] = rd.y1;
+
+ float x = state.x, y = state.y;
+ mat.InverseTransformPosition(x, y);
+
+ g_graphicsContext.SetTransform(mat, 1.0f, 1.0f);
+
float width_max = (float) res.Overscan.right - res.Overscan.left;
- float y, width, height;
+ float width, height;
m_layout->Update(m_text, width_max * 0.9f, false, true); // true to force LTR reading order (most Hebrew subs are this format)
m_layout->GetTextExtent(width, height);
@@ -175,5 +187,6 @@ void COverlayText::Render(OVERLAY::SRenderState &state)
y = std::max(y, (float) res.Overscan.top);
y = std::min(y, res.Overscan.bottom - height);
- m_layout->RenderOutline(state.x, y, 0, 0xFF000000, XBFONT_CENTER_X, width_max);
+ m_layout->RenderOutline(x, y, 0, 0xFF000000, XBFONT_CENTER_X, width_max);
+ g_graphicsContext.RemoveTransform();
}
View
31 xbmc/guilib/GraphicContext.cpp
@@ -53,15 +53,13 @@ CGraphicContext::CGraphicContext(void) :
m_bCalibrating(false),
m_Resolution(RES_INVALID),
/*m_windowResolution,*/
- m_guiScaleX(1.0f),
- m_guiScaleY(1.0f)
/*,m_cameras, */
/*m_origins, */
/*m_clipRegions,*/
/*m_guiTransform,*/
/*m_finalTransform, */
/*m_groupTransform*/
- , m_stereoView(RENDER_STEREO_VIEW_OFF)
+ m_stereoView(RENDER_STEREO_VIEW_OFF)
, m_stereoMode(RENDER_STEREO_MODE_OFF)
, m_nextStereoMode(RENDER_STEREO_MODE_OFF)
{
@@ -790,12 +788,10 @@ void CGraphicContext::SetScalingResolution(const RESOLUTION_INFO &res, bool need
Lock();
m_windowResolution = res;
if (needsScaling && m_Resolution != RES_INVALID)
- GetGUIScaling(res, m_guiScaleX, m_guiScaleY, &m_guiTransform);
+ GetGUIScaling(res, m_guiTransform.scaleX, m_guiTransform.scaleY, &m_guiTransform.matrix);
else
{
m_guiTransform.Reset();
- m_guiScaleX = 1.0f;
- m_guiScaleY = 1.0f;
}
// reset our origin and camera
@@ -807,7 +803,7 @@ void CGraphicContext::SetScalingResolution(const RESOLUTION_INFO &res, bool need
m_cameras.push(CPoint(0.5f*m_iScreenWidth, 0.5f*m_iScreenHeight));
// and reset the final transform
- UpdateFinalTransform(m_guiTransform);
+ m_finalTransform = m_guiTransform;
Unlock();
}
@@ -819,15 +815,6 @@ void CGraphicContext::SetRenderingResolution(const RESOLUTION_INFO &res, bool ne
Unlock();
}
-void CGraphicContext::UpdateFinalTransform(const TransformMatrix &matrix)
-{
- // We could set the world transform here to GPU-ize the animation system.
- // trouble is that we require the resulting x,y coords to be rounded to
- // the nearest pixel (vertex shader perhaps?)
- m_finalTransform.Reset();
- m_finalTransform *= matrix;
-}
-
void CGraphicContext::SetStereoView(RENDER_STEREO_VIEW view)
{
m_stereoView = view;
@@ -847,14 +834,14 @@ void CGraphicContext::SetStereoView(RENDER_STEREO_VIEW view)
void CGraphicContext::InvertFinalCoords(float &x, float &y) const
{
- m_finalTransform.InverseTransformPosition(x, y);
+ m_finalTransform.matrix.InverseTransformPosition(x, y);
}
float CGraphicContext::GetScalingPixelRatio() const
{
// assume the resolutions are different - we want to return the aspect ratio of the video resolution
// but only once it's been corrected for the skin -> screen coordinates scaling
- return GetResInfo().fPixelRatio * (m_guiScaleY / m_guiScaleX);
+ return GetResInfo().fPixelRatio * (m_finalTransform.scaleY / m_finalTransform.scaleX);
}
void CGraphicContext::SetCameraPosition(const CPoint &camera)
@@ -926,9 +913,9 @@ void CGraphicContext::UpdateCameraPosition(const CPoint &camera)
bool CGraphicContext::RectIsAngled(float x1, float y1, float x2, float y2) const
{ // need only test 3 points, as they must be co-planer
- if (m_finalTransform.TransformZCoord(x1, y1, 0)) return true;
- if (m_finalTransform.TransformZCoord(x2, y2, 0)) return true;
- if (m_finalTransform.TransformZCoord(x1, y2, 0)) return true;
+ if (m_finalTransform.matrix.TransformZCoord(x1, y1, 0)) return true;
+ if (m_finalTransform.matrix.TransformZCoord(x2, y2, 0)) return true;
+ if (m_finalTransform.matrix.TransformZCoord(x1, y2, 0)) return true;
return false;
}
@@ -1013,7 +1000,7 @@ void CGraphicContext::Flip(const CDirtyRegionList& dirty)
void CGraphicContext::ApplyHardwareTransform()
{
- g_Windowing.ApplyHardwareTransform(m_finalTransform);
+ g_Windowing.ApplyHardwareTransform(m_finalTransform.matrix);
}
void CGraphicContext::RestoreHardwareTransform()
View
72 xbmc/guilib/GraphicContext.h
@@ -140,17 +140,17 @@ class CGraphicContext : public CCriticalSection,
float GetScalingPixelRatio() const;
void Flip(const CDirtyRegionList& dirty);
void InvertFinalCoords(float &x, float &y) const;
- inline float ScaleFinalXCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.TransformXCoord(x, y, 0); }
- inline float ScaleFinalYCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.TransformYCoord(x, y, 0); }
- inline float ScaleFinalZCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.TransformZCoord(x, y, 0); }
- inline void ScaleFinalCoords(float &x, float &y, float &z) const XBMC_FORCE_INLINE { m_finalTransform.TransformPosition(x, y, z); }
+ inline float ScaleFinalXCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformXCoord(x, y, 0); }
+ inline float ScaleFinalYCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformYCoord(x, y, 0); }
+ inline float ScaleFinalZCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformZCoord(x, y, 0); }
+ inline void ScaleFinalCoords(float &x, float &y, float &z) const XBMC_FORCE_INLINE { m_finalTransform.matrix.TransformPosition(x, y, z); }
bool RectIsAngled(float x1, float y1, float x2, float y2) const;
- inline float GetGUIScaleX() const XBMC_FORCE_INLINE { return m_guiScaleX; }
- inline float GetGUIScaleY() const XBMC_FORCE_INLINE { return m_guiScaleY; }
+ inline float GetGUIScaleX() const XBMC_FORCE_INLINE { return m_finalTransform.scaleX; }
+ inline float GetGUIScaleY() const XBMC_FORCE_INLINE { return m_finalTransform.scaleY; }
inline color_t MergeAlpha(color_t color) const XBMC_FORCE_INLINE
{
- color_t alpha = m_finalTransform.TransformAlpha((color >> 24) & 0xff);
+ color_t alpha = m_finalTransform.matrix.TransformAlpha((color >> 24) & 0xff);
if (alpha > 255) alpha = 255;
return ((alpha << 24) & 0xff000000) | (color & 0xffffff);
}
@@ -200,34 +200,34 @@ class CGraphicContext : public CCriticalSection,
void ClipRect(CRect &vertex, CRect &texture, CRect *diffuse = NULL);
inline void AddGUITransform()
{
- m_groupTransform.push(m_guiTransform);
- UpdateFinalTransform(m_groupTransform.top());
+ m_transforms.push(m_finalTransform);
+ m_finalTransform = m_guiTransform;
}
inline TransformMatrix AddTransform(const TransformMatrix &matrix)
{
- ASSERT(!m_groupTransform.empty());
- TransformMatrix absoluteMatrix = m_groupTransform.empty() ? matrix : m_groupTransform.top() * matrix;
- m_groupTransform.push(absoluteMatrix);
- UpdateFinalTransform(absoluteMatrix);
- return absoluteMatrix;
+ m_transforms.push(m_finalTransform);
+ m_finalTransform.matrix *= matrix;
+ return m_finalTransform.matrix;
}
inline void SetTransform(const TransformMatrix &matrix)
{
- // TODO: We only need to add it to the group transform as other transforms may be added on top of this one later on
- // Once all transforms are cached then this can be removed and UpdateFinalTransform can be called directly
- ASSERT(!m_groupTransform.empty());
- m_groupTransform.push(matrix);
- UpdateFinalTransform(m_groupTransform.top());
+ m_transforms.push(m_finalTransform);
+ m_finalTransform.matrix = matrix;
+ }
+ inline void SetTransform(const TransformMatrix &matrix, float scaleX, float scaleY)
+ {
+ m_transforms.push(m_finalTransform);
+ m_finalTransform.matrix = matrix;
+ m_finalTransform.scaleX = scaleX;
+ m_finalTransform.scaleY = scaleY;
}
inline void RemoveTransform()
{
- ASSERT(!m_groupTransform.empty());
- if (!m_groupTransform.empty())
- m_groupTransform.pop();
- if (!m_groupTransform.empty())
- UpdateFinalTransform(m_groupTransform.top());
- else
- UpdateFinalTransform(TransformMatrix());
+ if (!m_transforms.empty())
+ {
+ m_finalTransform = m_transforms.top();
+ m_transforms.pop();
+ }
}
/* modifies final coordinates according to stereo mode if needed */
@@ -250,18 +250,26 @@ class CGraphicContext : public CCriticalSection,
RESOLUTION m_Resolution;
private:
+ class UITransform
+ {
+ public:
+ UITransform() : matrix(), scaleX(1.0f), scaleY(1.0f) {};
+ UITransform(const TransformMatrix &m, const float sX = 1.0f, const float sY = 1.0f) : matrix(m), scaleX(sX), scaleY(sY) { };
+ void Reset() { matrix.Reset(); scaleX = scaleY = 1.0f; };
+
+ TransformMatrix matrix;
+ float scaleX;
+ float scaleY;
+ };
void UpdateCameraPosition(const CPoint &camera);
- void UpdateFinalTransform(const TransformMatrix &matrix);
RESOLUTION_INFO m_windowResolution;
- float m_guiScaleX;
- float m_guiScaleY;
std::stack<CPoint> m_cameras;
std::stack<CPoint> m_origins;
std::stack<CRect> m_clipRegions;
- TransformMatrix m_guiTransform;
- TransformMatrix m_finalTransform;
- std::stack<TransformMatrix> m_groupTransform;
+ UITransform m_guiTransform;
+ UITransform m_finalTransform;
+ std::stack<UITransform> m_transforms;
RENDER_STEREO_VIEW m_stereoView;
RENDER_STEREO_MODE m_stereoMode;
RENDER_STEREO_MODE m_nextStereoMode;
Please sign in to comment.
Something went wrong with that request. Please try again.