+
+ // 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<FontDescriptionRun>::ConstIterator it = fontDescriptionRunsBuffer,
+ endIt = mFontDescriptionRuns.End();
+ it != endIt;
+ ++it, ++runIndex)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *it;
+
+ if((fontDescriptionRun.characterRun.characterIndex <= index) &&
+ (index < fontDescriptionRun.characterRun.characterIndex + fontDescriptionRun.characterRun.numberOfCharacters))
+ {
+ if(fontDescriptionRun.familyDefined)
+ {
+ nameIndex = runIndex;
+ nameOverriden = true;
+ }
+
+ if(fontDescriptionRun.weightDefined)
+ {
+ weightIndex = runIndex;
+ weightOverriden = true;
+ }
+
+ if(fontDescriptionRun.widthDefined)
+ {
+ widthIndex = runIndex;
+ widthOverriden = true;
+ }
+
+ if(fontDescriptionRun.slantDefined)
+ {
+ slantIndex = runIndex;
+ slantOverriden = true;
+ }
+
+ if(fontDescriptionRun.sizeDefined)
+ {
+ sizeIndex = runIndex;
+ sizeOverriden = true;
+ }
+ }
+ }
+
+ // Set the font's family name if it's overriden.
+ if(nameOverriden)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *(fontDescriptionRunsBuffer + nameIndex);
+
+ style.familyName = std::string(fontDescriptionRun.familyName, fontDescriptionRun.familyLength);
+ style.isFamilyDefined = true;
+ }
+
+ // Set the font's weight if it's overriden.
+ if(weightOverriden)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *(fontDescriptionRunsBuffer + weightIndex);
+
+ style.weight = fontDescriptionRun.weight;
+ style.isWeightDefined = true;
+ }
+
+ // Set the font's width if it's overriden.
+ if(widthOverriden)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *(fontDescriptionRunsBuffer + widthIndex);
+
+ style.width = fontDescriptionRun.width;
+ style.isWidthDefined = true;
+ }
+
+ // Set the font's slant if it's overriden.
+ if(slantOverriden)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *(fontDescriptionRunsBuffer + slantIndex);
+
+ style.slant = fontDescriptionRun.slant;
+ style.isSlantDefined = true;
+ }
+
+ // Set the font's size if it's overriden.
+ if(sizeOverriden)
+ {
+ const FontDescriptionRun& fontDescriptionRun = *(fontDescriptionRunsBuffer + sizeIndex);
+
+ style.size = static_cast<float>(fontDescriptionRun.size) / 64.f;
+ style.isSizeDefined = true;
+ }
+}
+
+void LogicalModel::ClearFontDescriptionRuns()
+{
+ FreeFontFamilyNames(mFontDescriptionRuns);
+}
+
+void LogicalModel::ClearStrikethroughRuns()
+{
+ mStrikethroughCharacterRuns.Clear();
+}
+
+void LogicalModel::CreateParagraphInfo(CharacterIndex startIndex,
+ Length numberOfCharacters)
+{
+ const Length totalNumberOfCharacters = mLineBreakInfo.Count();
+
+ // Count the number of LINE_MUST_BREAK to reserve some space for the vector of paragraph's info.
+ Vector<CharacterIndex> paragraphs;
+ paragraphs.Reserve(numberOfCharacters);
+ const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = mLineBreakInfo.Begin();
+ const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters;
+ for(Length index = startIndex; index < lastCharacterIndexPlusOne; ++index)
+ {
+ if(TextAbstraction::LINE_MUST_BREAK == *(lineBreakInfoBuffer + index))
+ {
+ paragraphs.PushBack(index);
+ }
+ }
+
+ // Whether the current paragraphs are updated or set from scratch.
+ const bool updateCurrentParagraphs = numberOfCharacters < totalNumberOfCharacters;
+
+ // Reserve space for current paragraphs plus new ones.
+ const Length numberOfNewParagraphs = paragraphs.Count();
+ const Length totalNumberOfParagraphs = mParagraphInfo.Count() + numberOfNewParagraphs;
+ mParagraphInfo.Resize(totalNumberOfParagraphs);
+
+ ParagraphRun* paragraphInfoBuffer = NULL;
+ Vector<ParagraphRun> newParagraphs;
+
+ if(updateCurrentParagraphs)
+ {
+ newParagraphs.Resize(numberOfNewParagraphs);
+ paragraphInfoBuffer = newParagraphs.Begin();
+ }
+ else
+ {
+ paragraphInfoBuffer = mParagraphInfo.Begin();
+ }
+
+ // Find where to insert the new paragraphs.
+ ParagraphRunIndex paragraphIndex = 0u;
+ CharacterIndex firstIndex = startIndex;
+
+ if(updateCurrentParagraphs)
+ {
+ for(Vector<ParagraphRun>::ConstIterator it = mParagraphInfo.Begin(),
+ endIt = mParagraphInfo.Begin() + totalNumberOfParagraphs - numberOfNewParagraphs;
+ it != endIt;
+ ++it)
+ {
+ const ParagraphRun& paragraph(*it);
+
+ if(startIndex < paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters)
+ {
+ firstIndex = paragraph.characterRun.characterIndex;
+ break;
+ }
+
+ ++paragraphIndex;
+ }
+ }
+
+ // Create the paragraph info.
+ ParagraphRunIndex newParagraphIndex = 0u;
+ for(Vector<CharacterIndex>::ConstIterator it = paragraphs.Begin(),
+ endIt = paragraphs.End();
+ it != endIt;
+ ++it, ++newParagraphIndex)
+ {
+ const CharacterIndex index = *it;
+
+ ParagraphRun& paragraph = *(paragraphInfoBuffer + newParagraphIndex);
+ paragraph.characterRun.characterIndex = firstIndex;
+ paragraph.characterRun.numberOfCharacters = 1u + index - firstIndex;
+
+ firstIndex += paragraph.characterRun.numberOfCharacters;
+ }
+
+ // Insert the new paragraphs.
+ if(updateCurrentParagraphs)
+ {
+ mParagraphInfo.Insert(mParagraphInfo.Begin() + paragraphIndex,
+ newParagraphs.Begin(),
+ newParagraphs.End());
+
+ mParagraphInfo.Resize(totalNumberOfParagraphs);
+
+ // Update the next paragraph indices.
+ for(Vector<ParagraphRun>::Iterator it = mParagraphInfo.Begin() + paragraphIndex + newParagraphs.Count(),
+ endIt = mParagraphInfo.End();
+ it != endIt;
+ ++it)
+ {
+ ParagraphRun& paragraph(*it);
+
+ paragraph.characterRun.characterIndex += numberOfCharacters;
+ }
+ }
+}
+
+void LogicalModel::FindParagraphs(CharacterIndex index,
+ Length numberOfCharacters,
+ Vector<ParagraphRunIndex>& paragraphs)
+{
+ // Reserve som space for the paragraph indices.
+ paragraphs.Reserve(mParagraphInfo.Count());
+
+ // Traverse the paragraphs to find which ones contain the given characters.
+ ParagraphRunIndex paragraphIndex = 0u;
+ for(Vector<ParagraphRun>::ConstIterator it = mParagraphInfo.Begin(),
+ endIt = mParagraphInfo.End();
+ it != endIt;
+ ++it, ++paragraphIndex)
+ {
+ const ParagraphRun& paragraph(*it);
+
+ if((paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters > index) &&
+ (paragraph.characterRun.characterIndex < index + numberOfCharacters))
+ {
+ paragraphs.PushBack(paragraphIndex);
+ }
+ }
+}
+
+Length LogicalModel::GetNumberOfBoundedParagraphRuns() const
+{
+ return mBoundedParagraphRuns.Count();
+}
+
+const Vector<BoundedParagraphRun>& LogicalModel::GetBoundedParagraphRuns() const
+{
+ return mBoundedParagraphRuns;
+}
+
+void LogicalModel::ClearEmbeddedImages()
+{
+ FreeEmbeddedItems(mEmbeddedItems);
+}
+
+void LogicalModel::ClearAnchors()
+{
+ FreeAnchors(mAnchors);