X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Flogical-model-impl.cpp;h=8af3e91d610e6a8e52022da88807b234f761c8cf;hb=b899c4999231a14190e804e13b941527c3c437a1;hp=80d6595442b4274a2cb63adab8db30bfc0c91fcf;hpb=56d412791a44c2a79135d2293c13fddb135c9d54;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index 80d6595..8af3e91 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -18,8 +18,9 @@ // CLASS HEADER #include -// EXTERNAL INCLUDES -#include +// INTERNAL INCLUDES +#include +#include namespace Dali { @@ -30,115 +31,22 @@ namespace Toolkit namespace Text { -LogicalModelPtr LogicalModel::New() -{ - return LogicalModelPtr( new LogicalModel() ); -} - -void LogicalModel::SetText( const Character* const text, - Length numberOfCharacters ) -{ - if( 0u == numberOfCharacters ) - { - mText.Clear(); - } - else - { - mText.Resize( numberOfCharacters ); - memcpy( mText.Begin(), text, numberOfCharacters * sizeof( Character ) ); - } -} - -Length LogicalModel::GetNumberOfCharacters() const -{ - return mText.Count(); -} - -void LogicalModel::GetText( Character* text, - CharacterIndex characterIndex, - Length numberOfCharacters ) const -{ - memcpy( text, mText.Begin() + characterIndex, numberOfCharacters * sizeof( Character ) ); -} - -Character LogicalModel::GetCharacter( CharacterIndex characterIndex ) const -{ - return mText[characterIndex]; -} - -void LogicalModel::ReplaceText( CharacterIndex characterIndex, - Length numberOfCharactersToRemove, - const Character* const text, - Length numberOfCharactersToInsert ) +void FreeFontFamilyNames( Vector& fontDescriptionRuns ) { -} - -void LogicalModel::SetScripts( const ScriptRun* const scripts, - Length numberOfRuns ) -{ - if( 0u == numberOfRuns ) - { - mScriptRuns.Clear(); - } - else - { - mScriptRuns.Resize( numberOfRuns ); - memcpy( mScriptRuns.Begin(), scripts, numberOfRuns * sizeof( ScriptRun ) ); - } -} - -void LogicalModel::GetNumberOfScriptRuns( CharacterIndex characterIndex, - Length numberOfCharacters, - ScriptRunIndex& firstScriptRun, - Length& numberOfScriptRuns ) const -{ - // Initialize the number of scripts and the index to the first script. - firstScriptRun = 0u; - numberOfScriptRuns = 0; - bool firstScriptFound = false; - - const CharacterIndex lastCharacterIndex = characterIndex + numberOfCharacters; - - // Traverse the scripts and count those scripts within the range of characters. - for( Vector::ConstIterator it = mScriptRuns.Begin(), - endIt = mScriptRuns.End(); + for( Vector::Iterator it = fontDescriptionRuns.Begin(), + endIt = fontDescriptionRuns.End(); it != endIt; ++it ) { - const ScriptRun& script = *it; - - if( ( script.characterRun.characterIndex + script.characterRun.numberOfCharacters > characterIndex ) && - ( lastCharacterIndex > script.characterRun.characterIndex ) ) - { - firstScriptFound = true; - ++numberOfScriptRuns; - } - else if( lastCharacterIndex <= script.characterRun.characterIndex ) - { - // nothing else to do. - break; - } - - if( !firstScriptFound ) - { - ++firstScriptRun; - } + delete (*it).familyName; } + + fontDescriptionRuns.Clear(); } -void LogicalModel::GetScriptRuns( ScriptRun* scriptRuns, - CharacterIndex characterIndex, - Length numberOfCharacters ) const +LogicalModelPtr LogicalModel::New() { - ScriptRunIndex firstScriptRun = 0u; - Length numberOfScriptRuns = 0u; - - GetNumberOfScriptRuns( characterIndex, - numberOfCharacters, - firstScriptRun, - numberOfScriptRuns ); - - memcpy( scriptRuns, mScriptRuns.Begin() + firstScriptRun, numberOfScriptRuns * sizeof( ScriptRun ) ); + return LogicalModelPtr( new LogicalModel() ); } Script LogicalModel::GetScript( CharacterIndex characterIndex ) const @@ -159,377 +67,362 @@ Script LogicalModel::GetScript( CharacterIndex characterIndex ) const return TextAbstraction::UNKNOWN; } -void LogicalModel::ReplaceScripts( CharacterIndex characterIndex, - Length numberOfCharactersToRemove, - const ScriptRun* const scriptRuns, - Length numberOfCharactersToInsert ) -{ -} - -void LogicalModel::SetFonts( const FontRun* const fonts, - Length numberOfRuns ) +CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const { - if( 0u == numberOfRuns ) - { - mFontRuns.Clear(); - } - else + if( characterIndex >= mCharacterDirections.Count() ) { - mFontRuns.Resize( numberOfRuns ); - memcpy( mFontRuns.Begin(), fonts, numberOfRuns * sizeof( FontRun ) ); + // The model has no right to left characters, so the vector of directions is void. + return false; } + + return *( mCharacterDirections.Begin() + characterIndex ); } -void LogicalModel::GetNumberOfFontRuns( CharacterIndex characterIndex, - Length numberOfCharacters, - FontRunIndex& firstFontRun, - Length& numberOfFontRuns ) const +void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo, + Length numberOfRuns, + CharacterIndex startIndex, + Length numberOfCharacters ) { - // Initialize the number of fonts and the index to the first font. - firstFontRun = 0u; - numberOfFontRuns = 0; - bool firstFontFound = false; + mVisualToLogicalMap.Resize( numberOfCharacters ); + mLogicalToVisualMap.Resize( numberOfCharacters ); - const CharacterIndex lastCharacterIndex = characterIndex + numberOfCharacters; + const Length numberOfCharactersPlus = numberOfCharacters + 1u; + mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus ); - // Traverse the fonts and count those fonts within the range of characters. - for( Vector::ConstIterator it = mFontRuns.Begin(), - endIt = mFontRuns.End(); - it != endIt; - ++it ) + CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin(); + CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin(); + + CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin(); + + CharacterIndex lastIndex = startIndex; + for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex ) { - const FontRun& font = *it; + const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex ); - if( ( font.characterRun.characterIndex + font.characterRun.numberOfCharacters > characterIndex ) && - ( characterIndex + numberOfCharacters > font.characterRun.characterIndex ) ) + if( bidiLineInfo.characterRun.characterIndex + bidiLineInfo.characterRun.numberOfCharacters <= startIndex ) { - firstFontFound = true; - ++numberOfFontRuns; - } - else if( lastCharacterIndex <= font.characterRun.characterIndex ) - { - // nothing else to do. - break; + // Skip this paragraph. It has been already processed. + continue; } - if( !firstFontFound ) + if( lastIndex < bidiLineInfo.characterRun.characterIndex ) { - ++firstFontRun; + // Fill with the identity. + for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex ) + { + *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; + } } - } -} - -void LogicalModel::GetFontRuns( FontRun* fontRuns, - CharacterIndex characterIndex, - Length numberOfCharacters ) const -{ - FontRunIndex firstFontRun = 0u; - Length numberOfFontRuns = 0u; - - GetNumberOfFontRuns( characterIndex, - numberOfCharacters, - firstFontRun, - numberOfFontRuns ); - - memcpy( fontRuns, mFontRuns.Begin() + firstFontRun, numberOfFontRuns * sizeof( FontRun ) ); -} - -FontId LogicalModel::GetFont( CharacterIndex characterIndex ) const -{ - for( Length index = 0u, length = mFontRuns.Count(); index < length; ++index ) - { - const FontRun* const fontRun = mFontRuns.Begin() + index; - if( ( fontRun->characterRun.characterIndex <= characterIndex ) && - ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) ) + // Fill the conversion table of the run. + for( CharacterIndex index = 0u; + index < bidiLineInfo.characterRun.numberOfCharacters; + ++index, ++lastIndex ) { - return fontRun->fontId; + *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index ); } } - return 0u; -} - -void LogicalModel::ReplaceFonts( CharacterIndex characterIndex, - Length numberOfCharactersToRemove, - const FontRun* const fontRuns, - Length numberOfCharactersToInsert ) -{ -} - -void LogicalModel::SetLineBreakInfo( const LineBreakInfo* const lineBreakInfo, - Length length ) -{ - if( 0u == length ) + // Complete with the identity if there are some left to right characters after the last right to left. + for( ; lastIndex < numberOfCharacters; ++lastIndex ) { - mLineBreakInfo.Clear(); + *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; } - else - { - mLineBreakInfo.Resize( length ); - memcpy( mLineBreakInfo.Begin(), lineBreakInfo, length * sizeof( LineBreakInfo ) ); - } -} - -void LogicalModel::GetLineBreakInfo( LineBreakInfo* lineBreakInfo, - CharacterIndex characterIndex, - Length numberOfItems ) const -{ - memcpy( lineBreakInfo, mLineBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( LineBreakInfo ) ); -} - -LineBreakInfo LogicalModel::GetLineBreakInfo( CharacterIndex characterIndex ) const -{ - return *( mLineBreakInfo.Begin() + characterIndex ); -} - -void LogicalModel::ReplaceLineBreakInfo( CharacterIndex characterIndex, - Length numberOfItemsToRemove, - const LineBreakInfo* const lineBreakInfo, - Length numberOfItemsToInsert ) -{ -} -void LogicalModel::SetWordBreakInfo( const WordBreakInfo* const wordBreakInfo, - Length length ) -{ - if( 0u == length ) - { - mWordBreakInfo.Clear(); - } - else + // Sets the logical to visual conversion map. + for( CharacterIndex index = startIndex; index < numberOfCharacters; ++index ) { - mWordBreakInfo.Resize( length ); - memcpy( mWordBreakInfo.Begin(), wordBreakInfo, length * sizeof( WordBreakInfo ) ); + *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index; } -} -void LogicalModel::GetWordBreakInfo( WordBreakInfo* wordBreakInfo, - CharacterIndex characterIndex, - Length numberOfItems ) const -{ - memcpy( wordBreakInfo, mWordBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( WordBreakInfo ) ); -} + // Sets the visual to logical conversion map for cursor positions. -WordBreakInfo LogicalModel::GetWordBreakInfo( CharacterIndex characterIndex ) const -{ - return *( mWordBreakInfo.Begin() + characterIndex ); -} + const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count(); + BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin(); + BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer; -void LogicalModel::ReplaceWordBreakInfo( CharacterIndex characterIndex, - Length numberOfItemsToRemove, - const WordBreakInfo* const wordBreakInfo, - Length numberOfItemsToInsert ) -{ -} + const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin(); -void LogicalModel::SetBidirectionalInfo( const BidirectionalParagraphInfoRun* const bidirectionalInfo, - Length numberOfRuns ) -{ - if( 0u == numberOfRuns ) - { - mBidirectionalParagraphInfo.Clear(); - } - else + Length bidirectionalParagraphIndex = 0u; + bool isRightToLeftParagraph = false; + for( CharacterIndex index = startIndex; index < numberOfCharactersPlus; ++index ) { - mBidirectionalParagraphInfo.Resize( numberOfRuns ); - memcpy( mBidirectionalParagraphInfo.Begin(), bidirectionalInfo, numberOfRuns * sizeof( BidirectionalParagraphInfoRun ) ); - } -} - -void LogicalModel::GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex, - Length numberOfCharacters, - BidirectionalRunIndex& firstBidirectionalRun, - Length& numberOfFontRuns ) const -{ - // Initialize the number of bidi paragraphs and the index to the first paragraph. - firstBidirectionalRun = 0u; - numberOfFontRuns = 0; - bool firstParagraphFound = false; - - // Traverse the bidirectional paragraph info and count those bidi paragraphs within the range of characters. - for( Vector::ConstIterator it = mBidirectionalParagraphInfo.Begin(), - endIt = mBidirectionalParagraphInfo.End(); - it != endIt; - ++it ) - { - const BidirectionalParagraphInfoRun& bidi = *it; - - if( ( bidi.characterRun.characterIndex + bidi.characterRun.numberOfCharacters > characterIndex ) && - ( characterIndex + numberOfCharacters > bidi.characterRun.characterIndex ) ) + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex == index ) ) { - firstParagraphFound = true; - ++numberOfFontRuns; + isRightToLeftParagraph = *( modelCharacterDirections + index ); } - if( !firstParagraphFound ) + if( 0u == index ) { - ++firstBidirectionalRun; + if( isRightToLeftParagraph ) + { + *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; + } + else // else logical position is zero. + { + *( modelVisualToLogicalCursorMap + index ) = 0u; + } } - } -} - -void LogicalModel::GetBidirectionalInfo( BidirectionalParagraphInfoRun* bidirectionalInfo, - CharacterIndex characterIndex, - Length numberOfCharacters ) const -{ - BidirectionalRunIndex firstBidirectionalRun = 0u; - Length numberOfFontRuns = 0u; + else if( numberOfCharacters == index ) + { + if( isRightToLeftParagraph ) + { + *( modelVisualToLogicalCursorMap + index ) = 0u; + } + else // else logical position is the number of characters. + { + *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; + } + } + else + { + // Get the character indexed by index - 1 and index + // and calculate the logical position according the directions of + // both characters and the direction of the paragraph. - GetNumberOfBidirectionalInfoRuns( characterIndex, - numberOfCharacters, - firstBidirectionalRun, - numberOfFontRuns ); + const CharacterIndex previousIndex = index - 1u; + const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex ); + const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index ); - memcpy( bidirectionalInfo, mBidirectionalParagraphInfo.Begin() + firstBidirectionalRun, numberOfFontRuns * sizeof( BidirectionalParagraphInfoRun ) ); -} + const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 ); + const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 ); -void ReplaceBidirectionalInfo( CharacterIndex characterIndex, - Length numberOfCharactersToRemove, - const BidirectionalParagraphInfoRun* const bidirectionalInfo, - Length numberOfCharactersToInsert ) -{ -} + if( direction0 == direction1 ) + { + // Both glyphs have the same direction. + if( direction0 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; + } + } + else + { + if( isRightToLeftParagraph ) + { + if( direction1 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; + } + } + else + { + if( direction0 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u; + } + } + } + } -void LogicalModel::SetCharacterDirections( const CharacterDirection* const directions, - Length numberOfCharacters ) -{ - if( 0u == numberOfCharacters ) - { - mCharacterDirections.Clear(); - } - else - { - mCharacterDirections.Resize( numberOfCharacters ); - memcpy( mCharacterDirections.Begin(), directions, numberOfCharacters * sizeof( CharacterDirection ) ); + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) ) + { + isRightToLeftParagraph = false; + ++bidirectionalParagraphIndex; + if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs ) + { + bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex; + } + else + { + bidirectionalParagraph = NULL; + } + } } } -void LogicalModel::GetCharacterDirections( CharacterDirection* directions, - CharacterIndex characterIndex, - Length numberOfCharacters ) const +CharacterIndex LogicalModel::GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const { - if( 0u == mCharacterDirections.Count() ) + if( 0u == mVisualToLogicalMap.Count() ) { - // Nothing to retrieve if the model has no right to left characters. - return; + // If there is no visual to logical info is because the whole text is left to right. + // Return the identity. + return visualCharacterIndex; } - memcpy( directions, mCharacterDirections.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterDirection ) ); + return *( mVisualToLogicalMap.Begin() + visualCharacterIndex ); } -CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const +void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharacters ) { - if( characterIndex >= mCharacterDirections.Count() ) - { - // The model has no right to left characters, so the vector of directions is void. - return false; - } + const Length totalNumberOfCharacters = mText.Count(); - return *( mCharacterDirections.Begin() + characterIndex ); + // Process the color runs. + Vector removedColorRuns; + UpdateCharacterRuns( index, + numberOfCharacters, + totalNumberOfCharacters, + mColorRuns, + removedColorRuns ); + + // Process the font description runs. + Vector removedFontDescriptionRuns; + UpdateCharacterRuns( index, + numberOfCharacters, + totalNumberOfCharacters, + mFontDescriptionRuns, + removedFontDescriptionRuns ); + + // Free memory allocated for the font family name. + FreeFontFamilyNames( removedFontDescriptionRuns ); } -void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo, - Length numberOfRuns ) +void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style ) { - if( 0u == numberOfRuns ) + unsigned int runIndex = 0u; + + // Set the text color. + bool colorOverriden = false; + unsigned int colorIndex = 0u; + const ColorRun* const colorRunsBuffer = mColorRuns.Begin(); + for( Vector::ConstIterator it = colorRunsBuffer, + endIt = mColorRuns.End(); + it != endIt; + ++it, ++runIndex ) { - mVisualToLogicalMap.Clear(); - mLogicalToVisualMap.Clear(); + const ColorRun& colorRun = *it; + + if( ( colorRun.characterRun.characterIndex <= index ) && + ( index < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) ) + { + colorIndex = runIndex; + colorOverriden = true; + } } - else + + // Set the text's color if it's overriden. + if( colorOverriden ) { - const Length numberOfCharacters = mText.Count(); - mVisualToLogicalMap.Resize( numberOfCharacters ); - mLogicalToVisualMap.Resize( numberOfCharacters ); + style.textColor = ( *( colorRunsBuffer + colorIndex ) ).color; + } - CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin(); - CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin(); + // Reset the run index. + runIndex = 0u; + + // Set the font's parameters. + bool nameOverriden = false; + bool weightOverriden = false; + bool widthOverriden = false; + bool slantOverriden = false; + bool sizeOverriden = false; + unsigned int nameIndex = 0u; + unsigned int weightIndex = 0u; + unsigned int widthIndex = 0u; + unsigned int slantIndex = 0u; + unsigned int sizeIndex = 0u; + const FontDescriptionRun* const fontDescriptionRunsBuffer = mFontDescriptionRuns.Begin(); + for( Vector::ConstIterator it = fontDescriptionRunsBuffer, + endIt = mFontDescriptionRuns.End(); + it != endIt; + ++it, ++runIndex ) + { + const FontDescriptionRun& fontDescriptionRun = *it; - CharacterIndex lastIndex = 0u; - for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex ) + if( ( fontDescriptionRun.characterRun.characterIndex <= index ) && + ( index < fontDescriptionRun.characterRun.characterIndex + fontDescriptionRun.characterRun.numberOfCharacters ) ) { - const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex ); + if( fontDescriptionRun.familyDefined ) + { + nameIndex = runIndex; + nameOverriden = true; + } - if( lastIndex < bidiLineInfo.characterRun.characterIndex ) + if( fontDescriptionRun.weightDefined ) { - // Fill with the identity. - for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex ) - { - *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; - } + weightIndex = runIndex; + weightOverriden = true; } - // Fill the conversion table of the run. - for( CharacterIndex index = 0u; - index < bidiLineInfo.characterRun.numberOfCharacters; - ++index, ++lastIndex ) + if( fontDescriptionRun.widthDefined ) { - *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index ); + widthIndex = runIndex; + widthOverriden = true; } - } - // Complete with the identity if there are some left to right characters after the last right to left. - for( ; lastIndex < numberOfCharacters; ++lastIndex ) - { - *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; - } + if( fontDescriptionRun.slantDefined ) + { + slantIndex = runIndex; + slantOverriden = true; + } - // Sets the logical to visual conversion map. - for( CharacterIndex index = 0u; index < numberOfCharacters; ++index ) - { - *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index; + if( fontDescriptionRun.sizeDefined ) + { + sizeIndex = runIndex; + sizeOverriden = true; + } } } -} -void LogicalModel::ReplaceVisualToLogicalMap( CharacterIndex characterIndex, - Length numberOfCharactersToRemove, - const BidirectionalLineInfoRun* const bidirectionalInfo, - Length numberOfCharactersToInsert ) -{ -} + // Set the font's family name if it's overriden. + if( nameOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + nameIndex ); -CharacterIndex LogicalModel::GetVisualCharacterIndex( CharacterIndex logicalCharacterIndex ) const -{ - if( 0u == mLogicalToVisualMap.Count() ) + style.familyName = std::string( fontDescriptionRun.familyName, fontDescriptionRun.familyLength ); + style.familyDefined = true; + } + + // Set the font's weight if it's overriden. + if( weightOverriden ) { - // If there is no logical to visual info is because the whole text is left to right. - // Return the identity. - return logicalCharacterIndex; + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + weightIndex ); + + style.weight = fontDescriptionRun.weight; + style.weightDefined = true; } - return *( mLogicalToVisualMap.Begin() + logicalCharacterIndex ); -} + // Set the font's width if it's overriden. + if( widthOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + widthIndex ); -CharacterIndex LogicalModel::GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const -{ - if( 0u == mVisualToLogicalMap.Count() ) + style.width = fontDescriptionRun.width; + style.widthDefined = true; + } + + // Set the font's slant if it's overriden. + if( slantOverriden ) { - // If there is no visual to logical info is because the whole text is left to right. - // Return the identity. - return visualCharacterIndex; + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + slantIndex ); + + style.slant = fontDescriptionRun.slant; + style.slantDefined = true; } - return *( mVisualToLogicalMap.Begin() + visualCharacterIndex ); -} + // Set the font's size if it's overriden. + if( sizeOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + sizeIndex ); -void LogicalModel::GetLogicalToVisualMap( CharacterIndex* logicalToVisualMap, - CharacterIndex characterIndex, - Length numberOfCharacters ) const -{ - memcpy( logicalToVisualMap, mLogicalToVisualMap.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterIndex ) ); + style.size = static_cast( fontDescriptionRun.size ) / 64.f; + style.sizeDefined = true; + } + + // Reset the run index. + runIndex = 0u; } -void LogicalModel::GetVisualToLogicalMap( CharacterIndex* visualToLogicalMap, - CharacterIndex characterIndex, - Length numberOfCharacters ) const +void LogicalModel::ClearFontDescriptionRuns() { - memcpy( visualToLogicalMap, mVisualToLogicalMap.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterIndex ) ); + FreeFontFamilyNames( mFontDescriptionRuns ); } LogicalModel::~LogicalModel() { + ClearFontDescriptionRuns(); } LogicalModel::LogicalModel()