int __cdecl main(int argc, char *argv[]) { unsigned char *str1 = (unsigned char*) "foo"; unsigned char str2[] = {0xC0, 0x80, 0xC0, 0x80, 0}; unsigned char str3[] = {0}; unsigned char *ret = NULL; /* * Initialize the PAL and return FAIL if this fails */ if (0 != (PAL_Initialize(argc, argv))) { return FAIL; } ret = _mbsdec(str1,str1+1); if (ret != str1) { Fail ("ERROR: _mbsdec returned %p. Expected %p\n", ret, str1); } ret = _mbsdec(str1,str1); if (ret != NULL) { Fail ("ERROR: _mbsdec returned %p. Expected %p\n", ret, NULL); } ret = _mbsdec(str1+100,str1); if (ret != NULL) { Fail ("ERROR: _mbsdec returned %p. Expected %p\n", ret, NULL); } ret = _mbsdec(str2,str2+1); if (ret != str2) { Fail ("ERROR: _mbsdec returned %p. Expected %p\n", ret, str2+1); } ret = _mbsdec(str3,str3+10); if (ret != str3+9) { Fail ("ERROR: _mbsdec returned %p. Expected %p\n", ret, str3+9); } PAL_Terminate(); return PASS; }
static PRBool IsPrevCharSlash(const char *str, const char *current) { const char *prev; if (str >= current) return PR_FALSE; prev = _mbsdec(str, current); return (prev == current - 1) && _PR_IS_SLASH(*prev); }
void __cdecl _tmakepath ( register _TSCHAR *path, const _TSCHAR *drive, const _TSCHAR *dir, const _TSCHAR *fname, const _TSCHAR *ext ) { register const _TSCHAR *p; /* we assume that the arguments are in the following form (although we * do not diagnose invalid arguments or illegal filenames (such as * names longer than 8.3 or with illegal characters in them) * * drive: * A ; or * A: * dir: * \top\next\last\ ; or * /top/next/last/ ; or * either of the above forms with either/both the leading * and trailing / or \ removed. Mixed use of '/' and '\' is * also tolerated * fname: * any valid file name * ext: * any valid extension (none if empty or null ) */ /* copy drive */ if (drive && *drive) { *path++ = *drive; *path++ = _T(':'); } /* copy dir */ if ((p = dir) && *p) { do { *path++ = *p++; } while (*p); #ifdef _MBCS if (*(p=_mbsdec(dir,p)) != _T('/') && *p != _T('\\')) { #else /* _MBCS */ if (*(p-1) != _T('/') && *(p-1) != _T('\\')) { #endif /* _MBCS */ *path++ = _T('\\'); } } /* copy fname */ if (p = fname) { while (*p) { *path++ = *p++; } } /* copy ext, including 0-terminator - check to see if a '.' needs * to be inserted. */ if (p = ext) { if (*p && *p != _T('.')) { *path++ = _T('.'); } while (*path++ = *p++) ; } else { /* better add the 0-terminator */ *path = _T('\0'); } }
HSURFACE CTextHelper::CreateWrappedSurface (ILTClient* pClientDE, int nWidth, HLTFONT hFont, char* pString, HLTCOLOR foreColor, HLTCOLOR backColor, int nAlignment, LTBOOL bCropped, int nExtraX, int nExtraY) { if (!pString || !pClientDE) return LTNULL; // check if we are supposed to do hard wrapping bool bHardTextWrap = false; { HSTRING hStr = pClientDE->FormatString(IDS_ENABLETEXTHARDWRAP); if (hStr) { const char* pComp = pClientDE->GetStringData(hStr); if (pComp != NULL) { if (stricmp(pComp,"TRUE") == 0) bHardTextWrap = true; } pClientDE->FreeString (hStr); } } // get period or other characters that are not supposed to be at start of a line char sPeriodChars[256] = "."; { HSTRING hStr = pClientDE->FormatString(IDS_EXCLULTLineSTARTCHARS); if (hStr) { const char* pComp = pClientDE->GetStringData(hStr); if (pComp != NULL) { _mbsncpy((unsigned char*)sPeriodChars, (const unsigned char*)pComp, 255); sPeriodChars[255] = '\0'; } pClientDE->FreeString (hStr); } } char* pWorkingString = new char [strlen (pString) + 1]; if (!pWorkingString) return LTNULL; CDynArray<uint32> surfaces (1, 2); // cannot create a dynarray of HSURFACES - compiler error C2926 uint32 nSurfaces = 0; char* ptr = (char*) pString; while (*ptr != '\0') { // copy what's left into the working string strcpy (pWorkingString, ptr); // create a string that will fit into the desired width LTBOOL bDone = LTFALSE; HSURFACE hSurface = LTNULL; while (!bDone) { // create a string surface from the working string to test HSTRING hString = pClientDE->CreateString (pWorkingString); if (!hString) break; hSurface = pClientDE->CreateSurfaceFromString (hFont, hString, foreColor, backColor, nExtraX, nExtraY); if (!hSurface) { pClientDE->FreeString (hString); break; } pClientDE->FreeString (hString); // get the dimensions of the surface uint32 nTestWidth = 0; uint32 nTestHeight = 0; pClientDE->GetSurfaceDims (hSurface, &nTestWidth, &nTestHeight); if (nTestWidth > (uint32)nWidth) { // string too long, remove some and try again char* pSpace; // remove by character if we are hard wrapping if (bHardTextWrap) { pSpace = pWorkingString; // find last hard in string pPrev char* pPrev = NULL; while (pSpace != NULL) { pPrev = pSpace; pSpace = (char*)_mbsinc ((const unsigned char*)pSpace); if (*pSpace == '\0') pSpace = NULL; } if (pPrev == NULL) pSpace = pWorkingString; else { //decrement 1 character pSpace = (char*)_mbsdec ((const unsigned char*)pWorkingString, (const unsigned char*)pPrev); // check if we are on a period then we need to decrement 3 more if ((char*)_mbsspnp((const unsigned char*)pPrev, (const unsigned char*)sPeriodChars) != pPrev) { if (pSpace != NULL) pSpace = (char*)_mbsdec ((const unsigned char*)pWorkingString, (const unsigned char*)pSpace); if (pSpace != NULL) pSpace = (char*)_mbsdec ((const unsigned char*)pWorkingString, (const unsigned char*)pSpace); } } } // remove by word if hard wrap is not on else { pSpace = (char*)_mbsrchr ((const unsigned char*)pWorkingString, ' '); if (!pSpace) pSpace = pWorkingString; while (_mbsnbcmp ((const unsigned char*)pSpace, (const unsigned char*)" ", 1) == 0 && pSpace != pWorkingString) { pSpace = (char*)_mbsdec ((const unsigned char*)pWorkingString, (const unsigned char*)pSpace); if (!pSpace) pSpace = pWorkingString; } } if (pSpace == pWorkingString) { bDone = LTTRUE; } else { pSpace = (char*)_mbsinc ((const unsigned char*)pSpace); *pSpace = '\0'; } pClientDE->DeleteSurface (hSurface); hSurface = LTNULL; } else { // it fits! bDone = LTTRUE; } } // if we got here without bDone being TRUE, there was an error if (!bDone) { delete [] pWorkingString; for (uint32 i = 0; i < nSurfaces; i++) { pClientDE->DeleteSurface ((HSURFACE)surfaces[i]); } return LTNULL; } // if bDone is true but there's no surface, we couldn't make it fit // just create a surface from the string and it will get clipped later if (bDone && !hSurface) { HSTRING hString = pClientDE->CreateString (pWorkingString); hSurface = pClientDE->CreateSurfaceFromString (hFont, hString, foreColor, backColor, nExtraX, nExtraY); if (!hString || !hSurface) { if (hString) pClientDE->FreeString (hString); if (hSurface) pClientDE->DeleteSurface (hSurface); delete [] pWorkingString; for (uint32 i = 0; i < nSurfaces; i++) { pClientDE->DeleteSurface ((HSURFACE)surfaces[i]); } return LTNULL; } pClientDE->FreeString (hString); } // add this surface to the array surfaces[nSurfaces] = (uint32) hSurface; nSurfaces++; // increment ptr to next character in the string ptr += strlen (pWorkingString); char* pPrev = NULL; while (_mbsnbcmp ((const unsigned char*)ptr, (const unsigned char*)" ", 1) == 0 && *ptr) { pPrev = ptr; ptr = (char*)_mbsinc ((const unsigned char*)ptr); if (!ptr) { ptr = pPrev; break; } } } delete [] pWorkingString; // ok, now we should have an array of surfaces that we can combine into one large one... if (!nSurfaces) return LTNULL; // crop the surfaces if they need to be cropped (leave a one-pixel border) if (bCropped) { for (uint32 i = 0; i < nSurfaces; i++) { HSURFACE hCropped = CropSurface (pClientDE, (HSURFACE)surfaces[i], LTNULL); if (hCropped) { pClientDE->DeleteSurface ((HSURFACE)surfaces[i]); surfaces[i] = (uint32) hCropped; } } } // get the final surface height uint32 nTotalHeight = 0; for (uint32 i = 0; i < nSurfaces; i++) { uint32 nSurfWidth = 0; uint32 nSurfHeight = 0; pClientDE->GetSurfaceDims ((HSURFACE)surfaces[i], &nSurfWidth, &nSurfHeight); nTotalHeight += nSurfHeight; } // create the final surface HSURFACE hFinalSurface = pClientDE->CreateSurface (nWidth, nTotalHeight); if (!hFinalSurface) { for (uint32 i = 0; i < nSurfaces; i++) { pClientDE->DeleteSurface ((HSURFACE)surfaces[i]); } return LTNULL; } pClientDE->FillRect ((HSURFACE)hFinalSurface, LTNULL, LTNULL); // draw the string surfaces onto final one int y = 0; for (int i = 0; i < nSurfaces; i++) { uint32 nSurfWidth = 0; uint32 nSurfHeight = 0; pClientDE->GetSurfaceDims ((HSURFACE)surfaces[i], &nSurfWidth, &nSurfHeight); int x = 0; switch (nAlignment) { case TH_ALIGN_CENTER: x = ((int)nWidth - (int)nSurfWidth) / 2; break; case TH_ALIGN_RIGHT: x = (int)nWidth - (int)nSurfWidth; break; } pClientDE->DrawSurfaceToSurface (hFinalSurface, (HSURFACE)surfaces[i], LTNULL, x, y); y += nSurfHeight; // delete this surface since we don't need it anymore pClientDE->DeleteSurface ((HSURFACE)surfaces[i]); } if (bCropped) { HSURFACE hCropped = CropSurface (pClientDE, hFinalSurface, backColor); if (hCropped) { pClientDE->DeleteSurface (hFinalSurface); return hCropped; } } return hFinalSurface; }
_WCRTLINK void __F_NAME(_makepath,_wmakepath)( CHAR_TYPE *path, const CHAR_TYPE *drive, const CHAR_TYPE *dir, const CHAR_TYPE *fname, const CHAR_TYPE *ext ) { UINT_WC_TYPE first_pc = NULLCHAR; #ifndef __WIDECHAR__ char *pathstart = path; unsigned ch; #endif if( drive != NULL ) { if( *drive != NULLCHAR ) { if( ( drive[0] == DIR_SEP ) && ( drive[1] == DIR_SEP ) ) { __F_NAME(strcpy, wcscpy)( path, drive ); path += __F_NAME(strlen, wcslen)( drive ); } else { *path++ = *drive; /* OK for MBCS */ *path++ = DRV_SEP; } } } *path = NULLCHAR; if( dir != NULL ) { if( *dir != NULLCHAR ) { do { #ifdef __WIDECHAR__ *path++ = pickup( *dir++, &first_pc ); #else ch = pickup( _mbsnextc( (unsigned char *)dir ), &first_pc ); _mbvtop( ch, (unsigned char *)path ); path[_mbclen( (unsigned char *)path )] = NULLCHAR; path = (char *)_mbsinc( (unsigned char *)path ); dir = (char *)_mbsinc( (unsigned char *)dir ); #endif } while( *dir != NULLCHAR ); /* if no path separator was specified then pick a default */ if( first_pc == NULLCHAR ) first_pc = DIR_SEP; /* if dir did not end in '/' then put in a provisional one */ #ifdef __WIDECHAR__ if( path[-1] == first_pc ) { path--; } else { *path = first_pc; } #else if( *(_mbsdec( (unsigned char *)pathstart, (unsigned char *)path )) == first_pc ) { path--; } else { *path = first_pc; } #endif } } /* if no path separator was specified thus far then pick a default */ if( first_pc == NULLCHAR ) first_pc = DIR_SEP; if( fname != NULL ) { #ifdef __WIDECHAR__ if( pickup( *fname, &first_pc ) != first_pc && *path == first_pc ) path++; #else ch = _mbsnextc( (unsigned char *)fname ); if( pickup( ch, &first_pc ) != first_pc && *path == first_pc ) path++; #endif while( *fname != NULLCHAR ) { //do { #ifdef __WIDECHAR__ *path++ = pickup( *fname++, &first_pc ); #else ch = pickup( _mbsnextc( (unsigned char *)fname ), &first_pc ); _mbvtop( ch, (unsigned char *)path ); path[_mbclen( (unsigned char *)path )] = NULLCHAR; path = (char *)_mbsinc( (unsigned char *)path ); fname = (char *)_mbsinc( (unsigned char *)fname ); #endif } //while( *fname != NULLCHAR ); } else { if( *path == first_pc ) { path++; } } if( ext != NULL ) { if( *ext != NULLCHAR ) { if( *ext != EXT_SEP ) *path++ = EXT_SEP; while( *ext != NULLCHAR ) { *path++ = *ext++; /* OK for MBCS */ } } } *path = NULLCHAR; }