void CG_DrawStringExtWithCursor( int x, int y, const char* str, int style, const vec4_t color, float scale, int maxChars, float shadowOffset, int cursorPos, int cursorChar ) { int charh; vec4_t newcolor; vec4_t lowlight; const float *drawcolor; const fontInfo_t *font; int decent; if( !str ) { return; } if ( !color ) { color = colorWhite; } if ((style & UI_BLINK) && ((cg.realTime/BLINK_DIVISOR) & 1)) return; if (style & UI_TINYFONT) { font = &cgs.media.tinyFont; charh = TINYCHAR_HEIGHT; } else if (style & UI_SMALLFONT) { font = &cgs.media.smallFont; charh = SMALLCHAR_HEIGHT; } else if (style & UI_GIANTFONT) { font = &cgs.media.bigFont; charh = GIANTCHAR_HEIGHT; } else { font = &cgs.media.textFont; charh = BIGCHAR_HEIGHT; } if ( scale <= 0 ) { scale = charh / 48.0f; } else { charh = 48 * scale; } if (style & UI_PULSE) { lowlight[0] = 0.8*color[0]; lowlight[1] = 0.8*color[1]; lowlight[2] = 0.8*color[2]; lowlight[3] = 0.8*color[3]; CG_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(cg.realTime/PULSE_DIVISOR)); drawcolor = newcolor; } else drawcolor = color; switch (style & UI_FORMATMASK) { case UI_CENTER: // center justify at x x = x - Text_Width( str, font, scale, 0 ) / 2; break; case UI_RIGHT: // right justify at x x = x - Text_Width( str, font, scale, 0 ); break; default: // left justify at x break; } if ( shadowOffset == 0 && ( style & UI_DROPSHADOW ) ) { shadowOffset = 2; } // This function expects that y is top of line, text_paint expects at baseline decent = -font->glyphs[(int)'g'].top + font->glyphs[(int)'g'].height; y = y + charh - decent * scale * font->glyphScale; if ( cursorChar >= 0 ) { Text_PaintWithCursor( x, y, font, scale, drawcolor, str, cursorPos, cursorChar, 0, maxChars, shadowOffset, ( style & UI_FORCECOLOR ) ); } else { Text_Paint( x, y, font, scale, drawcolor, str, 0, maxChars, shadowOffset, ( style & UI_FORCECOLOR ) ); } }
// Note: Update UI_DrawString in q3_ui if arguments are changed. void CG_DrawStringCommon( int x, int y, const char* str, int style, const fontInfo_t *font, const vec4_t color, float scale, int maxChars, float shadowOffset, float gradient, int cursorPos, int cursorChar, float wrapX ) { int charh; vec4_t newcolor; vec4_t lowlight; const float *drawcolor; int decent; if( !str ) { return; } if ( !color ) { color = colorWhite; } if ((style & UI_BLINK) && ((cg.realTime/BLINK_DIVISOR) & 1)) return; if ( (style & UI_FONTMASK) == UI_NUMBERFONT ) { // the original number bitmaps already have a gradient if ( font->glyphs[(int)'a'].xSkip == 0 ) { style &= ~UI_GRADIENT; } } charh = font->pointSize; if ( shadowOffset == 0 && ( style & UI_DROPSHADOW ) ) { shadowOffset = 2; } if ( gradient == 0 && ( style & UI_GRADIENT ) ) { gradient = 0.4f; } if ( scale <= 0 ) { scale = charh / 48.0f; } else { charh = 48 * scale; } if ( !( style & UI_NOSCALE ) && cg.cur_lc ) { if ( cg.numViewports != 1 ) { shadowOffset *= cg_splitviewTextScale.value; scale *= cg_splitviewTextScale.value; charh *= cg_splitviewTextScale.value; } else { shadowOffset *= cg_hudTextScale.value; scale *= cg_hudTextScale.value; charh *= cg_hudTextScale.value; } } if (style & UI_PULSE) { lowlight[0] = 0.8*color[0]; lowlight[1] = 0.8*color[1]; lowlight[2] = 0.8*color[2]; lowlight[3] = 0.8*color[3]; CG_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(cg.realTime/PULSE_DIVISOR)); drawcolor = newcolor; } else drawcolor = color; if ( wrapX <= 0 ) { switch (style & UI_FORMATMASK) { case UI_CENTER: // center justify at x x = x - Text_Width( str, font, scale, 0 ) / 2; break; case UI_RIGHT: // right justify at x x = x - Text_Width( str, font, scale, 0 ); break; case UI_LEFT: default: // left justify at x break; } switch (style & UI_VA_FORMATMASK) { case UI_VA_CENTER: // center justify at y y = y - charh /*Text_Height( str, font, scale, 0 )*/ / 2; break; case UI_VA_BOTTOM: // bottom justify at y y = y - charh /*Text_Height( str, font, scale, 0 )*/; break; case UI_VA_TOP: default: // top justify at y break; } } // // This function expects that y is top of line, text_paint expects at baseline // decent = -font->glyphs[(int)'g'].top + font->glyphs[(int)'g'].height; y = y + charh - decent * scale * font->glyphScale; if ( decent != 0 ) { // Make TrueType fonts line up with bigchars bitmap font which has 2 transparent pixels above glyphs at 16 point font size y += 2.0f * charh / 16.0f; } if ( cursorChar >= 0 ) { Text_PaintWithCursor( x, y, font, scale, drawcolor, str, cursorPos, cursorChar, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ) ); } else if ( wrapX > 0 ) { // replace 'char height' in line height with our scaled charh // ZTM: TODO: This text gap handling is kind of messy. Passing scale to CG_DrawStringLineHeight might make cleaner code here. int gap = CG_DrawStringLineHeight( style | UI_NOSCALE ) - font->pointSize; if ( !( style & UI_NOSCALE ) && cg.cur_lc ) { if ( cg.numViewports != 1 ) { gap *= cg_splitviewTextScale.value; } else { gap *= cg_hudTextScale.value; } } Text_Paint_AutoWrapped( x, y, font, scale, drawcolor, str, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ), wrapX, charh + gap, style ); } else { Text_Paint( x, y, font, scale, drawcolor, str, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ) ); } }