int32_t BMFont::getASCIITextWidth(const char* text) const { int32_t width = 0; size_t stringLen = std::strlen(text); for (size_t i = 0; i < stringLen; ++i) { uint32_t charID = static_cast<uint32_t>(text[i]); const CharInfo* info = getCharInfo(charID); if (info == nullptr) { std::cerr << "Unable to find character for: " << charID << std::endl; continue; } /// \todo On the first and last characters, take xoffset into account! /// First character: If xoffset is negative, then expand width. /// Last character: If xoffset is positive, then expand width. width += info->xadvance; // Get next character and adjust horizontal distance if the pair is in // the kerning pair map. if (i < stringLen - 1) { width += getKerningAdjustment(charID, static_cast<uint32_t>(text[i+1])); } } return width; }
// same getCharInfo but return true only if client has been allowad by su to connect bool checkSecurityInfo(NLNET::IModuleProxy *senderModuleProxy, uint32 & charId, NLMISC::CEntityId & clientEid, std::string & userPriv, std::string &extendedPriv) { bool ok = getCharInfo(senderModuleProxy, charId, clientEid, userPriv, extendedPriv); if (!ok ) { nlwarning("Warning: Security issues: a client '%s' without security data try to connect... ", senderModuleProxy->getModuleName().c_str() ); return false; } IServerEditionModule* edition = CDynamicMapService::getInstance()->getEditionModule(); if (!edition) { return false; } ok = edition->isClientAuthorized(charId); if (!ok) { nlwarning( "Warning: A client '%s' '%s' %u '%s' try to send messages, without begin allowed (he was disconnected)", senderModuleProxy->getModuleName().c_str(), clientEid.toString().c_str(), charId, userPriv.c_str()); edition->disconnectChar(charId); edition->returnToPreviousSession(charId); return false; } return true; }
const Common::Rect FontResource::calculateRectForText(uint16 *text, uint textLength) { int16 width = 0; for (uint i = 0; i < textLength && *text; i++) { width += getCharInfo(*text)->_width; text++; } return Common::Rect(width, getCharHeight() + getLineIncr()); }
bool OleMainStream::readCharInfoTable(const char *headerBuffer, const OleEntry &tableEntry) { //PlcfbteChpx structure is table with formatting for particular run of text unsigned int beginCharInfo = OleUtil::getU4Bytes(headerBuffer, 0xfa); // address of PlcfbteChpx structure std::size_t charInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0xfe); // length of PlcfbteChpx structure if (charInfoLength < 4) { return false; } OleStream tableStream(myStorage, tableEntry, myBaseStream); std::string buffer; if (!readToBuffer(buffer, beginCharInfo, charInfoLength, tableStream)) { return false; } static const unsigned int CHPX_SIZE = 4; std::size_t size = calcCountOfPLC(charInfoLength, CHPX_SIZE); std::vector<unsigned int> charBlocks; for (std::size_t index = 0, offset = (size + 1) * 4; index < size; ++index, offset += CHPX_SIZE) { charBlocks.push_back(OleUtil::getU4Bytes(buffer.c_str(), offset)); } char *formatPageBuffer = new char[OleStorage::BBD_BLOCK_SIZE]; for (std::size_t index = 0; index < charBlocks.size(); ++index) { seek(charBlocks.at(index) * OleStorage::BBD_BLOCK_SIZE, true); if (read(formatPageBuffer, OleStorage::BBD_BLOCK_SIZE) != OleStorage::BBD_BLOCK_SIZE) { return false; } unsigned int crun = OleUtil::getU1Byte(formatPageBuffer, 0x1ff); //offset with crun (count of 'run of text') for (unsigned int index2 = 0; index2 < crun; ++index2) { unsigned int offset = OleUtil::getU4Bytes(formatPageBuffer, index2 * 4); unsigned int chpxOffset = 2 * OleUtil::getU1Byte(formatPageBuffer, (crun + 1) * 4 + index2); unsigned int len = OleUtil::getU1Byte(formatPageBuffer, chpxOffset); unsigned int charPos = 0; if (!offsetToCharPos(offset, charPos, myPieces)) { continue; } unsigned int styleId = getStyleIdByCharPos(charPos, myStyleInfoList); CharInfo charInfo = getStyleFromStylesheet(styleId, myStyleSheet).CurrentCharInfo; if (chpxOffset != 0) { getCharInfo(chpxOffset, styleId, formatPageBuffer + 1, len - 1, charInfo); } myCharInfoList.push_back(CharPosToCharInfo(charPos, charInfo)); if (chpxOffset != 0) { InlineImageInfo pictureInfo; if (getInlineImageInfo(chpxOffset, formatPageBuffer + 1, len - 1, pictureInfo)) { myInlineImageInfoList.push_back(CharPosToInlineImageInfo(charPos, pictureInfo)); } } } } delete[] formatPageBuffer; return true; }
Int32 GFXFont::getWordWidth(const void *in_string) { Int32 totalWidth = 0; UInt32 index; GFXCharInfo *cInfo; RectI rect; const void *cptr = in_string; // ignore space characters at start of string if (fi.flags & FONT_UNICODE) { index = (UInt32)(*(WORD *)cptr); while (index && iswspace(index)) cptr = (const char *) (((const WORD *)cptr) + 1); } else { index = (UInt32)(*(BYTE *)cptr); while (index && isspace(index)) cptr = ((const char *)cptr) + 1; } while (index) { if (fi.flags & FONT_FIXED) totalWidth += fi.fontWidth + fi.spacing; else { getCharInfo(index, NULL, &rect, &cInfo); totalWidth += cInfo->width + fi.spacing; } // See note above about MS and Wat compiler problems... if ( fi.flags&FONT_UNICODE ) { cptr = (const char *) (((const WORD *)cptr) + 1); index = (UInt32)(*(WORD *)cptr); if (iswspace(index)) break; } else { cptr = ((const char *)cptr) + 1; index = (UInt32)(*(BYTE *)cptr); if (isspace(index)) break; } } return(((totalWidth - fi.spacing)*fi.scale.x) >> 16 ); }
Int32 GFXFont::getStrWidth(const void *in_string) { AssertFatal(in_string,"GFXFont::getStrWidth: null string"); Int32 totalWidth = 0; UInt32 index; GFXCharInfo *cInfo; RectI rect; const void *cptr = in_string; if (fi.flags & FONT_UNICODE) index = (UInt32)(*(WORD *)cptr); else index = (UInt32)(*(BYTE *)cptr); while (index) { if (fi.flags & FONT_FIXED) totalWidth += fi.fontWidth + fi.spacing; else { getCharInfo(index, NULL, &rect, &cInfo); totalWidth += cInfo->width + fi.spacing; } // See note above about MS and Wat compiler problems... if ( fi.flags&FONT_UNICODE ) { cptr = (const char *) (((const WORD *)cptr) + 1); index = (UInt32)(*(WORD *)cptr); } else { cptr = ((const char *)cptr) + 1; index = (UInt32)(*(BYTE *)cptr); } } return(((totalWidth - fi.spacing)*fi.scale.x) >> 16 ); }
Int32 GFXFont::getStrHeight( const void *in_string) { Int32 maxHeight = 0; Int32 height; UInt32 index; GFXCharInfo *cInfo; RectI rect; const void *cptr = in_string; if (fi.flags & FONT_UNICODE) index = (UInt32)(*(WORD *)cptr); else index = (UInt32)(*(BYTE *)cptr); while (index) { getCharInfo(index, NULL, &rect, &cInfo); height = cInfo->height; if (maxHeight < height) maxHeight = height; if (fi.flags & FONT_UNICODE) { cptr = (const char *) (((const WORD *)cptr) + 1); index = (UInt32)(*(WORD *)cptr); } else { cptr = ((const char *)cptr) + 1; index = (UInt32)(*(BYTE *)cptr); } } return((maxHeight * fi.scale.y) >> 16 ); }
PlatformFont::CharInfo &x86UNIXFont::getCharInfo(const UTF8 *str) const { return getCharInfo(oneUTF32toUTF16(oneUTF8toUTF32(str,NULL))); }
bool OleMainStream::readStylesheet(const char *headerBuffer, const OleEntry &tableEntry) { //STSH structure is a stylesheet unsigned int beginStshInfo = OleUtil::getU4Bytes(headerBuffer, 0xa2); // address of STSH structure std::size_t stshInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0xa6); // length of STSH structure OleStream tableStream(myStorage, tableEntry, myBaseStream); char *buffer = new char[stshInfoLength]; if (!tableStream.seek(beginStshInfo, true)) { ZLLogger::Instance().println("DocPlugin", "problems with reading STSH structure"); return false; } if (tableStream.read(buffer, stshInfoLength) != stshInfoLength) { ZLLogger::Instance().println("DocPlugin", "problems with reading STSH structure, invalid length"); return false; } std::size_t stdCount = (std::size_t)OleUtil::getU2Bytes(buffer, 2); std::size_t stdBaseInFile = (std::size_t)OleUtil::getU2Bytes(buffer, 4); myStyleSheet.resize(stdCount); std::vector<bool> isFilled; isFilled.resize(stdCount, false); std::size_t stdLen = 0; bool styleSheetWasChanged = false; do { //make it in while loop, because some base style can be after their successors styleSheetWasChanged = false; for (std::size_t index = 0, offset = 2 + (std::size_t)OleUtil::getU2Bytes(buffer, 0); index < stdCount; index++, offset += 2 + stdLen) { stdLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset); if (isFilled.at(index)) { continue; } if (stdLen == 0) { //if record is empty, left it default isFilled[index] = true; continue; } Style styleInfo = myStyleSheet.at(index); const unsigned int styleAndBaseType = OleUtil::getU2Bytes(buffer, offset + 4); const unsigned int styleType = styleAndBaseType % 16; const unsigned int baseStyleId = styleAndBaseType / 16; if (baseStyleId == Style::STYLE_NIL || baseStyleId == Style::STYLE_USER) { //if based on nil or user style, left default } else { int baseStyleIndex = getStyleIndex(baseStyleId, isFilled, myStyleSheet); if (baseStyleIndex < 0) { //this base style is not filled yet, so pass it at some time continue; } styleInfo = myStyleSheet.at(baseStyleIndex); styleInfo.StyleIdCurrent = Style::STYLE_INVALID; } // parse STD structure unsigned int tmp = OleUtil::getU2Bytes(buffer, offset + 6); unsigned int upxCount = tmp % 16; styleInfo.StyleIdNext = tmp / 16; //adding current style myStyleSheet[index] = styleInfo; isFilled[index] = true; styleSheetWasChanged = true; std::size_t pos = 2 + stdBaseInFile; std::size_t nameLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos); nameLen = nameLen * 2 + 2; //from Unicode characters to bytes + Unicode null charachter length pos += 2 + nameLen; if (pos % 2 != 0) { ++pos; } if (pos >= stdLen) { continue; } std::size_t upxLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos); if (pos + upxLen > stdLen) { //UPX length too large continue; } //for style info styleType must be equal 1 if (styleType == 1 && upxCount >= 1) { if (upxLen >= 2) { styleInfo.StyleIdCurrent = OleUtil::getU2Bytes(buffer, offset + pos + 2); getStyleInfo(0, buffer + offset + pos + 4, upxLen - 2, styleInfo); myStyleSheet[index] = styleInfo; } pos += 2 + upxLen; if (pos % 2 != 0) { ++pos; } upxLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos); } if (upxLen == 0 || pos + upxLen > stdLen) { //too small/too large continue; } //for char info styleType can be equal 1 or 2 if ((styleType == 1 && upxCount >= 2) || (styleType == 2 && upxCount >= 1)) { CharInfo charInfo; getCharInfo(0, Style::STYLE_INVALID, buffer + offset + pos + 2, upxLen, charInfo); styleInfo.CurrentCharInfo = charInfo; myStyleSheet[index] = styleInfo; } } } while (styleSheetWasChanged); delete[] buffer; return true; }
PlatformFont::CharInfo& EmscriptenFont::getCharInfo(const UTF8 *str) const { return getCharInfo( oneUTF32toUTF16(oneUTF8toUTF32(str,NULL)) ); }