Exemple #1
0
int GxTextRenderer::myGetCharIndex(int x, int y, int cx, int cy)
{
	// Check if the character is before the start or after the end of the text.
	if(cy <= y || myLines.empty()) return 0;
	if(cy >= y + myTextH) return myLen;

	// Find the correct line number.
	int lineIndex = 0;
	for(int l=0, ly=y; l<(int)myLines.size() && cy>=ly; ly += myFont->fontSize, ++l)
		lineIndex = l;

	// Process the line on which the character resides.
	const Line& line = myLines[lineIndex];
	const float ox = (float)x + GetOffsetX(myAlignH, line.width);
	const float px = (float)cx;

	// Go through each character.
	Pen pen = { 0, 0, line.spacemul };
	myResetPos();
	mySkipTo(line.begin);
	while(myReadPos < line.end)
	{
		const Glyph& glyph = myNextChar();
		myAdvance(pen, glyph);
		if(px < ox + pen.x + pen.advance*0.5f) return myPos;
	}

	// Only the last line is allowed to return one beyond the last character.
	if(myReadPos == myLen && myStr[myPos] != C_LINE_FEED) return myLen;

	// Otherwise, just return the last character.
	return myPos;
}
Exemple #2
0
void GxTextRenderer::myDrawUnderlines(float x, float y)
{
	// Fill in the vertex data by rendering out the lines of rects.	
	Glyph rect = { GxAreaf(0,1,0,2), GxAreaf(), 0, 0, 0, 0 };
	myResetPos();
	int index = 0;
	for(size_t l=0; l<myLines.size(); ++l)
	{
		const Line& line = myLines[l];
		Pen pen = { 0, 0, line.spacemul };
		const float ox = x + GetOffsetX(myAlignH, line.width);
		const float oy = y + (int)((l+1) * myFont->fontSize);

		// Emit underline quads for the current line.
		bool drawing = false;
		mySkipTo(line.begin);
		while(myReadPos < line.end)
		{
			const Glyph& glyph = myNextChar();
			myAdvance(pen, glyph);
			if(myInUnderline && !drawing)
			{
				rect.coords.l = pen.x;
				drawing = true;
			}
			if(drawing)
			{
				if(!myInUnderline)
				{
					myResizeBuffers(index + 2);
					myEmitQuad(rect, index, ox, oy);
					drawing = false;
				}
				else if(NonWhitespace(glyph))
				{
					rect.coords.r = pen.x + pen.advance;
				}
			}
		}
		if(drawing)
		{
			myResizeBuffers(index + 2);
			myEmitQuad(rect, index, ox, oy);
		}
	}

	// Finally it's time to render the vertices.
	myRenderQuads(0, index*6, 0);
}
Exemple #3
0
Game::Game(QObject *parent, int width, int height) :
    QGraphicsScene(parent),m_width(width),m_height(height)
{
    setSceneRect(0, 0, m_width, m_height);

    freePen.setColor(QColor(200,200,200));
    freePen.setWidth(0);

    keyMap[Qt::Key_Up] = X_KEY_UP;
    keyMap[Qt::Key_Down] = X_KEY_DOWN;
    keyMap[Qt::Key_Left] = X_KEY_LEFT;
    keyMap[Qt::Key_Right] = X_KEY_RIGHT;
    m_evils = 0;

    m_key_mask = 0;
    m_timer.setInterval(period);
    QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(myAdvance()));

    //startGame();
}
Exemple #4
0
GxRecti GxTextRenderer::myGetCharRect(float x, float y, int charIndex)
{
	// Empty string.
	if(myLines.empty())
		return GxRecti((int)x, (int)y, 0, myFont->fontSize);

	// Find the correct line number.
	int lineIndex = 0;
	for(int l=0; l<(int)myLines.size() && myLines[l].begin <= charIndex; ++l)
		lineIndex = l;

	// Process the line on which the character resides.
	const Line& line = myLines[lineIndex];
	const float ox = x + GetOffsetX(myAlignH, line.width);
	const float oy = y + (float)(lineIndex * myFont->fontSize);

	// If the index is before begin, we can return the position of the first character.
	if(charIndex < line.begin)
		return GxRecti((int)ox, (int)oy, 0, myFont->fontSize);

	// Go through the line until we reach the character at the index.
	Pen pen = { 0, 0, line.spacemul };
	myResetPos();
	mySkipTo(line.begin);
	while(myReadPos < line.end)
	{
		const Glyph& glyph = myNextChar();
		myAdvance(pen, glyph);
		if(myPos == charIndex)
			return GxRecti((int)(ox + pen.x), (int)oy, (int)pen.advance, myFont->fontSize);
	}

	// If the final line ends with a line feed, we return the start of the next line.
	if(myReadPos == myLen && myStr[myPos] == C_LINE_FEED)
		return GxRecti((int)ox, (int)oy + myFont->fontSize, 0, myFont->fontSize);

	// If not, we just return the end of the final line.
	return GxRecti((int)(ox + pen.x + pen.advance), (int)oy, 0, myFont->fontSize);
}
Exemple #5
0
void GxTextRenderer::myDrawHighlight(float x, float y)
{
	const int lineCount = (int)myLines.size();
	myResizeBuffers(lineCount * 2);

	// Fill in the vertex data by rendering out the lines of rects.	
	Glyph rect = { GxAreaf(0,(float)-myFont->fontSize,0,0), GxAreaf(), 0, 0, 0, 0 };
	myResetPos();
	int index = 0;
	for(int l=0; l<lineCount; ++l)
	{
		const Line& line = myLines[l];
		Pen pen = { 0, 0, line.spacemul };
		const float ox = x + GetOffsetX(myAlignH, line.width);
		const float oy = y + (float)((l+1) * myFont->fontSize);

		// Find the x-position of the start and end of the highlight rectangle.
		bool started = false;
		mySkipTo(line.begin);
		while(myReadPos < line.end)
		{
			const Glyph& glyph = myNextChar();
			myAdvance(pen, glyph);
			if(myInRange())
			{
				if(!started)
					rect.coords.l = pen.x, started = true;
				rect.coords.r = pen.x + pen.advance;
			}
		}

		// Emit a quad for the highlight rectangle.
		if(started) myEmitQuad(rect, index, ox, oy);
	}

	// Finally it's time to render the vertices.
	myRenderQuads(0, index*6, 0);
}
Exemple #6
0
void GxTextRenderer::myDrawText(float x, float y)
{
	const int lineCount = (int)myLines.size();
	const Glyph& period = myFont->GetGlyph('.');

	// Count the total number of quads and the number of quads per glyph page.
	const int pageCount = myFont->glyphPageCount;
	std::vector<PageQuads> quads(pageCount);

	myResetPos();
	int quadTotal = 0;
	for(int l=0; l<lineCount; ++l)
	{
		// Count the number of glyph quads.
		const Line& line = myLines[l];
		mySkipTo(line.begin);
		while(myReadPos < line.end)
		{
			const Glyph& glyph = myNextChar();
			if(myInRange() && NonWhitespace(glyph))
			{
				if(glyph.page >= 0)
					++quads[glyph.page].count;
				++quadTotal;
			}
		}

		// If there are ellipsis, count three extra quads.
		if(line.ellipsis)
		{
			quads[period.page].count += 3;
			quadTotal += 3;
		}
	}
	if(quadTotal == 0) return;

	// If there is a shadow effect, each quad has an additional shadow quad.
	if(myColorS.a)
	{
		for(int i=0; i<pageCount; ++i)
			quads[i].count *= 2;
		quadTotal *= 2;
	}

	// Draw underlines before the rest of the glyphs are drawn.
	if(myHasUnderlines)	myDrawUnderlines(x, y);

	// Assign each glyph page a portion of the allocated vertices.
	myResizeBuffers(quadTotal);
	for(int i=0, j=0; i<pageCount; ++i)
	{
		quads[i].index = j;
		j += quads[i].count;
	}

	// Fill in the vertex data and make a list of custom glyphs, which are rendered afterwards.
	myResetPos();
	myCustomGlyphs.clear();
	for(int l=0; l<lineCount; ++l)
	{
		const Line& line = myLines[l];
		Pen pen = { 0, 0, line.spacemul };
		const float ox = x + GetOffsetX(myAlignH, line.width);
		const float oy = y + (float)((l+1) * myFont->fontSize);

		mySkipTo(line.begin);
		while(myReadPos < line.end)
		{
			// If this is a printable character, we will emit a quad for it.
			const Glyph& glyph = myNextChar();
			myAdvance(pen, glyph);
			if(myInRange() && NonWhitespace(glyph))
			{
				if(glyph.page >= 0)
					myEmitQuad(glyph, quads[glyph.page].index, ox + pen.x, oy);
				else
					myCustomGlyphs.push_back(CGGxRecti(&glyph, ox + pen.x, oy));
			}
		}

		// If there are ellipsis, emit quads for them.
		if(line.ellipsis)
		{
			pen.x += pen.advance;
			int& index = quads[period.page].index;
			for(int j=0; j<3; ++j, pen.x += period.xAdvance)
				myEmitQuad(period, index, ox + pen.x, oy);
		}
	}

	// Finally it's time to render the glyph vertices.
	for(int i=0, idx=0, count=0; i<pageCount; ++i)
	{
		if(count = quads[i].count*6)
			myRenderQuads(idx, count, myFont->glyphPages[i].texture);
		idx += count;
	}

	// And after that, render the custom glyphs.
	if(myCustomGlyphs.size() > 0)
	{
		myResizeBuffers(8);

		GxFontDatabaseImp* database = GxFontDatabaseImp::singleton;
		for(size_t i=0; i<myCustomGlyphs.size(); ++i)
		{
			int idx = 0;
			const CGGxRecti& r = myCustomGlyphs[i];
			myEmitQuad(*myCustomGlyphs[i].glyph, idx, r.x, r.y);
			myRenderQuads(0, idx*6, database->GetCustomGlyphTexture(r.glyph));
		}
	}
}