1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- #include "DeviceContext.h"
- idVec4 idDeviceContext::colorPurple;
- idVec4 idDeviceContext::colorOrange;
- idVec4 idDeviceContext::colorYellow;
- idVec4 idDeviceContext::colorGreen;
- idVec4 idDeviceContext::colorBlue;
- idVec4 idDeviceContext::colorRed;
- idVec4 idDeviceContext::colorBlack;
- idVec4 idDeviceContext::colorWhite;
- idVec4 idDeviceContext::colorNone;
- idCVar gui_smallFontLimit( "gui_smallFontLimit", "0.30", CVAR_GUI | CVAR_ARCHIVE, "" );
- idCVar gui_mediumFontLimit( "gui_mediumFontLimit", "0.60", CVAR_GUI | CVAR_ARCHIVE, "" );
- idList<fontInfoEx_t> idDeviceContext::fonts;
- int idDeviceContext::FindFont( const char *name ) {
- int c = fonts.Num();
- for (int i = 0; i < c; i++) {
- if (idStr::Icmp(name, fonts[i].name) == 0) {
- return i;
- }
- }
- // If the font was not found, try to register it
- idStr fileName = name;
- fileName.Replace("fonts", va("fonts/%s", fontLang.c_str()) );
- fontInfoEx_t fontInfo;
- int index = fonts.Append( fontInfo );
- if ( renderSystem->RegisterFont( fileName, fonts[index] ) ){
- idStr::Copynz( fonts[index].name, name, sizeof( fonts[index].name ) );
- return index;
- } else {
- common->Printf( "Could not register font %s [%s]\n", name, fileName.c_str() );
- return -1;
- }
- }
- void idDeviceContext::SetupFonts() {
- fonts.SetGranularity( 1 );
- fontLang = cvarSystem->GetCVarString( "sys_lang" );
-
- // western european languages can use the english font
- if ( fontLang == "french" || fontLang == "german" || fontLang == "spanish" || fontLang == "italian" ) {
- fontLang = "english";
- }
- // Default font has to be added first
- FindFont( "fonts" );
- }
- void idDeviceContext::SetFont( int num ) {
- if ( num >= 0 && num < fonts.Num() ) {
- activeFont = &fonts[num];
- } else {
- activeFont = &fonts[0];
- }
- }
- void idDeviceContext::Init() {
- xScale = 0.0;
- SetSize(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
- whiteImage = declManager->FindMaterial("guis/assets/white.tga");
- whiteImage->SetSort( SS_GUI );
- mbcs = false;
- SetupFonts();
- activeFont = &fonts[0];
- colorPurple = idVec4(1, 0, 1, 1);
- colorOrange = idVec4(1, 1, 0, 1);
- colorYellow = idVec4(0, 1, 1, 1);
- colorGreen = idVec4(0, 1, 0, 1);
- colorBlue = idVec4(0, 0, 1, 1);
- colorRed = idVec4(1, 0, 0, 1);
- colorWhite = idVec4(1, 1, 1, 1);
- colorBlack = idVec4(0, 0, 0, 1);
- colorNone = idVec4(0, 0, 0, 0);
- cursorImages[CURSOR_ARROW] = declManager->FindMaterial("ui/assets/guicursor_arrow.tga");
- cursorImages[CURSOR_HAND] = declManager->FindMaterial("ui/assets/guicursor_hand.tga");
- scrollBarImages[SCROLLBAR_HBACK] = declManager->FindMaterial("ui/assets/scrollbarh.tga");
- scrollBarImages[SCROLLBAR_VBACK] = declManager->FindMaterial("ui/assets/scrollbarv.tga");
- scrollBarImages[SCROLLBAR_THUMB] = declManager->FindMaterial("ui/assets/scrollbar_thumb.tga");
- scrollBarImages[SCROLLBAR_RIGHT] = declManager->FindMaterial("ui/assets/scrollbar_right.tga");
- scrollBarImages[SCROLLBAR_LEFT] = declManager->FindMaterial("ui/assets/scrollbar_left.tga");
- scrollBarImages[SCROLLBAR_UP] = declManager->FindMaterial("ui/assets/scrollbar_up.tga");
- scrollBarImages[SCROLLBAR_DOWN] = declManager->FindMaterial("ui/assets/scrollbar_down.tga");
- cursorImages[CURSOR_ARROW]->SetSort( SS_GUI );
- cursorImages[CURSOR_HAND]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_HBACK]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_VBACK]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_THUMB]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_RIGHT]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_LEFT]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_UP]->SetSort( SS_GUI );
- scrollBarImages[SCROLLBAR_DOWN]->SetSort( SS_GUI );
- cursor = CURSOR_ARROW;
- enableClipping = true;
- overStrikeMode = true;
- mat.Identity();
- origin.Zero();
- initialized = true;
- }
- void idDeviceContext::Shutdown() {
- fontName.Clear();
- clipRects.Clear();
- fonts.Clear();
- Clear();
- }
- void idDeviceContext::Clear() {
- initialized = false;
- useFont = NULL;
- activeFont = NULL;
- mbcs = false;
- }
- idDeviceContext::idDeviceContext() {
- Clear();
- }
- void idDeviceContext::SetTransformInfo(const idVec3 &org, const idMat3 &m) {
- origin = org;
- mat = m;
- }
- //
- // added method
- void idDeviceContext::GetTransformInfo(idVec3& org, idMat3& m )
- {
- m = mat;
- org = origin;
- }
- //
- void idDeviceContext::PopClipRect() {
- if (clipRects.Num()) {
- clipRects.RemoveIndex(clipRects.Num()-1);
- }
- }
- void idDeviceContext::PushClipRect(idRectangle r) {
- clipRects.Append(r);
- }
- void idDeviceContext::PushClipRect(float x, float y, float w, float h) {
- clipRects.Append(idRectangle(x, y, w, h));
- }
- bool idDeviceContext::ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2) {
- if ( enableClipping == false || clipRects.Num() == 0 ) {
- return false;
- }
- int c = clipRects.Num();
- while( --c > 0 ) {
- idRectangle *clipRect = &clipRects[c];
-
- float ox = *x;
- float oy = *y;
- float ow = *w;
- float oh = *h;
- if ( ow <= 0.0f || oh <= 0.0f ) {
- break;
- }
- if (*x < clipRect->x) {
- *w -= clipRect->x - *x;
- *x = clipRect->x;
- } else if (*x > clipRect->x + clipRect->w) {
- *x = *w = *y = *h = 0;
- }
- if (*y < clipRect->y) {
- *h -= clipRect->y - *y;
- *y = clipRect->y;
- } else if (*y > clipRect->y + clipRect->h) {
- *x = *w = *y = *h = 0;
- }
- if (*w > clipRect->w) {
- *w = clipRect->w - *x + clipRect->x;
- } else if (*x + *w > clipRect->x + clipRect->w) {
- *w = clipRect->Right() - *x;
- }
- if (*h > clipRect->h) {
- *h = clipRect->h - *y + clipRect->y;
- } else if (*y + *h > clipRect->y + clipRect->h) {
- *h = clipRect->Bottom() - *y;
- }
- if ( s1 && s2 && t1 && t2 && ow > 0.0f ) {
- float ns1, ns2, nt1, nt2;
- // upper left
- float u = ( *x - ox ) / ow;
- ns1 = *s1 * ( 1.0f - u ) + *s2 * ( u );
- // upper right
- u = ( *x + *w - ox ) / ow;
- ns2 = *s1 * ( 1.0f - u ) + *s2 * ( u );
- // lower left
- u = ( *y - oy ) / oh;
- nt1 = *t1 * ( 1.0f - u ) + *t2 * ( u );
- // lower right
- u = ( *y + *h - oy ) / oh;
- nt2 = *t1 * ( 1.0f - u ) + *t2 * ( u );
- // set values
- *s1 = ns1;
- *s2 = ns2;
- *t1 = nt1;
- *t2 = nt2;
- }
- }
- return (*w == 0 || *h == 0) ? true : false;
- }
- void idDeviceContext::AdjustCoords(float *x, float *y, float *w, float *h) {
- if (x) {
- *x *= xScale;
- }
- if (y) {
- *y *= yScale;
- }
- if (w) {
- *w *= xScale;
- }
- if (h) {
- *h *= yScale;
- }
- }
- void idDeviceContext::DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader) {
- idDrawVert verts[4];
- glIndex_t indexes[6];
- indexes[0] = 3;
- indexes[1] = 0;
- indexes[2] = 2;
- indexes[3] = 2;
- indexes[4] = 0;
- indexes[5] = 1;
- verts[0].xyz[0] = x;
- verts[0].xyz[1] = y;
- verts[0].xyz[2] = 0;
- verts[0].st[0] = s1;
- verts[0].st[1] = t1;
- verts[0].normal[0] = 0;
- verts[0].normal[1] = 0;
- verts[0].normal[2] = 1;
- verts[0].tangents[0][0] = 1;
- verts[0].tangents[0][1] = 0;
- verts[0].tangents[0][2] = 0;
- verts[0].tangents[1][0] = 0;
- verts[0].tangents[1][1] = 1;
- verts[0].tangents[1][2] = 0;
- verts[1].xyz[0] = x + w;
- verts[1].xyz[1] = y;
- verts[1].xyz[2] = 0;
- verts[1].st[0] = s2;
- verts[1].st[1] = t1;
- verts[1].normal[0] = 0;
- verts[1].normal[1] = 0;
- verts[1].normal[2] = 1;
- verts[1].tangents[0][0] = 1;
- verts[1].tangents[0][1] = 0;
- verts[1].tangents[0][2] = 0;
- verts[1].tangents[1][0] = 0;
- verts[1].tangents[1][1] = 1;
- verts[1].tangents[1][2] = 0;
- verts[2].xyz[0] = x + w;
- verts[2].xyz[1] = y + h;
- verts[2].xyz[2] = 0;
- verts[2].st[0] = s2;
- verts[2].st[1] = t2;
- verts[2].normal[0] = 0;
- verts[2].normal[1] = 0;
- verts[2].normal[2] = 1;
- verts[2].tangents[0][0] = 1;
- verts[2].tangents[0][1] = 0;
- verts[2].tangents[0][2] = 0;
- verts[2].tangents[1][0] = 0;
- verts[2].tangents[1][1] = 1;
- verts[2].tangents[1][2] = 0;
- verts[3].xyz[0] = x;
- verts[3].xyz[1] = y + h;
- verts[3].xyz[2] = 0;
- verts[3].st[0] = s1;
- verts[3].st[1] = t2;
- verts[3].normal[0] = 0;
- verts[3].normal[1] = 0;
- verts[3].normal[2] = 1;
- verts[3].tangents[0][0] = 1;
- verts[3].tangents[0][1] = 0;
- verts[3].tangents[0][2] = 0;
- verts[3].tangents[1][0] = 0;
- verts[3].tangents[1][1] = 1;
- verts[3].tangents[1][2] = 0;
-
- bool ident = !mat.IsIdentity();
- if ( ident ) {
- verts[0].xyz -= origin;
- verts[0].xyz *= mat;
- verts[0].xyz += origin;
- verts[1].xyz -= origin;
- verts[1].xyz *= mat;
- verts[1].xyz += origin;
- verts[2].xyz -= origin;
- verts[2].xyz *= mat;
- verts[2].xyz += origin;
- verts[3].xyz -= origin;
- verts[3].xyz *= mat;
- verts[3].xyz += origin;
- }
- renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, ident );
-
- }
- void idDeviceContext::DrawMaterial(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex, float scaley) {
- renderSystem->SetColor(color);
- float s0, s1, t0, t1;
- //
- // handle negative scales as well
- if ( scalex < 0 )
- {
- w *= -1;
- scalex *= -1;
- }
- if ( scaley < 0 )
- {
- h *= -1;
- scaley *= -1;
- }
- //
- if( w < 0 ) { // flip about vertical
- w = -w;
- s0 = 1 * scalex;
- s1 = 0;
- }
- else {
- s0 = 0;
- s1 = 1 * scalex;
- }
- if( h < 0 ) { // flip about horizontal
- h = -h;
- t0 = 1 * scaley;
- t1 = 0;
- }
- else {
- t0 = 0;
- t1 = 1 * scaley;
- }
- if ( ClippedCoords( &x, &y, &w, &h, &s0, &t0, &s1, &t1 ) ) {
- return;
- }
- AdjustCoords(&x, &y, &w, &h);
- DrawStretchPic( x, y, w, h, s0, t0, s1, t1, mat);
- }
- void idDeviceContext::DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex, float scaley, float angle) {
-
- renderSystem->SetColor(color);
- float s0, s1, t0, t1;
- //
- // handle negative scales as well
- if ( scalex < 0 )
- {
- w *= -1;
- scalex *= -1;
- }
- if ( scaley < 0 )
- {
- h *= -1;
- scaley *= -1;
- }
- //
- if( w < 0 ) { // flip about vertical
- w = -w;
- s0 = 1 * scalex;
- s1 = 0;
- }
- else {
- s0 = 0;
- s1 = 1 * scalex;
- }
- if( h < 0 ) { // flip about horizontal
- h = -h;
- t0 = 1 * scaley;
- t1 = 0;
- }
- else {
- t0 = 0;
- t1 = 1 * scaley;
- }
- if ( angle == 0.0f && ClippedCoords( &x, &y, &w, &h, &s0, &t0, &s1, &t1 ) ) {
- return;
- }
- AdjustCoords(&x, &y, &w, &h);
- DrawStretchPicRotated( x, y, w, h, s0, t0, s1, t1, mat, angle);
- }
- void idDeviceContext::DrawStretchPicRotated(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader, float angle) {
-
- idDrawVert verts[4];
- glIndex_t indexes[6];
- indexes[0] = 3;
- indexes[1] = 0;
- indexes[2] = 2;
- indexes[3] = 2;
- indexes[4] = 0;
- indexes[5] = 1;
- verts[0].xyz[0] = x;
- verts[0].xyz[1] = y;
- verts[0].xyz[2] = 0;
- verts[0].st[0] = s1;
- verts[0].st[1] = t1;
- verts[0].normal[0] = 0;
- verts[0].normal[1] = 0;
- verts[0].normal[2] = 1;
- verts[0].tangents[0][0] = 1;
- verts[0].tangents[0][1] = 0;
- verts[0].tangents[0][2] = 0;
- verts[0].tangents[1][0] = 0;
- verts[0].tangents[1][1] = 1;
- verts[0].tangents[1][2] = 0;
- verts[1].xyz[0] = x + w;
- verts[1].xyz[1] = y;
- verts[1].xyz[2] = 0;
- verts[1].st[0] = s2;
- verts[1].st[1] = t1;
- verts[1].normal[0] = 0;
- verts[1].normal[1] = 0;
- verts[1].normal[2] = 1;
- verts[1].tangents[0][0] = 1;
- verts[1].tangents[0][1] = 0;
- verts[1].tangents[0][2] = 0;
- verts[1].tangents[1][0] = 0;
- verts[1].tangents[1][1] = 1;
- verts[1].tangents[1][2] = 0;
- verts[2].xyz[0] = x + w;
- verts[2].xyz[1] = y + h;
- verts[2].xyz[2] = 0;
- verts[2].st[0] = s2;
- verts[2].st[1] = t2;
- verts[2].normal[0] = 0;
- verts[2].normal[1] = 0;
- verts[2].normal[2] = 1;
- verts[2].tangents[0][0] = 1;
- verts[2].tangents[0][1] = 0;
- verts[2].tangents[0][2] = 0;
- verts[2].tangents[1][0] = 0;
- verts[2].tangents[1][1] = 1;
- verts[2].tangents[1][2] = 0;
- verts[3].xyz[0] = x;
- verts[3].xyz[1] = y + h;
- verts[3].xyz[2] = 0;
- verts[3].st[0] = s1;
- verts[3].st[1] = t2;
- verts[3].normal[0] = 0;
- verts[3].normal[1] = 0;
- verts[3].normal[2] = 1;
- verts[3].tangents[0][0] = 1;
- verts[3].tangents[0][1] = 0;
- verts[3].tangents[0][2] = 0;
- verts[3].tangents[1][0] = 0;
- verts[3].tangents[1][1] = 1;
- verts[3].tangents[1][2] = 0;
- bool ident = !mat.IsIdentity();
- if ( ident ) {
- verts[0].xyz -= origin;
- verts[0].xyz *= mat;
- verts[0].xyz += origin;
- verts[1].xyz -= origin;
- verts[1].xyz *= mat;
- verts[1].xyz += origin;
- verts[2].xyz -= origin;
- verts[2].xyz *= mat;
- verts[2].xyz += origin;
- verts[3].xyz -= origin;
- verts[3].xyz *= mat;
- verts[3].xyz += origin;
- }
- //Generate a translation so we can translate to the center of the image rotate and draw
- idVec3 origTrans;
- origTrans.x = x+(w/2);
- origTrans.y = y+(h/2);
- origTrans.z = 0;
- //Rotate the verts about the z axis before drawing them
- idMat4 rotz;
- rotz.Identity();
- float sinAng = idMath::Sin(angle);
- float cosAng = idMath::Cos(angle);
- rotz[0][0] = cosAng;
- rotz[0][1] = sinAng;
- rotz[1][0] = -sinAng;
- rotz[1][1] = cosAng;
- for(int i = 0; i < 4; i++) {
- //Translate to origin
- verts[i].xyz -= origTrans;
- //Rotate
- verts[i].xyz = rotz * verts[i].xyz;
- //Translate back
- verts[i].xyz += origTrans;
- }
- renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, (angle == 0.0) ? false : true );
- }
- void idDeviceContext::DrawFilledRect( float x, float y, float w, float h, const idVec4 &color) {
- if ( color.w == 0.0f ) {
- return;
- }
- renderSystem->SetColor(color);
-
- if (ClippedCoords(&x, &y, &w, &h, NULL, NULL, NULL, NULL)) {
- return;
- }
- AdjustCoords(&x, &y, &w, &h);
- DrawStretchPic( x, y, w, h, 0, 0, 0, 0, whiteImage);
- }
- void idDeviceContext::DrawRect( float x, float y, float w, float h, float size, const idVec4 &color) {
- if ( color.w == 0.0f ) {
- return;
- }
- renderSystem->SetColor(color);
-
- if (ClippedCoords(&x, &y, &w, &h, NULL, NULL, NULL, NULL)) {
- return;
- }
- AdjustCoords(&x, &y, &w, &h);
- DrawStretchPic( x, y, size, h, 0, 0, 0, 0, whiteImage );
- DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, whiteImage );
- DrawStretchPic( x, y, w, size, 0, 0, 0, 0, whiteImage );
- DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, whiteImage );
- }
- void idDeviceContext::DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color) {
- if ( color.w == 0.0f ) {
- return;
- }
- renderSystem->SetColor(color);
- DrawMaterial( x, y, size, h, mat, color );
- DrawMaterial( x + w - size, y, size, h, mat, color );
- DrawMaterial( x, y, w, size, mat, color );
- DrawMaterial( x, y + h - size, w, size, mat, color );
- }
- void idDeviceContext::SetCursor(int n) {
- cursor = (n < CURSOR_ARROW || n >= CURSOR_COUNT) ? CURSOR_ARROW : n;
- }
- void idDeviceContext::DrawCursor(float *x, float *y, float size) {
- if (*x < 0) {
- *x = 0;
- }
- if (*x >= vidWidth) {
- *x = vidWidth;
- }
- if (*y < 0) {
- *y = 0;
- }
- if (*y >= vidHeight) {
- *y = vidHeight;
- }
- renderSystem->SetColor(colorWhite);
- AdjustCoords(x, y, &size, &size);
- DrawStretchPic( *x, *y, size, size, 0, 0, 1, 1, cursorImages[cursor]);
- }
- /*
- =======================================================================================================================
- =======================================================================================================================
- */
- void idDeviceContext::PaintChar(float x,float y,float width,float height,float scale,float s,float t,float s2,float t2,const idMaterial *hShader) {
- float w, h;
- w = width * scale;
- h = height * scale;
- if (ClippedCoords(&x, &y, &w, &h, &s, &t, &s2, &t2)) {
- return;
- }
- AdjustCoords(&x, &y, &w, &h);
- DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader);
- }
- void idDeviceContext::SetFontByScale(float scale) {
- if (scale <= gui_smallFontLimit.GetFloat()) {
- useFont = &activeFont->fontInfoSmall;
- activeFont->maxHeight = activeFont->maxHeightSmall;
- activeFont->maxWidth = activeFont->maxWidthSmall;
- } else if (scale <= gui_mediumFontLimit.GetFloat()) {
- useFont = &activeFont->fontInfoMedium;
- activeFont->maxHeight = activeFont->maxHeightMedium;
- activeFont->maxWidth = activeFont->maxWidthMedium;
- } else {
- useFont = &activeFont->fontInfoLarge;
- activeFont->maxHeight = activeFont->maxHeightLarge;
- activeFont->maxWidth = activeFont->maxWidthLarge;
- }
- }
- int idDeviceContext::DrawText(float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor) {
- int len, count;
- idVec4 newColor;
- const glyphInfo_t *glyph;
- float useScale;
- SetFontByScale(scale);
- useScale = scale * useFont->glyphScale;
- count = 0;
- if ( text && color.w != 0.0f ) {
- const unsigned char *s = (const unsigned char*)text;
- renderSystem->SetColor(color);
- memcpy(&newColor[0], &color[0], sizeof(idVec4));
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- while (s && *s && count < len) {
- if ( *s < GLYPH_START || *s > GLYPH_END ) {
- s++;
- continue;
- }
- glyph = &useFont->glyphs[*s];
- //
- // int yadj = Assets.textFont.glyphs[text[i]].bottom +
- // Assets.textFont.glyphs[text[i]].top; float yadj = scale *
- // (Assets.textFont.glyphs[text[i]].imageHeight -
- // Assets.textFont.glyphs[text[i]].height);
- //
- if ( idStr::IsColor((const char*)s) ) {
- if ( *(s+1) == C_COLOR_DEFAULT ) {
- newColor = color;
- } else {
- newColor = idStr::ColorForIndex( *(s+1) );
- newColor[3] = color[3];
- }
- if (cursor == count || cursor == count+1) {
- float partialSkip = ((glyph->xSkip * useScale) + adjust) / 5.0f;
- if ( cursor == count ) {
- partialSkip *= 2.0f;
- } else {
- renderSystem->SetColor(newColor);
- }
- DrawEditCursor(x - partialSkip, y, scale);
- }
- renderSystem->SetColor(newColor);
- s += 2;
- count += 2;
- continue;
- } else {
- float yadj = useScale * glyph->top;
- PaintChar(x,y - yadj,glyph->imageWidth,glyph->imageHeight,useScale,glyph->s,glyph->t,glyph->s2,glyph->t2,glyph->glyph);
- if (cursor == count) {
- DrawEditCursor(x, y, scale);
- }
- x += (glyph->xSkip * useScale) + adjust;
- s++;
- count++;
- }
- }
- if (cursor == len) {
- DrawEditCursor(x, y, scale);
- }
- }
- return count;
- }
- void idDeviceContext::SetSize(float width, float height) {
- vidWidth = VIRTUAL_WIDTH;
- vidHeight = VIRTUAL_HEIGHT;
- xScale = yScale = 0.0f;
- if ( width != 0.0f && height != 0.0f ) {
- xScale = vidWidth * ( 1.0f / width );
- yScale = vidHeight * ( 1.0f / height );
- }
- }
- int idDeviceContext::CharWidth( const char c, float scale ) {
- glyphInfo_t *glyph;
- float useScale;
- SetFontByScale(scale);
- fontInfo_t *font = useFont;
- useScale = scale * font->glyphScale;
- glyph = &font->glyphs[(const unsigned char)c];
- return idMath::FtoiFast( glyph->xSkip * useScale );
- }
- int idDeviceContext::TextWidth( const char *text, float scale, int limit ) {
- int i, width;
- SetFontByScale( scale );
- const glyphInfo_t *glyphs = useFont->glyphs;
- if ( text == NULL ) {
- return 0;
- }
- width = 0;
- if ( limit > 0 ) {
- for ( i = 0; text[i] != '\0' && i < limit; i++ ) {
- if ( idStr::IsColor( text + i ) ) {
- i++;
- } else {
- width += glyphs[((const unsigned char *)text)[i]].xSkip;
- }
- }
- } else {
- for ( i = 0; text[i] != '\0'; i++ ) {
- if ( idStr::IsColor( text + i ) ) {
- i++;
- } else {
- width += glyphs[((const unsigned char *)text)[i]].xSkip;
- }
- }
- }
- return idMath::FtoiFast( scale * useFont->glyphScale * width );
- }
- int idDeviceContext::TextHeight(const char *text, float scale, int limit) {
- int len, count;
- float max;
- glyphInfo_t *glyph;
- float useScale;
- const char *s = text;
- SetFontByScale(scale);
- fontInfo_t *font = useFont;
- useScale = scale * font->glyphScale;
- max = 0;
- if (text) {
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- while (s && *s && count < len) {
- if ( idStr::IsColor(s) ) {
- s += 2;
- continue;
- }
- else {
- glyph = &font->glyphs[*(const unsigned char*)s];
- if (max < glyph->height) {
- max = glyph->height;
- }
- s++;
- count++;
- }
- }
- }
- return idMath::FtoiFast( max * useScale );
- }
- int idDeviceContext::MaxCharWidth(float scale) {
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- return idMath::FtoiFast( activeFont->maxWidth * useScale );
- }
- int idDeviceContext::MaxCharHeight(float scale) {
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- return idMath::FtoiFast( activeFont->maxHeight * useScale );
- }
- const idMaterial *idDeviceContext::GetScrollBarImage(int index) {
- if (index >= SCROLLBAR_HBACK && index < SCROLLBAR_COUNT) {
- return scrollBarImages[index];
- }
- return scrollBarImages[SCROLLBAR_HBACK];
- }
- // this only supports left aligned text
- idRegion *idDeviceContext::GetTextRegion(const char *text, float textScale, idRectangle rectDraw, float xStart, float yStart) {
- #if 0
- const char *p, *textPtr, *newLinePtr;
- char buff[1024];
- int len, textWidth, newLine, newLineWidth;
- float y;
- float charSkip = MaxCharWidth(textScale) + 1;
- float lineSkip = MaxCharHeight(textScale);
- textWidth = 0;
- newLinePtr = NULL;
- #endif
- return NULL;
- /*
- if (text == NULL) {
- return;
- }
- textPtr = text;
- if (*textPtr == '\0') {
- return;
- }
- y = lineSkip + rectDraw.y + yStart;
- len = 0;
- buff[0] = '\0';
- newLine = 0;
- newLineWidth = 0;
- p = textPtr;
- textWidth = 0;
- while (p) {
- if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0') {
- newLine = len;
- newLinePtr = p + 1;
- newLineWidth = textWidth;
- }
- if ((newLine && textWidth > rectDraw.w) || *p == '\n' || *p == '\0') {
- if (len) {
- float x = rectDraw.x ;
-
- buff[newLine] = '\0';
- DrawText(x, y, textScale, color, buff, 0, 0, 0);
- if (!wrap) {
- return;
- }
- }
- if (*p == '\0') {
- break;
- }
- y += lineSkip + 5;
- p = newLinePtr;
- len = 0;
- newLine = 0;
- newLineWidth = 0;
- continue;
- }
- buff[len++] = *p++;
- buff[len] = '\0';
- textWidth = TextWidth( buff, textScale, -1 );
- }
- */
- }
- void idDeviceContext::DrawEditCursor( float x, float y, float scale ) {
- if ( (int)( com_ticNumber >> 4 ) & 1 ) {
- return;
- }
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- const glyphInfo_t *glyph2 = &useFont->glyphs[(overStrikeMode) ? '_' : '|'];
- float yadj = useScale * glyph2->top;
- PaintChar(x, y - yadj,glyph2->imageWidth,glyph2->imageHeight,useScale,glyph2->s,glyph2->t,glyph2->s2,glyph2->t2,glyph2->glyph);
- }
- int idDeviceContext::DrawText( const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor, bool calcOnly, idList<int> *breaks, int limit ) {
- const char *p, *textPtr, *newLinePtr;
- char buff[1024];
- int len, newLine, newLineWidth, count;
- float y;
- float textWidth;
- float charSkip = MaxCharWidth( textScale ) + 1;
- float lineSkip = MaxCharHeight( textScale );
- float cursorSkip = ( cursor >= 0 ? charSkip : 0 );
- bool lineBreak, wordBreak;
- SetFontByScale( textScale );
- textWidth = 0;
- newLinePtr = NULL;
- if (!calcOnly && !(text && *text)) {
- if (cursor == 0) {
- renderSystem->SetColor(color);
- DrawEditCursor(rectDraw.x, lineSkip + rectDraw.y, textScale);
- }
- return idMath::FtoiFast( rectDraw.w / charSkip );
- }
- textPtr = text;
- y = lineSkip + rectDraw.y;
- len = 0;
- buff[0] = '\0';
- newLine = 0;
- newLineWidth = 0;
- p = textPtr;
- if ( breaks ) {
- breaks->Append(0);
- }
- count = 0;
- textWidth = 0;
- lineBreak = false;
- wordBreak = false;
- while (p) {
- if ( *p == '\n' || *p == '\r' || *p == '\0' ) {
- lineBreak = true;
- if ((*p == '\n' && *(p + 1) == '\r') || (*p == '\r' && *(p + 1) == '\n')) {
- p++;
- }
- }
- int nextCharWidth = ( idStr::CharIsPrintable(*p) ? CharWidth( *p, textScale ) : cursorSkip );
- // FIXME: this is a temp hack until the guis can be fixed not not overflow the bounding rectangles
- // the side-effect is that list boxes and edit boxes will draw over their scroll bars
- // The following line and the !linebreak in the if statement below should be removed
- nextCharWidth = 0;
- if ( !lineBreak && ( textWidth + nextCharWidth ) > rectDraw.w ) {
- // The next character will cause us to overflow, if we haven't yet found a suitable
- // break spot, set it to be this character
- if ( len > 0 && newLine == 0 ) {
- newLine = len;
- newLinePtr = p;
- newLineWidth = textWidth;
- }
- wordBreak = true;
- } else if ( lineBreak || ( wrap && (*p == ' ' || *p == '\t') ) ) {
- // The next character is in view, so if we are a break character, store our position
- newLine = len;
- newLinePtr = p + 1;
- newLineWidth = textWidth;
- }
- if ( lineBreak || wordBreak ) {
- float x = rectDraw.x;
- if (textAlign == ALIGN_RIGHT) {
- x = rectDraw.x + rectDraw.w - newLineWidth;
- } else if (textAlign == ALIGN_CENTER) {
- x = rectDraw.x + (rectDraw.w - newLineWidth) / 2;
- }
- if ( wrap || newLine > 0 ) {
- buff[newLine] = '\0';
- // This is a special case to handle breaking in the middle of a word.
- // if we didn't do this, the cursor would appear on the end of this line
- // and the beginning of the next.
- if ( wordBreak && cursor >= newLine && newLine == len ) {
- cursor++;
- }
- }
- if (!calcOnly) {
- count += DrawText(x, y, textScale, color, buff, 0, 0, 0, cursor);
- }
- if ( cursor < newLine ) {
- cursor = -1;
- } else if ( cursor >= 0 ) {
- cursor -= ( newLine + 1 );
- }
- if ( !wrap ) {
- return newLine;
- }
- if ( ( limit && count > limit ) || *p == '\0' ) {
- break;
- }
- y += lineSkip + 5;
- if ( !calcOnly && y > rectDraw.Bottom() ) {
- break;
- }
- p = newLinePtr;
- if (breaks) {
- breaks->Append(p - text);
- }
- len = 0;
- newLine = 0;
- newLineWidth = 0;
- textWidth = 0;
- lineBreak = false;
- wordBreak = false;
- continue;
- }
- buff[len++] = *p++;
- buff[len] = '\0';
- // update the width
- if ( *( buff + len - 1 ) != C_COLOR_ESCAPE && (len <= 1 || *( buff + len - 2 ) != C_COLOR_ESCAPE)) {
- textWidth += textScale * useFont->glyphScale * useFont->glyphs[ (const unsigned char)*( buff + len - 1 ) ].xSkip;
- }
- }
- return idMath::FtoiFast( rectDraw.w / charSkip );
- }
- /*
- =============
- idRectangle::String
- =============
- */
- char *idRectangle::String( void ) const {
- static int index = 0;
- static char str[ 8 ][ 48 ];
- char *s;
- // use an array so that multiple toString's won't collide
- s = str[ index ];
- index = (index + 1)&7;
- sprintf( s, "%.2f %.2f %.2f %.2f", x, y, w, h );
- return s;
- }
|