GxRecti GxTextRenderer::DrawHighlight(int x, int y) { y += GetOffsetY(myAlignV, myTextH); myDrawHighlight((float)x, (float)y); x += GetOffsetX(myAlignH, myTextW); return GxRecti(x, y, myTextW, myTextH); }
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; }
void PathBehavior::SerializeTo(gd::SerializerElement & element) const { SerializePathsTo(element.AddChild("paths")); element.SetAttribute("currentPath", GetCurrentPathName()); element.SetAttribute("speed", GetSpeed()); element.SetAttribute("offsetX", GetOffsetX()); element.SetAttribute("offsetY", GetOffsetY()); element.SetAttribute("angleOffset", angleOffset); element.SetAttribute("reverseAtEnd", ReverseAtEnd()); element.SetAttribute("stopAtEnd", StopAtEnd()); element.SetAttribute("followAngle", FollowAngle()); }
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); }
void CBullet::Render() { RECT tRect; tRect.left = 0; tRect.top = 0; if(GetIsScrew()) { tRect.right = tRect.left + 32; tRect.bottom = tRect.top + 32; } else { tRect.right = tRect.left + 16; tRect.bottom = tRect.top + 16; } TEXTUREMAN->DrawF(GetImageID(),GetPosX() - GetOffsetX(),GetPosY() - GetOffsetY(),-1.0f,1.0f,&tRect,1.0f,1.0f,GetRotation()); }
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); }
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); }
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)); } } }
GxRecti GxTextRenderer::GetTextRect(int x, int y) { y += GetOffsetY(myAlignV, myTextH); x += GetOffsetX(myAlignH, myTextW); return GxRecti(x, y, myTextW, myTextH); }