LINUX.ORG.RU

История изменений

Исправление KivApple, (текущая версия) :

Сделал всё же не «моноширинный» режим:

struct FontGlyphInfo {
	glm::vec2 texCoord;
	glm::vec2 texSize;
	glm::vec2 offset;
	glm::vec2 size;
	float width;
};

...

void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
	int x0 = (index % m_colCount) * m_maxCharWidth;
	int y0 = (index / m_colCount) * m_maxCharHeight;
	
	glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
	glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
	glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
	glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
	glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
	glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
	glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
	glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
	glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
	
	auto base = m_deserializer.adapter().currentReadPos();
	for (int y = 0; y < header.height; y++) {
		int j = (y0 + y) * m_textureWidth + x0;
		for (int x = 0; x < header.width; x++) {
			int i = y * header.width + x;
			uint8_t byte = m_data[base + i / 8];
			if ((byte & (1 << (7 - i % 8))) != 0) {
				m_textureData[j + x] = {255, 255, 255, 255};
			}
		}
	}
}

...

	glm::vec2 p(0.0f);
	for (auto c : text) {
		if (c != '\n') {
			auto &glyph = m_font->glyphInfo(c);
			auto o = glyph.offset;
			auto s = glyph.size;
			auto t1 = glyph.texCoord;
			auto t2 = t1 + glyph.texSize;
			m_vertexData.insert(m_data.end(), {
					{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
					
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
			});
			p.x += glyph.width;
		} else {
			p.y -= 1.0f;
			p.x = 0.0f;
		}
	}

Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:

https://freeimage.host/i/iIhtOG

Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?

Исправление KivApple, :

Сделал всё же не «моноширинный режим»:

struct FontGlyphInfo {
	glm::vec2 texCoord;
	glm::vec2 texSize;
	glm::vec2 offset;
	glm::vec2 size;
	float width;
};

...

void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
	int x0 = (index % m_colCount) * m_maxCharWidth;
	int y0 = (index / m_colCount) * m_maxCharHeight;
	
	glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
	glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
	glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
	glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
	glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
	glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
	glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
	glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
	glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
	
	auto base = m_deserializer.adapter().currentReadPos();
	for (int y = 0; y < header.height; y++) {
		int j = (y0 + y) * m_textureWidth + x0;
		for (int x = 0; x < header.width; x++) {
			int i = y * header.width + x;
			uint8_t byte = m_data[base + i / 8];
			if ((byte & (1 << (7 - i % 8))) != 0) {
				m_textureData[j + x] = {255, 255, 255, 255};
			}
		}
	}
}

...

	glm::vec2 p(0.0f);
	for (auto c : text) {
		if (c != '\n') {
			auto &glyph = m_font->glyphInfo(c);
			auto o = glyph.offset;
			auto s = glyph.size;
			auto t1 = glyph.texCoord;
			auto t2 = t1 + glyph.texSize;
			m_vertexData.insert(m_data.end(), {
					{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
					
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
			});
			p.x += glyph.width;
		} else {
			p.y -= 1.0f;
			p.x = 0.0f;
		}
	}

Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:

https://freeimage.host/i/iIhtOG

Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?

Исходная версия KivApple, :

Сделал всё не «моноширинный режим»:

struct FontGlyphInfo {
	glm::vec2 texCoord;
	glm::vec2 texSize;
	glm::vec2 offset;
	glm::vec2 size;
	float width;
};

...

void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header, FontGlyphInfo &glyph) {
	int x0 = (index % m_colCount) * m_maxCharWidth;
	int y0 = (index / m_colCount) * m_maxCharHeight;
	
	glyph.texCoord.x = static_cast<float>(x0) / static_cast<float>(m_textureWidth);
	glyph.texCoord.y = static_cast<float>(y0) / static_cast<float>(m_textureHeight);
	glyph.texSize.x = static_cast<float>(header.width) / static_cast<float>(m_textureWidth);
	glyph.texSize.y = static_cast<float>(header.height) / static_cast<float>(m_textureHeight);
	glyph.offset.x = static_cast<float>(header.xOffset) / static_cast<float>(m_pointSize);
	glyph.offset.y = static_cast<float>(header.yOffset) / static_cast<float>(m_pointSize);
	glyph.size.x = static_cast<float>(header.width) / static_cast<float>(m_pointSize);
	glyph.size.y = static_cast<float>(header.height) / static_cast<float>(m_pointSize);
	glyph.width = static_cast<float>(header.deviceWidth) / static_cast<float>(m_pointSize);
	
	auto base = m_deserializer.adapter().currentReadPos();
	for (int y = 0; y < header.height; y++) {
		int j = (y0 + y) * m_textureWidth + x0;
		for (int x = 0; x < header.width; x++) {
			int i = y * header.width + x;
			uint8_t byte = m_data[base + i / 8];
			if ((byte & (1 << (7 - i % 8))) != 0) {
				m_textureData[j + x] = {255, 255, 255, 255};
			}
		}
	}
}

...

	glm::vec2 p(0.0f);
	for (auto c : text) {
		if (c != '\n') {
			auto &glyph = m_font->glyphInfo(c);
			auto o = glyph.offset;
			auto s = glyph.size;
			auto t1 = glyph.texCoord;
			auto t2 = t1 + glyph.texSize;
			m_vertexData.insert(m_data.end(), {
					{{o.x + p.x, o.y + p.y + s.y}, {t1.x, t1.y}}, // 1
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}}, // 3
					
					{{o.x + p.x + s.x, o.y + p.y + s.y}, {t2.x, t1.y}}, // 2
					{{o.x + p.x + s.x, o.y + p.y}, {t2.x, t2.y}}, // 4
					{{o.x + p.x, o.y + p.y}, {t1.x, t2.y}} // 3
			});
			p.x += glyph.width;
		} else {
			p.y -= 1.0f;
			p.x = 0.0f;
		}
	}

Такой подход в сочетании с тем фактом, что в OpenGL координата Y инвентировона дал нормальный рендеринг:

https://freeimage.host/i/iIhtOG

Но получается, что я вообще не использую параметры ascent и descent, нормально ли это или я что-то упускаю?