diff --git a/src/vulkanrenderer.cpp b/src/vulkanrenderer.cpp index 6c0302a..27d83c3 100644 --- a/src/vulkanrenderer.cpp +++ b/src/vulkanrenderer.cpp @@ -2126,6 +2126,28 @@ void VulkanRenderer::generateWaveEffect(std::vector& vertices, } } +float VulkanRenderer::calculateTextWidth(const std::string& text, float scale) +{ + if (m_charInfoMap.empty()) { + return 0.0f; + } + + float width = 0.0f; + for (size_t i = 0; i < text.length(); i++) { + char c = text[i]; + + // Skip newlines and characters not in atlas + if (c == '\n' || m_charInfoMap.find(c) == m_charInfoMap.end()) { + continue; + } + + const CharInfo& ch = m_charInfoMap[c]; + width += ch.advance * scale; + } + + return width; +} + void VulkanRenderer::generateTextQuads(const std::string& text, float x, float y, float scale, const float color[4], std::vector& vertices, @@ -2300,21 +2322,51 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount, float magenta[4] = {1.0f, 0.78f, 1.0f, 1.0f}; float gray[4] = {0.78f, 0.78f, 0.78f, 1.0f}; + // Use reference resolution (1920x1080) for consistent text size across different window sizes + const float refWidth = m_width; + const float refHeight = m_height; + + // Calculate uniform scale factor based on height to avoid text distortion + // Use height as the primary factor since vertical space is usually more constrained + float scale = m_height / refHeight; + + // For positioning, we still need to account for the actual window dimensions + // But use the same scale factor for both X and Y to prevent distortion + float scaleX = scale; + float scaleY = scale; + if (!paintingEnabled) { // Screen locked state std::string title = "PAINTING DISABLED"; std::string subtitle = "(Screen Locked)"; - generateTextQuads(title, m_width / 2.0f - 250.0f, m_height / 2.0f - 50.0f, 0.6f, white, vertices, indices); - generateTextQuads(subtitle, m_width / 2.0f - 180.0f, m_height / 2.0f + 30.0f, 0.5f, gray, vertices, indices); + // Calculate centered positions + float titleScale = 0.6f; + float subtitleScale = 0.5f; + float titleWidth = calculateTextWidth(title, titleScale); + float subtitleWidth = calculateTextWidth(subtitle, subtitleScale); + + float titleX = (refWidth - titleWidth) / 2.0f * scaleX; + float titleY = (refHeight / 2.0f - 30.0f) * scaleY; + float subtitleX = (refWidth - subtitleWidth) / 2.0f * scaleX; + float subtitleY = (refHeight / 2.0f + 30.0f) * scaleY; + + generateTextQuads(title, titleX, titleY, titleScale, white, vertices, indices); + generateTextQuads(subtitle, subtitleX, subtitleY, subtitleScale, gray, vertices, indices); // Stats std::string stats = "Total Frames Painted: " + std::to_string(frameCount); - generateTextQuads(stats, 20.0f, m_height - 60.0f, 0.3f, gray, vertices, indices); + generateTextQuads(stats, 20.0f * scaleX, m_height - 60.0f * scaleY, 0.3f, gray, vertices, indices); } else { // Active rendering state std::string title = "Screen Lock Detector - Painting Active"; - generateTextQuads(title, m_width / 2.0f - 150.0f, 30.0f, 0.4f, white, vertices, indices); + + // Calculate centered position for title + float titleScale = 0.7f; + float titleWidth = calculateTextWidth(title, titleScale); + float titleX = (refWidth - titleWidth) / 2.0f * scaleX; + + generateTextQuads(title, titleX - 10.0f * scaleX, 60.0f * scaleY, titleScale, white, vertices, indices); // Stats info box std::string frameStr = "Frame Count: " + std::to_string(frameCount); @@ -2322,15 +2374,15 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount, std::string rotStr = "Rotation: " + std::to_string((int)m_ubo.rotation) + "°"; std::string timeStr = "Running Time: " + std::to_string((int)m_ubo.time) + "s"; - generateTextQuads(frameStr, 20.0f, 90.0f, 0.3f, green, vertices, indices); - generateTextQuads(fpsStr, 20.0f, 130.0f, 0.3f, green, vertices, indices); - generateTextQuads(rotStr, 20.0f, 170.0f, 0.3f, green, vertices, indices); - generateTextQuads(timeStr, 20.0f, 210.0f, 0.3f, green, vertices, indices); + generateTextQuads(frameStr, 20.0f * scaleX, 130.0f * scaleY, 0.3f, green, vertices, indices); + generateTextQuads(fpsStr, 20.0f * scaleX, 150.0f * scaleY, 0.3f, green, vertices, indices); + generateTextQuads(rotStr, 20.0f * scaleX, 170.0f * scaleY, 0.3f, green, vertices, indices); + generateTextQuads(timeStr, 20.0f * scaleX, 190.0f * scaleY, 0.3f, green, vertices, indices); // Lock info (if available) if (!lockInfo.empty()) { std::string lockTitle = "Last Lock Info:"; - generateTextQuads(lockTitle, 20.0f, 270.0f, 0.3f, magenta, vertices, indices); + generateTextQuads(lockTitle, 20.0f * scaleX, 210.0f * scaleY, 0.3f, magenta, vertices, indices); // Parse lock info (assuming format from lockInfo string) size_t pos = 0; @@ -2339,19 +2391,23 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount, while ((pos = info.find('\n')) != std::string::npos) { std::string token = info.substr(0, pos); if (!token.empty()) { - generateTextQuads(token, 20.0f, 310.0f + line * 40.0f, 0.2f, magenta, vertices, indices); + generateTextQuads(token, 20.0f * scaleX, (230.0f + line * 20.0f) * scaleY, 0.2f, magenta, vertices, indices); line++; } info.erase(0, pos + 1); } if (!info.empty()) { - generateTextQuads(info, 20.0f, 310.0f + line * 40.0f, 0.2f, magenta, vertices, indices); + generateTextQuads(info, 20.0f * scaleX, (230.0f + line * 20.0f) * scaleY, 0.2f, magenta, vertices, indices); } } - // Hint at bottom + // Hint at bottom - centered std::string hint = "Lock your screen to see the painting stop automatically!"; - generateTextQuads(hint, m_width / 2.0f - 420.0f, m_height - 50.0f, 0.3f, yellow, vertices, indices); + float hintScale = 0.5f; + float hintWidth = calculateTextWidth(hint, hintScale); + float hintX = (refWidth - hintWidth) / 2.0f * scaleX; + + generateTextQuads(hint, hintX, m_height - 50.0f * scaleY, hintScale, yellow, vertices, indices); } // Create temporary buffers for text diff --git a/src/vulkanrenderer.h b/src/vulkanrenderer.h index b41815b..1174ad6 100644 --- a/src/vulkanrenderer.h +++ b/src/vulkanrenderer.h @@ -263,6 +263,11 @@ private: std::vector& indices, double wavePhase); + /** + * @brief 计算文本宽度(像素) + */ + float calculateTextWidth(const std::string& text, float scale); + /** * @brief 生成文本四边形顶点 */