00001 /*! \file 00002 * X-Forge Util <br> 00003 * Copyright 2000-2003 Fathammer Ltd 00004 * 00005 * \brief Primitive RLESprite font printer class. 00006 * Needs some work (create instead of init; gl sprites instead 00007 * of the glsurface drawing currently in use. 00008 * 00009 * $Id: XFuRLESpritePrinter.cpp,v 1.10 2003/04/10 06:57:26 kkallio Exp $ 00010 * $Date: 2003/04/10 06:57:26 $ 00011 * $Revision: 1.10 $ 00012 */ 00013 00014 #include <stdlib.h> 00015 #include <xfcore/XFcCore.h> 00016 #include <xfutil/XFuPrinter.h> 00017 #include <xfutil/XFuRLESpritePrinter.h> 00018 #include <xfcore/XFcPixelConverter.h> 00019 00020 00021 XFuRLESpritePrinter * XFuRLESpritePrinter::create(const CHAR *aFname) 00022 { 00023 return create(aFname,0xff000000,0x00000000,REALi(1),REALi(1)); 00024 } 00025 00026 XFuRLESpritePrinter * XFuRLESpritePrinter::create(const CHAR *aFname, UINT32 aBaseMask, UINT32 aBaseColor) 00027 { 00028 return create(aFname,aBaseMask,aBaseColor,REALi(1),REALi(1)); 00029 } 00030 00031 XFuRLESpritePrinter * XFuRLESpritePrinter::create(const CHAR *aFname, UINT32 aBaseMask, UINT32 aBaseColor, REAL aXScale, REAL aYScale) 00032 { 00033 INT32 wid, ht; 00034 INT32 i; 00035 00036 XFcGLSurface *img = XFcImageLoader::load(aFname,XFCGF_A8R8G8B8); 00037 if (img == NULL) return NULL; 00038 00039 XFuRLESpritePrinter *p = new XFuRLESpritePrinter(); 00040 00041 if (p == NULL) 00042 { 00043 delete img; 00044 return NULL; 00045 } 00046 00047 p->mLetterSpacing = 2; // default letter spacing 00048 00049 wid = img->getWidth(); 00050 ht = img->getHeight(); 00051 00052 p->mLineSpacing = (INT32)(aXScale * (REAL)wid); 00053 p->mLineHeight = (INT32)(aYScale * (REAL)wid); 00054 00055 p->mMaxletter = ht / wid; 00056 p->mLetterSprite = new XFcRLESprite *[p->mMaxletter]; 00057 00058 if (p->mLetterSprite == NULL) 00059 { 00060 delete img; 00061 delete p; 00062 return NULL; 00063 } 00064 00065 XFcGLSurface *tImg = XFcGLSurface::create(wid,wid,XFCGF_A8R8G8B8); 00066 00067 if (tImg == NULL) 00068 { 00069 delete img; 00070 delete p; 00071 return NULL; 00072 } 00073 00074 // init to NULL so that delete wouldn't fail if creation fails 00075 for (i = 0; i < p->mMaxletter; ++i) 00076 p->mLetterSprite[i] = NULL; 00077 00078 UINT32 *pic; 00079 INT32 pitch = img->lock((void **)(&pic)); 00080 if (pitch == 0) 00081 { 00082 delete tImg; 00083 delete img; 00084 delete p; 00085 return NULL; 00086 } 00087 00088 pitch /= 4; 00089 for (i = 0; i < p->mMaxletter; ++i) 00090 { 00091 INT32 letterofs = i * wid * pitch; 00092 00093 UINT32 *fb; 00094 INT32 tPitch = tImg->lock((void **)&fb); 00095 if (tPitch == 0) 00096 { 00097 delete tImg; 00098 img->unlock(); 00099 delete img; 00100 delete p; 00101 return NULL; 00102 } 00103 tPitch /= 4; 00104 00105 INT32 j,k; 00106 for (j = 0; j < wid; j++) 00107 { 00108 for (k = 0; k < wid; k++) 00109 { 00110 fb[j*tPitch + k] = pic[letterofs + j*pitch + k]; 00111 } 00112 } 00113 00114 tImg->unlock(); 00115 00116 if (aXScale != REALi(1) || aYScale != REALi(1)) 00117 { 00118 XFcGLSurface *tImg2 = XFcGLSurfaceToolkit::resampleSurface(tImg,aXScale,aYScale); 00119 if (tImg2) 00120 p->mLetterSprite[i] = XFcRLESprite::create(tImg2, aBaseMask, aBaseColor); 00121 delete tImg2; 00122 } 00123 else 00124 p->mLetterSprite[i] = XFcRLESprite::create(tImg, aBaseMask, aBaseColor); 00125 00126 if (p->mLetterSprite[i] == NULL) 00127 { 00128 delete tImg; 00129 img->unlock(); 00130 delete img; 00131 delete p; 00132 return NULL; 00133 } 00134 if (p->mLetterSprite[i]->getWidth() == 0) 00135 { 00136 delete p->mLetterSprite[i]; 00137 p->mLetterSprite[i] = NULL; 00138 } 00139 else 00140 { 00141 p->mLetterSprite[i]->setXOffset(0); 00142 } 00143 } 00144 img->unlock(); 00145 delete tImg; 00146 delete img; 00147 00148 if (p->mLetterSprite['0' - 33]) 00149 p->mSpaceWidth = p->mLetterSprite['0' - 33]->getWidth() / 2; 00150 else 00151 p->mSpaceWidth = p->mLineHeight / 2; 00152 00153 return p; 00154 00155 } 00156 00157 00158 void XFuRLESpritePrinter::print(XFcGLSurface *aTarget, INT32 aX, INT32 aY, const CHAR *aText, 00159 INT32 aBlendType, INT32 /*aBlendValue*/, XFcRectangle *aClipRect) 00160 { 00161 if (this == NULL) return; 00162 unsigned char *p = (unsigned char *)aText; 00163 int xo = 0; 00164 INT32 i; 00165 00166 XFcRectangle tRect; 00167 if (aClipRect == NULL) 00168 { 00169 tRect.mX = 0; 00170 tRect.mY = 0; 00171 tRect.mWidth = aTarget->getWidth(); 00172 tRect.mHeight = aTarget->getHeight(); 00173 aClipRect = &tRect; 00174 } 00175 00176 while (*p) 00177 { 00178 if (*p == 32) 00179 { 00180 xo += mSpaceWidth + mLetterSpacing; 00181 } 00182 else 00183 { 00184 if (*p == '\n') 00185 { 00186 xo = 0; 00187 aY += mLineSpacing; 00188 } 00189 else 00190 { 00191 i = ((UINT8)*p) - 33; 00192 if (i >= 0 && i < mMaxletter) 00193 { 00194 if (mLetterSprite[i] != NULL) 00195 { 00196 INT32 w = mLetterSprite[i]->getWidth(); 00197 INT32 xp = aX + xo; 00198 switch (aBlendType) 00199 { 00200 case XFCBLEND_NONE: 00201 mLetterSprite[i]->blit(aTarget,aClipRect,xp,aY); 00202 break; 00203 case XFCBLEND_MUL: 00204 mLetterSprite[i]->blitMultiplicative(aTarget,aClipRect,xp,aY); 00205 break; 00206 case XFCBLEND_ADD: 00207 mLetterSprite[i]->blitAdditive(aTarget,aClipRect,xp,aY); 00208 break; 00209 default: 00210 mLetterSprite[i]->blit(aTarget,aClipRect,xp,aY); 00211 break; 00212 } 00213 xo += w; 00214 } 00215 xo += mLetterSpacing; 00216 } 00217 } 00218 } 00219 ++p; 00220 } 00221 } 00222 00223 00224 void XFuRLESpritePrinter::stringMetrics(const CHAR *aText, INT32 &aWidth, INT32 &aHeight) 00225 { 00226 if (aText == NULL) 00227 { 00228 aHeight = 0; 00229 aWidth = 0; 00230 return; 00231 } 00232 unsigned char *p = (unsigned char *)aText; 00233 int xo = 0, y = 0; 00234 int maxx = 0; 00235 INT32 i; 00236 while (*p) 00237 { 00238 if (*p == 32) 00239 { 00240 xo += mSpaceWidth; 00241 if (maxx < xo) maxx = xo; 00242 xo += mLetterSpacing; 00243 } 00244 else 00245 { 00246 if (*p == '\n') 00247 { 00248 xo = 0; 00249 y += mLineSpacing; 00250 } 00251 else 00252 { 00253 i = ((UINT8)*p) - 33; 00254 if ( i >= 0 && i < mMaxletter ) 00255 { 00256 if (mLetterSprite[i]) 00257 xo += mLetterSprite[i]->getWidth(); 00258 if (maxx < xo) maxx = xo; 00259 xo += mLetterSpacing; 00260 } 00261 } 00262 } 00263 00264 ++p; 00265 00266 } 00267 y += mLineHeight; 00268 aHeight = y; 00269 aWidth = maxx; 00270 } 00271 00272 00273 INT32 XFuRLESpritePrinter:: getCharWidth(CHAR aChar) 00274 { 00275 INT32 i = (INT32)(((UINT8)aChar) - 33); 00276 if (aChar == 32) 00277 return mSpaceWidth; 00278 else if (i < 0 || i >= mMaxletter || mLetterSprite[i] == NULL) 00279 return 0; 00280 else 00281 return mLetterSprite[i]->getWidth(); 00282 } 00283 00284 00285 XFuRLESpritePrinter::~XFuRLESpritePrinter() 00286 { 00287 int i; 00288 if (mLetterSprite) 00289 { 00290 for (i = 0; i < mMaxletter; ++i) 00291 delete mLetterSprite[i]; 00292 } 00293 delete[] mLetterSprite; 00294 } 00295 00296 00297 XFuRLESpritePrinter::XFuRLESpritePrinter() 00298 { 00299 mLetterSprite = NULL; 00300 }
![]() | ||||
![]() |
Confidential Copyright © 2002-2003 Fathammer | with doxygen by Dimitri van Heesch |