Fix incorrect glyph rect for text outline
This commit is contained in:
parent
3b1ff125b0
commit
4d2e5b18e2
@ -614,8 +614,11 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert the glyph to a bitmap (i.e. rasterize it)
|
// Convert the glyph to a bitmap (i.e. rasterize it)
|
||||||
|
// Warning! After this line, do not read any data from glyphDesc directly, use
|
||||||
|
// bitmapGlyph.root to access the FT_Glyph data.
|
||||||
FT_Glyph_To_Bitmap(&glyphDesc, FT_RENDER_MODE_NORMAL, 0, 1);
|
FT_Glyph_To_Bitmap(&glyphDesc, FT_RENDER_MODE_NORMAL, 0, 1);
|
||||||
FT_Bitmap& bitmap = reinterpret_cast<FT_BitmapGlyph>(glyphDesc)->bitmap;
|
FT_BitmapGlyph bitmapGlyph = reinterpret_cast<FT_BitmapGlyph>(glyphDesc);
|
||||||
|
FT_Bitmap& bitmap = bitmapGlyph->bitmap;
|
||||||
|
|
||||||
// Apply bold if necessary -- fallback technique using bitmap (lower quality)
|
// Apply bold if necessary -- fallback technique using bitmap (lower quality)
|
||||||
if (!outline)
|
if (!outline)
|
||||||
@ -628,7 +631,7 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the glyph's advance offset
|
// Compute the glyph's advance offset
|
||||||
glyph.advance = static_cast<float>(face->glyph->metrics.horiAdvance) / static_cast<float>(1 << 6);
|
glyph.advance = std::round(static_cast<float>(bitmapGlyph->root.advance.x) / static_cast<float>(1 << 16));
|
||||||
if (bold)
|
if (bold)
|
||||||
glyph.advance += static_cast<float>(weight) / static_cast<float>(1 << 6);
|
glyph.advance += static_cast<float>(weight) / static_cast<float>(1 << 6);
|
||||||
|
|
||||||
@ -661,10 +664,10 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
|
|||||||
glyph.textureRect.height -= 2 * padding;
|
glyph.textureRect.height -= 2 * padding;
|
||||||
|
|
||||||
// Compute the glyph's bounding box
|
// Compute the glyph's bounding box
|
||||||
glyph.bounds.left = static_cast<float>(face->glyph->metrics.horiBearingX) / static_cast<float>(1 << 6);
|
glyph.bounds.left = bitmapGlyph->left;
|
||||||
glyph.bounds.top = -static_cast<float>(face->glyph->metrics.horiBearingY) / static_cast<float>(1 << 6);
|
glyph.bounds.top = -bitmapGlyph->top;
|
||||||
glyph.bounds.width = static_cast<float>(face->glyph->metrics.width) / static_cast<float>(1 << 6) + outlineThickness * 2;
|
glyph.bounds.width = bitmap.width;
|
||||||
glyph.bounds.height = static_cast<float>(face->glyph->metrics.height) / static_cast<float>(1 << 6) + outlineThickness * 2;
|
glyph.bounds.height = bitmap.rows;
|
||||||
|
|
||||||
// Resize the pixel buffer to the new size and fill it with transparent white pixels
|
// Resize the pixel buffer to the new size and fill it with transparent white pixels
|
||||||
m_pixelBuffer.resize(width * height * 4);
|
m_pixelBuffer.resize(width * height * 4);
|
||||||
|
@ -34,21 +34,21 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Add an underline or strikethrough line to the vertex array
|
// Add an underline or strikethrough line to the vertex array
|
||||||
void addLine(sf::VertexArray& vertices, float lineLength, float lineTop, const sf::Color& color, float offset, float thickness, float outlineThickness = 0)
|
void addLine(sf::VertexArray& vertices, float lineLength, float lineTop, const sf::Color& color, float offset, float thickness)
|
||||||
{
|
{
|
||||||
float top = std::floor(lineTop + offset - (thickness / 2) + 0.5f);
|
float top = std::floor(lineTop + offset - (thickness / 2) + 0.5f);
|
||||||
float bottom = top + std::floor(thickness + 0.5f);
|
float bottom = top + std::floor(thickness + 0.5f);
|
||||||
|
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(-outlineThickness, top - outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(0, top), color, sf::Vector2f(1, 1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(lineLength + outlineThickness, top - outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(lineLength, top), color, sf::Vector2f(1, 1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(-outlineThickness, bottom + outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(0, bottom), color, sf::Vector2f(1, 1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(-outlineThickness, bottom + outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(0, bottom), color, sf::Vector2f(1, 1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(lineLength + outlineThickness, top - outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(lineLength, top), color, sf::Vector2f(1, 1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(lineLength + outlineThickness, bottom + outlineThickness), color, sf::Vector2f(1, 1)));
|
vertices.append(sf::Vertex(sf::Vector2f(lineLength, bottom), color, sf::Vector2f(1, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a glyph quad to the vertex array
|
// Add a glyph quad to the vertex array
|
||||||
void addGlyphQuad(sf::VertexArray& vertices, sf::Vector2f position, const sf::Color& color, const sf::Glyph& glyph, float italicShear, float outlineThickness = 0)
|
void addGlyphQuad(sf::VertexArray& vertices, sf::Vector2f position, const sf::Color& color, const sf::Glyph& glyph, float italicShear)
|
||||||
{
|
{
|
||||||
float padding = 1.0;
|
float padding = 1.0;
|
||||||
|
|
||||||
@ -62,12 +62,12 @@ namespace
|
|||||||
float u2 = static_cast<float>(glyph.textureRect.left + glyph.textureRect.width) + padding;
|
float u2 = static_cast<float>(glyph.textureRect.left + glyph.textureRect.width) + padding;
|
||||||
float v2 = static_cast<float>(glyph.textureRect.top + glyph.textureRect.height) + padding;
|
float v2 = static_cast<float>(glyph.textureRect.top + glyph.textureRect.height) + padding;
|
||||||
|
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * top - outlineThickness, position.y + top - outlineThickness), color, sf::Vector2f(u1, v1)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * top , position.y + top), color, sf::Vector2f(u1, v1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * top - outlineThickness, position.y + top - outlineThickness), color, sf::Vector2f(u2, v1)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * top , position.y + top), color, sf::Vector2f(u2, v1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * bottom - outlineThickness, position.y + bottom - outlineThickness), color, sf::Vector2f(u1, v2)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * bottom, position.y + bottom), color, sf::Vector2f(u1, v2)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * bottom - outlineThickness, position.y + bottom - outlineThickness), color, sf::Vector2f(u1, v2)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * bottom, position.y + bottom), color, sf::Vector2f(u1, v2)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * top - outlineThickness, position.y + top - outlineThickness), color, sf::Vector2f(u2, v1)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * top , position.y + top), color, sf::Vector2f(u2, v1)));
|
||||||
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * bottom - outlineThickness, position.y + bottom - outlineThickness), color, sf::Vector2f(u2, v2)));
|
vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * bottom, position.y + bottom), color, sf::Vector2f(u2, v2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ void Text::ensureGeometryUpdate() const
|
|||||||
addLine(m_vertices, x, y, m_fillColor, underlineOffset, underlineThickness);
|
addLine(m_vertices, x, y, m_fillColor, underlineOffset, underlineThickness);
|
||||||
|
|
||||||
if (m_outlineThickness != 0)
|
if (m_outlineThickness != 0)
|
||||||
addLine(m_outlineVertices, x, y, m_outlineColor, underlineOffset, underlineThickness, m_outlineThickness);
|
addLine(m_outlineVertices, x, y, m_outlineColor, underlineOffset, underlineThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're using the strike through style and there's a new line, draw a line across all characters
|
// If we're using the strike through style and there's a new line, draw a line across all characters
|
||||||
@ -468,7 +468,7 @@ void Text::ensureGeometryUpdate() const
|
|||||||
addLine(m_vertices, x, y, m_fillColor, strikeThroughOffset, underlineThickness);
|
addLine(m_vertices, x, y, m_fillColor, strikeThroughOffset, underlineThickness);
|
||||||
|
|
||||||
if (m_outlineThickness != 0)
|
if (m_outlineThickness != 0)
|
||||||
addLine(m_outlineVertices, x, y, m_outlineColor, strikeThroughOffset, underlineThickness, m_outlineThickness);
|
addLine(m_outlineVertices, x, y, m_outlineColor, strikeThroughOffset, underlineThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
prevChar = curChar;
|
prevChar = curChar;
|
||||||
@ -506,13 +506,13 @@ void Text::ensureGeometryUpdate() const
|
|||||||
float bottom = glyph.bounds.top + glyph.bounds.height;
|
float bottom = glyph.bounds.top + glyph.bounds.height;
|
||||||
|
|
||||||
// Add the outline glyph to the vertices
|
// Add the outline glyph to the vertices
|
||||||
addGlyphQuad(m_outlineVertices, Vector2f(x, y), m_outlineColor, glyph, italicShear, m_outlineThickness);
|
addGlyphQuad(m_outlineVertices, Vector2f(x, y), m_outlineColor, glyph, italicShear);
|
||||||
|
|
||||||
// Update the current bounds with the outlined glyph bounds
|
// Update the current bounds with the outlined glyph bounds
|
||||||
minX = std::min(minX, x + left - italicShear * bottom - m_outlineThickness);
|
minX = std::min(minX, x + left - italicShear * bottom);
|
||||||
maxX = std::max(maxX, x + right - italicShear * top - m_outlineThickness);
|
maxX = std::max(maxX, x + right - italicShear * top);
|
||||||
minY = std::min(minY, y + top - m_outlineThickness);
|
minY = std::min(minY, y + top);
|
||||||
maxY = std::max(maxY, y + bottom - m_outlineThickness);
|
maxY = std::max(maxY, y + bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the current glyph's description
|
// Extract the current glyph's description
|
||||||
@ -545,7 +545,7 @@ void Text::ensureGeometryUpdate() const
|
|||||||
addLine(m_vertices, x, y, m_fillColor, underlineOffset, underlineThickness);
|
addLine(m_vertices, x, y, m_fillColor, underlineOffset, underlineThickness);
|
||||||
|
|
||||||
if (m_outlineThickness != 0)
|
if (m_outlineThickness != 0)
|
||||||
addLine(m_outlineVertices, x, y, m_outlineColor, underlineOffset, underlineThickness, m_outlineThickness);
|
addLine(m_outlineVertices, x, y, m_outlineColor, underlineOffset, underlineThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're using the strike through style, add the last line across all characters
|
// If we're using the strike through style, add the last line across all characters
|
||||||
@ -554,7 +554,7 @@ void Text::ensureGeometryUpdate() const
|
|||||||
addLine(m_vertices, x, y, m_fillColor, strikeThroughOffset, underlineThickness);
|
addLine(m_vertices, x, y, m_fillColor, strikeThroughOffset, underlineThickness);
|
||||||
|
|
||||||
if (m_outlineThickness != 0)
|
if (m_outlineThickness != 0)
|
||||||
addLine(m_outlineVertices, x, y, m_outlineColor, strikeThroughOffset, underlineThickness, m_outlineThickness);
|
addLine(m_outlineVertices, x, y, m_outlineColor, strikeThroughOffset, underlineThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the bounding rectangle
|
// Update the bounding rectangle
|
||||||
|
Loading…
Reference in New Issue
Block a user