2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/text/text-view.h>
22 #include <dali/devel-api/text-abstraction/font-client.h>
23 #include <dali/public-api/math/vector2.h>
27 #include <dali-toolkit/internal/text/glyph-metrics-helper.h>
28 #include <dali-toolkit/internal/text/rendering/styles/character-spacing-helper-functions.h>
38 VisualModelPtr mVisualModel;
39 LogicalModelPtr mLogicalModel;
40 TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
46 mImpl = new View::Impl();
48 mImpl->mFontClient = TextAbstraction::FontClient::Get();
56 void View::SetVisualModel(VisualModelPtr visualModel)
58 mImpl->mVisualModel = visualModel;
61 void View::SetLogicalModel(LogicalModelPtr logicalModel)
63 mImpl->mLogicalModel = logicalModel;
66 const Vector2& View::GetControlSize() const
68 if(mImpl->mVisualModel)
70 return mImpl->mVisualModel->mControlSize;
76 const Vector2& View::GetLayoutSize() const
78 if(mImpl->mVisualModel)
80 return mImpl->mVisualModel->GetLayoutSize();
86 Length View::GetNumberOfGlyphs() const
88 if(mImpl->mVisualModel)
90 const VisualModel& model = *mImpl->mVisualModel;
92 const Length glyphCount = model.mGlyphs.Count();
93 const Length positionCount = model.mGlyphPositions.Count();
95 DALI_ASSERT_DEBUG(positionCount <= glyphCount && "Invalid glyph positions in Model");
97 return (positionCount < glyphCount) ? positionCount : glyphCount;
103 Length View::GetGlyphs(GlyphInfo* glyphs,
104 Vector2* glyphPositions,
105 float& minLineOffset,
106 GlyphIndex glyphIndex,
107 Length numberOfGlyphs) const
109 Length numberOfLaidOutGlyphs = 0u;
110 Length numberOfActualLaidOutGlyphs = 0u;
111 const float modelCharacterSpacing = mImpl->mVisualModel->GetCharacterSpacing();
112 Vector<CharacterIndex>& glyphToCharacterMap = mImpl->mVisualModel->mGlyphsToCharacters;
113 const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
114 float calculatedAdvance = 0.f;
115 const Character* textBuffer = mImpl->mLogicalModel->mText.Begin();
117 if(mImpl->mVisualModel)
119 // Get the character-spacing runs.
120 const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = mImpl->mVisualModel->GetCharacterSpacingGlyphRuns();
122 bool textElided = false;
123 DevelText::EllipsisPosition::Type ellipsisPosition = GetEllipsisPosition();
125 //Reset indices of ElidedGlyphs
126 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(0u);
127 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(numberOfGlyphs - 1u); // Initialization is the last index of Glyphs
128 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u);
129 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u);
131 // If ellipsis is enabled, the number of glyphs the layout engine has laid out may be less than 'numberOfGlyphs'.
132 // Check the last laid out line to know if the layout engine elided some text.
134 const Length numberOfLines = mImpl->mVisualModel->mLines.Count();
135 if(numberOfLines > 0u)
137 const LineRun* const lines = mImpl->mVisualModel->mLines.Begin();
139 //Get line of ellipsis
140 const LineRun* ellipsisLine = nullptr;
141 const LineRun* ellipsisNextLine = nullptr;
142 bool hasEllipsis = false;
143 for(Length lineIndex = 0; lineIndex < numberOfLines; lineIndex++)
145 const LineRun* line = (lines + lineIndex);
150 if(lineIndex < numberOfLines - 1u)
152 ellipsisNextLine = (lines + lineIndex + 1u);
158 // If ellipsis is enabled, calculate the number of laid out glyphs.
159 // Otherwise use the given number of glyphs.
163 numberOfLaidOutGlyphs = numberOfGlyphs;
165 if(ellipsisPosition == DevelText::EllipsisPosition::START)
167 numberOfActualLaidOutGlyphs = numberOfGlyphs - ellipsisLine->glyphRun.glyphIndex;
169 else if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
171 numberOfActualLaidOutGlyphs = 0u;
172 for(Length lineIndex = 0u; lineIndex < numberOfLines; lineIndex++)
174 numberOfActualLaidOutGlyphs += lines[lineIndex].glyphRun.numberOfGlyphs + lines[lineIndex].glyphRunSecondHalf.numberOfGlyphs;
177 else // DevelText::EllipsisPosition::END
179 numberOfActualLaidOutGlyphs = ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs;
184 numberOfActualLaidOutGlyphs = numberOfLaidOutGlyphs = numberOfGlyphs;
187 if(0u < numberOfActualLaidOutGlyphs)
189 // Retrieve from the visual model the glyphs and positions.
190 mImpl->mVisualModel->GetGlyphs(glyphs,
192 numberOfLaidOutGlyphs);
194 mImpl->mVisualModel->GetGlyphPositions(glyphPositions,
196 numberOfLaidOutGlyphs);
198 // Get the lines for the given range of glyphs.
199 // The lines contain the alignment offset which needs to be added to the glyph's position.
200 LineIndex firstLineIndex = 0u;
201 Length numberOfLines = 0u;
202 mImpl->mVisualModel->GetNumberOfLines(glyphIndex,
203 numberOfLaidOutGlyphs,
207 Vector<LineRun> lines;
208 lines.Resize(numberOfLines);
209 LineRun* lineBuffer = lines.Begin();
211 mImpl->mVisualModel->GetLinesOfGlyphRange(lineBuffer,
213 numberOfLaidOutGlyphs);
215 // Get the first line for the given glyph range.
216 LineIndex lineIndex = firstLineIndex;
217 LineRun* line = lineBuffer + lineIndex;
219 // Index of the last glyph of the line.
220 GlyphIndex lastGlyphIndexOfLine = (line->isSplitToTwoHalves ? line->glyphRunSecondHalf.glyphIndex + line->glyphRunSecondHalf.numberOfGlyphs : line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs) - 1u;
222 // Add the alignment offset to the glyph's position.
224 minLineOffset = line->alignmentOffset;
225 float penY = line->ascender;
226 for(Length index = 0u; index < numberOfLaidOutGlyphs; ++index)
228 Vector2& position = *(glyphPositions + index);
229 position.x += line->alignmentOffset;
232 if(lastGlyphIndexOfLine == index)
234 penY += -line->descender + line->lineSpacing;
236 // Get the next line.
239 if(lineIndex < numberOfLines)
241 line = lineBuffer + lineIndex;
242 minLineOffset = std::min(minLineOffset, line->alignmentOffset);
244 lastGlyphIndexOfLine = (line->isSplitToTwoHalves ? line->glyphRunSecondHalf.glyphIndex + line->glyphRunSecondHalf.numberOfGlyphs : line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs) - 1u;
246 penY += line->ascender;
251 // Set index where to set Ellipsis according to the selected position of Ellipsis.
252 // Start with this index to replace its glyph by Ellipsis, if the width is not enough, then remove more glyphs.
253 GlyphIndex startIndexOfEllipsis = 0u;
256 if(ellipsisPosition == DevelText::EllipsisPosition::START)
258 // It's the fisrt glyph in line.
259 startIndexOfEllipsis = ellipsisLine->glyphRun.glyphIndex;
261 else if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
263 // It's the second middle of the line in case the line split to two halves.
264 // Otherwise it's It's the last glyph in line (line before all removed lines).
265 startIndexOfEllipsis = ellipsisLine->isSplitToTwoHalves ? (ellipsisLine->glyphRunSecondHalf.glyphIndex) : (ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u);
267 else // DevelText::EllipsisPosition::END
269 // It's the last glyph in line.
270 startIndexOfEllipsis = ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u;
274 if(1u == numberOfLaidOutGlyphs)
276 // not a point try to do ellipsis with only one laid out character.
278 return numberOfLaidOutGlyphs;
283 const LineRun& elidedLine = *ellipsisLine;
285 if((1u == numberOfLines) &&
286 (GetLineHeight(elidedLine, true) > mImpl->mVisualModel->mControlSize.height))
288 // Replace the first glyph with ellipsis glyph
289 auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u;
291 // Regardless where the location of ellipsis,in-case the hight of line is greater than control's height
292 // then replace the first glyph with ellipsis glyph.
294 // Get the first glyph which is going to be replaced and the ellipsis glyph.
295 GlyphInfo& glyphInfo = *(glyphs + indexOfFirstGlyph);
296 const GlyphInfo& ellipsisGlyph = mImpl->mFontClient.GetEllipsisGlyph(mImpl->mFontClient.GetPointSize(glyphInfo.fontId));
298 // Change the 'x' and 'y' position of the ellipsis glyph.
299 Vector2& position = *(glyphPositions + indexOfFirstGlyph);
300 position.x = ellipsisGlyph.xBearing;
301 position.y = mImpl->mVisualModel->mControlSize.height - ellipsisGlyph.yBearing;
303 // Replace the glyph by the ellipsis glyph.
304 glyphInfo = ellipsisGlyph;
306 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(indexOfFirstGlyph);
307 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(indexOfFirstGlyph);
308 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(indexOfFirstGlyph);
309 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(indexOfFirstGlyph);
311 numberOfLaidOutGlyphs = 1u;
313 return numberOfLaidOutGlyphs;
316 // firstPenX, penY and firstPenSet are used to position the ellipsis glyph if needed.
317 float firstPenX = 0.f; // Used if rtl text is elided.
319 bool firstPenSet = false;
321 // Add the ellipsis glyph.
322 bool inserted = false;
323 float removedGlypsWidth = 0.f;
324 Length numberOfRemovedGlyphs = 0u;
325 GlyphIndex indexOfEllipsis = startIndexOfEllipsis;
327 // Tail Mode: start by the end of line.
328 const bool isTailMode = ellipsisPosition == DevelText::EllipsisPosition::END ||
329 (ellipsisPosition == DevelText::EllipsisPosition::MIDDLE && numberOfLines != 1u);
331 // The ellipsis glyph has to fit in the place where the last glyph(s) is(are) removed.
334 const GlyphInfo& glyphToRemove = *(glyphs + indexOfEllipsis);
336 if(0u != glyphToRemove.fontId)
338 // i.e. The font id of the glyph shaped from the '\n' character is zero.
340 // Need to reshape the glyph as the font may be different in size.
341 const GlyphInfo& ellipsisGlyph = mImpl->mFontClient.GetEllipsisGlyph(mImpl->mFontClient.GetPointSize(glyphToRemove.fontId));
345 const Vector2& position = *(glyphPositions + indexOfEllipsis);
347 // Calculates the penY of the current line. It will be used to position the ellipsis glyph.
348 penY = position.y + glyphToRemove.yBearing;
350 // Calculates the first penX which will be used if rtl text is elided.
351 firstPenX = position.x - glyphToRemove.xBearing;
352 if(firstPenX < -ellipsisGlyph.xBearing)
354 // Avoids to exceed the bounding box when rtl text is elided.
355 firstPenX = -ellipsisGlyph.xBearing;
358 removedGlypsWidth = -ellipsisGlyph.xBearing;
363 const float characterSpacing = GetGlyphCharacterSpacing(indexOfEllipsis, characterSpacingGlyphRuns, modelCharacterSpacing);
364 calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + indexOfEllipsis))), characterSpacing, glyphToRemove.advance);
365 removedGlypsWidth += std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width));
367 // Calculate the width of the ellipsis glyph and check if it fits.
368 const float ellipsisGlyphWidth = ellipsisGlyph.width + ellipsisGlyph.xBearing;
369 if((ellipsisGlyphWidth < removedGlypsWidth) || (isTailMode ? (indexOfEllipsis == 0u) : (indexOfEllipsis == numberOfGlyphs - 1u)))
371 GlyphInfo& glyphInfo = *(glyphs + indexOfEllipsis);
372 Vector2& position = *(glyphPositions + indexOfEllipsis);
373 position.x -= (0.f > glyphInfo.xBearing) ? glyphInfo.xBearing : 0.f;
375 // Replace the glyph by the ellipsis glyph.
376 glyphInfo = ellipsisGlyph;
378 // Change the 'x' and 'y' position of the ellipsis glyph.
380 if(position.x > firstPenX)
382 position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth;
385 position.x += ellipsisGlyph.xBearing;
386 position.y = penY - ellipsisGlyph.yBearing;
394 if(isTailMode && indexOfEllipsis > 0u)
396 // Tail Mode: remove glyphs from startIndexOfEllipsis then decrement indexOfEllipsis, until arrive to index zero.
399 else if(!isTailMode && indexOfEllipsis < numberOfLaidOutGlyphs - 1u)
401 // Not Tail Mode: remove glyphs from startIndexOfEllipsis then increase indexOfEllipsis, until arrive to last index (numberOfGlyphs - 1u).
406 // No space for the ellipsis.
409 ++numberOfRemovedGlyphs;
413 // 'Removes' all the glyphs after the ellipsis glyph.
414 if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
416 //Reduce size, shift glyphs and start from ellipsis glyph
417 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
419 GlyphIndex firstMiddleIndexOfElidedGlyphs = 0u;
420 GlyphIndex secondMiddleIndexOfElidedGlyphs = 0u;
422 bool isOnlySecondHalf = false;
425 // Multi-lines case with MIDDLE
426 // In case the Ellipsis in the end of line,
427 // then this index will be the firstMiddleIndex.
428 // The secondMiddleIndex will be the fisrt index in next line.
429 // But in case there is no line after Ellipsis's line then secondMiddleIndex and endIndex equal firstMiddle
431 // A: are laid out glyphs in line has Ellipsis in the end.
432 // N: are laid out glyphs in lines after removed lines.
433 // R: are removed glyphs.
434 // L: are removed glyphs when removed lines.
435 // AAAAAAAAAAAA...RRR => Here's the firstMiddleIndex (First index after last A)
438 // NNNNNNNNNNNNNN => Here's the secondMiddleIndex (First N)
441 firstMiddleIndexOfElidedGlyphs = indexOfEllipsis;
442 if(ellipsisNextLine != nullptr)
444 secondMiddleIndexOfElidedGlyphs = ellipsisNextLine->glyphRun.glyphIndex;
448 secondMiddleIndexOfElidedGlyphs = firstMiddleIndexOfElidedGlyphs;
449 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(firstMiddleIndexOfElidedGlyphs);
454 // Single line case with MIDDLE
455 // In case the Ellipsis in the middle of line,
456 // Then the last index in first half will be firstMiddleIndex.
457 // And the indexOfEllipsis will be secondMiddleIndex, which is the first index in second half.
459 // A: are laid out glyphs in first half of line.
460 // N: are laid out glyphs in second half of line.
461 // R: are removed glyphs.
462 // L: re removed glyphs when layouting text
463 // AAAAAAALLLLLLLLLLLRRR...NNNNN
464 // firstMiddleIndex (index of last A)
465 // secondMiddleIndex (index before first N)
467 firstMiddleIndexOfElidedGlyphs = (ellipsisLine->glyphRun.numberOfGlyphs > 0u) ? (ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u) : (ellipsisLine->glyphRun.glyphIndex);
468 secondMiddleIndexOfElidedGlyphs = indexOfEllipsis;
469 isOnlySecondHalf = ellipsisLine->glyphRun.numberOfGlyphs == 0u && ellipsisLine->glyphRunSecondHalf.numberOfGlyphs > 0u;
472 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(firstMiddleIndexOfElidedGlyphs);
473 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(secondMiddleIndexOfElidedGlyphs);
475 // The number of shifted glyphs and shifting positions will be different according to Single-line or Multi-lines.
476 // isOnlySecondHalf will be true when MIDDLE Ellipsis glyph in single line.
479 Length numberOfSecondHalfGlyphs = numberOfLaidOutGlyphs - firstMiddleIndexOfElidedGlyphs;
481 //Copy elided glyphs after the ellipsis glyph.
482 memcpy(glyphs + firstMiddleIndexOfElidedGlyphs, glyphs + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(GlyphInfo));
483 memcpy(glyphPositions + firstMiddleIndexOfElidedGlyphs, glyphPositions + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(Vector2));
487 Length numberOfSecondHalfGlyphs = numberOfLaidOutGlyphs - firstMiddleIndexOfElidedGlyphs + 1u;
489 //Copy elided glyphs after the ellipsis glyph.
490 memcpy(glyphs + firstMiddleIndexOfElidedGlyphs + 1u, glyphs + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(GlyphInfo));
491 memcpy(glyphPositions + firstMiddleIndexOfElidedGlyphs + 1u, glyphPositions + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(Vector2));
494 else if(ellipsisPosition == DevelText::EllipsisPosition::START)
496 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
497 //Copy elided glyphs after the ellipsis glyph.
498 memcpy(glyphs, glyphs + startIndexOfEllipsis + numberOfRemovedGlyphs, numberOfLaidOutGlyphs * sizeof(GlyphInfo));
499 memcpy(glyphPositions, glyphPositions + startIndexOfEllipsis + numberOfRemovedGlyphs, numberOfLaidOutGlyphs * sizeof(Vector2));
500 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(indexOfEllipsis);
502 else // DevelText::EllipsisPosition::END
504 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
505 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(indexOfEllipsis);
512 return numberOfLaidOutGlyphs;
515 const Vector4* const View::GetColors() const
517 if(mImpl->mVisualModel)
519 return mImpl->mVisualModel->mColors.Begin();
525 const ColorIndex* const View::GetColorIndices() const
527 if(mImpl->mVisualModel)
529 return mImpl->mVisualModel->mColorIndices.Begin();
535 const Vector4* const View::GetBackgroundColors() const
537 if(mImpl->mVisualModel)
539 return mImpl->mVisualModel->mBackgroundColors.Begin();
545 const ColorIndex* const View::GetBackgroundColorIndices() const
547 if(mImpl->mVisualModel)
549 return mImpl->mVisualModel->mBackgroundColorIndices.Begin();
555 bool const View::IsMarkupBackgroundColorSet() const
557 if(mImpl->mVisualModel)
559 return (mImpl->mVisualModel->mBackgroundColors.Count() > 0);
565 const Vector4& View::GetTextColor() const
567 if(mImpl->mVisualModel)
569 return mImpl->mVisualModel->GetTextColor();
571 return Vector4::ZERO;
574 const Vector2& View::GetShadowOffset() const
576 if(mImpl->mVisualModel)
578 return mImpl->mVisualModel->GetShadowOffset();
580 return Vector2::ZERO;
583 const Vector4& View::GetShadowColor() const
585 if(mImpl->mVisualModel)
587 return mImpl->mVisualModel->GetShadowColor();
589 return Vector4::ZERO;
592 const Vector4& View::GetUnderlineColor() const
594 if(mImpl->mVisualModel)
596 return mImpl->mVisualModel->GetUnderlineColor();
598 return Vector4::ZERO;
601 bool View::IsUnderlineEnabled() const
603 if(mImpl->mVisualModel)
605 return mImpl->mVisualModel->IsUnderlineEnabled();
610 const GlyphInfo* View::GetHyphens() const
612 if(mImpl->mVisualModel)
614 return mImpl->mVisualModel->mHyphen.glyph.Begin();
620 const Length* View::GetHyphenIndices() const
622 if(mImpl->mVisualModel)
624 return mImpl->mVisualModel->mHyphen.index.Begin();
630 Length View::GetHyphensCount() const
632 if(mImpl->mVisualModel)
634 return mImpl->mVisualModel->mHyphen.glyph.Size();
639 float View::GetUnderlineHeight() const
641 if(mImpl->mVisualModel)
643 return mImpl->mVisualModel->GetUnderlineHeight();
648 Text::Underline::Type View::GetUnderlineType() const
650 Text::Underline::Type type = Text::Underline::Type::SOLID;
651 if(mImpl->mVisualModel)
653 type = mImpl->mVisualModel->GetUnderlineType();
658 float View::GetDashedUnderlineWidth() const
661 if(mImpl->mVisualModel)
663 width = mImpl->mVisualModel->GetDashedUnderlineWidth();
668 float View::GetDashedUnderlineGap() const
671 if(mImpl->mVisualModel)
673 gap = mImpl->mVisualModel->GetDashedUnderlineGap();
678 Length View::GetNumberOfUnderlineRuns() const
680 if(mImpl->mVisualModel)
682 return mImpl->mVisualModel->GetNumberOfUnderlineRuns();
688 void View::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns,
689 UnderlineRunIndex index,
690 Length numberOfRuns) const
692 if(mImpl->mVisualModel)
694 mImpl->mVisualModel->GetUnderlineRuns(underlineRuns,
700 const Vector4& View::GetOutlineColor() const
702 if(mImpl->mVisualModel)
704 return mImpl->mVisualModel->GetOutlineColor();
706 return Vector4::ZERO;
709 uint16_t View::GetOutlineWidth() const
711 if(mImpl->mVisualModel)
713 return mImpl->mVisualModel->GetOutlineWidth();
718 DevelText::EllipsisPosition::Type View::GetEllipsisPosition() const
720 DevelText::EllipsisPosition::Type ellipsisPosition = DevelText::EllipsisPosition::END;
721 if(mImpl->mVisualModel)
723 const VisualModel& model = *mImpl->mVisualModel;
724 ellipsisPosition = model.GetEllipsisPosition();
727 return ellipsisPosition;
730 bool View::IsTextElideEnabled() const
732 bool isTextElideEnabled = false;
734 if(mImpl->mVisualModel)
736 const VisualModel& model = *mImpl->mVisualModel;
737 isTextElideEnabled = model.IsTextElideEnabled();
740 return isTextElideEnabled;
743 GlyphIndex View::GetStartIndexOfElidedGlyphs() const
745 GlyphIndex startIndexOfElidedGlyphs = 0u;
747 if(mImpl->mVisualModel)
749 const VisualModel& model = *mImpl->mVisualModel;
750 startIndexOfElidedGlyphs = model.GetStartIndexOfElidedGlyphs();
753 return startIndexOfElidedGlyphs;
756 GlyphIndex View::GetEndIndexOfElidedGlyphs() const
758 GlyphIndex endIndexOfElidedGlyphs = 0u;
760 if(mImpl->mVisualModel)
762 const VisualModel& model = *mImpl->mVisualModel;
763 endIndexOfElidedGlyphs = model.GetEndIndexOfElidedGlyphs();
766 return endIndexOfElidedGlyphs;
769 GlyphIndex View::GetFirstMiddleIndexOfElidedGlyphs() const
771 GlyphIndex firstMiddleIndexOfElidedGlyphs = 0u;
773 if(mImpl->mVisualModel)
775 const VisualModel& model = *mImpl->mVisualModel;
776 firstMiddleIndexOfElidedGlyphs = model.GetFirstMiddleIndexOfElidedGlyphs();
779 return firstMiddleIndexOfElidedGlyphs;
782 GlyphIndex View::GetSecondMiddleIndexOfElidedGlyphs() const
784 GlyphIndex secondMiddleIndexOfElidedGlyphs = 0u;
786 if(mImpl->mVisualModel)
788 const VisualModel& model = *mImpl->mVisualModel;
789 secondMiddleIndexOfElidedGlyphs = model.GetSecondMiddleIndexOfElidedGlyphs();
792 return secondMiddleIndexOfElidedGlyphs;
795 const Vector4& View::GetStrikethroughColor() const
797 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughColor() : Vector4::ZERO;
800 bool View::IsStrikethroughEnabled() const
802 return (mImpl->mVisualModel) ? mImpl->mVisualModel->IsStrikethroughEnabled() : false;
805 float View::GetStrikethroughHeight() const
807 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughHeight() : 0.0f;
810 Length View::GetNumberOfStrikethroughRuns() const
812 if(mImpl->mVisualModel)
814 return mImpl->mVisualModel->GetNumberOfStrikethroughRuns();
820 void View::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns,
821 StrikethroughRunIndex index,
822 Length numberOfRuns) const
824 if(mImpl->mVisualModel)
826 mImpl->mVisualModel->GetStrikethroughRuns(strikethroughRuns,
832 Length View::GetNumberOfBoundedParagraphRuns() const
834 if(mImpl->mLogicalModel)
836 return mImpl->mLogicalModel->GetNumberOfBoundedParagraphRuns();
842 const Vector<BoundedParagraphRun>& View::GetBoundedParagraphRuns() const
844 return mImpl->mLogicalModel->GetBoundedParagraphRuns();
847 Length View::GetNumberOfCharacterSpacingGlyphRuns() const
849 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetNumberOfCharacterSpacingGlyphRuns() : 0u;
852 const Vector<CharacterSpacingGlyphRun>& View::GetCharacterSpacingGlyphRuns() const
854 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacingGlyphRuns() : GetEmptyCharacterSpacingGlyphRuns();
857 const float View::GetCharacterSpacing() const
859 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacing() : 0.f;
862 const Character* View::GetTextBuffer() const
864 return (mImpl->mVisualModel) ? mImpl->mLogicalModel->mText.Begin() : nullptr;
867 const Vector<CharacterIndex>& View::GetGlyphsToCharacters() const
869 return mImpl->mVisualModel->GetGlyphsToCharacters();
874 } // namespace Toolkit