/*!*************************************************************************** @Function PVRTUnicodeUTF8ToUTF32 @Input pUTF8 A UTF8 string, which is null terminated. @Output aUTF32 An array of Unicode code points. @Returns Success or failure. @Description Decodes a UTF8-encoded string in to Unicode code points (UTF32). If pUTF8 is not null terminated, the results are undefined. *****************************************************************************/ EPVRTError PVRTUnicodeUTF8ToUTF32(const PVRTuint8* const pUTF8, CPVRTArray<PVRTuint32>& aUTF32) { unsigned int uiTailLen, uiIndex; unsigned int uiBytes = (unsigned int) strlen((const char*)pUTF8); PVRTuint32 c32; const PVRTuint8* pC = pUTF8; while(*pC) { // Quick optimisation for ASCII characters while(*pC && *pC < VALID_ASCII) { aUTF32.Append(*pC++); } // Done if(!*pC) break; c32 = *pC++; uiTailLen = c_u8UTF8Lengths[c32]; // Check for invalid tail length. Maximum 4 bytes for each UTF8 character. // Also check to make sure the tail length is inside the provided buffer. if(uiTailLen == 0 || (pC + uiTailLen > pUTF8 + uiBytes)) return PVR_OVERFLOW; c32 &= (TAIL_MASK >> uiTailLen); // Get the data out of the first byte. This depends on the length of the tail. // Get the data out of each tail byte uiIndex = 0; while(uiIndex < uiTailLen) { if((pC[uiIndex] & 0xC0) != 0x80) return PVR_FAIL; // Invalid tail byte! c32 = (c32 << BYTES_PER_TAIL) + (pC[uiIndex] & TAIL_MASK); uiIndex++; } pC += uiIndex; // Check overlong values. if(c32 < c_u32MinVals[uiTailLen]) return PVR_FAIL; if(!CheckGenericUnicode(c32)) return PVR_FAIL; // OK aUTF32.Append(c32); } return PVR_SUCCESS; }
/*!*************************************************************************** @Function PVRTUnicodeUTF16ToUTF32 @Input pUTF16 A UTF16 string, which is null terminated. @Output aUTF32 An array of Unicode code points. @Returns Success or failure. @Description Decodes a UTF16-encoded string in to Unicode code points (UTF32). If pUTF16 is not null terminated, the results are undefined. *****************************************************************************/ EPVRTError PVRTUnicodeUTF16ToUTF32(const PVRTuint16* const pUTF16, CPVRTArray<PVRTuint32>& aUTF32) { const PVRTuint16* pC = pUTF16; // Determine the number of shorts while(*++pC && (pC - pUTF16) < MAX_LEN); unsigned int uiBufferLen = (unsigned int) (pC - pUTF16); if(uiBufferLen == MAX_LEN) return PVR_OVERFLOW; // Probably not NULL terminated. // Reset to start. pC = pUTF16; PVRTuint32 c32; while(*pC) { // Straight copy. We'll check for surrogate pairs next... c32 = *pC++; // Check surrogate pair if(c32 >= UTF16_SURG_H_MARK && c32 <= UTF16_SURG_H_END) { // Make sure the next 2 bytes are in range... if(pC + 1 > pUTF16 + uiBufferLen || *pC == 0) return PVR_OVERFLOW; // Check that the next value is in the low surrogate range if(*pC < UTF16_SURG_L_MARK || *pC > UTF16_SURG_L_END) return PVR_FAIL; // Decode c32 = ((c32 - UTF16_SURG_H_MARK) << 10) + (*pC - UTF16_SURG_L_MARK) + 0x10000; pC++; } if(!CheckGenericUnicode(c32)) return PVR_FAIL; // OK aUTF32.Append(c32); } return PVR_SUCCESS; }
/*!**************************************************************************** @Function InitApplication @Return bool true if no error occurred @Description Code in InitApplication() will be called by PVRShell once per run, before the rendering context is created. Used to initialize variables that are not dependent on it (e.g. external modules, loading meshes, etc.) If the rendering context is lost, InitApplication() will not be called again. ******************************************************************************/ bool OGLES2IntroducingPrint3D::InitApplication() { /* CPVRTResourceFile is a resource file helper class. Resource files can be placed on disk next to the executable or in a platform dependent read path. We need to tell the class where that read path is. Additionally, it is possible to wrap files into cpp modules and link them directly into the executable. In this case no path will be used. Files on disk will override "memory files". */ // Get and set the read path for content files CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath)); /* Get and set the load/release functions for loading external files. In the majority of cases the PVRShell will return NULL function pointers implying that nothing special is required to load external files. */ CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc)); /* Because the C++ standard states that only ASCII characters are valid in compiled code, we are instead using an external resource file which contains all of the text to be rendered. This allows complete control over the encoding of the resource file which in this case is encoded as UTF-8. */ CPVRTResourceFile TextResource(c_szResTextFile); if(!TextResource.IsOpen()) { PVRShellSet(prefExitMessage, "ERROR: Failed to load text resource file!"); return false; } /* The following code simply pulls out each line in the resource file and adds it to an array so we can render each line separately. */ const PVRTuint8* pStart = (PVRTuint8*)TextResource.DataPtr(); const PVRTuint8* pC = pStart; while(*pC && ((unsigned int)(pC - pStart) < TextResource.Size())) { // Read how many characters on this line. const PVRTuint8* pLStart = pC; while(*pC && *pC != '\n') pC++; unsigned int uiDataLen = (unsigned int) (pC - pLStart + 1); PVRTuint8* pLineData = new PVRTuint8[uiDataLen + 1]; memset(pLineData, 0, uiDataLen + 1); pC = pLStart; unsigned int uiIndex; for(uiIndex = 0; uiIndex < uiDataLen; ++uiIndex) pLineData[uiIndex] = pC[uiIndex]; pC += uiDataLen; m_TextLines.Append(pLineData); } m_fTextOffset = TEXT_START_Y; m_ulPrevFrameT = 0; m_eTitleLang = eLang_English; return true; }