[colobot] 49/145: Hack to finally fix #738

Didier Raboud odyx at moszumanska.debian.org
Mon Jul 11 12:56:16 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit 71a77c77f6d94c84b0aaf02772ea7d7d104b6cf9
Author: Piotr Dziwinski <piotrdz at gmail.com>
Date:   Wed Apr 6 22:21:41 2016 +1200

    Hack to finally fix #738
    
    Text rendering is now done in window coordinates corresponding to window
    pixels to avoid floating-point rounding errors that show up as rendering
    artifacts
---
 src/graphics/engine/engine.cpp |  31 ++++++++--
 src/graphics/engine/engine.h   |   3 +
 src/graphics/engine/text.cpp   | 130 +++++++++++++++++++++++++++++------------
 src/graphics/engine/text.h     |  10 ++--
 4 files changed, 127 insertions(+), 47 deletions(-)

diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 5b2fc6e..8b0b40e 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -3789,9 +3789,7 @@ void CEngine::DrawInterface()
     m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
     m_device->SetRenderState(RENDER_STATE_FOG, false);
 
-    m_device->SetTransform(TRANSFORM_VIEW,       m_matViewInterface);
-    m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
-    m_device->SetTransform(TRANSFORM_WORLD,      m_matWorldInterface);
+    SetInterfaceCoordinates();
 
     // Force new state to disable lighting
     m_interfaceMode = true;
@@ -3890,9 +3888,7 @@ void CEngine::DrawInterface()
 
         m_device->SetRenderMode(RENDER_MODE_INTERFACE);
 
-        m_device->SetTransform(TRANSFORM_VIEW,       m_matViewInterface);
-        m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
-        m_device->SetTransform(TRANSFORM_WORLD,      m_matWorldInterface);
+        SetInterfaceCoordinates();
     }
 
     // Draw foreground color
@@ -5184,4 +5180,27 @@ void CEngine::SetDebugGotoBitmap(std::unique_ptr<CImage> debugImage)
     UpdateGroundSpotTextures();
 }
 
+void CEngine::SetInterfaceCoordinates()
+{
+    m_device->SetTransform(TRANSFORM_VIEW,       m_matViewInterface);
+    m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
+    m_device->SetTransform(TRANSFORM_WORLD,      m_matWorldInterface);
+}
+
+void CEngine::SetWindowCoordinates()
+{
+    Math::Matrix matWorldWindow;
+    matWorldWindow.LoadIdentity();
+
+    Math::Matrix matViewWindow;
+    matViewWindow.LoadIdentity();
+
+    Math::Matrix matProjWindow;
+    Math::LoadOrthoProjectionMatrix(matProjWindow, 0.0f, m_size.x, m_size.y, 0.0f, -1.0f, 1.0f);
+
+    m_device->SetTransform(TRANSFORM_VIEW,       matViewWindow);
+    m_device->SetTransform(TRANSFORM_PROJECTION, matProjWindow);
+    m_device->SetTransform(TRANSFORM_WORLD,      matWorldWindow);
+}
+
 } // namespace Gfx
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index a64b8c3..1f5cfe8 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -1196,6 +1196,9 @@ public:
     void            AddDebugGotoLine(std::vector<Gfx::VertexCol> line);
     void            SetDebugGotoBitmap(std::unique_ptr<CImage> debugImage);
 
