/* ======================== idSWFBitStream::ReadMatrix ======================== */ void idSWFBitStream::ReadMatrix( swfMatrix_t& matrix ) { uint64 regCurrentBit = 0; uint64 regCurrentByte = 0; unsigned int hasScale = ReadInternalU( regCurrentBit, regCurrentByte, 1 ); int xx; int yy; if( !hasScale ) { xx = 65536; yy = 65536; } else { int nBits = ReadInternalU( regCurrentBit, regCurrentByte, 5 ); xx = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); yy = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); } unsigned int hasRotate = ReadInternalU( regCurrentBit, regCurrentByte, 1 ); int yx; int xy; if( !hasRotate ) { yx = 0; xy = 0; } else { int nBits = ReadInternalU( regCurrentBit, regCurrentByte, 5 ); yx = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); xy = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); } int nBits = ReadInternalU( regCurrentBit, regCurrentByte, 5 ); int tx = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); int ty = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); currentBit = regCurrentBit; currentByte = regCurrentByte; matrix.xx = SWFFIXED16( xx ); matrix.yy = SWFFIXED16( yy ); matrix.yx = SWFFIXED16( yx ); matrix.xy = SWFFIXED16( xy ); matrix.tx = SWFTWIP( tx ); matrix.ty = SWFTWIP( ty ); }
/* ======================== idSWFBitStream::ReadRect ======================== */ void idSWFBitStream::ReadRect( swfRect_t& rect ) { uint64 regCurrentBit = 0; uint64 regCurrentByte = 0; int nBits = ReadInternalU( regCurrentBit, regCurrentByte, 5 ); int tl_x = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); int br_x = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); int tl_y = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); int br_y = ReadInternalS( regCurrentBit, regCurrentByte, nBits ); rect.tl.x = SWFTWIP( tl_x ); rect.br.x = SWFTWIP( br_x ); rect.tl.y = SWFTWIP( tl_y ); rect.br.y = SWFTWIP( br_y ); currentBit = regCurrentBit; currentByte = regCurrentByte; }
/* ======================== idSWFTextInstance::GetTextLength ======================== */ float idSWFTextInstance::GetTextLength() { // CURRENTLY ONLY WORKS FOR SINGLE LINE TEXTFIELDS if ( lengthCalculated && variable.IsEmpty() ) { return textLength; } idStr txtLengthCheck = ""; float len = 0.0f; if ( verify( swf != NULL ) ) { if ( !variable.IsEmpty() ) { idSWFScriptVar var = swf->GetGlobal( variable ); if ( var.IsUndefined() ) { txtLengthCheck = text; } else { txtLengthCheck = var.ToString(); } txtLengthCheck = idLocalization::GetString( txtLengthCheck ); } else { txtLengthCheck = idLocalization::GetString( text ); } const idSWFEditText * shape = editText; idSWFDictionaryEntry * fontEntry = swf->FindDictionaryEntry( shape->fontID, SWF_DICT_FONT ); idSWFFont * swfFont = fontEntry->font; float width = fabs( shape->bounds.br.x - shape->bounds.tl.x ); float postTrans = SWFTWIP( shape->fontHeight ); const idFont * fontInfo = swfFont->fontID; float glyphScale = postTrans / 48.0f; int tlen = txtLengthCheck.Length(); int index = 0; while ( index < tlen ) { scaledGlyphInfo_t glyph; fontInfo->GetScaledGlyph( glyphScale, txtLengthCheck.UTF8Char( index ), glyph ); len += glyph.xSkip; if ( useStroke ) { len += ( swf_textStrokeSizeGlyphSpacer.GetFloat() * strokeWeight * glyphScale ); } if ( !( shape->flags & SWF_ET_AUTOSIZE ) && len >= width ) { len = width; break; } } } lengthCalculated = true; textLength = len; return textLength; }
int idSWFTextInstance::CalcNumLines() { const idSWFEditText * shape = editText; if ( !( shape->flags & SWF_ET_MULTILINE ) ) { return 1; } idSWFDictionaryEntry * fontEntry = swf->FindDictionaryEntry( shape->fontID, SWF_DICT_FONT ); if ( fontEntry == NULL ) { return 1; } idStr textCheck; if ( variable.IsEmpty() ) { textCheck = idLocalization::GetString( text ); } else { textCheck = idLocalization::GetString( variable ); } if ( textCheck.IsEmpty() ) { return 1; } if ( swf == NULL ) { return 1; } idSWFFont * swfFont = fontEntry->font; float postTransformHeight = SWFTWIP( shape->fontHeight ); const idFont * fontInfo = swfFont->fontID; float glyphScale = postTransformHeight / 48.0f; swfRect_t bounds; bounds.tl.x = ( shape->bounds.tl.x + SWFTWIP( shape->leftMargin ) ); bounds.br.x = ( shape->bounds.br.x - SWFTWIP( shape->rightMargin ) ); bounds.tl.y = ( shape->bounds.tl.y + ( 1.15f * glyphScale ) ); bounds.br.y = ( shape->bounds.br.y ); float linespacing = fontInfo->GetAscender( 1.15f * glyphScale ); if ( shape->leading != 0 ) { linespacing += ( glyphScale * SWFTWIP( shape->leading ) ); } float x = bounds.tl.x; int maxLines = idMath::Ftoi( ( bounds.br.y - bounds.tl.y ) / linespacing ); if ( maxLines == 0 ) { maxLines = 1; } // tracks the last breakable character we found int numLines = 1; int lastbreak = 0; int charIndex = 0; while ( charIndex < textCheck.Length() ) { if ( textCheck[ charIndex ] == '\n' ) { if ( numLines == maxLines ) { return maxLines; } numLines++; lastbreak = 0; x = bounds.tl.x; charIndex++; } else { uint32 tc = textCheck[ charIndex++ ]; scaledGlyphInfo_t glyph; fontInfo->GetScaledGlyph( glyphScale, tc, glyph ); float glyphSkip = glyph.xSkip; if ( useStroke ) { glyphSkip += ( swf_textStrokeSizeGlyphSpacer.GetFloat() * strokeWeight * glyphScale ); } if ( x + glyphSkip > bounds.br.x ) { if ( numLines == maxLines ) { return maxLines; } else { numLines++; if ( lastbreak != 0 ) { charIndex = charIndex - ( charIndex - lastbreak ); } x = bounds.tl.x; lastbreak = 0; } } else { x += glyphSkip; if ( tc == ' ' || tc == '-' ) { lastbreak = charIndex; } } } } return numLines; }