+    void            SetWindowCoordinates();
+    void            SetInterfaceCoordinates();
+
 protected:
     //! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
     /** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index 7ecf204..0af5723 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -214,7 +214,9 @@ void CText::DrawText(const std::string &text, std::vector<FontMetaChar>::iterato
         pos.x -= sw;
     }
 
-    DrawString(text, format, end, size, pos, width, eol, color);
+    Math::IntPoint intPos = m_engine->InterfaceToWindowCoords(pos);
+    int intWidth = width * m_engine->GetWindowSize().x;
+    DrawString(text, format, end, size, intPos, intWidth, eol, color);
 }
 
 void CText::DrawText(const std::string &text, FontType font,
@@ -236,7 +238,9 @@ void CText::DrawText(const std::string &text, FontType font,
         pos.x -= sw;
     }
 
-    DrawString(text, font, size, pos, width, eol, color);
+    Math::IntPoint intPos = m_engine->InterfaceToWindowCoords(pos);
+    int intWidth = width * m_engine->GetWindowSize().x;
+    DrawString(text, font, size, intPos, intWidth, eol, color);
 }
 
 void CText::SizeText(const std::string &text, std::vector<FontMetaChar>::iterator format,
@@ -322,6 +326,14 @@ float CText::GetHeight(FontType font, float size)
     return ifSize.y;
 }
 
+int CText::GetHeightInt(FontType font, float size)
+{
+    assert(font != FONT_BUTTON);
+
+    CachedFont* cf = GetOrOpenFont(font, size);
+    assert(cf != nullptr);
+    return TTF_FontHeight(cf->font);
+}
 
 float CText::GetStringWidth(const std::string &text,
                             std::vector<FontMetaChar>::iterator format,
@@ -416,6 +428,46 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset)
     return charSize.x * width;
 }
 
+int CText::GetCharWidthInt(UTF8Char ch, FontType font, float size, float offset)
+{
+    if (font == FONT_BUTTON)
+    {
+        Math::IntPoint windowSize = m_engine->GetWindowSize();
+        int height = GetHeightInt(FONT_COLOBOT, size);
+        int width = height*(static_cast<float>(windowSize.y)/windowSize.x);
+        return width;
+    }
+
+    int width = 1;
+    if (ch.c1 < 32 && ch.c1 >= 0)
+    {
+        if (ch.c1 == '\t')
+            width = m_tabSize;
+
+        // TODO: tab sizing at intervals?
+
+        ch.c1 = ':';
+    }
+
+    CachedFont* cf = GetOrOpenFont(font, size);
+    assert(cf != nullptr);
+
+    Math::IntPoint charSize;
+    auto it = cf->cache.find(ch);
+    if (it != cf->cache.end())
+    {
+        charSize = (*it).second.charSize;
+    }
+    else
+    {
+        std::string text;
+        text.append({ch.c1, ch.c2, ch.c3});
+        TTF_SizeUTF8(cf->font, text.c_str(), &charSize.x, &charSize.y);
+    }
+
+    return charSize.x * width;
+}
+
 
 int CText::Justify(const std::string &text, std::vector<FontMetaChar>::iterator format,
                    std::vector<FontMetaChar>::iterator end,
@@ -636,11 +688,11 @@ UTF8Char CText::TranslateSpecialChar(int specialChar)
 
 void CText::DrawString(const std::string &text, std::vector<FontMetaChar>::iterator format,
                        std::vector<FontMetaChar>::iterator end,
-                       float size, Math::Point pos, float width, int eol, Color color)
+                       float size, Math::IntPoint pos, int width, int eol, Color color)
 {
     m_engine->SetState(ENG_RSTATE_TEXT);
 
-    float start = pos.x;
+    int start = pos.x;
 
     unsigned int fmtIndex = 0;
 
@@ -654,12 +706,12 @@ void CText::DrawString(const std::string &text, std::vector<FontMetaChar>::itera
 
         UTF8Char ch = *it;
 
-        float offset = pos.x - start;
-        float cw = GetCharWidth(ch, font, size, offset);
+        int offset = pos.x - start;
+        int cw = GetCharWidthInt(ch, font, size, offset);
         if (offset + cw > width)  // exceeds the maximum width?
         {
             ch = TranslateSpecialChar(CHAR_SKIP_RIGHT);
-            cw = GetCharWidth(ch, font, size, offset);
+            cw = GetCharWidthInt(ch, font, size, offset);
             pos.x = start + width - cw;
             color = Color(1.0f, 0.0f, 0.0f);
             DrawCharAndAdjustPos(ch, font, size, pos, color);
@@ -700,9 +752,9 @@ void CText::DrawString(const std::string &text, std::vector<FontMetaChar>::itera
             }
             else
             {
-                Math::Point charSize;
-                charSize.x = GetCharWidth(ch, font, size, offset);
-                charSize.y = GetHeight(font, size);
+                Math::IntPoint charSize;
+                charSize.x = GetCharWidthInt(ch, font, size, offset);
+                charSize.y = GetHeightInt(font, size);
                 DrawHighlight(hl, pos, charSize);
             }
         }
@@ -788,7 +840,7 @@ void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &
 }
 
 void CText::DrawString(const std::string &text, FontType font,
-                       float size, Math::Point pos, float width, int eol, Color color)
+                       float size, Math::IntPoint pos, int width, int eol, Color color)
 {
     assert(font != FONT_BUTTON);
 
@@ -802,7 +854,7 @@ void CText::DrawString(const std::string &text, FontType font,
     }
 }
 
-void CText::DrawHighlight(FontHighlight hl, Math::Point pos, Math::Point size)
+void CText::DrawHighlight(FontHighlight hl, Math::IntPoint pos, Math::IntPoint size)
 {
     // Gradient colors
     Color grad[4];
@@ -827,9 +879,9 @@ void CText::DrawHighlight(FontHighlight hl, Math::Point pos, Math::Point size)
     Math::IntPoint vsize = m_engine->GetWindowSize();
     float h = 0.0f;
     if (vsize.y <= 768.0f)    // 1024x768 or less?
-        h = 1.01f / vsize.y;  // 1 pixel
+        h = 1.01f;  // 1 pixel
     else                      // more than 1024x768?
-        h = 2.0f / vsize.y;   // 2 pixels
+        h = 2.0f;   // 2 pixels
 
     Math::Point p1, p2;
     p1.x = pos.x;
@@ -856,22 +908,24 @@ void CText::DrawHighlight(FontHighlight hl, Math::Point pos, Math::Point size)
         VertexCol(Math::Vector(p2.x, p2.y, 0.0f), grad[1])
     };
 
+    m_engine->SetWindowCoordinates();
     m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+    m_engine->SetInterfaceCoordinates();
     m_engine->AddStatisticTriangle(2);
 
     m_device->SetTextureEnabled(0, true);
 }
 
-void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::Point &pos, Color color)
+void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::IntPoint &pos, Color color)
 {
-    if(font == FONT_BUTTON)
+    if (font == FONT_BUTTON)
     {
         Math::IntPoint windowSize = m_engine->GetWindowSize();
-        float height = GetHeight(FONT_COLOBOT, size);
-        float width = height*(static_cast<float>(windowSize.y)/windowSize.x);
+        int height = GetHeightInt(FONT_COLOBOT, size);
+        int width = height * (static_cast<float>(windowSize.y)/windowSize.x);
 
-        Math::Point p1(pos.x, pos.y);
-        Math::Point p2(pos.x + width, pos.y + height);
+        Math::IntPoint p1(pos.x, pos.y - height);
+        Math::IntPoint p2(pos.x + width, pos.y);
 
         Math::Vector n(0.0f, 0.0f, -1.0f);  // normal
 
@@ -909,13 +963,15 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P
 
         Vertex quad[4] =
         {
-            Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(uv1.x, uv2.y)),
-            Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(uv1.x, uv1.y)),
-            Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(uv2.x, uv2.y)),
-            Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(uv2.x, uv1.y))
+            Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(uv1.x, uv2.y)),
+            Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(uv1.x, uv1.y)),
+            Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(uv2.x, uv2.y)),
+            Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(uv2.x, uv1.y))
         };
 
+        m_engine->SetWindowCoordinates();
         m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, quad, 4, color);
+        m_engine->SetInterfaceCoordinates();
         m_engine->AddStatisticTriangle(2);
 
         pos.x += width;
@@ -939,31 +995,31 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P
 
         CharTexture tex = GetCharTexture(ch, font, size);
 
-        Math::Point charInterfaceSize = m_engine->WindowToInterfaceSize(tex.charSize);
-
-        Math::Point p1(pos.x, pos.y);
-        Math::Point p2(pos.x + charInterfaceSize.x, pos.y + charInterfaceSize.y);
+        Math::Point p1(pos.x, pos.y - tex.charSize.y);
+        Math::Point p2(pos.x + tex.charSize.x, pos.y);
 
         const float halfPixelMargin = 0.5f;
         Math::Point texCoord1(static_cast<float>(tex.charPos.x + halfPixelMargin) / FONT_TEXTURE_SIZE.x,
                               static_cast<float>(tex.charPos.y + halfPixelMargin) / FONT_TEXTURE_SIZE.y);
-        Math::Point texCoord2(static_cast<float>(tex.charPos.x + tex.charSize.x + halfPixelMargin) / FONT_TEXTURE_SIZE.x,
-                              static_cast<float>(tex.charPos.y + tex.charSize.y + halfPixelMargin) / FONT_TEXTURE_SIZE.y);
+        Math::Point texCoord2(static_cast<float>(tex.charPos.x + tex.charSize.x - halfPixelMargin) / FONT_TEXTURE_SIZE.x,
+                              static_cast<float>(tex.charPos.y + tex.charSize.y - halfPixelMargin) / FONT_TEXTURE_SIZE.y);
         Math::Vector n(0.0f, 0.0f, -1.0f);  // normal
 
         Vertex quad[4] =
         {
-            Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(texCoord1.x, texCoord2.y)),
-            Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(texCoord1.x, texCoord1.y)),
-            Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(texCoord2.x, texCoord2.y)),
-            Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(texCoord2.x, texCoord1.y))
+            Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(texCoord1.x, texCoord2.y)),
+            Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(texCoord1.x, texCoord1.y)),
+            Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(texCoord2.x, texCoord2.y)),
+            Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(texCoord2.x, texCoord1.y))
         };
 
         m_device->SetTexture(0, tex.id);
+        m_engine->SetWindowCoordinates();
         m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, quad, 4, color);
+        m_engine->SetInterfaceCoordinates();
         m_engine->AddStatisticTriangle(2);
 
-        pos.x += charInterfaceSize.x * width;
+        pos.x += tex.charSize.x * width;
     }
 }
 
@@ -1063,8 +1119,8 @@ CharTexture CText::CreateCharTexture(UTF8Char ch, CachedFont* font)
     }
 
     const int pixelMargin = 1;
-    Math::IntPoint tileSize(Math::NextPowerOfTwo(textSurface->w) + pixelMargin,
-                            Math::NextPowerOfTwo(textSurface->h) + pixelMargin);
+    Math::IntPoint tileSize(Math::Max(16, Math::NextPowerOfTwo(textSurface->w)) + pixelMargin,
+                            Math::Max(16, Math::NextPowerOfTwo(textSurface->h)) + pixelMargin);
 
     FontTexture* fontTexture = GetOrCreateFontTexture(tileSize);
 
diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h
index 6ee0a86..909dada 100644
--- a/src/graphics/engine/text.h
+++ b/src/graphics/engine/text.h
@@ -281,6 +281,7 @@ public:
     float       GetDescent(FontType font, float size);
     //! Returns the height font metric
     float       GetHeight(FontType font, float size);
+    int GetHeightInt(FontType font, float size);
 
     //! Returns width of string (multi-format)
     TEST_VIRTUAL float GetStringWidth(const std::string& text,
@@ -290,6 +291,7 @@ public:
     TEST_VIRTUAL float GetStringWidth(std::string text, FontType font, float size);
     //! Returns width of single character
     TEST_VIRTUAL float GetCharWidth(UTF8Char ch, FontType font, float size, float offset);
+    int GetCharWidthInt(UTF8Char ch, FontType font, float size, float offset);
 
     //! Justifies a line of text (multi-format)
     int         Justify(const std::string &text, std::vector<FontMetaChar>::iterator format,
@@ -319,11 +321,11 @@ protected:
 
     void        DrawString(const std::string &text, std::vector<FontMetaChar>::iterator format,
                            std::vector<FontMetaChar>::iterator end,
-                           float size, Math::Point pos, float width, int eol, Color color);
+                           float size, Math::IntPoint pos, int width, int eol, Color color);
     void        DrawString(const std::string &text, FontType font,
-                           float size, Math::Point pos, float width, int eol, Color color);
-    void        DrawHighlight(FontHighlight hl, Math::Point pos, Math::Point size);
-    void        DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::Point &pos, Color color);
+                           float size, Math::IntPoint pos, int width, int eol, Color color);
+    void        DrawHighlight(FontHighlight hl, Math::IntPoint pos, Math::IntPoint size);
+    void        DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::IntPoint &pos, Color color);
     void        StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &chars);
     void        StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &chars, std::vector<FontMetaChar>::iterator format, std::vector<FontMetaChar>::iterator end);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list